3 namespace Shaarli\Api\Controllers
;
6 use Shaarli\Config\ConfigManager
;
8 use Slim\Http\Environment
;
10 use Slim\Http\Response
;
15 * Test POST Link REST API service.
17 * @package Shaarli\Api\Controllers
19 class PostLinkTest
extends \PHPUnit_Framework_TestCase
22 * @var string datastore to test write operations
24 protected static $testDatastore = 'sandbox/datastore.php';
27 * @var ConfigManager instance
32 * @var \ReferenceLinkDB instance.
34 protected $refDB = null;
37 * @var Container instance.
42 * @var Links controller instance.
44 protected $controller;
47 * Number of JSON field per link.
49 const NB_FIELDS_LINK
= 9;
52 * Before every test, instantiate a new Api with its config, plugins and links.
54 public function setUp()
56 $this->conf
= new ConfigManager('tests/utils/config/configJson.json.php');
57 $this->refDB
= new \
ReferenceLinkDB();
58 $this->refDB
->write(self
::$testDatastore);
60 $this->container
= new Container();
61 $this->container
['conf'] = $this->conf
;
62 $this->container
['db'] = new \
LinkDB(self
::$testDatastore, true, false);
64 $this->controller
= new Links($this->container
);
66 $mock = $this->getMock('\Slim\Router', ['relativePathFor']);
67 $mock->expects($this->any())
68 ->method('relativePathFor')
69 ->willReturn('api/v1/links/1');
71 // affect @property-read... seems to work
72 $this->controller
->getCi()->router
= $mock;
74 // Used by index_url().
75 $this->controller
->getCi()['environment'] = [
76 'SERVER_NAME' => 'domain.tld',
83 * After every test, remove the test datastore.
85 public function tearDown()
87 @unlink(self
::$testDatastore);
91 * Test link creation without any field: creates a blank note.
93 public function testPostLinkMinimal()
95 $env = Environment
::mock([
96 'REQUEST_METHOD' => 'POST',
99 $request = Request
::createFromEnvironment($env);
101 $response = $this->controller
->postLink($request, new Response());
102 $this->assertEquals(201, $response->getStatusCode());
103 $this->assertEquals('api/v1/links/1', $response->getHeader('Location')[0]);
104 $data = json_decode((string) $response->getBody(), true);
105 $this->assertEquals(self
::NB_FIELDS_LINK
, count($data));
106 $this->assertEquals(43, $data['id']);
107 $this->assertRegExp('/[\w-_]{6}/', $data['shorturl']);
108 $this->assertEquals('http://domain.tld/?' . $data['shorturl'], $data['url']);
109 $this->assertEquals('?' . $data['shorturl'], $data['title']);
110 $this->assertEquals('', $data['description']);
111 $this->assertEquals([], $data['tags']);
112 $this->assertEquals(false, $data['private']);
113 $this->assertTrue(new \
DateTime('5 seconds ago') < \DateTime
::createFromFormat(\DateTime
::ATOM
, $data['created']));
114 $this->assertEquals('', $data['updated']);
118 * Test link creation with all available fields.
120 public function testPostLinkFull()
123 'url' => 'website.tld/test?foo=bar',
124 'title' => 'new entry',
125 'description' => 'shaare description',
126 'tags' => ['one', 'two'],
129 $env = Environment
::mock([
130 'REQUEST_METHOD' => 'POST',
131 'CONTENT_TYPE' => 'application/json'
134 $request = Request
::createFromEnvironment($env);
135 $request = $request->withParsedBody($link);
136 $response = $this->controller
->postLink($request, new Response());
138 $this->assertEquals(201, $response->getStatusCode());
139 $this->assertEquals('api/v1/links/1', $response->getHeader('Location')[0]);
140 $data = json_decode((string) $response->getBody(), true);
141 $this->assertEquals(self
::NB_FIELDS_LINK
, count($data));
142 $this->assertEquals(43, $data['id']);
143 $this->assertRegExp('/[\w-_]{6}/', $data['shorturl']);
144 $this->assertEquals('http://' . $link['url'], $data['url']);
145 $this->assertEquals($link['title'], $data['title']);
146 $this->assertEquals($link['description'], $data['description']);
147 $this->assertEquals($link['tags'], $data['tags']);
148 $this->assertEquals(true, $data['private']);
149 $this->assertTrue(new \
DateTime('2 seconds ago') < \DateTime
::createFromFormat(\DateTime
::ATOM
, $data['created']));
150 $this->assertEquals('', $data['updated']);
154 * Test link creation with an existing link (duplicate URL). Should return a 409 HTTP error and the existing link.
156 public function testPostLinkDuplicate()
159 'url' => 'mediagoblin.org/',
160 'title' => 'new entry',
161 'description' => 'shaare description',
162 'tags' => ['one', 'two'],
165 $env = Environment
::mock([
166 'REQUEST_METHOD' => 'POST',
167 'CONTENT_TYPE' => 'application/json'
170 $request = Request
::createFromEnvironment($env);
171 $request = $request->withParsedBody($link);
172 $response = $this->controller
->postLink($request, new Response());
174 $this->assertEquals(409, $response->getStatusCode());
175 $data = json_decode((string) $response->getBody(), true);
176 $this->assertEquals(self
::NB_FIELDS_LINK
, count($data));
177 $this->assertEquals(7, $data['id']);
178 $this->assertEquals('IuWvgA', $data['shorturl']);
179 $this->assertEquals('http://mediagoblin.org/', $data['url']);
180 $this->assertEquals('MediaGoblin', $data['title']);
181 $this->assertEquals('A free software media publishing platform #hashtagOther', $data['description']);
182 $this->assertEquals(['gnu', 'media', 'web', '.hidden', 'hashtag'], $data['tags']);
183 $this->assertEquals(false, $data['private']);
185 \DateTime
::createFromFormat(\LinkDB
::LINK_DATE_FORMAT
, '20130614_184135'),
186 \DateTime
::createFromFormat(\DateTime
::ATOM
, $data['created'])
189 \DateTime
::createFromFormat(\LinkDB
::LINK_DATE_FORMAT
, '20130615_184230'),
190 \DateTime
::createFromFormat(\DateTime
::ATOM
, $data['updated'])