diff options
-rw-r--r-- | application/api/ApiUtils.php | 21 | ||||
-rw-r--r-- | application/api/controllers/Links.php | 12 | ||||
-rw-r--r-- | tests/api/controllers/links/PostLinkTest.php | 48 | ||||
-rw-r--r-- | tests/api/controllers/links/PutLinkTest.php | 48 |
4 files changed, 123 insertions, 6 deletions
diff --git a/application/api/ApiUtils.php b/application/api/ApiUtils.php index 05a2840a..9228bb2d 100644 --- a/application/api/ApiUtils.php +++ b/application/api/ApiUtils.php | |||
@@ -91,13 +91,17 @@ class ApiUtils | |||
91 | * If no URL is provided, it will generate a local note URL. | 91 | * If no URL is provided, it will generate a local note URL. |
92 | * If no title is provided, it will use the URL as title. | 92 | * If no title is provided, it will use the URL as title. |
93 | * | 93 | * |
94 | * @param array|null $input Request Link. | 94 | * @param array|null $input Request Link. |
95 | * @param bool $defaultPrivate Setting defined if a bookmark is private by default. | 95 | * @param bool $defaultPrivate Setting defined if a bookmark is private by default. |
96 | * @param string $tagsSeparator Tags separator loaded from the config file. | ||
96 | * | 97 | * |
97 | * @return Bookmark instance. | 98 | * @return Bookmark instance. |
98 | */ | 99 | */ |
99 | public static function buildBookmarkFromRequest(?array $input, bool $defaultPrivate): Bookmark | 100 | public static function buildBookmarkFromRequest( |
100 | { | 101 | ?array $input, |
102 | bool $defaultPrivate, | ||
103 | string $tagsSeparator | ||
104 | ): Bookmark { | ||
101 | $bookmark = new Bookmark(); | 105 | $bookmark = new Bookmark(); |
102 | $url = ! empty($input['url']) ? cleanup_url($input['url']) : ''; | 106 | $url = ! empty($input['url']) ? cleanup_url($input['url']) : ''; |
103 | if (isset($input['private'])) { | 107 | if (isset($input['private'])) { |
@@ -109,6 +113,15 @@ class ApiUtils | |||
109 | $bookmark->setTitle(! empty($input['title']) ? $input['title'] : ''); | 113 | $bookmark->setTitle(! empty($input['title']) ? $input['title'] : ''); |
110 | $bookmark->setUrl($url); | 114 | $bookmark->setUrl($url); |
111 | $bookmark->setDescription(! empty($input['description']) ? $input['description'] : ''); | 115 | $bookmark->setDescription(! empty($input['description']) ? $input['description'] : ''); |
116 | |||
117 | // Be permissive with provided tags format | ||
118 | if (is_string($input['tags'] ?? null)) { | ||
119 | $input['tags'] = tags_str2array($input['tags'], $tagsSeparator); | ||
120 | } | ||
121 | if (is_array($input['tags'] ?? null) && count($input['tags']) === 1 && is_string($input['tags'][0])) { | ||
122 | $input['tags'] = tags_str2array($input['tags'][0], $tagsSeparator); | ||
123 | } | ||
124 | |||
112 | $bookmark->setTags(! empty($input['tags']) ? $input['tags'] : []); | 125 | $bookmark->setTags(! empty($input['tags']) ? $input['tags'] : []); |
113 | $bookmark->setPrivate($private); | 126 | $bookmark->setPrivate($private); |
114 | 127 | ||
diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php index c379b962..b83b2260 100644 --- a/application/api/controllers/Links.php +++ b/application/api/controllers/Links.php | |||
@@ -117,7 +117,11 @@ class Links extends ApiController | |||
117 | public function postLink($request, $response) | 117 | public function postLink($request, $response) |
118 | { | 118 | { |
119 | $data = (array) ($request->getParsedBody() ?? []); | 119 | $data = (array) ($request->getParsedBody() ?? []); |
120 | $bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links')); | 120 | $bookmark = ApiUtils::buildBookmarkFromRequest( |
121 | $data, | ||
122 | $this->conf->get('privacy.default_private_links'), | ||
123 | $this->conf->get('general.tags_separator', ' ') | ||
124 | ); | ||
121 | // duplicate by URL, return 409 Conflict | 125 | // duplicate by URL, return 409 Conflict |
122 | if ( | 126 | if ( |
123 | ! empty($bookmark->getUrl()) | 127 | ! empty($bookmark->getUrl()) |
@@ -158,7 +162,11 @@ class Links extends ApiController | |||
158 | $index = index_url($this->ci['environment']); | 162 | $index = index_url($this->ci['environment']); |
159 | $data = $request->getParsedBody(); | 163 | $data = $request->getParsedBody(); |
160 | 164 | ||
161 | $requestBookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links')); | 165 | $requestBookmark = ApiUtils::buildBookmarkFromRequest( |
166 | $data, | ||
167 | $this->conf->get('privacy.default_private_links'), | ||
168 | $this->conf->get('general.tags_separator', ' ') | ||
169 | ); | ||
162 | // duplicate URL on a different link, return 409 Conflict | 170 | // duplicate URL on a different link, return 409 Conflict |
163 | if ( | 171 | if ( |
164 | ! empty($requestBookmark->getUrl()) | 172 | ! empty($requestBookmark->getUrl()) |
diff --git a/tests/api/controllers/links/PostLinkTest.php b/tests/api/controllers/links/PostLinkTest.php index e12f803b..f755e2d2 100644 --- a/tests/api/controllers/links/PostLinkTest.php +++ b/tests/api/controllers/links/PostLinkTest.php | |||
@@ -229,4 +229,52 @@ class PostLinkTest extends TestCase | |||
229 | \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) | 229 | \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']) |
230 | ); | 230 | ); |
231 | } | 231 | } |
232 | |||
233 | /** | ||
234 | * Test link creation with a tag string provided | ||
235 | */ | ||
236 | public function testPostLinkWithTagString(): void | ||
237 | { | ||
238 | $link = [ | ||
239 | 'tags' => 'one two', | ||
240 | ]; | ||
241 | $env = Environment::mock([ | ||
242 | 'REQUEST_METHOD' => 'POST', | ||
243 | 'CONTENT_TYPE' => 'application/json' | ||
244 | ]); | ||
245 | |||
246 | $request = Request::createFromEnvironment($env); | ||
247 | $request = $request->withParsedBody($link); | ||
248 | $response = $this->controller->postLink($request, new Response()); | ||
249 | |||
250 | $this->assertEquals(201, $response->getStatusCode()); | ||
251 | $this->assertEquals('/api/v1/bookmarks/1', $response->getHeader('Location')[0]); | ||
252 | $data = json_decode((string) $response->getBody(), true); | ||
253 | $this->assertEquals(self::NB_FIELDS_LINK, count($data)); | ||
254 | $this->assertEquals(['one', 'two'], $data['tags']); | ||
255 | } | ||
256 | |||
257 | /** | ||
258 | * Test link creation with a tag string provided | ||
259 | */ | ||
260 | public function testPostLinkWithTagString2(): void | ||
261 | { | ||
262 | $link = [ | ||
263 | 'tags' => ['one two'], | ||
264 | ]; | ||
265 | $env = Environment::mock([ | ||
266 | 'REQUEST_METHOD' => 'POST', | ||
267 | 'CONTENT_TYPE' => 'application/json' | ||
268 | ]); | ||
269 | |||
270 | $request = Request::createFromEnvironment($env); | ||
271 | $request = $request->withParsedBody($link); | ||
272 | $response = $this->controller->postLink($request, new Response()); | ||
273 | |||
274 | $this->assertEquals(201, $response->getStatusCode()); | ||
275 | $this->assertEquals('/api/v1/bookmarks/1', $response->getHeader('Location')[0]); | ||
276 | $data = json_decode((string) $response->getBody(), true); | ||
277 | $this->assertEquals(self::NB_FIELDS_LINK, count($data)); | ||
278 | $this->assertEquals(['one', 'two'], $data['tags']); | ||
279 | } | ||
232 | } | 280 | } |
diff --git a/tests/api/controllers/links/PutLinkTest.php b/tests/api/controllers/links/PutLinkTest.php index 240ee323..fe24f2eb 100644 --- a/tests/api/controllers/links/PutLinkTest.php +++ b/tests/api/controllers/links/PutLinkTest.php | |||
@@ -233,4 +233,52 @@ class PutLinkTest extends \Shaarli\TestCase | |||
233 | 233 | ||
234 | $this->controller->putLink($request, new Response(), ['id' => -1]); | 234 | $this->controller->putLink($request, new Response(), ['id' => -1]); |
235 | } | 235 | } |
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 | } | ||
236 | } | 284 | } |