diff options
Diffstat (limited to 'src/Wallabag/AnnotationBundle')
10 files changed, 747 insertions, 0 deletions
diff --git a/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php new file mode 100644 index 00000000..5f981eb5 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Controller/WallabagAnnotationController.php | |||
@@ -0,0 +1,146 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\Controller; | ||
4 | |||
5 | use FOS\RestBundle\Controller\FOSRestController; | ||
6 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | ||
7 | use Symfony\Component\HttpFoundation\Request; | ||
8 | use Symfony\Component\HttpFoundation\Response; | ||
9 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; | ||
10 | use Wallabag\AnnotationBundle\Entity\Annotation; | ||
11 | use Wallabag\CoreBundle\Entity\Entry; | ||
12 | |||
13 | class WallabagAnnotationController extends FOSRestController | ||
14 | { | ||
15 | /** | ||
16 | * Retrieve annotations for an entry. | ||
17 | * | ||
18 | * @ApiDoc( | ||
19 | * requirements={ | ||
20 | * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} | ||
21 | * } | ||
22 | * ) | ||
23 | * | ||
24 | * @return Response | ||
25 | */ | ||
26 | public function getAnnotationsAction(Entry $entry) | ||
27 | { | ||
28 | $annotationRows = $this | ||
29 | ->getDoctrine() | ||
30 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
31 | ->findAnnotationsByPageId($entry->getId(), $this->getUser()->getId()); | ||
32 | $total = count($annotationRows); | ||
33 | $annotations = array('total' => $total, 'rows' => $annotationRows); | ||
34 | |||
35 | $json = $this->get('serializer')->serialize($annotations, 'json'); | ||
36 | |||
37 | return $this->renderJsonResponse($json); | ||
38 | } | ||
39 | |||
40 | /** | ||
41 | * Creates a new annotation. | ||
42 | * | ||
43 | * @param Entry $entry | ||
44 | * | ||
45 | * @ApiDoc( | ||
46 | * requirements={ | ||
47 | * {"name"="ranges", "dataType"="array", "requirement"="\w+", "description"="The range array for the annotation"}, | ||
48 | * {"name"="quote", "dataType"="string", "required"=false, "description"="Optional, quote for the annotation"}, | ||
49 | * {"name"="text", "dataType"="string", "required"=true, "description"=""}, | ||
50 | * } | ||
51 | * ) | ||
52 | * | ||
53 | * @return Response | ||
54 | */ | ||
55 | public function postAnnotationAction(Request $request, Entry $entry) | ||
56 | { | ||
57 | $data = json_decode($request->getContent(), true); | ||
58 | |||
59 | $em = $this->getDoctrine()->getManager(); | ||
60 | |||
61 | $annotation = new Annotation($this->getUser()); | ||
62 | |||
63 | $annotation->setText($data['text']); | ||
64 | if (array_key_exists('quote', $data)) { | ||
65 | $annotation->setQuote($data['quote']); | ||
66 | } | ||
67 | if (array_key_exists('ranges', $data)) { | ||
68 | $annotation->setRanges($data['ranges']); | ||
69 | } | ||
70 | |||
71 | $annotation->setEntry($entry); | ||
72 | |||
73 | $em->persist($annotation); | ||
74 | $em->flush(); | ||
75 | |||
76 | $json = $this->get('serializer')->serialize($annotation, 'json'); | ||
77 | |||
78 | return $this->renderJsonResponse($json); | ||
79 | } | ||
80 | |||
81 | /** | ||
82 | * Updates an annotation. | ||
83 | * | ||
84 | * @ApiDoc( | ||
85 | * requirements={ | ||
86 | * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} | ||
87 | * } | ||
88 | * ) | ||
89 | * | ||
90 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | ||
91 | * | ||
92 | * @return Response | ||
93 | */ | ||
94 | public function putAnnotationAction(Annotation $annotation, Request $request) | ||
95 | { | ||
96 | $data = json_decode($request->getContent(), true); | ||
97 | |||
98 | if (!is_null($data['text'])) { | ||
99 | $annotation->setText($data['text']); | ||
100 | } | ||
101 | |||
102 | $em = $this->getDoctrine()->getManager(); | ||
103 | $em->flush(); | ||
104 | |||
105 | $json = $this->get('serializer')->serialize($annotation, 'json'); | ||
106 | |||
107 | return $this->renderJsonResponse($json); | ||
108 | } | ||
109 | |||
110 | /** | ||
111 | * Removes an annotation. | ||
112 | * | ||
113 | * @ApiDoc( | ||
114 | * requirements={ | ||
115 | * {"name"="annotation", "dataType"="string", "requirement"="\w+", "description"="The annotation ID"} | ||
116 | * } | ||
117 | * ) | ||
118 | * | ||
119 | * @ParamConverter("annotation", class="WallabagAnnotationBundle:Annotation") | ||
120 | * | ||
121 | * @return Response | ||
122 | */ | ||
123 | public function deleteAnnotationAction(Annotation $annotation) | ||
124 | { | ||
125 | $em = $this->getDoctrine()->getManager(); | ||
126 | $em->remove($annotation); | ||
127 | $em->flush(); | ||
128 | |||
129 | $json = $this->get('serializer')->serialize($annotation, 'json'); | ||
130 | |||
131 | return $this->renderJsonResponse($json); | ||
132 | } | ||
133 | |||
134 | /** | ||
135 | * Send a JSON Response. | ||
136 | * We don't use the Symfony JsonRespone, because it takes an array as parameter instead of a JSON string. | ||
137 | * | ||
138 | * @param string $json | ||
139 | * | ||
140 | * @return Response | ||
141 | */ | ||
142 | private function renderJsonResponse($json, $code = 200) | ||
143 | { | ||
144 | return new Response($json, $code, array('application/json')); | ||
145 | } | ||
146 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/DataFixtures/ORM/LoadAnnotationData.php b/src/Wallabag/AnnotationBundle/DataFixtures/ORM/LoadAnnotationData.php new file mode 100644 index 00000000..20e07fa3 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/DataFixtures/ORM/LoadAnnotationData.php | |||
@@ -0,0 +1,45 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\DataFixtures\ORM; | ||
4 | |||
5 | use Doctrine\Common\DataFixtures\AbstractFixture; | ||
6 | use Doctrine\Common\DataFixtures\OrderedFixtureInterface; | ||
7 | use Doctrine\Common\Persistence\ObjectManager; | ||
8 | use Wallabag\AnnotationBundle\Entity\Annotation; | ||
9 | |||
10 | class LoadAnnotationData extends AbstractFixture implements OrderedFixtureInterface | ||
11 | { | ||
12 | /** | ||
13 | * {@inheritdoc} | ||
14 | */ | ||
15 | public function load(ObjectManager $manager) | ||
16 | { | ||
17 | $annotation1 = new Annotation($this->getReference('admin-user')); | ||
18 | $annotation1->setEntry($this->getReference('entry1')); | ||
19 | $annotation1->setText('This is my annotation /o/'); | ||
20 | $annotation1->setQuote('content'); | ||
21 | |||
22 | $manager->persist($annotation1); | ||
23 | |||
24 | $this->addReference('annotation1', $annotation1); | ||
25 | |||
26 | $annotation2 = new Annotation($this->getReference('admin-user')); | ||
27 | $annotation2->setEntry($this->getReference('entry2')); | ||
28 | $annotation2->setText('This is my 2nd annotation /o/'); | ||
29 | $annotation2->setQuote('content'); | ||
30 | |||
31 | $manager->persist($annotation2); | ||
32 | |||
33 | $this->addReference('annotation2', $annotation2); | ||
34 | |||
35 | $manager->flush(); | ||
36 | } | ||
37 | |||
38 | /** | ||
39 | * {@inheritdoc} | ||
40 | */ | ||
41 | public function getOrder() | ||
42 | { | ||
43 | return 35; | ||
44 | } | ||
45 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/DependencyInjection/Configuration.php b/src/Wallabag/AnnotationBundle/DependencyInjection/Configuration.php new file mode 100644 index 00000000..5e4e4e9c --- /dev/null +++ b/src/Wallabag/AnnotationBundle/DependencyInjection/Configuration.php | |||
@@ -0,0 +1,20 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\DependencyInjection; | ||
4 | |||
5 | use Symfony\Component\Config\Definition\Builder\TreeBuilder; | ||
6 | use Symfony\Component\Config\Definition\ConfigurationInterface; | ||
7 | |||
8 | class Configuration implements ConfigurationInterface | ||
9 | { | ||
10 | /** | ||
11 | * {@inheritdoc} | ||
12 | */ | ||
13 | public function getConfigTreeBuilder() | ||
14 | { | ||
15 | $treeBuilder = new TreeBuilder(); | ||
16 | $rootNode = $treeBuilder->root('wallabag_annotation'); | ||
17 | |||
18 | return $treeBuilder; | ||
19 | } | ||
20 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/DependencyInjection/WallabagAnnotationExtension.php b/src/Wallabag/AnnotationBundle/DependencyInjection/WallabagAnnotationExtension.php new file mode 100644 index 00000000..159576d6 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/DependencyInjection/WallabagAnnotationExtension.php | |||
@@ -0,0 +1,18 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\DependencyInjection; | ||
4 | |||
5 | use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
6 | use Symfony\Component\HttpKernel\DependencyInjection\Extension; | ||
7 | |||
8 | class WallabagAnnotationExtension extends Extension | ||
9 | { | ||
10 | /** | ||
11 | * {@inheritdoc} | ||
12 | */ | ||
13 | public function load(array $configs, ContainerBuilder $container) | ||
14 | { | ||
15 | $configuration = new Configuration(); | ||
16 | $config = $this->processConfiguration($configuration, $configs); | ||
17 | } | ||
18 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/Entity/Annotation.php b/src/Wallabag/AnnotationBundle/Entity/Annotation.php new file mode 100644 index 00000000..db9590b0 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Entity/Annotation.php | |||
@@ -0,0 +1,270 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\Entity; | ||
4 | |||
5 | use Doctrine\ORM\Mapping as ORM; | ||
6 | use JMS\Serializer\Annotation\ExclusionPolicy; | ||
7 | use JMS\Serializer\Annotation\Exclude; | ||
8 | use JMS\Serializer\Annotation\VirtualProperty; | ||
9 | use JMS\Serializer\Annotation\SerializedName; | ||
10 | use Wallabag\UserBundle\Entity\User; | ||
11 | use Wallabag\CoreBundle\Entity\Entry; | ||
12 | |||
13 | /** | ||
14 | * Annotation. | ||
15 | * | ||
16 | * @ORM\Table(name="annotation") | ||
17 | * @ORM\Entity(repositoryClass="Wallabag\AnnotationBundle\Repository\AnnotationRepository") | ||
18 | * @ORM\HasLifecycleCallbacks() | ||
19 | * @ExclusionPolicy("none") | ||
20 | */ | ||
21 | class Annotation | ||
22 | { | ||
23 | /** | ||
24 | * @var int | ||
25 | * | ||
26 | * @ORM\Column(name="id", type="integer") | ||
27 | * @ORM\Id | ||
28 | * @ORM\GeneratedValue(strategy="AUTO") | ||
29 | */ | ||
30 | private $id; | ||
31 | |||
32 | /** | ||
33 | * @var string | ||
34 | * | ||
35 | * @ORM\Column(name="text", type="text") | ||
36 | */ | ||
37 | private $text; | ||
38 | |||
39 | /** | ||
40 | * @var \DateTime | ||
41 | * | ||
42 | * @ORM\Column(name="created_at", type="datetime") | ||
43 | */ | ||
44 | private $createdAt; | ||
45 | |||
46 | /** | ||
47 | * @var \DateTime | ||
48 | * | ||
49 | * @ORM\Column(name="updated_at", type="datetime") | ||
50 | */ | ||
51 | private $updatedAt; | ||
52 | |||
53 | /** | ||
54 | * @var string | ||
55 | * | ||
56 | * @ORM\Column(name="quote", type="string") | ||
57 | */ | ||
58 | private $quote; | ||
59 | |||
60 | /** | ||
61 | * @var array | ||
62 | * | ||
63 | * @ORM\Column(name="ranges", type="array") | ||
64 | */ | ||
65 | private $ranges; | ||
66 | |||
67 | /** | ||
68 | * @Exclude | ||
69 | * | ||
70 | * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User") | ||
71 | */ | ||
72 | private $user; | ||
73 | |||
74 | /** | ||
75 | * @Exclude | ||
76 | * | ||
77 | * @ORM\ManyToOne(targetEntity="Wallabag\CoreBundle\Entity\Entry", inversedBy="annotations") | ||
78 | * @ORM\JoinColumn(name="entry_id", referencedColumnName="id") | ||
79 | */ | ||
80 | private $entry; | ||
81 | |||
82 | /* | ||
83 | * @param User $user | ||
84 | */ | ||
85 | public function __construct(\Wallabag\UserBundle\Entity\User $user) | ||
86 | { | ||
87 | $this->user = $user; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * Get id. | ||
92 | * | ||
93 | * @return int | ||
94 | */ | ||
95 | public function getId() | ||
96 | { | ||
97 | return $this->id; | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * Set text. | ||
102 | * | ||
103 | * @param string $text | ||
104 | * | ||
105 | * @return Annotation | ||
106 | */ | ||
107 | public function setText($text) | ||
108 | { | ||
109 | $this->text = $text; | ||
110 | |||
111 | return $this; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * Get text. | ||
116 | * | ||
117 | * @return string | ||
118 | */ | ||
119 | public function getText() | ||
120 | { | ||
121 | return $this->text; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * @ORM\PrePersist | ||
126 | * @ORM\PreUpdate | ||
127 | */ | ||
128 | public function timestamps() | ||
129 | { | ||
130 | if (is_null($this->createdAt)) { | ||
131 | $this->createdAt = new \DateTime(); | ||
132 | } | ||
133 | $this->updatedAt = new \DateTime(); | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * Get created. | ||
138 | * | ||
139 | * @return \DateTime | ||
140 | */ | ||
141 | public function getCreatedAt() | ||
142 | { | ||
143 | return $this->createdAt; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * Get updated. | ||
148 | * | ||
149 | * @return \DateTime | ||
150 | */ | ||
151 | public function getUpdatedAt() | ||
152 | { | ||
153 | return $this->updatedAt; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * Get quote. | ||
158 | * | ||
159 | * @return string | ||
160 | */ | ||
161 | public function getQuote() | ||
162 | { | ||
163 | return $this->quote; | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * Set quote. | ||
168 | * | ||
169 | * @param string $quote | ||
170 | * | ||
171 | * @return Annotation | ||
172 | */ | ||
173 | public function setQuote($quote) | ||
174 | { | ||
175 | $this->quote = $quote; | ||
176 | |||
177 | return $this; | ||
178 | } | ||
179 | |||
180 | /** | ||
181 | * Get ranges. | ||
182 | * | ||
183 | * @return array | ||
184 | */ | ||
185 | public function getRanges() | ||
186 | { | ||
187 | return $this->ranges; | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Set ranges. | ||
192 | * | ||
193 | * @param array $ranges | ||
194 | * | ||
195 | * @return Annotation | ||
196 | */ | ||
197 | public function setRanges($ranges) | ||
198 | { | ||
199 | $this->ranges = $ranges; | ||
200 | |||
201 | return $this; | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * Set user. | ||
206 | * | ||
207 | * @param string $user | ||
208 | * | ||
209 | * @return Annotation | ||
210 | */ | ||
211 | public function setUser($user) | ||
212 | { | ||
213 | $this->user = $user; | ||
214 | |||
215 | return $this; | ||
216 | } | ||
217 | |||
218 | /** | ||
219 | * Get user. | ||
220 | * | ||
221 | * @return string | ||
222 | */ | ||
223 | public function getUser() | ||
224 | { | ||
225 | return $this->user; | ||
226 | } | ||
227 | |||
228 | /** | ||
229 | * @VirtualProperty | ||
230 | * @SerializedName("user") | ||
231 | */ | ||
232 | public function getUserName() | ||
233 | { | ||
234 | return $this->user->getName(); | ||
235 | } | ||
236 | |||
237 | /** | ||
238 | * Set entry. | ||
239 | * | ||
240 | * @param Entry $entry | ||
241 | * | ||
242 | * @return Annotation | ||
243 | */ | ||
244 | public function setEntry($entry) | ||
245 | { | ||
246 | $this->entry = $entry; | ||
247 | $entry->setAnnotation($this); | ||
248 | |||
249 | return $this; | ||
250 | } | ||
251 | |||
252 | /** | ||
253 | * Get entry. | ||
254 | * | ||
255 | * @return Entry | ||
256 | */ | ||
257 | public function getEntry() | ||
258 | { | ||
259 | return $this->entry; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * @VirtualProperty | ||
264 | * @SerializedName("annotator_schema_version") | ||
265 | */ | ||
266 | public function getVersion() | ||
267 | { | ||
268 | return 'v1.0'; | ||
269 | } | ||
270 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php new file mode 100644 index 00000000..c1c6e638 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php | |||
@@ -0,0 +1,91 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\Repository; | ||
4 | |||
5 | use Doctrine\ORM\EntityRepository; | ||
6 | |||
7 | /** | ||
8 | * AnnotationRepository. | ||
9 | */ | ||
10 | class AnnotationRepository extends EntityRepository | ||
11 | { | ||
12 | /** | ||
13 | * Return a query builder to used by other getBuilderFor* method. | ||
14 | * | ||
15 | * @param int $userId | ||
16 | * | ||
17 | * @return QueryBuilder | ||
18 | */ | ||
19 | private function getBuilderByUser($userId) | ||
20 | { | ||
21 | return $this->createQueryBuilder('a') | ||
22 | ->leftJoin('a.user', 'u') | ||
23 | ->andWhere('u.id = :userId')->setParameter('userId', $userId) | ||
24 | ->orderBy('a.id', 'desc') | ||
25 | ; | ||
26 | } | ||
27 | |||
28 | /** | ||
29 | * Retrieves all annotations for a user. | ||
30 | * | ||
31 | * @param int $userId | ||
32 | * | ||
33 | * @return QueryBuilder | ||
34 | */ | ||
35 | public function getBuilderForAllByUser($userId) | ||
36 | { | ||
37 | return $this | ||
38 | ->getBuilderByUser($userId) | ||
39 | ; | ||
40 | } | ||
41 | |||
42 | /** | ||
43 | * Get annotation for this id. | ||
44 | * | ||
45 | * @param int $annotationId | ||
46 | * | ||
47 | * @return array | ||
48 | */ | ||
49 | public function findAnnotationById($annotationId) | ||
50 | { | ||
51 | return $this->createQueryBuilder('a') | ||
52 | ->andWhere('a.id = :annotationId')->setParameter('annotationId', $annotationId) | ||
53 | ->getQuery()->getSingleResult() | ||
54 | ; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Find annotations for entry id. | ||
59 | * | ||
60 | * @param int $entryId | ||
61 | * @param int $userId | ||
62 | * | ||
63 | * @return array | ||
64 | */ | ||
65 | public function findAnnotationsByPageId($entryId, $userId) | ||
66 | { | ||
67 | return $this->createQueryBuilder('a') | ||
68 | ->where('a.entry = :entryId')->setParameter('entryId', $entryId) | ||
69 | ->andwhere('a.user = :userId')->setParameter('userId', $userId) | ||
70 | ->getQuery()->getResult() | ||
71 | ; | ||
72 | } | ||
73 | |||
74 | /** | ||
75 | * Find last annotation for a given entry id. Used only for tests. | ||
76 | * | ||
77 | * @param int $entryId | ||
78 | * | ||
79 | * @return array | ||
80 | */ | ||
81 | public function findLastAnnotationByPageId($entryId, $userId) | ||
82 | { | ||
83 | return $this->createQueryBuilder('a') | ||
84 | ->where('a.entry = :entryId')->setParameter('entryId', $entryId) | ||
85 | ->andwhere('a.user = :userId')->setParameter('userId', $userId) | ||
86 | ->orderBy('a.id', 'DESC') | ||
87 | ->setMaxResults(1) | ||
88 | ->getQuery() | ||
89 | ->getOneOrNullResult(); | ||
90 | } | ||
91 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml b/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml new file mode 100644 index 00000000..4f3a5c93 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Resources/config/routing_annotations.yml | |||
@@ -0,0 +1,4 @@ | |||
1 | annotations: | ||
2 | type: rest | ||
3 | resource: "WallabagAnnotationBundle:WallabagAnnotation" | ||
4 | name_prefix: annotations_ | ||
diff --git a/src/Wallabag/AnnotationBundle/Tests/Controller/AnnotationControllerTest.php b/src/Wallabag/AnnotationBundle/Tests/Controller/AnnotationControllerTest.php new file mode 100644 index 00000000..c0efe272 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Tests/Controller/AnnotationControllerTest.php | |||
@@ -0,0 +1,81 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\Tests\Controller; | ||
4 | |||
5 | use Wallabag\AnnotationBundle\Tests\WallabagAnnotationTestCase; | ||
6 | |||
7 | class AnnotationControllerTest extends WallabagAnnotationTestCase | ||
8 | { | ||
9 | public function testGetAnnotations() | ||
10 | { | ||
11 | $annotation = $this->client->getContainer() | ||
12 | ->get('doctrine.orm.entity_manager') | ||
13 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
14 | ->findOneBy(array('user' => 1)); | ||
15 | |||
16 | if (!$annotation) { | ||
17 | $this->markTestSkipped('No content found in db.'); | ||
18 | } | ||
19 | $this->logInAs('admin'); | ||
20 | $crawler = $this->client->request('GET', 'annotations/'.$annotation->getEntry()->getId().'.json'); | ||
21 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | ||
22 | |||
23 | $content = json_decode($this->client->getResponse()->getContent(), true); | ||
24 | $this->assertEquals(1, $content['total']); | ||
25 | $this->assertEquals($annotation->getText(), $content['rows'][0]['text']); | ||
26 | } | ||
27 | |||
28 | public function testSetAnnotation() | ||
29 | { | ||
30 | $this->logInAs('admin'); | ||
31 | |||
32 | $entry = $this->client->getContainer() | ||
33 | ->get('doctrine.orm.entity_manager') | ||
34 | ->getRepository('WallabagCoreBundle:Entry') | ||
35 | ->findOneBy(array('user' => 1)); | ||
36 | |||
37 | $headers = array('CONTENT_TYPE' => 'application/json'); | ||
38 | $content = json_encode(array( | ||
39 | 'text' => 'my annotation', | ||
40 | 'quote' => 'my quote', | ||
41 | 'range' => '[{"start":"","startOffset":24,"end":"","endOffset":31}]', | ||
42 | )); | ||
43 | $crawler = $this->client->request('POST', 'annotations/'.$entry->getId().'.json', array(), array(), $headers, $content); | ||
44 | |||
45 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | ||
46 | |||
47 | $annotation = $this->client->getContainer() | ||
48 | ->get('doctrine.orm.entity_manager') | ||
49 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
50 | ->findLastAnnotationByPageId($entry->getId(), 1); | ||
51 | |||
52 | $this->assertEquals('my annotation', $annotation->getText()); | ||
53 | } | ||
54 | |||
55 | public function testEditAnnotation() | ||
56 | { | ||
57 | $annotation = $this->client->getContainer() | ||
58 | ->get('doctrine.orm.entity_manager') | ||
59 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
60 | ->findOneBy(array('user' => 1)); | ||
61 | |||
62 | $this->logInAs('admin'); | ||
63 | |||
64 | $headers = array('CONTENT_TYPE' => 'application/json'); | ||
65 | $content = json_encode(array( | ||
66 | 'text' => 'a modified annotation', | ||
67 | )); | ||
68 | $crawler = $this->client->request('PUT', 'annotations/'.$annotation->getId().'.json', array(), array(), $headers, $content); | ||
69 | $this->assertEquals(200, $this->client->getResponse()->getStatusCode()); | ||
70 | |||
71 | $content = json_decode($this->client->getResponse()->getContent(), true); | ||
72 | |||
73 | $this->assertEquals('a modified annotation', $content['text']); | ||
74 | |||
75 | $annotationUpdated = $this->client->getContainer() | ||
76 | ->get('doctrine.orm.entity_manager') | ||
77 | ->getRepository('WallabagAnnotationBundle:Annotation') | ||
78 | ->findAnnotationById($annotation->getId()); | ||
79 | $this->assertEquals('a modified annotation', $annotationUpdated->getText()); | ||
80 | } | ||
81 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/Tests/WallabagAnnotationTestCase.php b/src/Wallabag/AnnotationBundle/Tests/WallabagAnnotationTestCase.php new file mode 100644 index 00000000..2deff6bf --- /dev/null +++ b/src/Wallabag/AnnotationBundle/Tests/WallabagAnnotationTestCase.php | |||
@@ -0,0 +1,63 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle\Tests; | ||
4 | |||
5 | use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; | ||
6 | use Symfony\Component\BrowserKit\Cookie; | ||
7 | |||
8 | abstract class WallabagAnnotationTestCase extends WebTestCase | ||
9 | { | ||
10 | /** | ||
11 | * @var Client | ||
12 | */ | ||
13 | protected $client = null; | ||
14 | |||
15 | /** | ||
16 | * @var \FOS\UserBundle\Model\UserInterface | ||
17 | */ | ||
18 | protected $user; | ||
19 | |||
20 | public function setUp() | ||
21 | { | ||
22 | $this->client = $this->createAuthorizedClient(); | ||
23 | } | ||
24 | |||
25 | public function logInAs($username) | ||
26 | { | ||
27 | $crawler = $this->client->request('GET', '/login'); | ||
28 | $form = $crawler->filter('button[type=submit]')->form(); | ||
29 | $data = array( | ||
30 | '_username' => $username, | ||
31 | '_password' => 'mypassword', | ||
32 | ); | ||
33 | |||
34 | $this->client->submit($form, $data); | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * @return Client | ||
39 | */ | ||
40 | protected function createAuthorizedClient() | ||
41 | { | ||
42 | $client = static::createClient(); | ||
43 | $container = $client->getContainer(); | ||
44 | |||
45 | /** @var $userManager \FOS\UserBundle\Doctrine\UserManager */ | ||
46 | $userManager = $container->get('fos_user.user_manager'); | ||
47 | /** @var $loginManager \FOS\UserBundle\Security\LoginManager */ | ||
48 | $loginManager = $container->get('fos_user.security.login_manager'); | ||
49 | $firewallName = $container->getParameter('fos_user.firewall_name'); | ||
50 | |||
51 | $this->user = $userManager->findUserBy(array('username' => 'admin')); | ||
52 | $loginManager->loginUser($firewallName, $this->user); | ||
53 | |||
54 | // save the login token into the session and put it in a cookie | ||
55 | $container->get('session')->set('_security_'.$firewallName, serialize($container->get('security.token_storage')->getToken())); | ||
56 | $container->get('session')->save(); | ||
57 | |||
58 | $session = $container->get('session'); | ||
59 | $client->getCookieJar()->set(new Cookie($session->getName(), $session->getId())); | ||
60 | |||
61 | return $client; | ||
62 | } | ||
63 | } | ||
diff --git a/src/Wallabag/AnnotationBundle/WallabagAnnotationBundle.php b/src/Wallabag/AnnotationBundle/WallabagAnnotationBundle.php new file mode 100644 index 00000000..b64920a3 --- /dev/null +++ b/src/Wallabag/AnnotationBundle/WallabagAnnotationBundle.php | |||
@@ -0,0 +1,9 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\AnnotationBundle; | ||
4 | |||
5 | use Symfony\Component\HttpKernel\Bundle\Bundle; | ||
6 | |||
7 | class WallabagAnnotationBundle extends Bundle | ||
8 | { | ||
9 | } | ||