]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - tests/api/controllers/tags/PutTagTest.php
New plugin hook: ability to add custom filters to Shaarli search engine
[github/shaarli/Shaarli.git] / tests / api / controllers / tags / PutTagTest.php
1 <?php
2
3 namespace Shaarli\Api\Controllers;
4
5 use malkusch\lock\mutex\NoMutex;
6 use Shaarli\Api\Exceptions\ApiBadParametersException;
7 use Shaarli\Bookmark\BookmarkFileService;
8 use Shaarli\Bookmark\LinkDB;
9 use Shaarli\Config\ConfigManager;
10 use Shaarli\History;
11 use Shaarli\Plugin\PluginManager;
12 use Slim\Container;
13 use Slim\Http\Environment;
14 use Slim\Http\Request;
15 use Slim\Http\Response;
16
17 class PutTagTest extends \Shaarli\TestCase
18 {
19 /**
20 * @var string datastore to test write operations
21 */
22 protected static $testDatastore = 'sandbox/datastore.php';
23
24 /**
25 * @var string datastore to test write operations
26 */
27 protected static $testHistory = 'sandbox/history.php';
28
29 /**
30 * @var ConfigManager instance
31 */
32 protected $conf;
33
34 /**
35 * @var \ReferenceLinkDB instance.
36 */
37 protected $refDB = null;
38
39 /**
40 * @var HistoryController instance.
41 */
42 protected $history;
43
44 /**
45 * @var Container instance.
46 */
47 protected $container;
48
49 /**
50 * @var BookmarkFileService instance.
51 */
52 protected $bookmarkService;
53
54 /**
55 * @var Tags controller instance.
56 */
57 protected $controller;
58
59 /** @var PluginManager */
60 protected $pluginManager;
61
62 /**
63 * Number of JSON field per link.
64 */
65 const NB_FIELDS_TAG = 2;
66
67 /**
68 * Before every test, instantiate a new Api with its config, plugins and bookmarks.
69 */
70 protected function setUp(): void
71 {
72 $mutex = new NoMutex();
73 $this->conf = new ConfigManager('tests/utils/config/configJson');
74 $this->conf->set('resource.datastore', self::$testDatastore);
75 $this->refDB = new \ReferenceLinkDB();
76 $this->refDB->write(self::$testDatastore);
77 $refHistory = new \ReferenceHistory();
78 $refHistory->write(self::$testHistory);
79 $this->history = new History(self::$testHistory);
80 $this->pluginManager = new PluginManager($this->conf);
81 $this->bookmarkService = new BookmarkFileService(
82 $this->conf,
83 $this->pluginManager,
84 $this->history,
85 $mutex,
86 true
87 );
88
89 $this->container = new Container();
90 $this->container['conf'] = $this->conf;
91 $this->container['db'] = $this->bookmarkService;
92 $this->container['history'] = $this->history;
93
94 $this->controller = new Tags($this->container);
95 }
96
97 /**
98 * After every test, remove the test datastore.
99 */
100 protected function tearDown(): void
101 {
102 @unlink(self::$testDatastore);
103 @unlink(self::$testHistory);
104 }
105
106 /**
107 * Test tags update
108 */
109 public function testPutLinkValid()
110 {
111 $env = Environment::mock([
112 'REQUEST_METHOD' => 'PUT',
113 ]);
114 $tagName = 'gnu';
115 $update = ['name' => $newName = 'newtag'];
116 $request = Request::createFromEnvironment($env);
117 $request = $request->withParsedBody($update);
118
119 $response = $this->controller->putTag($request, new Response(), ['tagName' => $tagName]);
120 $this->assertEquals(200, $response->getStatusCode());
121 $data = json_decode((string) $response->getBody(), true);
122 $this->assertEquals(self::NB_FIELDS_TAG, count($data));
123 $this->assertEquals($newName, $data['name']);
124 $this->assertEquals(2, $data['occurrences']);
125
126 $tags = $this->bookmarkService->bookmarksCountPerTag();
127 $this->assertNotTrue(isset($tags[$tagName]));
128 $this->assertEquals(2, $tags[$newName]);
129
130 $historyEntry = $this->history->getHistory()[0];
131 $this->assertEquals(History::UPDATED, $historyEntry['event']);
132 $this->assertTrue(
133 (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime']
134 );
135 $historyEntry = $this->history->getHistory()[1];
136 $this->assertEquals(History::UPDATED, $historyEntry['event']);
137 $this->assertTrue(
138 (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime']
139 );
140 }
141
142 /**
143 * Test tag update with an existing tag: they should be merged
144 */
145 public function testPutTagMerge()
146 {
147 $tagName = 'gnu';
148 $newName = 'w3c';
149
150 $tags = $this->bookmarkService->bookmarksCountPerTag();
151 $this->assertEquals(1, $tags[$newName]);
152 $this->assertEquals(2, $tags[$tagName]);
153
154 $env = Environment::mock([
155 'REQUEST_METHOD' => 'PUT',
156 ]);
157 $update = ['name' => $newName];
158 $request = Request::createFromEnvironment($env);
159 $request = $request->withParsedBody($update);
160
161 $response = $this->controller->putTag($request, new Response(), ['tagName' => $tagName]);
162 $this->assertEquals(200, $response->getStatusCode());
163 $data = json_decode((string) $response->getBody(), true);
164 $this->assertEquals(self::NB_FIELDS_TAG, count($data));
165 $this->assertEquals($newName, $data['name']);
166 $this->assertEquals(3, $data['occurrences']);
167
168 $tags = $this->bookmarkService->bookmarksCountPerTag();
169 $this->assertNotTrue(isset($tags[$tagName]));
170 $this->assertEquals(3, $tags[$newName]);
171 }
172
173 /**
174 * Test tag update with an empty new tag name => ApiBadParametersException
175 */
176 public function testPutTagEmpty()
177 {
178 $this->expectException(\Shaarli\Api\Exceptions\ApiBadParametersException::class);
179 $this->expectExceptionMessage('New tag name is required in the request body');
180
181 $tagName = 'gnu';
182 $newName = '';
183
184 $tags = $this->bookmarkService->bookmarksCountPerTag();
185 $this->assertEquals(2, $tags[$tagName]);
186
187 $env = Environment::mock([
188 'REQUEST_METHOD' => 'PUT',
189 ]);
190 $request = Request::createFromEnvironment($env);
191
192 $env = Environment::mock([
193 'REQUEST_METHOD' => 'PUT',
194 ]);
195 $update = ['name' => $newName];
196 $request = Request::createFromEnvironment($env);
197 $request = $request->withParsedBody($update);
198
199 try {
200 $this->controller->putTag($request, new Response(), ['tagName' => $tagName]);
201 } catch (ApiBadParametersException $e) {
202 $tags = $this->bookmarkService->bookmarksCountPerTag();
203 $this->assertEquals(2, $tags[$tagName]);
204 throw $e;
205 }
206 }
207
208 /**
209 * Test tag update on non existent tag => ApiTagNotFoundException.
210 */
211 public function testPutTag404()
212 {
213 $this->expectException(\Shaarli\Api\Exceptions\ApiTagNotFoundException::class);
214 $this->expectExceptionMessage('Tag not found');
215
216 $env = Environment::mock([
217 'REQUEST_METHOD' => 'PUT',
218 ]);
219 $request = Request::createFromEnvironment($env);
220
221 $this->controller->putTag($request, new Response(), ['tagName' => 'nopenope']);
222 }
223 }