]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/api/controllers/links/PutLinkTest.php
Merge pull request #1698 from ArthurHoaro/feature/plugins-search-filter
[github/shaarli/Shaarli.git] / tests / api / controllers / links / PutLinkTest.php
CommitLineData
cf9181dd
A
1<?php
2
3
4namespace Shaarli\Api\Controllers;
5
fd1ddad9 6use malkusch\lock\mutex\NoMutex;
e26e2060
A
7use Shaarli\Bookmark\Bookmark;
8use Shaarli\Bookmark\BookmarkFileService;
cf9181dd 9use Shaarli\Config\ConfigManager;
dea72c71 10use Shaarli\History;
bcba6bd3 11use Shaarli\Plugin\PluginManager;
cf9181dd
A
12use Slim\Container;
13use Slim\Http\Environment;
14use Slim\Http\Request;
15use Slim\Http\Response;
16
a5a9cf23 17class PutLinkTest extends \Shaarli\TestCase
cf9181dd
A
18{
19 /**
20 * @var string datastore to test write operations
21 */
22 protected static $testDatastore = 'sandbox/datastore.php';
23
813849e5
A
24 /**
25 * @var string datastore to test write operations
26 */
27 protected static $testHistory = 'sandbox/history.php';
28
cf9181dd
A
29 /**
30 * @var ConfigManager instance
31 */
32 protected $conf;
33
34 /**
35 * @var \ReferenceLinkDB instance.
36 */
37 protected $refDB = null;
38
e26e2060
A
39 /**
40 * @var BookmarkFileService instance.
41 */
42 protected $bookmarkService;
43
813849e5 44 /**
dea72c71 45 * @var HistoryController instance.
813849e5
A
46 */
47 protected $history;
48
cf9181dd
A
49 /**
50 * @var Container instance.
51 */
52 protected $container;
53
54 /**
55 * @var Links controller instance.
56 */
57 protected $controller;
58
59 /**
60 * Number of JSON field per link.
61 */
62 const NB_FIELDS_LINK = 9;
63
64 /**
e26e2060 65 * Before every test, instantiate a new Api with its config, plugins and bookmarks.
cf9181dd 66 */
8f60e120 67 protected function setUp(): void
cf9181dd 68 {
fd1ddad9 69 $mutex = new NoMutex();
e26e2060
A
70 $this->conf = new ConfigManager('tests/utils/config/configJson');
71 $this->conf->set('resource.datastore', self::$testDatastore);
cf9181dd
A
72 $this->refDB = new \ReferenceLinkDB();
73 $this->refDB->write(self::$testDatastore);
813849e5
A
74 $refHistory = new \ReferenceHistory();
75 $refHistory->write(self::$testHistory);
dea72c71 76 $this->history = new History(self::$testHistory);
bcba6bd3
A
77 $pluginManager = new PluginManager($this->conf);
78 $this->bookmarkService = new BookmarkFileService(
79 $this->conf,
80 $pluginManager,
81 $this->history,
82 $mutex,
83 true
84 );
cf9181dd
A
85 $this->container = new Container();
86 $this->container['conf'] = $this->conf;
e26e2060
A
87 $this->container['db'] = $this->bookmarkService;
88 $this->container['history'] = $this->history;
cf9181dd
A
89
90 $this->controller = new Links($this->container);
91
92 // Used by index_url().
93 $this->controller->getCi()['environment'] = [
94 'SERVER_NAME' => 'domain.tld',
95 'SERVER_PORT' => 80,
96 'SCRIPT_NAME' => '/',
97 ];
98 }
99
100 /**
101 * After every test, remove the test datastore.
102 */
8f60e120 103 protected function tearDown(): void
cf9181dd
A
104 {
105 @unlink(self::$testDatastore);
813849e5 106 @unlink(self::$testHistory);
cf9181dd
A
107 }
108
109 /**
110 * Test link update without value: reset the link to default values
111 */
112 public function testPutLinkMinimal()
113 {
114 $env = Environment::mock([
115 'REQUEST_METHOD' => 'PUT',
116 ]);
117 $id = '41';
118 $request = Request::createFromEnvironment($env);
119
120 $response = $this->controller->putLink($request, new Response(), ['id' => $id]);
121 $this->assertEquals(200, $response->getStatusCode());
122 $data = json_decode((string) $response->getBody(), true);
123 $this->assertEquals(self::NB_FIELDS_LINK, count($data));
124 $this->assertEquals($id, $data['id']);
125 $this->assertEquals('WDWyig', $data['shorturl']);
301c7ab1
A
126 $this->assertEquals('http://domain.tld/shaare/WDWyig', $data['url']);
127 $this->assertEquals('/shaare/WDWyig', $data['title']);
cf9181dd
A
128 $this->assertEquals('', $data['description']);
129 $this->assertEquals([], $data['tags']);
e26e2060 130 $this->assertEquals(true, $data['private']);
cf9181dd
A
131 $this->assertEquals(
132 \DateTime::createFromFormat('Ymd_His', '20150310_114651'),
133 \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])
134 );
9d9f6d75
V
135 $this->assertTrue(
136 new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])
137 );
813849e5
A
138
139 $historyEntry = $this->history->getHistory()[0];
dea72c71 140 $this->assertEquals(History::UPDATED, $historyEntry['event']);
813849e5
A
141 $this->assertTrue(
142 (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime']
143 );
144 $this->assertEquals($id, $historyEntry['id']);
cf9181dd
A
145 }
146
147 /**
148 * Test link update with new values
149 */
150 public function testPutLinkWithValues()
151 {
152 $env = Environment::mock([
153 'REQUEST_METHOD' => 'PUT',
154 'CONTENT_TYPE' => 'application/json'
155 ]);
156 $id = 41;
157 $update = [
158 'url' => 'http://somewhere.else',
159 'title' => 'Le Cid',
160 'description' => 'Percé jusques au fond du cœur [...]',
161 'tags' => ['corneille', 'rodrigue'],
162 'private' => true,
163 ];
164 $request = Request::createFromEnvironment($env);
165 $request = $request->withParsedBody($update);
166
167 $response = $this->controller->putLink($request, new Response(), ['id' => $id]);
168 $this->assertEquals(200, $response->getStatusCode());
169 $data = json_decode((string) $response->getBody(), true);
170 $this->assertEquals(self::NB_FIELDS_LINK, count($data));
171 $this->assertEquals($id, $data['id']);
172 $this->assertEquals('WDWyig', $data['shorturl']);
173 $this->assertEquals('http://somewhere.else', $data['url']);
174 $this->assertEquals('Le Cid', $data['title']);
175 $this->assertEquals('Percé jusques au fond du cœur [...]', $data['description']);
176 $this->assertEquals(['corneille', 'rodrigue'], $data['tags']);
177 $this->assertEquals(true, $data['private']);
178 $this->assertEquals(
179 \DateTime::createFromFormat('Ymd_His', '20150310_114651'),
180 \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])
181 );
9d9f6d75
V
182 $this->assertTrue(
183 new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])
184 );
cf9181dd
A
185 }
186
187 /**
188 * Test link update with an existing URL: 409 Conflict with the existing link as body
189 */
190 public function testPutLinkDuplicate()
191 {
192 $link = [
193 'url' => 'mediagoblin.org/',
194 'title' => 'new entry',
195 'description' => 'shaare description',
196 'tags' => ['one', 'two'],
197 'private' => true,
198 ];
199 $env = Environment::mock([
200 'REQUEST_METHOD' => 'PUT',
201 'CONTENT_TYPE' => 'application/json'
202 ]);
203
204 $request = Request::createFromEnvironment($env);
205 $request = $request->withParsedBody($link);
206 $response = $this->controller->putLink($request, new Response(), ['id' => 41]);
207
208 $this->assertEquals(409, $response->getStatusCode());
209 $data = json_decode((string) $response->getBody(), true);
210 $this->assertEquals(self::NB_FIELDS_LINK, count($data));
211 $this->assertEquals(7, $data['id']);
212 $this->assertEquals('IuWvgA', $data['shorturl']);
213 $this->assertEquals('http://mediagoblin.org/', $data['url']);
214 $this->assertEquals('MediaGoblin', $data['title']);
215 $this->assertEquals('A free software media publishing platform #hashtagOther', $data['description']);
216 $this->assertEquals(['gnu', 'media', 'web', '.hidden', 'hashtag'], $data['tags']);
217 $this->assertEquals(false, $data['private']);
218 $this->assertEquals(
e26e2060 219 \DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20130614_184135'),
cf9181dd
A
220 \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])
221 );
222 $this->assertEquals(
e26e2060 223 \DateTime::createFromFormat(Bookmark::LINK_DATE_FORMAT, '20130615_184230'),
cf9181dd
A
224 \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])
225 );
226 }
227
228 /**
229 * Test link update on non existent link => ApiLinkNotFoundException.
cf9181dd
A
230 */
231 public function testGetLink404()
232 {
b1baca99
A
233 $this->expectException(\Shaarli\Api\Exceptions\ApiLinkNotFoundException::class);
234 $this->expectExceptionMessage('Link not found');
235
cf9181dd
A
236 $env = Environment::mock([
237 'REQUEST_METHOD' => 'PUT',
238 ]);
239 $request = Request::createFromEnvironment($env);
240
241 $this->controller->putLink($request, new Response(), ['id' => -1]);
242 }
0640c1a6
A
243
244 /**
245 * Test link creation with a tag string provided
246 */
247 public function testPutLinkWithTagString(): void
248 {
249 $link = [
250 'tags' => 'one two',
251 ];
252 $id = '41';
253 $env = Environment::mock([
254 'REQUEST_METHOD' => 'PUT',
255 'CONTENT_TYPE' => 'application/json'
256 ]);
257
258 $request = Request::createFromEnvironment($env);
259 $request = $request->withParsedBody($link);
260 $response = $this->controller->putLink($request, new Response(), ['id' => $id]);
261
262 $this->assertEquals(200, $response->getStatusCode());
263 $data = json_decode((string) $response->getBody(), true);
264 $this->assertEquals(self::NB_FIELDS_LINK, count($data));
265 $this->assertEquals(['one', 'two'], $data['tags']);
266 }
267
268 /**
269 * Test link creation with a tag string provided
270 */
271 public function testPutLinkWithTagString2(): void
272 {
273 $link = [
274 'tags' => ['one two'],
275 ];
276 $id = '41';
277 $env = Environment::mock([
278 'REQUEST_METHOD' => 'PUT',
279 'CONTENT_TYPE' => 'application/json'
280 ]);
281
282 $request = Request::createFromEnvironment($env);
283 $request = $request->withParsedBody($link);
284 $response = $this->controller->putLink($request, new Response(), ['id' => $id]);
285
286 $this->assertEquals(200, $response->getStatusCode());
287 $data = json_decode((string) $response->getBody(), true);
288 $this->assertEquals(self::NB_FIELDS_LINK, count($data));
289 $this->assertEquals(['one', 'two'], $data['tags']);
290 }
cf9181dd 291}