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