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