aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/CoreBundle
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/CoreBundle')
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php24
-rw-r--r--src/Wallabag/CoreBundle/Controller/FooterController.php27
-rw-r--r--src/Wallabag/CoreBundle/Controller/StaticController.php4
-rw-r--r--src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php7
-rw-r--r--src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php8
-rw-r--r--src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php1
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php19
-rw-r--r--src/Wallabag/CoreBundle/Entity/Tag.php23
-rw-r--r--src/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformer.php2
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/ConfigType.php6
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php36
-rw-r--r--src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php6
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/parameters.yml12
-rw-r--r--src/Wallabag/CoreBundle/Resources/public/themes/baggy/css/ratatouille.css2
-rwxr-xr-xsrc/Wallabag/CoreBundle/Resources/public/themes/material/css/main.css3
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.da.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.de.yml4
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.en.yml24
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.es.yml4
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml46
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml10
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.it.yml1
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig3
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig5
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/baggy/Static/howto.html.twig10
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig2
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig7
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/Static/howto.html.twig10
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/footer.html.twig41
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig42
-rw-r--r--src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php279
-rw-r--r--src/Wallabag/CoreBundle/Tests/Command/TagAllCommandTest.php60
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php652
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/DeveloperControllerTest.php71
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php619
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php251
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php126
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php72
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/SettingsControllerTest.php32
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/StaticControllerTest.php28
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php128
-rw-r--r--src/Wallabag/CoreBundle/Tests/EventListener/LocaleListenerTest.php82
-rw-r--r--src/Wallabag/CoreBundle/Tests/EventListener/RegistrationConfirmedListenerTest.php91
-rw-r--r--src/Wallabag/CoreBundle/Tests/EventListener/UserLocaleListenerTest.php58
-rw-r--r--src/Wallabag/CoreBundle/Tests/Form/DataTransformer/StringToListTransformerTest.php50
-rw-r--r--src/Wallabag/CoreBundle/Tests/Helper/ContentProxyTest.php318
-rw-r--r--src/Wallabag/CoreBundle/Tests/Helper/RedirectTest.php55
-rw-r--r--src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php212
-rw-r--r--src/Wallabag/CoreBundle/Tests/Mock/InstallCommandMock.php22
-rw-r--r--src/Wallabag/CoreBundle/Tests/ParamConverter/UsernameRssTokenConverterTest.php219
-rw-r--r--src/Wallabag/CoreBundle/Tests/Subscriber/TablePrefixSubscriberTest.php114
-rw-r--r--src/Wallabag/CoreBundle/Tests/Twig/WallabagExtensionTest.php17
-rw-r--r--src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php51
57 files changed, 269 insertions, 3737 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 69dfd4b1..4eb314f7 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -23,10 +23,16 @@ class EntryController extends Controller
23 { 23 {
24 try { 24 try {
25 $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl()); 25 $entry = $this->get('wallabag_core.content_proxy')->updateEntry($entry, $entry->getUrl());
26
26 $em = $this->getDoctrine()->getManager(); 27 $em = $this->getDoctrine()->getManager();
27 $em->persist($entry); 28 $em->persist($entry);
28 $em->flush(); 29 $em->flush();
29 } catch (\Exception $e) { 30 } catch (\Exception $e) {
31 $this->get('logger')->error('Error while saving an entry', [
32 'exception' => $e,
33 'entry' => $entry,
34 ]);
35
30 return false; 36 return false;
31 } 37 }
32 38
@@ -60,11 +66,12 @@ class EntryController extends Controller
60 return $this->redirect($this->generateUrl('view', ['id' => $existingEntry->getId()])); 66 return $this->redirect($this->generateUrl('view', ['id' => $existingEntry->getId()]));
61 } 67 }
62 68
63 $this->updateEntry($entry); 69 $message = 'flashes.entry.notice.entry_saved';
64 $this->get('session')->getFlashBag()->add( 70 if (false === $this->updateEntry($entry)) {
65 'notice', 71 $message = 'flashes.entry.notice.entry_saved_failed';
66 'flashes.entry.notice.entry_saved' 72 }
67 ); 73
74 $this->get('session')->getFlashBag()->add('notice', $message);
68 75
69 return $this->redirect($this->generateUrl('homepage')); 76 return $this->redirect($this->generateUrl('homepage'));
70 } 77 }
@@ -399,7 +406,7 @@ class EntryController extends Controller
399 $url = $this->generateUrl( 406 $url = $this->generateUrl(
400 'view', 407 'view',
401 ['id' => $entry->getId()], 408 ['id' => $entry->getId()],
402 UrlGeneratorInterface::ABSOLUTE_URL 409 UrlGeneratorInterface::ABSOLUTE_PATH
403 ); 410 );
404 411
405 $em = $this->getDoctrine()->getManager(); 412 $em = $this->getDoctrine()->getManager();
@@ -411,8 +418,9 @@ class EntryController extends Controller
411 'flashes.entry.notice.entry_deleted' 418 'flashes.entry.notice.entry_deleted'
412 ); 419 );
413 420
414 // don't redirect user to the deleted entry 421 // don't redirect user to the deleted entry (check that the referer doesn't end with the same url)
415 $to = ($url !== $request->headers->get('referer') ? $request->headers->get('referer') : null); 422 $referer = $request->headers->get('referer');
423 $to = (1 !== preg_match('#'.$url.'$#i', $referer) ? $referer : null);
416 424
417 $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($to); 425 $redirectUrl = $this->get('wallabag_core.helper.redirect')->to($to);
418 426
diff --git a/src/Wallabag/CoreBundle/Controller/FooterController.php b/src/Wallabag/CoreBundle/Controller/FooterController.php
new file mode 100644
index 00000000..fd93c436
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Controller/FooterController.php
@@ -0,0 +1,27 @@
1<?php
2
3namespace Wallabag\CoreBundle\Controller;
4
5use Symfony\Bundle\FrameworkBundle\Controller\Controller;
6
7class FooterController extends Controller
8{
9 /**
10 * Display the footer.
11 *
12 * @return \Symfony\Component\HttpFoundation\Response
13 */
14 public function indexAction()
15 {
16 $addonsUrl = $this->container->getParameter('addons_url');
17 $socialsUrl = $this->container->getParameter('socials_url');
18
19 return $this->render(
20 'WallabagCoreBundle::footer.html.twig',
21 [
22 'addonsUrl' => $addonsUrl,
23 'socialsUrl' => $socialsUrl,
24 ]
25 );
26 }
27}
diff --git a/src/Wallabag/CoreBundle/Controller/StaticController.php b/src/Wallabag/CoreBundle/Controller/StaticController.php
index b41302f8..2a57f06f 100644
--- a/src/Wallabag/CoreBundle/Controller/StaticController.php
+++ b/src/Wallabag/CoreBundle/Controller/StaticController.php
@@ -12,9 +12,11 @@ class StaticController extends Controller
12 */ 12 */
13 public function howtoAction() 13 public function howtoAction()
14 { 14 {
15 $addonsUrl = $this->container->getParameter('addons_url');
16
15 return $this->render( 17 return $this->render(
16 'WallabagCoreBundle:Static:howto.html.twig', 18 'WallabagCoreBundle:Static:howto.html.twig',
17 [] 19 ['addonsUrl' => $addonsUrl]
18 ); 20 );
19 } 21 }
20 22
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
index 5a376453..03be9667 100644
--- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php
@@ -6,7 +6,6 @@ use Doctrine\Common\DataFixtures\AbstractFixture;
6use Doctrine\Common\DataFixtures\OrderedFixtureInterface; 6use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
7use Doctrine\Common\Persistence\ObjectManager; 7use Doctrine\Common\Persistence\ObjectManager;
8use Wallabag\CoreBundle\Entity\Config; 8use Wallabag\CoreBundle\Entity\Config;
9use Wallabag\CoreBundle\Entity\TaggingRule;
10 9
11class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface 10class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface
12{ 11{
@@ -16,12 +15,6 @@ class LoadConfigData extends AbstractFixture implements OrderedFixtureInterface
16 public function load(ObjectManager $manager) 15 public function load(ObjectManager $manager)
17 { 16 {
18 $adminConfig = new Config($this->getReference('admin-user')); 17 $adminConfig = new Config($this->getReference('admin-user'));
19 $taggingRule = new TaggingRule();
20
21 $taggingRule->setConfig($adminConfig);
22 $taggingRule->setRule('title matches "wallabag"');
23 $taggingRule->setTags(['wallabag']);
24 $manager->persist($taggingRule);
25 18
26 $adminConfig->setTheme('material'); 19 $adminConfig->setTheme('material');
27 $adminConfig->setItemsPerPage(30); 20 $adminConfig->setItemsPerPage(30);
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php
index 2e1cc270..7efe6356 100644
--- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadTaggingRuleData.php
@@ -28,6 +28,14 @@ class LoadTaggingRuleData extends AbstractFixture implements OrderedFixtureInter
28 28
29 $manager->persist($tr2); 29 $manager->persist($tr2);
30 30
31 $tr3 = new TaggingRule();
32
33 $tr3->setRule('title matches "wallabag"');
34 $tr3->setTags(['wallabag']);
35 $tr3->setConfig($this->getReference('admin-config'));
36
37 $manager->persist($tr3);
38
31 $manager->flush(); 39 $manager->flush();
32 } 40 }
33 41
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
index 84599f0d..7d08b73b 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
@@ -25,6 +25,7 @@ class WallabagCoreExtension extends Extension
25 25
26 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 26 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
27 $loader->load('services.yml'); 27 $loader->load('services.yml');
28 $loader->load('parameters.yml');
28 } 29 }
29 30
30 public function getAlias() 31 public function getAlias()
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index 1271f1f5..ceae78b0 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -177,8 +177,16 @@ class Entry
177 private $user; 177 private $user;
178 178
179 /** 179 /**
180 * @ORM\ManyToMany(targetEntity="Tag", inversedBy="entries", cascade={"persist", "remove"}) 180 * @ORM\ManyToMany(targetEntity="Tag", inversedBy="entries", cascade={"persist"})
181 * @ORM\JoinTable 181 * @ORM\JoinTable(
182 * name="entry_tag",
183 * joinColumns={
184 * @ORM\JoinColumn(name="entry_id", referencedColumnName="id")
185 * },
186 * inverseJoinColumns={
187 * @ORM\JoinColumn(name="tag_id", referencedColumnName="id")
188 * }
189 * )
182 * 190 *
183 * @Groups({"entries_for_user", "export_all"}) 191 * @Groups({"entries_for_user", "export_all"})
184 */ 192 */
@@ -526,13 +534,18 @@ class Entry
526 } 534 }
527 } 535 }
528 536
529 $this->tags[] = $tag; 537 $this->tags->add($tag);
530 $tag->addEntry($this); 538 $tag->addEntry($this);
531 } 539 }
532 540
533 public function removeTag(Tag $tag) 541 public function removeTag(Tag $tag)
534 { 542 {
543 if (!$this->tags->contains($tag)) {
544 return;
545 }
546
535 $this->tags->removeElement($tag); 547 $this->tags->removeElement($tag);
548 $tag->removeEntry($this);
536 } 549 }
537 550
538 /** 551 /**
diff --git a/src/Wallabag/CoreBundle/Entity/Tag.php b/src/Wallabag/CoreBundle/Entity/Tag.php
index b4adbbd3..4b480ff1 100644
--- a/src/Wallabag/CoreBundle/Entity/Tag.php
+++ b/src/Wallabag/CoreBundle/Entity/Tag.php
@@ -98,9 +98,30 @@ class Tag
98 return $this->slug; 98 return $this->slug;
99 } 99 }
100 100
101 /**
102 * @param Entry $entry
103 */
101 public function addEntry(Entry $entry) 104 public function addEntry(Entry $entry)
102 { 105 {
103 $this->entries[] = $entry; 106 if ($this->entries->contains($entry)) {
107 return;
108 }
109
110 $this->entries->add($entry);
111 $entry->addTag($this);
112 }
113
114 /**
115 * @param Entry $entry
116 */
117 public function removeEntry(Entry $entry)
118 {
119 if (!$this->entries->contains($entry)) {
120 return;
121 }
122
123 $this->entries->removeElement($entry);
124 $entry->removeTag($this);
104 } 125 }
105 126
106 public function hasEntry($entry) 127 public function hasEntry($entry)
diff --git a/src/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformer.php b/src/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformer.php
index b712ad15..cb4bee83 100644
--- a/src/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformer.php
+++ b/src/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformer.php
@@ -16,7 +16,7 @@ class StringToListTransformer implements DataTransformerInterface
16 private $separator; 16 private $separator;
17 17
18 /** 18 /**
19 * @param string $separator The separator used in the list. 19 * @param string $separator The separator used in the list
20 */ 20 */
21 public function __construct($separator = ',') 21 public function __construct($separator = ',')
22 { 22 {
diff --git a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php
index 4cf22200..7d25cc80 100644
--- a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php
@@ -21,7 +21,9 @@ class ConfigType extends AbstractType
21 { 21 {
22 $this->themes = array_combine( 22 $this->themes = array_combine(
23 $themes, 23 $themes,
24 array_map(function ($s) { return ucwords(strtolower(str_replace('-', ' ', $s))); }, $themes) 24 array_map(function ($s) {
25 return ucwords(strtolower(str_replace('-', ' ', $s)));
26 }, $themes)
25 ); 27 );
26 28
27 $this->languages = $languages; 29 $this->languages = $languages;
@@ -32,7 +34,6 @@ class ConfigType extends AbstractType
32 $builder 34 $builder
33 ->add('theme', ChoiceType::class, [ 35 ->add('theme', ChoiceType::class, [
34 'choices' => array_flip($this->themes), 36 'choices' => array_flip($this->themes),
35 'choices_as_values' => true,
36 'label' => 'config.form_settings.theme_label', 37 'label' => 'config.form_settings.theme_label',
37 ]) 38 ])
38 ->add('items_per_page', null, [ 39 ->add('items_per_page', null, [
@@ -49,7 +50,6 @@ class ConfigType extends AbstractType
49 ]) 50 ])
50 ->add('language', ChoiceType::class, [ 51 ->add('language', ChoiceType::class, [
51 'choices' => array_flip($this->languages), 52 'choices' => array_flip($this->languages),
52 'choices_as_values' => true,
53 'label' => 'config.form_settings.language_label', 53 'label' => 'config.form_settings.language_label',
54 ]) 54 ])
55 ->add('save', SubmitType::class, [ 55 ->add('save', SubmitType::class, [
diff --git a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
index cd4d3490..3c597b5d 100644
--- a/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/EntryFilterType.php
@@ -36,17 +36,26 @@ class EntryFilterType extends AbstractType
36 $builder 36 $builder
37 ->add('readingTime', NumberRangeFilterType::class, [ 37 ->add('readingTime', NumberRangeFilterType::class, [
38 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { 38 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
39 $value = $values['value']; 39 $lower = $values['value']['left_number'][0];
40 $upper = $values['value']['right_number'][0];
41
42 $min = (int) ($lower * $this->user->getConfig()->getReadingSpeed());
43 $max = (int) ($upper * $this->user->getConfig()->getReadingSpeed());
40 44
41 if (null === $value['left_number'][0] || null === $value['right_number'][0]) { 45 if (null === $lower && null === $upper) {
46 // no value? no filter
42 return; 47 return;
48 } elseif (null === $lower && null !== $upper) {
49 // only lower value is defined: query all entries with reading LOWER THAN this value
50 $expression = $filterQuery->getExpr()->lte($field, $max);
51 } elseif (null !== $lower && null === $upper) {
52 // only upper value is defined: query all entries with reading GREATER THAN this value
53 $expression = $filterQuery->getExpr()->gte($field, $min);
54 } else {
55 // both value are defined, perform a between
56 $expression = $filterQuery->getExpr()->between($field, $min, $max);
43 } 57 }
44 58
45 $min = (int) ($value['left_number'][0] * $this->user->getConfig()->getReadingSpeed());
46 $max = (int) ($value['right_number'][0] * $this->user->getConfig()->getReadingSpeed());
47
48 $expression = $filterQuery->getExpr()->between($field, $min, $max);
49
50 return $filterQuery->createCondition($expression); 59 return $filterQuery->createCondition($expression);
51 }, 60 },
52 'label' => 'entry.filters.reading_time.label', 61 'label' => 'entry.filters.reading_time.label',
@@ -87,6 +96,18 @@ class EntryFilterType extends AbstractType
87 ->add('isStarred', CheckboxFilterType::class, [ 96 ->add('isStarred', CheckboxFilterType::class, [
88 'label' => 'entry.filters.starred_label', 97 'label' => 'entry.filters.starred_label',
89 ]) 98 ])
99 ->add('isUnread', CheckboxFilterType::class, [
100 'label' => 'entry.filters.unread_label',
101 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
102 if (false === $values['value']) {
103 return;
104 }
105
106 $expression = $filterQuery->getExpr()->eq('e.isArchived', 'false');
107
108 return $filterQuery->createCondition($expression);
109 },
110 ])
90 ->add('previewPicture', CheckboxFilterType::class, [ 111 ->add('previewPicture', CheckboxFilterType::class, [
91 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) { 112 'apply_filter' => function (QueryInterface $filterQuery, $field, $values) {
92 if (false === $values['value']) { 113 if (false === $values['value']) {
@@ -101,7 +122,6 @@ class EntryFilterType extends AbstractType
101 ]) 122 ])
102 ->add('language', ChoiceFilterType::class, [ 123 ->add('language', ChoiceFilterType::class, [
103 'choices' => array_flip($this->repository->findDistinctLanguageByUser($this->user->getId())), 124 'choices' => array_flip($this->repository->findDistinctLanguageByUser($this->user->getId())),
104 'choices_as_values' => true,
105 'label' => 'entry.filters.language_label', 125 'label' => 'entry.filters.language_label',
106 ]) 126 ])
107 ; 127 ;
diff --git a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php
index 14ef4a64..239d09ae 100644
--- a/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php
+++ b/src/Wallabag/CoreBundle/Helper/RuleBasedTagger.php
@@ -25,7 +25,7 @@ class RuleBasedTagger
25 /** 25 /**
26 * Add tags from rules defined by the user. 26 * Add tags from rules defined by the user.
27 * 27 *
28 * @param Entry $entry Entry to tag. 28 * @param Entry $entry Entry to tag
29 */ 29 */
30 public function tag(Entry $entry) 30 public function tag(Entry $entry)
31 { 31 {
@@ -49,7 +49,7 @@ class RuleBasedTagger
49 * 49 *
50 * @param User $user 50 * @param User $user
51 * 51 *
52 * @return array<Entry> A list of modified entries. 52 * @return array<Entry> A list of modified entries
53 */ 53 */
54 public function tagAllForUser(User $user) 54 public function tagAllForUser(User $user)
55 { 55 {
@@ -75,7 +75,7 @@ class RuleBasedTagger
75 /** 75 /**
76 * Fetch a tag. 76 * Fetch a tag.
77 * 77 *
78 * @param string $label The tag's label. 78 * @param string $label The tag's label
79 * 79 *
80 * @return Tag 80 * @return Tag
81 */ 81 */
diff --git a/src/Wallabag/CoreBundle/Resources/config/parameters.yml b/src/Wallabag/CoreBundle/Resources/config/parameters.yml
new file mode 100644
index 00000000..abd9ab68
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/config/parameters.yml
@@ -0,0 +1,12 @@
1parameters:
2 addons_url:
3 firefox: https://addons.mozilla.org/firefox/addon/wallabag-v2/
4 chrome: https://chrome.google.com/webstore/detail/wallabagit/peehlcgckcnclnjlndmoddifcicdnabm
5 f_droid: https://f-droid.org/app/fr.gaulupeau.apps.InThePoche
6 google_play: https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche
7 ios: https://itunes.apple.com/app/wallabag/id828331015?mt=8
8 windows: https://www.microsoft.com/store/apps/wallabag/9nblggh11646
9 socials_url:
10 twitter: https://twitter.com/wallabagapp
11 google_plus: https://plus.google.com/+WallabagOrg/posts
12 facebook: https://facebook.com/Wallabag
diff --git a/src/Wallabag/CoreBundle/Resources/public/themes/baggy/css/ratatouille.css b/src/Wallabag/CoreBundle/Resources/public/themes/baggy/css/ratatouille.css
index b203cbb8..605eb641 100644
--- a/src/Wallabag/CoreBundle/Resources/public/themes/baggy/css/ratatouille.css
+++ b/src/Wallabag/CoreBundle/Resources/public/themes/baggy/css/ratatouille.css
@@ -64,7 +64,7 @@ pre {
64 max-width: 61.25em;/*980px*/ 64 max-width: 61.25em;/*980px*/
65} 65}
66 66
67table, img { 67table, img, figure {
68 max-width: 100%; 68 max-width: 100%;
69 height :auto; 69 height :auto;
70} 70}
diff --git a/src/Wallabag/CoreBundle/Resources/public/themes/material/css/main.css b/src/Wallabag/CoreBundle/Resources/public/themes/material/css/main.css
index b106d91a..b4e082d3 100755
--- a/src/Wallabag/CoreBundle/Resources/public/themes/material/css/main.css
+++ b/src/Wallabag/CoreBundle/Resources/public/themes/material/css/main.css
@@ -345,7 +345,8 @@ main ul.row {
345 max-width: 40em; 345 max-width: 40em;
346} 346}
347 347
348#article img { 348#article img,
349#article figure {
349 max-width: 100%; 350 max-width: 100%;
350 height: auto; 351 height: auto;
351} 352}
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index 8d392063..213d5790 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Status' 154 status_label: 'Status'
155 archived_label: 'Arkiveret' 155 archived_label: 'Arkiveret'
156 starred_label: 'Favorit' 156 starred_label: 'Favorit'
157 unread_label: 'Ulæst'
157 preview_picture_label: 'Har et vist billede' 158 preview_picture_label: 'Har et vist billede'
158 preview_picture_help: 'Forhåndsvis billede' 159 preview_picture_help: 'Forhåndsvis billede'
159 language_label: 'Sprog' 160 language_label: 'Sprog'
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 # entry_already_saved: 'Entry already saved on %date%' 398 # entry_already_saved: 'Entry already saved on %date%'
398 # entry_saved: 'Entry saved' 399 # entry_saved: 'Entry saved'
400 # entry_saved_failed: 'Failed to save entry'
399 # entry_updated: 'Entry updated' 401 # entry_updated: 'Entry updated'
400 # entry_reloaded: 'Entry reloaded' 402 # entry_reloaded: 'Entry reloaded'
401 # entry_reload_failed: 'Failed to reload entry' 403 # entry_reload_failed: 'Failed to reload entry'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index c7a89492..c98cf0fc 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Status' 154 status_label: 'Status'
155 archived_label: 'Archiviert' 155 archived_label: 'Archiviert'
156 starred_label: 'Favorisiert' 156 starred_label: 'Favorisiert'
157 unread_label: 'Ungelesene'
157 preview_picture_label: 'Vorschaubild vorhanden' 158 preview_picture_label: 'Vorschaubild vorhanden'
158 preview_picture_help: 'Vorschaubild' 159 preview_picture_help: 'Vorschaubild'
159 language_label: 'Sprache' 160 language_label: 'Sprache'
@@ -395,7 +396,8 @@ flashes:
395 entry: 396 entry:
396 notice: 397 notice:
397 entry_already_saved: 'Eintrag bereits am %date% gespeichert' 398 entry_already_saved: 'Eintrag bereits am %date% gespeichert'
398 entry_saved: 'Eintag gespeichert' 399 entry_saved: 'Eintrag gespeichert'
400 # entry_saved_failed: 'Failed to save entry'
399 entry_updated: 'Eintrag aktualisiert' 401 entry_updated: 'Eintrag aktualisiert'
400 entry_reloaded: 'Eintrag neugeladen' 402 entry_reloaded: 'Eintrag neugeladen'
401 entry_reload_failed: 'Neuladen des Eintrags fehlgeschlagen' 403 entry_reload_failed: 'Neuladen des Eintrags fehlgeschlagen'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 1cc42404..b65e4522 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -81,7 +81,7 @@ config:
81 archive: 'archived' 81 archive: 'archived'
82 rss_limit: 'Number of items in the feed' 82 rss_limit: 'Number of items in the feed'
83 form_user: 83 form_user:
84 two_factor_description: "Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion" 84 two_factor_description: "Enabling two factor authentication means you'll receive an email with a code on every new untrusted connection."
85 name_label: 'Name' 85 name_label: 'Name'
86 email_label: 'Email' 86 email_label: 'Email'
87 twoFactorAuthentication_label: 'Two factor authentication' 87 twoFactorAuthentication_label: 'Two factor authentication'
@@ -98,9 +98,9 @@ config:
98 faq: 98 faq:
99 title: 'FAQ' 99 title: 'FAQ'
100 tagging_rules_definition_title: 'What does « tagging rules » mean?' 100 tagging_rules_definition_title: 'What does « tagging rules » mean?'
101 tagging_rules_definition_description: 'They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble to manually classify your entries.' 101 tagging_rules_definition_description: 'They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble of manually classifying your entries.'
102 how_to_use_them_title: 'How do I use them?' 102 how_to_use_them_title: 'How do I use them?'
103 how_to_use_them_description: 'Let assume you want to tag new entries as « <i>short reading</i> » when the reading time is inferior to 3 minutes.<br />In that case, you should put « readingTime &lt;= 3 » in the <i>Rule</i> field and « <i>short reading</i> » in the <i>Tags</i> field.<br />Several tags can added simultaneously by separating them by a comma: « <i>short reading, must read</i> »<br />Complex rules can be written by using predefined operators: if « <i>readingTime &gt;= 5 AND domainName = "github.com"</i> » then tag as « <i>long reading, github </i> »' 103 how_to_use_them_description: 'Let us assume you want to tag new entries as « <i>short reading</i> » when the reading time is under 3 minutes.<br />In that case, you should put « readingTime &lt;= 3 » in the <i>Rule</i> field and « <i>short reading</i> » in the <i>Tags</i> field.<br />Several tags can added simultaneously by separating them with a comma: « <i>short reading, must read</i> »<br />Complex rules can be written by using predefined operators: if « <i>readingTime &gt;= 5 AND domainName = "github.com"</i> » then tag as « <i>long reading, github </i> »'
104 variables_available_title: 'Which variables and operators can I use to write rules?' 104 variables_available_title: 'Which variables and operators can I use to write rules?'
105 variables_available_description: 'The following variables and operators can be used to create tagging rules:' 105 variables_available_description: 'The following variables and operators can be used to create tagging rules:'
106 meaning: 'Meaning' 106 meaning: 'Meaning'
@@ -140,7 +140,7 @@ entry:
140 archived: 'Archived entries' 140 archived: 'Archived entries'
141 filtered: 'Filtered entries' 141 filtered: 'Filtered entries'
142 list: 142 list:
143 number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.' 143 number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
144 reading_time: 'estimated reading time' 144 reading_time: 'estimated reading time'
145 reading_time_minutes: 'estimated reading time: %readingTime% min' 145 reading_time_minutes: 'estimated reading time: %readingTime% min'
146 reading_time_less_one_minute: 'estimated reading time: <small class="inferieur">&lt;</small> 1 min' 146 reading_time_less_one_minute: 'estimated reading time: <small class="inferieur">&lt;</small> 1 min'
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Status' 154 status_label: 'Status'
155 archived_label: 'Archived' 155 archived_label: 'Archived'
156 starred_label: 'Starred' 156 starred_label: 'Starred'
157 unread_label: 'Unread'
157 preview_picture_label: 'Has a preview picture' 158 preview_picture_label: 'Has a preview picture'
158 preview_picture_help: 'Preview picture' 159 preview_picture_help: 'Preview picture'
159 language_label: 'Language' 160 language_label: 'Language'
@@ -222,14 +223,14 @@ about:
222 bug_reports: 'Bug reports' 223 bug_reports: 'Bug reports'
223 support: '<a href="https://support.wallabag.org">On our support website</a> or <a href="https://github.com/wallabag/wallabag/issues">on GitHub</a>' 224 support: '<a href="https://support.wallabag.org">On our support website</a> or <a href="https://github.com/wallabag/wallabag/issues">on GitHub</a>'
224 helping: 225 helping:
225 description: 'wallabag is free and opensource. You can help us:' 226 description: 'wallabag is free and open source. You can help us:'
226 by_contributing: 'by contributing to the project:' 227 by_contributing: 'by contributing to the project:'
227 by_contributing_2: 'an issue lists all our needs' 228 by_contributing_2: 'an issue lists all our needs'
228 by_paypal: 'via Paypal' 229 by_paypal: 'via Paypal'
229 contributors: 230 contributors:
230 description: 'Thank you to contributors on wallabag web application' 231 description: 'Thank you to contributors on wallabag web application'
231 third_party: 232 third_party:
232 description: 'Here are the list of third-party libraries used in wallabag (with their licenses):' 233 description: 'Here is the list of third-party libraries used in wallabag (with their licenses):'
233 package: 'Package' 234 package: 'Package'
234 license: 'License' 235 license: 'License'
235 236
@@ -258,7 +259,7 @@ quickstart:
258 page_title: 'Quickstart' 259 page_title: 'Quickstart'
259 intro: 260 intro:
260 title: 'Welcome to wallabag!' 261 title: 'Welcome to wallabag!'
261 paragraph_1: "We'll accompany you to visit wallabag and show you some features which can interest you." 262 paragraph_1: "We'll accompany you on your visit to wallabag and show you some features that might interest you."
262 paragraph_2: 'Follow us!' 263 paragraph_2: 'Follow us!'
263 configure: 264 configure:
264 title: 'Configure the application' 265 title: 'Configure the application'
@@ -290,7 +291,7 @@ quickstart:
290 title: 'Full documentation' 291 title: 'Full documentation'
291 annotate: 'Annotate your article' 292 annotate: 'Annotate your article'
292 export: 'Convert your articles into ePUB or PDF' 293 export: 'Convert your articles into ePUB or PDF'
293 search_filters: 'See how you can look for an article by using search engine and filters' 294 search_filters: 'See how you can look for an article by using the search engine and filters'
294 fetching_errors: 'What can I do if an article encounters errors during fetching?' 295 fetching_errors: 'What can I do if an article encounters errors during fetching?'
295 all_docs: 'And so many other articles!' 296 all_docs: 'And so many other articles!'
296 support: 297 support:
@@ -303,11 +304,11 @@ quickstart:
303tag: 304tag:
304 page_title: 'Tags' 305 page_title: 'Tags'
305 list: 306 list:
306 number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.' 307 number_on_the_page: '{0} There are no tags.|{1} There is one tag.|]1,Inf[ There are %count% tags.'
307 308
308import: 309import:
309 page_title: 'Import' 310 page_title: 'Import'
310 page_description: 'Welcome to wallabag importer. Please select your previous service that you want to migrate.' 311 page_description: 'Welcome to wallabag importer. Please select your previous service from which you want to migrate.'
311 action: 312 action:
312 import_contents: 'Import contents' 313 import_contents: 'Import contents'
313 form: 314 form:
@@ -317,7 +318,7 @@ import:
317 save_label: 'Upload file' 318 save_label: 'Upload file'
318 pocket: 319 pocket:
319 page_title: 'Import > Pocket' 320 page_title: 'Import > Pocket'
320 description: "This importer will import all your Pocket data. Pocket doesn't allow us to retrieve content from their service, so the readable content of each article will be re-fetched by wallabag." 321 description: "This importer will import all of your Pocket data. Pocket doesn't allow us to retrieve content from their service, so the readable content of each article will be re-fetched by wallabag."
321 config_missing: 322 config_missing:
322 description: "Pocket import isn't configured." 323 description: "Pocket import isn't configured."
323 admin_message: 'You need to define %keyurls%a pocket_consumer_key%keyurle%.' 324 admin_message: 'You need to define %keyurls%a pocket_consumer_key%keyurle%.'
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 entry_already_saved: 'Entry already saved on %date%' 398 entry_already_saved: 'Entry already saved on %date%'
398 entry_saved: 'Entry saved' 399 entry_saved: 'Entry saved'
400 entry_saved_failed: 'Failed to save entry'
399 entry_updated: 'Entry updated' 401 entry_updated: 'Entry updated'
400 entry_reloaded: 'Entry reloaded' 402 entry_reloaded: 'Entry reloaded'
401 entry_reload_failed: 'Failed to reload entry' 403 entry_reload_failed: 'Failed to reload entry'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index e8461247..75978f16 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -135,7 +135,7 @@ config:
135 135
136entry: 136entry:
137 page_titles: 137 page_titles:
138 unread: 'Artúclos no leídos' 138 unread: 'Artículos no leídos'
139 starred: 'Artículos favoritos' 139 starred: 'Artículos favoritos'
140 archived: 'Artículos archivados' 140 archived: 'Artículos archivados'
141 filtered: 'Artículos filtrados' 141 filtered: 'Artículos filtrados'
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Estatus' 154 status_label: 'Estatus'
155 archived_label: 'Archivado' 155 archived_label: 'Archivado'
156 starred_label: 'Favorito' 156 starred_label: 'Favorito'
157 unread_label: 'Sin leer'
157 preview_picture_label: 'Hay una foto' 158 preview_picture_label: 'Hay una foto'
158 preview_picture_help: 'Foto de preview' 159 preview_picture_help: 'Foto de preview'
159 language_label: 'Idioma' 160 language_label: 'Idioma'
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 entry_already_saved: 'Entrada ya guardada por %fecha%' 398 entry_already_saved: 'Entrada ya guardada por %fecha%'
398 entry_saved: 'Entrada guardada' 399 entry_saved: 'Entrada guardada'
400 # entry_saved_failed: 'Failed to save entry'
399 entry_updated: 'Entrada actualizada' 401 entry_updated: 'Entrada actualizada'
400 entry_reloaded: 'Entrada recargada' 402 entry_reloaded: 'Entrada recargada'
401 entry_reload_failed: 'Entrada recargada reprobada' 403 entry_reload_failed: 'Entrada recargada reprobada'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index d34ff8ff..db6e5960 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -96,8 +96,8 @@ config:
96 rule_label: 'قانون' 96 rule_label: 'قانون'
97 tags_label: 'برچسب‌ها' 97 tags_label: 'برچسب‌ها'
98 faq: 98 faq:
99 title: 'پرسش‌های متداول' 99 title: 'پرسش‌های متداول'
100 tagging_rules_definition_title: 'برچسب‌گذاری خودکار یعنی چه؟' 100 tagging_rules_definition_title: 'برچسب‌گذاری خودکار یعنی چه؟'
101 # tagging_rules_definition_description: 'They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble to manually classify your entries.' 101 # tagging_rules_definition_description: 'They are rules used by Wallabag to automatically tag new entries.<br />Each time a new entry is added, all the tagging rules will be used to add the tags you configured, thus saving you the trouble to manually classify your entries.'
102 # how_to_use_them_title: 'How do I use them?' 102 # how_to_use_them_title: 'How do I use them?'
103 # how_to_use_them_description: 'Let assume you want to tag new entries as « <i>short reading</i> » when the reading time is inferior to 3 minutes.<br />In that case, you should put « readingTime &lt;= 3 » in the <i>Rule</i> field and « <i>short reading</i> » in the <i>Tags</i> field.<br />Several tags can added simultaneously by separating them by a comma: « <i>short reading, must read</i> »<br />Complex rules can be written by using predefined operators: if « <i>readingTime &gt;= 5 AND domainName = "github.com"</i> » then tag as « <i>long reading, github </i> »' 103 # how_to_use_them_description: 'Let assume you want to tag new entries as « <i>short reading</i> » when the reading time is inferior to 3 minutes.<br />In that case, you should put « readingTime &lt;= 3 » in the <i>Rule</i> field and « <i>short reading</i> » in the <i>Tags</i> field.<br />Several tags can added simultaneously by separating them by a comma: « <i>short reading, must read</i> »<br />Complex rules can be written by using predefined operators: if « <i>readingTime &gt;= 5 AND domainName = "github.com"</i> » then tag as « <i>long reading, github </i> »'
@@ -154,6 +154,7 @@ entry:
154 status_label: 'وضعیت' 154 status_label: 'وضعیت'
155 archived_label: 'بایگانی‌شده' 155 archived_label: 'بایگانی‌شده'
156 starred_label: 'برگزیده' 156 starred_label: 'برگزیده'
157 unread_label: 'خوانده‌نشده'
157 preview_picture_label: 'دارای عکس پیش‌نمایش' 158 preview_picture_label: 'دارای عکس پیش‌نمایش'
158 preview_picture_help: 'پیش‌نمایش عکس' 159 preview_picture_help: 'پیش‌نمایش عکس'
159 language_label: 'زبان' 160 language_label: 'زبان'
@@ -383,30 +384,31 @@ developer:
383flashes: 384flashes:
384 config: 385 config:
385 notice: 386 notice:
386 config_saved: 'پیکربندی ذخیره شد. برخی از تنظیمات پس از این که قطع شدید اعمال می‌شود.' 387 config_saved: 'پیکربندی ذخیره شد. برخی از تنظیمات پس از این که قطع شدید اعمال می‌شود.'
387 password_updated: 'رمز به‌روز شد' 388 password_updated: 'رمز به‌روز شد'
388 password_not_updated_demo: "در حالت نمایشی نمی‌توانید رمز کاربر را عوض کنید." 389 password_not_updated_demo: "در حالت نمایشی نمی‌توانید رمز کاربر را عوض کنید."
389 user_updated: 'اطلاعات به‌روز شد' 390 user_updated: 'اطلاعات به‌روز شد'
390 rss_updated: 'اطلاعات آر-اس-اس به‌روز شد' 391 rss_updated: 'اطلاعات آر-اس-اس به‌روز شد'
391 tagging_rules_updated: 'برچسب‌گذاری خودکار به‌روز شد' 392 tagging_rules_updated: 'برچسب‌گذاری خودکار به‌روز شد'
392 tagging_rules_deleted: 'قانون برچسب‌گذاری پاک شد' 393 tagging_rules_deleted: 'قانون برچسب‌گذاری پاک شد'
393 user_added: 'کابر "%username%" اÙزوده شد' 394 user_added: 'کابر "%username%" اÙزوده شد'
394 rss_token_updated: 'کد آر-اس-اس به‌روز شد' 395 rss_token_updated: 'کد آر-اس-اس به‌روز شد'
395 entry: 396 entry:
396 notice: 397 notice:
397 entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود' 398 entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود'
398 entry_saved: 'مقاله ذخیره شد' 399 entry_saved: 'مقاله ذخیره شد'
399 entry_updated: 'مقاله به‌روز شد' 400 # entry_saved_failed: 'Failed to save entry'
400 entry_reloaded: 'مقاله به‌روز شد' 401 entry_updated: 'مقاله به‌روز شد'
401 entry_reload_failed: 'به‌روزرسانی مقاله شکست خورد' 402 entry_reloaded: 'مقاله به‌روز شد'
402 entry_archived: 'مقاله بایگانی شد' 403 entry_reload_failed: 'به‌روزرسانی مقاله شکست خورد'
403 entry_unarchived: 'مقاله از بایگانی درآمد' 404 entry_archived: 'مقاله بایگانی شد'
404 entry_starred: 'مقاله برگزیده شد' 405 entry_unarchived: 'مقاله از بایگانی درآمد'
405 entry_unstarred: 'مقاله نابرگزیده شد' 406 entry_starred: 'مقاله برگزیده شد'
406 entry_deleted: 'مقاله پاک شد' 407 entry_unstarred: 'مقاله نابرگزیده شد'
408 entry_deleted: 'مقاله پاک شد'
407 tag: 409 tag:
408 notice: 410 notice:
409 tag_added: 'برچسب اÙزوده شد' 411 tag_added: 'برچسب اÙزوده شد'
410 import: 412 import:
411 notice: 413 notice:
412 failed: 'درون‌ریزی شکست خورد. لطÙاً دوباره تلاش کنید.' 414 failed: 'درون‌ریزی شکست خورد. لطÙاً دوباره تلاش کنید.'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 80ba0546..94300596 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Status' 154 status_label: 'Status'
155 archived_label: 'Lus' 155 archived_label: 'Lus'
156 starred_label: 'Favoris' 156 starred_label: 'Favoris'
157 unread_label: 'Non lus'
157 preview_picture_label: 'A une photo' 158 preview_picture_label: 'A une photo'
158 preview_picture_help: 'Photo' 159 preview_picture_help: 'Photo'
159 language_label: 'Langue' 160 language_label: 'Langue'
@@ -267,12 +268,12 @@ quickstart:
267 tagging_rules: 'Écrivez des règles pour classer automatiquement vos articles' 268 tagging_rules: 'Écrivez des règles pour classer automatiquement vos articles'
268 admin: 269 admin:
269 title: 'Administration' 270 title: 'Administration'
270 description: "En tant qu'adminitrasteur sur wallabag, vous avez des privilèges qui vous permette de :" 271 description: "En tant qu'administrateur sur wallabag, vous avez des privilèges qui vous permettent de :"
271 new_user: 'Créer un nouvel utilisateur' 272 new_user: 'Créer un nouvel utilisateur'
272 analytics: 'Configurer les statistiques' 273 analytics: 'Configurer les statistiques'
273 sharing: 'Activer des paramètres de partages' 274 sharing: 'Activer des paramètres de partages'
274 export: 'Configurer les export' 275 export: "Configurer les formats d'export"
275 import: 'Configurer les import' 276 import: "Configurer l'import"
276 first_steps: 277 first_steps:
277 title: 'Premiers pas' 278 title: 'Premiers pas'
278 new_article: 'Ajoutez votre premier article' 279 new_article: 'Ajoutez votre premier article'
@@ -288,7 +289,7 @@ quickstart:
288 create_application: 'Créer votre application tierce' 289 create_application: 'Créer votre application tierce'
289 docs: 290 docs:
290 title: 'Documentation complète' 291 title: 'Documentation complète'
291 annotate: 'Annotater votre article' 292 annotate: 'Annoter votre article'
292 export: 'Convertissez vos articles en ePub ou en PDF' 293 export: 'Convertissez vos articles en ePub ou en PDF'
293 search_filters: "Apprenez à utiliser le moteur de recherche et les filtres pour retrouver l'article qui vous intéresse" 294 search_filters: "Apprenez à utiliser le moteur de recherche et les filtres pour retrouver l'article qui vous intéresse"
294 fetching_errors: "Que faire si mon article n'est pas correctement récupéré ?" 295 fetching_errors: "Que faire si mon article n'est pas correctement récupéré ?"
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 entry_already_saved: 'Article déjà sauvergardé le %date%' 398 entry_already_saved: 'Article déjà sauvergardé le %date%'
398 entry_saved: 'Article enregistré' 399 entry_saved: 'Article enregistré'
400 entry_saved_failed: "L'enregistrement a échoué"
399 entry_updated: 'Article mis à jour' 401 entry_updated: 'Article mis à jour'
400 entry_reloaded: 'Article rechargé' 402 entry_reloaded: 'Article rechargé'
401 entry_reload_failed: "Le rechargement de l'article a échoué" 403 entry_reload_failed: "Le rechargement de l'article a échoué"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index 4f3ac090..00ed9c98 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -396,6 +396,7 @@ flashes:
396 notice: 396 notice:
397 entry_already_saved: 'Contenuto già salvato in data %date%' 397 entry_already_saved: 'Contenuto già salvato in data %date%'
398 entry_saved: 'Contenuto salvato' 398 entry_saved: 'Contenuto salvato'
399 # entry_saved_failed: 'Failed to save entry'
399 entry_updated: 'Contenuto aggiornato' 400 entry_updated: 'Contenuto aggiornato'
400 entry_reloaded: 'Contenuto ricaricato' 401 entry_reloaded: 'Contenuto ricaricato'
401 entry_reload_failed: 'Errore nel ricaricamento del contenuto' 402 entry_reload_failed: 'Errore nel ricaricamento del contenuto'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index 46f58bbf..c81c852b 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Estatus' 154 status_label: 'Estatus'
155 archived_label: 'Legits' 155 archived_label: 'Legits'
156 starred_label: 'Favorits' 156 starred_label: 'Favorits'
157 unread_label: 'Pas legits'
157 preview_picture_label: 'A una fotò' 158 preview_picture_label: 'A una fotò'
158 preview_picture_help: 'Fotò' 159 preview_picture_help: 'Fotò'
159 language_label: 'Lenga' 160 language_label: 'Lenga'
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 entry_already_saved: 'Article ja salvargardat lo %date%' 398 entry_already_saved: 'Article ja salvargardat lo %date%'
398 entry_saved: 'Article enregistrat' 399 entry_saved: 'Article enregistrat'
400 # entry_saved_failed: 'Failed to save entry'
399 entry_updated: 'Article mes a jorn' 401 entry_updated: 'Article mes a jorn'
400 entry_reloaded: 'Article recargat' 402 entry_reloaded: 'Article recargat'
401 entry_reload_failed: "Fracàs de l'actualizacion de l'article" 403 entry_reload_failed: "Fracàs de l'actualizacion de l'article"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index 292749ed..3707a857 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Status' 154 status_label: 'Status'
155 archived_label: 'Zarchiwizowane' 155 archived_label: 'Zarchiwizowane'
156 starred_label: 'Oznaczone gwiazdkÄ…' 156 starred_label: 'Oznaczone gwiazdkÄ…'
157 unread_label: 'Nieprzeczytane'
157 preview_picture_label: 'Posiada podglÄ…d obrazu' 158 preview_picture_label: 'Posiada podglÄ…d obrazu'
158 preview_picture_help: 'PodglÄ…d obrazu' 159 preview_picture_help: 'PodglÄ…d obrazu'
159 language_label: 'Język' 160 language_label: 'Język'
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 entry_already_saved: 'Wpis już został dodany %date%' 398 entry_already_saved: 'Wpis już został dodany %date%'
398 entry_saved: 'Wpis zapisany' 399 entry_saved: 'Wpis zapisany'
400 # entry_saved_failed: 'Failed to save entry'
399 entry_updated: 'Wpis zaktualizowany' 401 entry_updated: 'Wpis zaktualizowany'
400 entry_reloaded: 'Wpis ponownie załadowany' 402 entry_reloaded: 'Wpis ponownie załadowany'
401 entry_reload_failed: 'Błąd ponownego załadowania' 403 entry_reload_failed: 'Błąd ponownego załadowania'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index 45040f35..27be1edc 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Status' 154 status_label: 'Status'
155 archived_label: 'Arhivat' 155 archived_label: 'Arhivat'
156 starred_label: 'Steluțe' 156 starred_label: 'Steluțe'
157 unread_label: 'Necitite'
157 preview_picture_label: 'Are o imagine de previzualizare' 158 preview_picture_label: 'Are o imagine de previzualizare'
158 preview_picture_help: 'Previzualizare imagine' 159 preview_picture_help: 'Previzualizare imagine'
159 language_label: 'Limbă' 160 language_label: 'Limbă'
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 # entry_already_saved: 'Entry already saved on %date%' 398 # entry_already_saved: 'Entry already saved on %date%'
398 # entry_saved: 'Entry saved' 399 # entry_saved: 'Entry saved'
400 # entry_saved_failed: 'Failed to save entry'
399 # entry_updated: 'Entry updated' 401 # entry_updated: 'Entry updated'
400 # entry_reloaded: 'Entry reloaded' 402 # entry_reloaded: 'Entry reloaded'
401 # entry_reload_failed: 'Failed to reload entry' 403 # entry_reload_failed: 'Failed to reload entry'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index 8a095a5b..85ee7316 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -154,6 +154,7 @@ entry:
154 status_label: 'Durum' 154 status_label: 'Durum'
155 archived_label: 'ArÅŸiv' 155 archived_label: 'ArÅŸiv'
156 starred_label: 'Favori' 156 starred_label: 'Favori'
157 unread_label: 'Okunmayan'
157 preview_picture_label: 'Resim önizlemesi varsa' 158 preview_picture_label: 'Resim önizlemesi varsa'
158 preview_picture_help: 'Resim önizlemesi' 159 preview_picture_help: 'Resim önizlemesi'
159 language_label: 'Dil' 160 language_label: 'Dil'
@@ -396,6 +397,7 @@ flashes:
396 notice: 397 notice:
397 entry_already_saved: 'Entry already saved on %date%' 398 entry_already_saved: 'Entry already saved on %date%'
398 entry_saved: 'Makale kaydedildi' 399 entry_saved: 'Makale kaydedildi'
400 # entry_saved_failed: 'Failed to save entry'
399 # entry_updated: 'Entry updated' 401 # entry_updated: 'Entry updated'
400 entry_reloaded: 'Makale içeriği yenilendi' 402 entry_reloaded: 'Makale içeriği yenilendi'
401 # entry_reload_failed: 'Failed to reload entry' 403 # entry_reload_failed: 'Failed to reload entry'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
index c51f90d2..a8abe8d3 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
@@ -134,7 +134,8 @@
134 </fieldset> 134 </fieldset>
135 {% endif %} 135 {% endif %}
136 136
137 {{ form_rest(form.user) }} 137 {{ form_widget(form.user._token) }}
138 {{ form_widget(form.user.save) }}
138 </form> 139 </form>
139 140
140 <h2>{{ 'config.tab_menu.password'|trans }}</h2> 141 <h2>{{ 'config.tab_menu.password'|trans }}</h2>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
index a2caaebf..778625ae 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
@@ -54,6 +54,11 @@
54 </div> 54 </div>
55 55
56 <div class="input-field"> 56 <div class="input-field">
57 {{ form_widget(form.isUnread) }}
58 {{ form_label(form.isUnread) }}
59 </div>
60
61 <div class="input-field">
57 {{ form_widget(form.previewPicture) }} 62 {{ form_widget(form.previewPicture) }}
58 {{ form_label(form.previewPicture) }} 63 {{ form_label(form.previewPicture) }}
59 </div> 64 </div>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Static/howto.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Static/howto.html.twig
index eab092c7..b529a0ac 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Static/howto.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/Static/howto.html.twig
@@ -11,14 +11,14 @@
11 </ul> 11 </ul>
12 <h3>{{ 'howto.top_menu.browser_addons'|trans }}</h3> 12 <h3>{{ 'howto.top_menu.browser_addons'|trans }}</h3>
13 <ul> 13 <ul>
14 <li><a href="https://addons.mozilla.org/firefox/addon/wallabag-v2/" target="_blank">{{ 'howto.browser_addons.firefox'|trans }}</a></li> 14 <li><a href="{{ addonsUrl.firefox }}" target="_blank">{{ 'howto.browser_addons.firefox'|trans }}</a></li>
15 <li><a href="https://chrome.google.com/webstore/detail/wallabag/bepdcjnnkglfjehplaogpoonpffbdcdj" target="_blank">{{ 'howto.browser_addons.chrome'|trans }}</a></li> 15 <li><a href="{{ addonsUrl.chrome }}" target="_blank">{{ 'howto.browser_addons.chrome'|trans }}</a></li>
16 </ul> 16 </ul>
17 <h3>{{ 'howto.top_menu.mobile_apps'|trans }}</h3> 17 <h3>{{ 'howto.top_menu.mobile_apps'|trans }}</h3>
18 <ul> 18 <ul>
19 <li>Android: <a href="https://f-droid.org/app/fr.gaulupeau.apps.InThePoche" target="_blank">{{ 'howto.mobile_apps.android.via_f_droid'|trans }}</a> / <a href="https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche" target="_blank">{{ 'howto.mobile_apps.android.via_google_play'|trans }}</a></li> 19 <li>Android: <a href="{{ addonsUrl.f_droid }}" target="_blank">{{ 'howto.mobile_apps.android.via_f_droid'|trans }}</a> / <a href="{{ addonsUrl.google_play }}" target="_blank">{{ 'howto.mobile_apps.android.via_google_play'|trans }}</a></li>
20 <li>iOS: <a href="https://itunes.apple.com/app/wallabag/id828331015?mt=8" target="_blank">{{ 'howto.mobile_apps.ios'|trans }}</a></li> 20 <li>iOS: <a href="{{ addonsUrl.ios }}" target="_blank">{{ 'howto.mobile_apps.ios'|trans }}</a></li>
21 <li>Windows Phone: <a href="http://www.windowsphone.com/en-US/store/app/wallabag/d5226cf1-f422-4e00-996c-88e9c5233332" target="_blank">{{ 'howto.mobile_apps.windows'|trans }}</a></li> 21 <li>Windows Phone: <a href="{{ addonsUrl.windows }}" target="_blank">{{ 'howto.mobile_apps.windows'|trans }}</a></li>
22 </ul> 22 </ul>
23 <h3>{{ 'howto.top_menu.bookmarklet'|trans }}</h3> 23 <h3>{{ 'howto.top_menu.bookmarklet'|trans }}</h3>
24 <p> 24 <p>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
index 5a90f227..afd5b499 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
@@ -158,7 +158,7 @@
158 {% endif %} 158 {% endif %}
159 159
160 {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }} 160 {{ form_widget(form.user.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
161 {{ form_rest(form.user) }} 161 {{ form_widget(form.user._token) }}
162 </form> 162 </form>
163 </div> 163 </div>
164 164
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
index cc4038c5..920fa933 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
@@ -32,7 +32,7 @@
32 32
33 <div class="card-content"> 33 <div class="card-content">
34 {% if not entry.previewPicture is null %} 34 {% if not entry.previewPicture is null %}
35 <i class="card-title grey-text text-darken-4 activator mdi-navigation-more-vert right"></i> 35 <i class="card-title grey-text text-darken-4 activator mdi-navigation-more-horiz right"></i>
36 {% endif %} 36 {% endif %}
37 37
38 <span class="card-title"><a href="{{ path('view', { 'id': entry.id }) }}" title="{{ entry.title|raw }}">{{ entry.title|striptags|slice(0, 42)|raw }}</a></span> 38 <span class="card-title"><a href="{{ path('view', { 'id': entry.id }) }}" title="{{ entry.title|raw }}">{{ entry.title|striptags|slice(0, 42)|raw }}</a></span>
@@ -126,6 +126,11 @@
126 {{ form_label(form.isStarred) }} 126 {{ form_label(form.isStarred) }}
127 </div> 127 </div>
128 128
129 <div class="input-field col s6 with-checkbox">
130 {{ form_widget(form.isUnread) }}
131 {{ form_label(form.isUnread) }}
132 </div>
133
129 <div class="col s12"> 134 <div class="col s12">
130 <label>{{ 'entry.filters.preview_picture_help'|trans }}</label> 135 <label>{{ 'entry.filters.preview_picture_help'|trans }}</label>
131 </div> 136 </div>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/howto.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/howto.html.twig
index 4354a6b7..6a177d6b 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/howto.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Static/howto.html.twig
@@ -18,17 +18,17 @@
18 <div class="col s12"> 18 <div class="col s12">
19 <h5>{{ 'howto.top_menu.browser_addons'|trans }}</h5> 19 <h5>{{ 'howto.top_menu.browser_addons'|trans }}</h5>
20 <ul> 20 <ul>
21 <li><a href="https://addons.mozilla.org/firefox/addon/wallabag-v2/" target="_blank">{{ 'howto.browser_addons.firefox'|trans }}</a></li> 21 <li><a href="{{ addonsUrl.firefox }}" target="_blank">{{ 'howto.browser_addons.firefox'|trans }}</a></li>
22 <li><a href="https://chrome.google.com/webstore/detail/wallabag/bepdcjnnkglfjehplaogpoonpffbdcdj" target="_blank">{{ 'howto.browser_addons.chrome'|trans }}</a></li> 22 <li><a href="{{ addonsUrl.chrome }}" target="_blank">{{ 'howto.browser_addons.chrome'|trans }}</a></li>
23 </ul> 23 </ul>
24 </div> 24 </div>
25 25
26 <div class="col s12"> 26 <div class="col s12">
27 <h5>{{ 'howto.top_menu.mobile_apps'|trans }}</h5> 27 <h5>{{ 'howto.top_menu.mobile_apps'|trans }}</h5>
28 <ul> 28 <ul>
29 <li>Android: <a href="https://f-droid.org/app/fr.gaulupeau.apps.InThePoche" target="_blank">{{ 'howto.mobile_apps.android.via_f_droid'|trans }}</a> / <a href="https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche" target="_blank">{{ 'howto.mobile_apps.android.via_google_play'|trans }}</a></li> 29 <li>Android: <a href="{{ addonsUrl.f_droid }}" target="_blank">{{ 'howto.mobile_apps.android.via_f_droid'|trans }}</a> / <a href="{{ addonsUrl.google_play }}" target="_blank">{{ 'howto.mobile_apps.android.via_google_play'|trans }}</a></li>
30 <li>iOS: <a href="https://itunes.apple.com/app/wallabag/id828331015?mt=8" target="_blank">{{ 'howto.mobile_apps.ios'|trans }}</a></li> 30 <li>iOS: <a href="{{ addonsUrl.ios }}" target="_blank">{{ 'howto.mobile_apps.ios'|trans }}</a></li>
31 <li>Windows Phone: <a href="http://www.windowsphone.com/en-US/store/app/wallabag/d5226cf1-f422-4e00-996c-88e9c5233332" target="_blank">{{ 'howto.mobile_apps.windows'|trans }}</a></li> 31 <li>Windows Phone: <a href="{{ addonsUrl.windows }}" target="_blank">{{ 'howto.mobile_apps.windows'|trans }}</a></li>
32 </ul> 32 </ul>
33 </div> 33 </div>
34 34
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/footer.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/footer.html.twig
new file mode 100644
index 00000000..7cb19966
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/footer.html.twig
@@ -0,0 +1,41 @@
1<footer class="page-footer cyan darken-2">
2 <div class="container">
3 <div class="row">
4 <div class="col l6 s12">
5 <h5 class="white-text">{{ 'footer.wallabag.elsewhere'|trans }}</h5>
6 <p class="grey-text text-lighten-4">
7 <a target="_blank" class="grey-text text-lighten-3" href="{{ addonsUrl.google_play }}" title="Android">
8 <span class="icon-android"></span>
9 </a>
10 <a target="_blank" class="grey-text text-lighten-3" href="{{ addonsUrl.ios }}" title="iOS">
11 <span class="icon-apple"></span>
12 </a>
13 <a target="_blank" class="grey-text text-lighten-3" href="{{ addonsUrl.firefox }}" title="Firefox">
14 <span class="icon-firefox"></span>
15 </a>
16 <a target="_blank" class="grey-text text-lighten-3" href="{{ addonsUrl.chrome }}" title="Chrome">
17 <span class="icon-chrome"></span>
18 </a>
19 </p>
20 </div>
21 <div class="col l4 offset-l2 s12">
22 <h5 class="white-text">{{ 'footer.wallabag.social'|trans }}</h5>
23 <a target="_blank" class="grey-text text-lighten-3" href="{{ socialsUrl.twitter }}" title="Twitter">
24 <span class="icon-twitter"></span>
25 </a>
26 <a target="_blank" class="grey-text text-lighten-3" href="{{ socialsUrl.google_plus }}" title="Google+">
27 <span class="icon-google-plus2"></span>
28 </a>
29 <a target="_blank" class="grey-text text-lighten-3" href="{{ socialsUrl.facebook }}" title="Facebook">
30 <span class="icon-facebook2"></span>
31 </a>
32 </div>
33 </div>
34 </div>
35 <div class="footer-copyright">
36 <div class="container">
37 <p>{{ 'footer.wallabag.powered_by'|trans }} <a target="_blank" href="https://wallabag.org" class="grey-text text-lighten-4">wallabag</a></p>
38 <a class="grey-text text-lighten-4 right" href="{{ path('about') }}">{{ 'footer.wallabag.about'|trans }}</a>
39 </div>
40 </div>
41</footer>
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
index 25ad23dd..a5c16792 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
@@ -122,45 +122,5 @@
122{% endblock %} 122{% endblock %}
123 123
124{% block footer %} 124{% block footer %}
125 <footer class="page-footer cyan darken-2"> 125 {{ render(controller("WallabagCoreBundle:Footer:index")) }}
126 <div class="container">
127 <div class="row">
128 <div class="col l6 s12">
129 <h5 class="white-text">{{ 'footer.wallabag.elsewhere'|trans }}</h5>
130 <p class="grey-text text-lighten-4">
131 <a target="_blank" class="grey-text text-lighten-3" href="https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche" title="Android">
132 <span class="icon-android"></span>
133 </a>
134 <a target="_blank" class="grey-text text-lighten-3" href="https://itunes.apple.com/app/id828331015" title="iOS">
135 <span class="icon-apple"></span>
136 </a>
137 <a target="_blank" class="grey-text text-lighten-3" href="https://addons.mozilla.org/firefox/addon/wallabag/" title="Firefox">
138 <span class="icon-firefox"></span>
139 </a>
140 <a target="_blank" class="grey-text text-lighten-3" href="https://chrome.google.com/webstore/detail/wallabagit/peehlcgckcnclnjlndmoddifcicdnabm" title="Chrome">
141 <span class="icon-chrome"></span>
142 </a>
143 </p>
144 </div>
145 <div class="col l4 offset-l2 s12">
146 <h5 class="white-text">{{ 'footer.wallabag.social'|trans }}</h5>
147 <a target="_blank" class="grey-text text-lighten-3" href="https://twitter.com/wallabagapp" title="Twitter">
148 <span class="icon-twitter"></span>
149 </a>
150 <a target="_blank" class="grey-text text-lighten-3" href="https://plus.google.com/+WallabagOrg/posts" title="Google+">
151 <span class="icon-google-plus2"></span>
152 </a>
153 <a target="_blank" class="grey-text text-lighten-3" href="https://facebook.com/Wallabag" title="Facebook">
154 <span class="icon-facebook2"></span>
155 </a>
156 </div>
157 </div>
158 </div>
159 <div class="footer-copyright">
160 <div class="container">
161 <p>{{ 'footer.wallabag.powered_by'|trans }} <a target="_blank" href="https://wallabag.org" class="grey-text text-lighten-4">wallabag</a></p>
162 <a class="grey-text text-lighten-4 right" href="{{ path('about') }}">{{ 'footer.wallabag.about'|trans }}</a>
163 </div>
164 </div>
165 </footer>
166{% endblock %} 126{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
deleted file mode 100644
index 0673d581..00000000
--- a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
+++ /dev/null
@@ -1,279 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Command;
4
5use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand;
6use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand;
7use Symfony\Bundle\FrameworkBundle\Console\Application;
8use Symfony\Component\Console\Input\ArrayInput;
9use Symfony\Component\Console\Output\NullOutput;
10use Symfony\Component\Console\Tester\CommandTester;
11use Wallabag\CoreBundle\Command\InstallCommand;
12use Wallabag\CoreBundle\Tests\Mock\InstallCommandMock;
13use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
14
15class InstallCommandTest extends WallabagCoreTestCase
16{
17 public function setUp()
18 {
19 parent::setUp();
20
21 if ($this->getClient()->getContainer()->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOPgSql\Driver) {
22 /*
23 * LOG: statement: CREATE DATABASE "wallabag"
24 * ERROR: source database "template1" is being accessed by other users
25 * DETAIL: There is 1 other session using the database.
26 * STATEMENT: CREATE DATABASE "wallabag"
27 * FATAL: database "wallabag" does not exist
28 *
29 * http://stackoverflow.com/a/14374832/569101
30 */
31 $this->markTestSkipped('PostgreSQL spotted: can find a good way to drop current database, skipping.');
32 }
33 }
34
35 public static function tearDownAfterClass()
36 {
37 $application = new Application(static::$kernel);
38 $application->setAutoExit(false);
39
40 $code = $application->run(new ArrayInput([
41 'command' => 'doctrine:fixtures:load',
42 '--no-interaction' => true,
43 '--env' => 'test',
44 ]), new NullOutput());
45 }
46
47 public function testRunInstallCommand()
48 {
49 $application = new Application($this->getClient()->getKernel());
50 $application->add(new InstallCommandMock());
51
52 $command = $application->find('wallabag:install');
53
54 // We mock the QuestionHelper
55 $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
56 ->disableOriginalConstructor()
57 ->getMock();
58 $question->expects($this->any())
59 ->method('ask')
60 ->will($this->returnValue('yes_'.uniqid('', true)));
61
62 // We override the standard helper with our mock
63 $command->getHelperSet()->set($question, 'question');
64
65 $tester = new CommandTester($command);
66 $tester->execute([
67 'command' => $command->getName(),
68 ]);
69
70 $this->assertContains('Checking system requirements.', $tester->getDisplay());
71 $this->assertContains('Setting up database.', $tester->getDisplay());
72 $this->assertContains('Administration setup.', $tester->getDisplay());
73 $this->assertContains('Config setup.', $tester->getDisplay());
74 $this->assertContains('Installing assets.', $tester->getDisplay());
75 }
76
77 public function testRunInstallCommandWithReset()
78 {
79 $application = new Application($this->getClient()->getKernel());
80 $application->add(new InstallCommandMock());
81
82 $command = $application->find('wallabag:install');
83
84 // We mock the QuestionHelper
85 $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
86 ->disableOriginalConstructor()
87 ->getMock();
88 $question->expects($this->any())
89 ->method('ask')
90 ->will($this->returnValue('yes_'.uniqid('', true)));
91
92 // We override the standard helper with our mock
93 $command->getHelperSet()->set($question, 'question');
94
95 $tester = new CommandTester($command);
96 $tester->execute([
97 'command' => $command->getName(),
98 '--reset' => true,
99 ]);
100
101 $this->assertContains('Checking system requirements.', $tester->getDisplay());
102 $this->assertContains('Setting up database.', $tester->getDisplay());
103 $this->assertContains('Droping database, creating database and schema, clearing the cache', $tester->getDisplay());
104 $this->assertContains('Administration setup.', $tester->getDisplay());
105 $this->assertContains('Config setup.', $tester->getDisplay());
106 $this->assertContains('Installing assets.', $tester->getDisplay());
107
108 // we force to reset everything
109 $this->assertContains('Droping database, creating database and schema, clearing the cache', $tester->getDisplay());
110 }
111
112 public function testRunInstallCommandWithDatabaseRemoved()
113 {
114 $application = new Application($this->getClient()->getKernel());
115 $application->add(new DropDatabaseDoctrineCommand());
116
117 // drop database first, so the install command won't ask to reset things
118 $command = $application->find('doctrine:database:drop');
119 $command->run(new ArrayInput([
120 'command' => 'doctrine:database:drop',
121 '--force' => true,
122 ]), new NullOutput());
123
124 // start a new application to avoid lagging connexion to pgsql
125 $client = static::createClient();
126 $application = new Application($client->getKernel());
127 $application->add(new InstallCommand());
128
129 $command = $application->find('wallabag:install');
130
131 // We mock the QuestionHelper
132 $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
133 ->disableOriginalConstructor()
134 ->getMock();
135 $question->expects($this->any())
136 ->method('ask')
137 ->will($this->returnValue('yes_'.uniqid('', true)));
138
139 // We override the standard helper with our mock
140 $command->getHelperSet()->set($question, 'question');
141
142 $tester = new CommandTester($command);
143 $tester->execute([
144 'command' => $command->getName(),
145 ]);
146
147 $this->assertContains('Checking system requirements.', $tester->getDisplay());
148 $this->assertContains('Setting up database.', $tester->getDisplay());
149 $this->assertContains('Administration setup.', $tester->getDisplay());
150 $this->assertContains('Config setup.', $tester->getDisplay());
151 $this->assertContains('Installing assets.', $tester->getDisplay());
152
153 // the current database doesn't already exist
154 $this->assertContains('Creating database and schema, clearing the cache', $tester->getDisplay());
155 }
156
157 public function testRunInstallCommandChooseResetSchema()
158 {
159 $application = new Application($this->getClient()->getKernel());
160 $application->add(new InstallCommandMock());
161
162 $command = $application->find('wallabag:install');
163
164 // We mock the QuestionHelper
165 $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
166 ->disableOriginalConstructor()
167 ->getMock();
168
169 $question->expects($this->exactly(3))
170 ->method('ask')
171 ->will($this->onConsecutiveCalls(
172 false, // don't want to reset the entire database
173 true, // do want to reset the schema
174 false // don't want to create a new user
175 ));
176
177 // We override the standard helper with our mock
178 $command->getHelperSet()->set($question, 'question');
179
180 $tester = new CommandTester($command);
181 $tester->execute([
182 'command' => $command->getName(),
183 ]);
184
185 $this->assertContains('Checking system requirements.', $tester->getDisplay());
186 $this->assertContains('Setting up database.', $tester->getDisplay());
187 $this->assertContains('Administration setup.', $tester->getDisplay());
188 $this->assertContains('Config setup.', $tester->getDisplay());
189 $this->assertContains('Installing assets.', $tester->getDisplay());
190
191 $this->assertContains('Droping schema and creating schema', $tester->getDisplay());
192 }
193
194 public function testRunInstallCommandChooseNothing()
195 {
196 $application = new Application($this->getClient()->getKernel());
197 $application->add(new InstallCommand());
198 $application->add(new DropDatabaseDoctrineCommand());
199 $application->add(new CreateDatabaseDoctrineCommand());
200
201 // drop database first, so the install command won't ask to reset things
202 $command = new DropDatabaseDoctrineCommand();
203 $command->setApplication($application);
204 $command->run(new ArrayInput([
205 'command' => 'doctrine:database:drop',
206 '--force' => true,
207 ]), new NullOutput());
208
209 $this->getClient()->getContainer()->get('doctrine')->getConnection()->close();
210
211 $command = new CreateDatabaseDoctrineCommand();
212 $command->setApplication($application);
213 $command->run(new ArrayInput([
214 'command' => 'doctrine:database:create',
215 '--env' => 'test',
216 ]), new NullOutput());
217
218 $command = $application->find('wallabag:install');
219
220 // We mock the QuestionHelper
221 $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
222 ->disableOriginalConstructor()
223 ->getMock();
224
225 $question->expects($this->exactly(2))
226 ->method('ask')
227 ->will($this->onConsecutiveCalls(
228 false, // don't want to reset the entire database
229 false // don't want to create a new user
230 ));
231
232 // We override the standard helper with our mock
233 $command->getHelperSet()->set($question, 'question');
234
235 $tester = new CommandTester($command);
236 $tester->execute([
237 'command' => $command->getName(),
238 ]);
239
240 $this->assertContains('Checking system requirements.', $tester->getDisplay());
241 $this->assertContains('Setting up database.', $tester->getDisplay());
242 $this->assertContains('Administration setup.', $tester->getDisplay());
243 $this->assertContains('Config setup.', $tester->getDisplay());
244 $this->assertContains('Installing assets.', $tester->getDisplay());
245
246 $this->assertContains('Creating schema', $tester->getDisplay());
247 }
248
249 public function testRunInstallCommandNoInteraction()
250 {
251 $application = new Application($this->getClient()->getKernel());
252 $application->add(new InstallCommandMock());
253
254 $command = $application->find('wallabag:install');
255
256 // We mock the QuestionHelper
257 $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
258 ->disableOriginalConstructor()
259 ->getMock();
260 $question->expects($this->any())
261 ->method('ask')
262 ->will($this->returnValue('yes_'.uniqid('', true)));
263
264 // We override the standard helper with our mock
265 $command->getHelperSet()->set($question, 'question');
266
267 $tester = new CommandTester($command);
268 $tester->execute([
269 'command' => $command->getName(),
270 '--no-interaction' => true,
271 ]);
272
273 $this->assertContains('Checking system requirements.', $tester->getDisplay());
274 $this->assertContains('Setting up database.', $tester->getDisplay());
275 $this->assertContains('Administration setup.', $tester->getDisplay());
276 $this->assertContains('Config setup.', $tester->getDisplay());
277 $this->assertContains('Installing assets.', $tester->getDisplay());
278 }
279}
diff --git a/src/Wallabag/CoreBundle/Tests/Command/TagAllCommandTest.php b/src/Wallabag/CoreBundle/Tests/Command/TagAllCommandTest.php
deleted file mode 100644
index 4f544c1d..00000000
--- a/src/Wallabag/CoreBundle/Tests/Command/TagAllCommandTest.php
+++ /dev/null
@@ -1,60 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Command;
4
5use Symfony\Bundle\FrameworkBundle\Console\Application;
6use Symfony\Component\Console\Tester\CommandTester;
7use Wallabag\CoreBundle\Command\TagAllCommand;
8use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
9
10class TagAllCommandTest extends WallabagCoreTestCase
11{
12 /**
13 * @expectedException Symfony\Component\Console\Exception\RuntimeException
14 * @expectedExceptionMessage Not enough arguments (missing: "username")
15 */
16 public function testRunTagAllCommandWithoutUsername()
17 {
18 $application = new Application($this->getClient()->getKernel());
19 $application->add(new TagAllCommand());
20
21 $command = $application->find('wallabag:tag:all');
22
23 $tester = new CommandTester($command);
24 $tester->execute([
25 'command' => $command->getName(),
26 ]);
27 }
28
29 public function testRunTagAllCommandWithBadUsername()
30 {
31 $application = new Application($this->getClient()->getKernel());
32 $application->add(new TagAllCommand());
33
34 $command = $application->find('wallabag:tag:all');
35
36 $tester = new CommandTester($command);
37 $tester->execute([
38 'command' => $command->getName(),
39 'username' => 'unknown',
40 ]);
41
42 $this->assertContains('User "unknown" not found', $tester->getDisplay());
43 }
44
45 public function testRunTagAllCommand()
46 {
47 $application = new Application($this->getClient()->getKernel());
48 $application->add(new TagAllCommand());
49
50 $command = $application->find('wallabag:tag:all');
51
52 $tester = new CommandTester($command);
53 $tester->execute([
54 'command' => $command->getName(),
55 'username' => 'admin',
56 ]);
57
58 $this->assertContains('Tagging entries for user « admin »... Done', $tester->getDisplay());
59 }
60}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
deleted file mode 100644
index 8cdedfda..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
+++ /dev/null
@@ -1,652 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7class ConfigControllerTest extends WallabagCoreTestCase
8{
9 public function testLogin()
10 {
11 $client = $this->getClient();
12
13 $client->request('GET', '/new');
14
15 $this->assertEquals(302, $client->getResponse()->getStatusCode());
16 $this->assertContains('login', $client->getResponse()->headers->get('location'));
17 }
18
19 public function testIndex()
20 {
21 $this->logInAs('admin');
22 $client = $this->getClient();
23
24 $crawler = $client->request('GET', '/config');
25
26 $this->assertEquals(200, $client->getResponse()->getStatusCode());
27
28 $this->assertCount(1, $crawler->filter('button[id=config_save]'));
29 $this->assertCount(1, $crawler->filter('button[id=change_passwd_save]'));
30 $this->assertCount(1, $crawler->filter('button[id=update_user_save]'));
31 $this->assertCount(1, $crawler->filter('button[id=new_user_save]'));
32 $this->assertCount(1, $crawler->filter('button[id=rss_config_save]'));
33 }
34
35 public function testUpdate()
36 {
37 $this->logInAs('admin');
38 $client = $this->getClient();
39
40 $crawler = $client->request('GET', '/config');
41
42 $this->assertEquals(200, $client->getResponse()->getStatusCode());
43
44 $form = $crawler->filter('button[id=config_save]')->form();
45
46 $data = [
47 'config[theme]' => 'baggy',
48 'config[items_per_page]' => '30',
49 'config[reading_speed]' => '0.5',
50 'config[language]' => 'en',
51 ];
52
53 $client->submit($form, $data);
54
55 $this->assertEquals(302, $client->getResponse()->getStatusCode());
56
57 $crawler = $client->followRedirect();
58
59 $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text']));
60 $this->assertContains('flashes.config.notice.config_saved', $alert[0]);
61 }
62
63 public function testChangeReadingSpeed()
64 {
65 $this->logInAs('admin');
66 $client = $this->getClient();
67
68 $crawler = $client->request('GET', '/unread/list');
69 $form = $crawler->filter('button[id=submit-filter]')->form();
70 $dataFilters = [
71 'entry_filter[readingTime][right_number]' => 22,
72 'entry_filter[readingTime][left_number]' => 22,
73 ];
74 $crawler = $client->submit($form, $dataFilters);
75 $this->assertCount(1, $crawler->filter('div[class=entry]'));
76
77 // Change reading speed
78 $crawler = $client->request('GET', '/config');
79 $form = $crawler->filter('button[id=config_save]')->form();
80 $data = [
81 'config[reading_speed]' => '2',
82 ];
83 $client->submit($form, $data);
84
85 // Is the entry still available via filters?
86 $crawler = $client->request('GET', '/unread/list');
87 $form = $crawler->filter('button[id=submit-filter]')->form();
88 $crawler = $client->submit($form, $dataFilters);
89 $this->assertCount(0, $crawler->filter('div[class=entry]'));
90
91 // Restore old configuration
92 $crawler = $client->request('GET', '/config');
93 $form = $crawler->filter('button[id=config_save]')->form();
94 $data = [
95 'config[reading_speed]' => '0.5',
96 ];
97 $client->submit($form, $data);
98 }
99
100 public function dataForUpdateFailed()
101 {
102 return [
103 [[
104 'config[theme]' => 'baggy',
105 'config[items_per_page]' => '',
106 'config[language]' => 'en',
107 ]],
108 ];
109 }
110
111 /**
112 * @dataProvider dataForUpdateFailed
113 */
114 public function testUpdateFailed($data)
115 {
116 $this->logInAs('admin');
117 $client = $this->getClient();
118
119 $crawler = $client->request('GET', '/config');
120
121 $this->assertEquals(200, $client->getResponse()->getStatusCode());
122
123 $form = $crawler->filter('button[id=config_save]')->form();
124
125 $crawler = $client->submit($form, $data);
126
127 $this->assertEquals(200, $client->getResponse()->getStatusCode());
128
129 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
130 $this->assertContains('This value should not be blank', $alert[0]);
131 }
132
133 public function dataForChangePasswordFailed()
134 {
135 return [
136 [
137 [
138 'change_passwd[old_password]' => 'material',
139 'change_passwd[new_password][first]' => '',
140 'change_passwd[new_password][second]' => '',
141 ],
142 'validator.password_wrong_value',
143 ],
144 [
145 [
146 'change_passwd[old_password]' => 'mypassword',
147 'change_passwd[new_password][first]' => '',
148 'change_passwd[new_password][second]' => '',
149 ],
150 'This value should not be blank',
151 ],
152 [
153 [
154 'change_passwd[old_password]' => 'mypassword',
155 'change_passwd[new_password][first]' => 'hop',
156 'change_passwd[new_password][second]' => '',
157 ],
158 'validator.password_must_match',
159 ],
160 [
161 [
162 'change_passwd[old_password]' => 'mypassword',
163 'change_passwd[new_password][first]' => 'hop',
164 'change_passwd[new_password][second]' => 'hop',
165 ],
166 'validator.password_too_short',
167 ],
168 ];
169 }
170
171 /**
172 * @dataProvider dataForChangePasswordFailed
173 */
174 public function testChangePasswordFailed($data, $expectedMessage)
175 {
176 $this->logInAs('admin');
177 $client = $this->getClient();
178
179 $crawler = $client->request('GET', '/config');
180
181 $this->assertEquals(200, $client->getResponse()->getStatusCode());
182
183 $form = $crawler->filter('button[id=change_passwd_save]')->form();
184
185 $crawler = $client->submit($form, $data);
186
187 $this->assertEquals(200, $client->getResponse()->getStatusCode());
188
189 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
190 $this->assertContains($expectedMessage, $alert[0]);
191 }
192
193 public function testChangePassword()
194 {
195 $this->logInAs('admin');
196 $client = $this->getClient();
197
198 $crawler = $client->request('GET', '/config');
199
200 $this->assertEquals(200, $client->getResponse()->getStatusCode());
201
202 $form = $crawler->filter('button[id=change_passwd_save]')->form();
203
204 $data = [
205 'change_passwd[old_password]' => 'mypassword',
206 'change_passwd[new_password][first]' => 'mypassword',
207 'change_passwd[new_password][second]' => 'mypassword',
208 ];
209
210 $client->submit($form, $data);
211
212 $this->assertEquals(302, $client->getResponse()->getStatusCode());
213
214 $crawler = $client->followRedirect();
215
216 $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text']));
217 $this->assertContains('flashes.config.notice.password_updated', $alert[0]);
218 }
219
220 public function dataForUserFailed()
221 {
222 return [
223 [
224 [
225 'update_user[name]' => '',
226 'update_user[email]' => '',
227 ],
228 'fos_user.email.blank',
229 ],
230 [
231 [
232 'update_user[name]' => '',
233 'update_user[email]' => 'test',
234 ],
235 'fos_user.email.invalid',
236 ],
237 ];
238 }
239
240 /**
241 * @dataProvider dataForUserFailed
242 */
243 public function testUserFailed($data, $expectedMessage)
244 {
245 $this->logInAs('admin');
246 $client = $this->getClient();
247
248 $crawler = $client->request('GET', '/config');
249
250 $this->assertEquals(200, $client->getResponse()->getStatusCode());
251
252 $form = $crawler->filter('button[id=update_user_save]')->form();
253
254 $crawler = $client->submit($form, $data);
255
256 $this->assertEquals(200, $client->getResponse()->getStatusCode());
257
258 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
259 $this->assertContains($expectedMessage, $alert[0]);
260 }
261
262 public function testUserUpdate()
263 {
264 $this->logInAs('admin');
265 $client = $this->getClient();
266
267 $crawler = $client->request('GET', '/config');
268
269 $this->assertEquals(200, $client->getResponse()->getStatusCode());
270
271 $form = $crawler->filter('button[id=update_user_save]')->form();
272
273 $data = [
274 'update_user[name]' => 'new name',
275 'update_user[email]' => 'admin@wallabag.io',
276 ];
277
278 $client->submit($form, $data);
279
280 $this->assertEquals(302, $client->getResponse()->getStatusCode());
281
282 $crawler = $client->followRedirect();
283
284 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
285 $this->assertContains('flashes.config.notice.user_updated', $alert[0]);
286 }
287
288 public function dataForNewUserFailed()
289 {
290 return [
291 [
292 [
293 'new_user[username]' => '',
294 'new_user[plainPassword][first]' => '',
295 'new_user[plainPassword][second]' => '',
296 'new_user[email]' => '',
297 ],
298 'fos_user.username.blank',
299 ],
300 [
301 [
302 'new_user[username]' => 'a',
303 'new_user[plainPassword][first]' => 'mypassword',
304 'new_user[plainPassword][second]' => 'mypassword',
305 'new_user[email]' => '',
306 ],
307 'fos_user.username.short',
308 ],
309 [
310 [
311 'new_user[username]' => 'wallace',
312 'new_user[plainPassword][first]' => 'mypassword',
313 'new_user[plainPassword][second]' => 'mypassword',
314 'new_user[email]' => 'test',
315 ],
316 'fos_user.email.invalid',
317 ],
318 [
319 [
320 'new_user[username]' => 'admin',
321 'new_user[plainPassword][first]' => 'wallacewallace',
322 'new_user[plainPassword][second]' => 'wallacewallace',
323 'new_user[email]' => 'wallace@wallace.me',
324 ],
325 'fos_user.username.already_used',
326 ],
327 [
328 [
329 'new_user[username]' => 'wallace',
330 'new_user[plainPassword][first]' => 'mypassword1',
331 'new_user[plainPassword][second]' => 'mypassword2',
332 'new_user[email]' => 'wallace@wallace.me',
333 ],
334 'validator.password_must_match',
335 ],
336 ];
337 }
338
339 /**
340 * @dataProvider dataForNewUserFailed
341 */
342 public function testNewUserFailed($data, $expectedMessage)
343 {
344 $this->logInAs('admin');
345 $client = $this->getClient();
346
347 $crawler = $client->request('GET', '/config');
348
349 $this->assertEquals(200, $client->getResponse()->getStatusCode());
350
351 $form = $crawler->filter('button[id=new_user_save]')->form();
352
353 $crawler = $client->submit($form, $data);
354
355 $this->assertEquals(200, $client->getResponse()->getStatusCode());
356
357 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
358 $this->assertContains($expectedMessage, $alert[0]);
359 }
360
361 public function testNewUserCreated()
362 {
363 $this->logInAs('admin');
364 $client = $this->getClient();
365
366 $crawler = $client->request('GET', '/config');
367
368 $this->assertEquals(200, $client->getResponse()->getStatusCode());
369
370 $form = $crawler->filter('button[id=new_user_save]')->form();
371
372 $data = [
373 'new_user[username]' => 'wallace',
374 'new_user[plainPassword][first]' => 'wallace1',
375 'new_user[plainPassword][second]' => 'wallace1',
376 'new_user[email]' => 'wallace@wallace.me',
377 ];
378
379 $client->submit($form, $data);
380
381 $this->assertEquals(302, $client->getResponse()->getStatusCode());
382
383 $crawler = $client->followRedirect();
384
385 $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text']));
386 $this->assertContains('flashes.config.notice.user_added', $alert[0]);
387
388 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
389 $user = $em
390 ->getRepository('WallabagUserBundle:User')
391 ->findOneByUsername('wallace');
392
393 $this->assertTrue(false !== $user);
394 $this->assertTrue($user->isEnabled());
395 $this->assertEquals('material', $user->getConfig()->getTheme());
396 $this->assertEquals(12, $user->getConfig()->getItemsPerPage());
397 $this->assertEquals(50, $user->getConfig()->getRssLimit());
398 $this->assertEquals('en', $user->getConfig()->getLanguage());
399 $this->assertEquals(1, $user->getConfig()->getReadingSpeed());
400 }
401
402 public function testRssUpdateResetToken()
403 {
404 $this->logInAs('admin');
405 $client = $this->getClient();
406
407 // reset the token
408 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
409 $user = $em
410 ->getRepository('WallabagUserBundle:User')
411 ->findOneByUsername('admin');
412
413 if (!$user) {
414 $this->markTestSkipped('No user found in db.');
415 }
416
417 $config = $user->getConfig();
418 $config->setRssToken(null);
419 $em->persist($config);
420 $em->flush();
421
422 $crawler = $client->request('GET', '/config');
423
424 $this->assertEquals(200, $client->getResponse()->getStatusCode());
425
426 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
427 $this->assertContains('config.form_rss.no_token', $body[0]);
428
429 $client->request('GET', '/generate-token');
430 $this->assertEquals(302, $client->getResponse()->getStatusCode());
431
432 $crawler = $client->followRedirect();
433
434 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
435 $this->assertNotContains('config.form_rss.no_token', $body[0]);
436 }
437
438 public function testGenerateTokenAjax()
439 {
440 $this->logInAs('admin');
441 $client = $this->getClient();
442
443 $client->request(
444 'GET',
445 '/generate-token',
446 [],
447 [],
448 ['HTTP_X-Requested-With' => 'XMLHttpRequest']
449 );
450
451 $this->assertEquals(200, $client->getResponse()->getStatusCode());
452 $content = json_decode($client->getResponse()->getContent(), true);
453 $this->assertArrayHasKey('token', $content);
454 }
455
456 public function testRssUpdate()
457 {
458 $this->logInAs('admin');
459 $client = $this->getClient();
460
461 $crawler = $client->request('GET', '/config');
462
463 $this->assertEquals(200, $client->getResponse()->getStatusCode());
464
465 $form = $crawler->filter('button[id=rss_config_save]')->form();
466
467 $data = [
468 'rss_config[rss_limit]' => 12,
469 ];
470
471 $client->submit($form, $data);
472
473 $this->assertEquals(302, $client->getResponse()->getStatusCode());
474
475 $crawler = $client->followRedirect();
476
477 $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text']));
478 $this->assertContains('flashes.config.notice.rss_updated', $alert[0]);
479 }
480
481 public function dataForRssFailed()
482 {
483 return [
484 [
485 [
486 'rss_config[rss_limit]' => 0,
487 ],
488 'This value should be 1 or more.',
489 ],
490 [
491 [
492 'rss_config[rss_limit]' => 1000000000000,
493 ],
494 'validator.rss_limit_too_hight',
495 ],
496 ];
497 }
498
499 /**
500 * @dataProvider dataForRssFailed
501 */
502 public function testRssFailed($data, $expectedMessage)
503 {
504 $this->logInAs('admin');
505 $client = $this->getClient();
506
507 $crawler = $client->request('GET', '/config');
508
509 $this->assertEquals(200, $client->getResponse()->getStatusCode());
510
511 $form = $crawler->filter('button[id=rss_config_save]')->form();
512
513 $crawler = $client->submit($form, $data);
514
515 $this->assertEquals(200, $client->getResponse()->getStatusCode());
516
517 $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text']));
518 $this->assertContains($expectedMessage, $alert[0]);
519 }
520
521 public function testTaggingRuleCreation()
522 {
523 $this->logInAs('admin');
524 $client = $this->getClient();
525
526 $crawler = $client->request('GET', '/config');
527
528 $this->assertTrue($client->getResponse()->isSuccessful());
529
530 $form = $crawler->filter('button[id=tagging_rule_save]')->form();
531
532 $data = [
533 'tagging_rule[rule]' => 'readingTime <= 3',
534 'tagging_rule[tags]' => 'short reading',
535 ];
536
537 $client->submit($form, $data);
538
539 $this->assertEquals(302, $client->getResponse()->getStatusCode());
540
541 $crawler = $client->followRedirect();
542
543 $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text']));
544 $this->assertContains('flashes.config.notice.tagging_rules_updated', $alert[0]);
545
546 $deleteLink = $crawler->filter('.delete')->last()->link();
547
548 $crawler = $client->click($deleteLink);
549 $this->assertEquals(302, $client->getResponse()->getStatusCode());
550
551 $crawler = $client->followRedirect();
552 $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text']));
553 $this->assertContains('flashes.config.notice.tagging_rules_deleted', $alert[0]);
554 }
555
556 public function dataForTaggingRuleFailed()
557 {
558 return [
559 [
560 [
561 'tagging_rule[rule]' => 'unknownVar <= 3',
562 'tagging_rule[tags]' => 'cool tag',
563 ],
564 [
565 'The variable',
566 'does not exist.',
567 ],
568 ],
569 [
570 [
571 'tagging_rule[rule]' => 'length(domainName) <= 42',
572 'tagging_rule[tags]' => 'cool tag',
573 ],
574 [
575 'The operator',
576 'does not exist.',
577 ],
578 ],
579 ];
580 }
581
582 /**
583 * @dataProvider dataForTaggingRuleFailed
584 */
585 public function testTaggingRuleCreationFail($data, $messages)
586 {
587 $this->logInAs('admin');
588 $client = $this->getClient();
589
590 $crawler = $client->request('GET', '/config');
591
592 $this->assertTrue($client->getResponse()->isSuccessful());
593
594 $form = $crawler->filter('button[id=tagging_rule_save]')->form();
595
596 $crawler = $client->submit($form, $data);
597
598 $this->assertEquals(200, $client->getResponse()->getStatusCode());
599
600 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
601
602 foreach ($messages as $message) {
603 $this->assertContains($message, $body[0]);
604 }
605 }
606
607 public function testDeletingTaggingRuleFromAnOtherUser()
608 {
609 $this->logInAs('bob');
610 $client = $this->getClient();
611
612 $rule = $client->getContainer()->get('doctrine.orm.entity_manager')
613 ->getRepository('WallabagCoreBundle:TaggingRule')
614 ->findAll()[0];
615
616 $crawler = $client->request('GET', '/tagging-rule/delete/'.$rule->getId());
617
618 $this->assertEquals(403, $client->getResponse()->getStatusCode());
619 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
620 $this->assertContains('You can not access this tagging rule', $body[0]);
621 }
622
623 public function testDemoMode()
624 {
625 $this->logInAs('admin');
626 $client = $this->getClient();
627
628 $config = $client->getContainer()->get('craue_config');
629 $config->set('demo_mode_enabled', 1);
630 $config->set('demo_mode_username', 'admin');
631
632 $crawler = $client->request('GET', '/config');
633
634 $this->assertEquals(200, $client->getResponse()->getStatusCode());
635
636 $form = $crawler->filter('button[id=change_passwd_save]')->form();
637
638 $data = [
639 'change_passwd[old_password]' => 'mypassword',
640 'change_passwd[new_password][first]' => 'mypassword',
641 'change_passwd[new_password][second]' => 'mypassword',
642 ];
643
644 $client->submit($form, $data);
645
646 $this->assertEquals(302, $client->getResponse()->getStatusCode());
647 $this->assertContains('flashes.config.notice.password_not_updated_demo', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]);
648
649 $config->set('demo_mode_enabled', 0);
650 $config->set('demo_mode_username', 'wallabag');
651 }
652}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/DeveloperControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/DeveloperControllerTest.php
deleted file mode 100644
index fc220b85..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/DeveloperControllerTest.php
+++ /dev/null
@@ -1,71 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7class DeveloperControllerTest extends WallabagCoreTestCase
8{
9 public function testCreateClient()
10 {
11 $this->logInAs('admin');
12 $client = $this->getClient();
13 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
14 $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
15
16 $crawler = $client->request('GET', '/developer/client/create');
17 $this->assertEquals(200, $client->getResponse()->getStatusCode());
18
19 $form = $crawler->filter('button[type=submit]')->form();
20
21 $client->submit($form);
22
23 $this->assertEquals(200, $client->getResponse()->getStatusCode());
24
25 $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
26 $this->assertGreaterThan(count($nbClients), count($newNbClients));
27 }
28
29 public function testListingClient()
30 {
31 $this->logInAs('admin');
32 $client = $this->getClient();
33 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
34 $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
35
36 $crawler = $client->request('GET', '/developer');
37 $this->assertEquals(200, $client->getResponse()->getStatusCode());
38 $this->assertEquals(count($nbClients), $crawler->filter('ul[class=collapsible] li')->count());
39 }
40
41 public function testDeveloperHowto()
42 {
43 $this->logInAs('admin');
44 $client = $this->getClient();
45
46 $crawler = $client->request('GET', '/developer/howto/first-app');
47 $this->assertEquals(200, $client->getResponse()->getStatusCode());
48 }
49
50 public function testRemoveClient()
51 {
52 $this->logInAs('admin');
53 $client = $this->getClient();
54 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
55 $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
56
57 $crawler = $client->request('GET', '/developer');
58
59 $link = $crawler
60 ->filter('div[class=collapsible-body] p a')
61 ->eq(0)
62 ->link()
63 ;
64
65 $client->click($link);
66 $this->assertEquals(302, $client->getResponse()->getStatusCode());
67
68 $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll();
69 $this->assertGreaterThan(count($newNbClients), count($nbClients));
70 }
71}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
deleted file mode 100644
index df4c34cd..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
+++ /dev/null
@@ -1,619 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6use Wallabag\CoreBundle\Entity\Entry;
7
8class EntryControllerTest extends WallabagCoreTestCase
9{
10 public $url = 'http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html';
11
12 public function testLogin()
13 {
14 $client = $this->getClient();
15
16 $client->request('GET', '/new');
17
18 $this->assertEquals(302, $client->getResponse()->getStatusCode());
19 $this->assertContains('login', $client->getResponse()->headers->get('location'));
20 }
21
22 public function testQuickstart()
23 {
24 $this->logInAs('empty');
25 $client = $this->getClient();
26
27 $client->request('GET', '/unread/list');
28 $crawler = $client->followRedirect();
29
30 $this->assertEquals(200, $client->getResponse()->getStatusCode());
31 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
32 $this->assertContains('quickstart.intro.paragraph_1', $body[0]);
33
34 // Test if quickstart is disabled when user has 1 entry
35 $crawler = $client->request('GET', '/new');
36
37 $this->assertEquals(200, $client->getResponse()->getStatusCode());
38
39 $form = $crawler->filter('form[name=entry]')->form();
40
41 $data = [
42 'entry[url]' => $this->url,
43 ];
44
45 $client->submit($form, $data);
46 $this->assertEquals(302, $client->getResponse()->getStatusCode());
47 $client->followRedirect();
48
49 $crawler = $client->request('GET', '/unread/list');
50 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
51 $this->assertContains('entry.list.number_on_the_page', $body[0]);
52 }
53
54 public function testGetNew()
55 {
56 $this->logInAs('admin');
57 $client = $this->getClient();
58
59 $crawler = $client->request('GET', '/new');
60
61 $this->assertEquals(200, $client->getResponse()->getStatusCode());
62
63 $this->assertCount(1, $crawler->filter('input[type=url]'));
64 $this->assertCount(1, $crawler->filter('form[name=entry]'));
65 }
66
67 public function testPostNewViaBookmarklet()
68 {
69 $this->logInAs('admin');
70 $client = $this->getClient();
71
72 $crawler = $client->request('GET', '/');
73
74 $this->assertCount(4, $crawler->filter('div[class=entry]'));
75
76 // Good URL
77 $client->request('GET', '/bookmarklet', ['url' => $this->url]);
78 $this->assertEquals(302, $client->getResponse()->getStatusCode());
79 $client->followRedirect();
80 $crawler = $client->request('GET', '/');
81 $this->assertCount(5, $crawler->filter('div[class=entry]'));
82
83 $em = $client->getContainer()
84 ->get('doctrine.orm.entity_manager');
85 $entry = $em
86 ->getRepository('WallabagCoreBundle:Entry')
87 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
88 $em->remove($entry);
89 $em->flush();
90 }
91
92 public function testPostNewEmpty()
93 {
94 $this->logInAs('admin');
95 $client = $this->getClient();
96
97 $crawler = $client->request('GET', '/new');
98
99 $this->assertEquals(200, $client->getResponse()->getStatusCode());
100
101 $form = $crawler->filter('form[name=entry]')->form();
102
103 $crawler = $client->submit($form);
104
105 $this->assertEquals(200, $client->getResponse()->getStatusCode());
106 $this->assertCount(1, $alert = $crawler->filter('form ul li')->extract(['_text']));
107 $this->assertEquals('This value should not be blank.', $alert[0]);
108 }
109
110 /**
111 * This test will require an internet connection.
112 */
113 public function testPostNewOk()
114 {
115 $this->logInAs('admin');
116 $client = $this->getClient();
117
118 $crawler = $client->request('GET', '/new');
119
120 $this->assertEquals(200, $client->getResponse()->getStatusCode());
121
122 $form = $crawler->filter('form[name=entry]')->form();
123
124 $data = [
125 'entry[url]' => $this->url,
126 ];
127
128 $client->submit($form, $data);
129
130 $this->assertEquals(302, $client->getResponse()->getStatusCode());
131
132 $content = $client->getContainer()
133 ->get('doctrine.orm.entity_manager')
134 ->getRepository('WallabagCoreBundle:Entry')
135 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
136
137 $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
138 $this->assertEquals($this->url, $content->getUrl());
139 $this->assertContains('Google', $content->getTitle());
140 }
141
142 public function testPostNewOkUrlExist()
143 {
144 $this->logInAs('admin');
145 $client = $this->getClient();
146
147 $crawler = $client->request('GET', '/new');
148
149 $this->assertEquals(200, $client->getResponse()->getStatusCode());
150
151 $form = $crawler->filter('form[name=entry]')->form();
152
153 $data = [
154 'entry[url]' => $this->url,
155 ];
156
157 $client->submit($form, $data);
158
159 $this->assertEquals(302, $client->getResponse()->getStatusCode());
160 $this->assertContains('/view/', $client->getResponse()->getTargetUrl());
161 }
162
163 /**
164 * This test will require an internet connection.
165 */
166 public function testPostNewThatWillBeTaggued()
167 {
168 $this->logInAs('admin');
169 $client = $this->getClient();
170
171 $crawler = $client->request('GET', '/new');
172
173 $this->assertEquals(200, $client->getResponse()->getStatusCode());
174
175 $form = $crawler->filter('form[name=entry]')->form();
176
177 $data = [
178 'entry[url]' => $url = 'https://github.com/wallabag/wallabag',
179 ];
180
181 $client->submit($form, $data);
182
183 $this->assertEquals(302, $client->getResponse()->getStatusCode());
184
185 $client->followRedirect();
186
187 $em = $client->getContainer()
188 ->get('doctrine.orm.entity_manager');
189 $entry = $em
190 ->getRepository('WallabagCoreBundle:Entry')
191 ->findOneByUrl($url);
192 $tags = $entry->getTags();
193
194 $this->assertCount(1, $tags);
195 $this->assertEquals('wallabag', $tags[0]->getLabel());
196
197 $em->remove($entry);
198 $em->flush();
199 }
200
201 public function testArchive()
202 {
203 $this->logInAs('admin');
204 $client = $this->getClient();
205
206 $client->request('GET', '/archive/list');
207
208 $this->assertEquals(200, $client->getResponse()->getStatusCode());
209 }
210
211 public function testStarred()
212 {
213 $this->logInAs('admin');
214 $client = $this->getClient();
215
216 $client->request('GET', '/starred/list');
217
218 $this->assertEquals(200, $client->getResponse()->getStatusCode());
219 }
220
221 public function testRangeException()
222 {
223 $this->logInAs('admin');
224 $client = $this->getClient();
225
226 $client->request('GET', '/all/list/900');
227
228 $this->assertEquals(302, $client->getResponse()->getStatusCode());
229 $this->assertEquals('/all/list', $client->getResponse()->getTargetUrl());
230 }
231
232 /**
233 * @depends testPostNewOk
234 */
235 public function testView()
236 {
237 $this->logInAs('admin');
238 $client = $this->getClient();
239
240 $content = $client->getContainer()
241 ->get('doctrine.orm.entity_manager')
242 ->getRepository('WallabagCoreBundle:Entry')
243 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
244
245 $crawler = $client->request('GET', '/view/'.$content->getId());
246
247 $this->assertEquals(200, $client->getResponse()->getStatusCode());
248 $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text']));
249 $this->assertContains($content->getTitle(), $body[0]);
250 }
251
252 /**
253 * @depends testPostNewOk
254 *
255 * This test will require an internet connection.
256 */
257 public function testReload()
258 {
259 $this->logInAs('admin');
260 $client = $this->getClient();
261
262 $content = $client->getContainer()
263 ->get('doctrine.orm.entity_manager')
264 ->getRepository('WallabagCoreBundle:Entry')
265 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
266
267 // empty content
268 $content->setContent('');
269 $client->getContainer()->get('doctrine.orm.entity_manager')->persist($content);
270 $client->getContainer()->get('doctrine.orm.entity_manager')->flush();
271
272 $client->request('GET', '/reload/'.$content->getId());
273
274 $this->assertEquals(302, $client->getResponse()->getStatusCode());
275
276 $content = $client->getContainer()
277 ->get('doctrine.orm.entity_manager')
278 ->getRepository('WallabagCoreBundle:Entry')
279 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
280
281 $this->assertNotEmpty($content->getContent());
282 }
283
284 public function testEdit()
285 {
286 $this->logInAs('admin');
287 $client = $this->getClient();
288
289 $content = $client->getContainer()
290 ->get('doctrine.orm.entity_manager')
291 ->getRepository('WallabagCoreBundle:Entry')
292 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
293
294 $crawler = $client->request('GET', '/edit/'.$content->getId());
295
296 $this->assertEquals(200, $client->getResponse()->getStatusCode());
297
298 $this->assertCount(1, $crawler->filter('input[id=entry_title]'));
299 $this->assertCount(1, $crawler->filter('button[id=entry_save]'));
300 }
301
302 public function testEditUpdate()
303 {
304 $this->logInAs('admin');
305 $client = $this->getClient();
306
307 $content = $client->getContainer()
308 ->get('doctrine.orm.entity_manager')
309 ->getRepository('WallabagCoreBundle:Entry')
310 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
311
312 $crawler = $client->request('GET', '/edit/'.$content->getId());
313
314 $this->assertEquals(200, $client->getResponse()->getStatusCode());
315
316 $form = $crawler->filter('button[type=submit]')->form();
317
318 $data = [
319 'entry[title]' => 'My updated title hehe :)',
320 ];
321
322 $client->submit($form, $data);
323
324 $this->assertEquals(302, $client->getResponse()->getStatusCode());
325
326 $crawler = $client->followRedirect();
327
328 $this->assertGreaterThan(1, $alert = $crawler->filter('div[id=article] h1')->extract(['_text']));
329 $this->assertContains('My updated title hehe :)', $alert[0]);
330 }
331
332 public function testToggleArchive()
333 {
334 $this->logInAs('admin');
335 $client = $this->getClient();
336
337 $content = $client->getContainer()
338 ->get('doctrine.orm.entity_manager')
339 ->getRepository('WallabagCoreBundle:Entry')
340 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
341
342 $client->request('GET', '/archive/'.$content->getId());
343
344 $this->assertEquals(302, $client->getResponse()->getStatusCode());
345
346 $res = $client->getContainer()
347 ->get('doctrine.orm.entity_manager')
348 ->getRepository('WallabagCoreBundle:Entry')
349 ->find($content->getId());
350
351 $this->assertEquals($res->isArchived(), true);
352 }
353
354 public function testToggleStar()
355 {
356 $this->logInAs('admin');
357 $client = $this->getClient();
358
359 $content = $client->getContainer()
360 ->get('doctrine.orm.entity_manager')
361 ->getRepository('WallabagCoreBundle:Entry')
362 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
363
364 $client->request('GET', '/star/'.$content->getId());
365
366 $this->assertEquals(302, $client->getResponse()->getStatusCode());
367
368 $res = $client->getContainer()
369 ->get('doctrine.orm.entity_manager')
370 ->getRepository('WallabagCoreBundle:Entry')
371 ->findOneById($content->getId());
372
373 $this->assertEquals($res->isStarred(), true);
374 }
375
376 public function testDelete()
377 {
378 $this->logInAs('admin');
379 $client = $this->getClient();
380
381 $content = $client->getContainer()
382 ->get('doctrine.orm.entity_manager')
383 ->getRepository('WallabagCoreBundle:Entry')
384 ->findByUrlAndUserId($this->url, $this->getLoggedInUserId());
385
386 $client->request('GET', '/delete/'.$content->getId());
387
388 $this->assertEquals(302, $client->getResponse()->getStatusCode());
389
390 $client->request('GET', '/delete/'.$content->getId());
391
392 $this->assertEquals(404, $client->getResponse()->getStatusCode());
393 }
394
395 /**
396 * It will create a new entry.
397 * Browse to it.
398 * Then remove it.
399 *
400 * And it'll check that user won't be redirected to the view page of the content when it had been removed
401 */
402 public function testViewAndDelete()
403 {
404 $this->logInAs('admin');
405 $client = $this->getClient();
406
407 // add a new content to be removed later
408 $user = $client->getContainer()
409 ->get('doctrine.orm.entity_manager')
410 ->getRepository('WallabagUserBundle:User')
411 ->findOneByUserName('admin');
412
413 $content = new Entry($user);
414 $content->setUrl('http://1.1.1.1/entry');
415 $content->setReadingTime(12);
416 $content->setDomainName('domain.io');
417 $content->setMimetype('text/html');
418 $content->setTitle('test title entry');
419 $content->setContent('This is my content /o/');
420 $content->setArchived(true);
421 $content->setLanguage('fr');
422
423 $client->getContainer()
424 ->get('doctrine.orm.entity_manager')
425 ->persist($content);
426 $client->getContainer()
427 ->get('doctrine.orm.entity_manager')
428 ->flush();
429
430 $client->request('GET', '/view/'.$content->getId());
431 $this->assertEquals(200, $client->getResponse()->getStatusCode());
432
433 $client->request('GET', '/delete/'.$content->getId());
434 $this->assertEquals(302, $client->getResponse()->getStatusCode());
435
436 $client->followRedirect();
437 $this->assertEquals(200, $client->getResponse()->getStatusCode());
438 }
439
440 public function testViewOtherUserEntry()
441 {
442 $this->logInAs('admin');
443 $client = $this->getClient();
444
445 $content = $client->getContainer()
446 ->get('doctrine.orm.entity_manager')
447 ->getRepository('WallabagCoreBundle:Entry')
448 ->findOneByUsernameAndNotArchived('bob');
449
450 $client->request('GET', '/view/'.$content->getId());
451
452 $this->assertEquals(403, $client->getResponse()->getStatusCode());
453 }
454
455 public function testFilterOnReadingTime()
456 {
457 $this->logInAs('admin');
458 $client = $this->getClient();
459
460 $crawler = $client->request('GET', '/unread/list');
461
462 $form = $crawler->filter('button[id=submit-filter]')->form();
463
464 $data = [
465 'entry_filter[readingTime][right_number]' => 22,
466 'entry_filter[readingTime][left_number]' => 22,
467 ];
468
469 $crawler = $client->submit($form, $data);
470
471 $this->assertCount(1, $crawler->filter('div[class=entry]'));
472 }
473
474 public function testFilterOnCreationDate()
475 {
476 $this->logInAs('admin');
477 $client = $this->getClient();
478
479 $crawler = $client->request('GET', '/unread/list');
480
481 $form = $crawler->filter('button[id=submit-filter]')->form();
482
483 $data = [
484 'entry_filter[createdAt][left_date]' => date('d/m/Y'),
485 'entry_filter[createdAt][right_date]' => date('d/m/Y', strtotime('+1 day')),
486 ];
487
488 $crawler = $client->submit($form, $data);
489
490 $this->assertCount(5, $crawler->filter('div[class=entry]'));
491
492 $data = [
493 'entry_filter[createdAt][left_date]' => date('d/m/Y'),
494 'entry_filter[createdAt][right_date]' => date('d/m/Y'),
495 ];
496
497 $crawler = $client->submit($form, $data);
498
499 $this->assertCount(5, $crawler->filter('div[class=entry]'));
500
501 $data = [
502 'entry_filter[createdAt][left_date]' => '01/01/1970',
503 'entry_filter[createdAt][right_date]' => '01/01/1970',
504 ];
505
506 $crawler = $client->submit($form, $data);
507
508 $this->assertCount(0, $crawler->filter('div[class=entry]'));
509 }
510
511 public function testPaginationWithFilter()
512 {
513 $this->logInAs('admin');
514 $client = $this->getClient();
515 $crawler = $client->request('GET', '/config');
516
517 $form = $crawler->filter('button[id=config_save]')->form();
518
519 $data = [
520 'config[items_per_page]' => '1',
521 ];
522
523 $client->submit($form, $data);
524
525 $parameters = '?entry_filter%5BreadingTime%5D%5Bleft_number%5D=&entry_filter%5BreadingTime%5D%5Bright_number%5D=';
526
527 $client->request('GET', 'unread/list'.$parameters);
528
529 $this->assertContains($parameters, $client->getResponse()->getContent());
530
531 // reset pagination
532 $crawler = $client->request('GET', '/config');
533 $form = $crawler->filter('button[id=config_save]')->form();
534 $data = [
535 'config[items_per_page]' => '12',
536 ];
537 $client->submit($form, $data);
538 }
539
540 public function testFilterOnDomainName()
541 {
542 $this->logInAs('admin');
543 $client = $this->getClient();
544
545 $crawler = $client->request('GET', '/unread/list');
546 $form = $crawler->filter('button[id=submit-filter]')->form();
547 $data = [
548 'entry_filter[domainName]' => 'domain',
549 ];
550
551 $crawler = $client->submit($form, $data);
552 $this->assertCount(5, $crawler->filter('div[class=entry]'));
553
554 $form = $crawler->filter('button[id=submit-filter]')->form();
555 $data = [
556 'entry_filter[domainName]' => 'wallabag',
557 ];
558
559 $crawler = $client->submit($form, $data);
560 $this->assertCount(0, $crawler->filter('div[class=entry]'));
561 }
562
563 public function testFilterOnStatus()
564 {
565 $this->logInAs('admin');
566 $client = $this->getClient();
567
568 $crawler = $client->request('GET', '/unread/list');
569 $form = $crawler->filter('button[id=submit-filter]')->form();
570 $form['entry_filter[isArchived]']->tick();
571 $form['entry_filter[isStarred]']->untick();
572
573 $crawler = $client->submit($form);
574 $this->assertCount(1, $crawler->filter('div[class=entry]'));
575
576 $form = $crawler->filter('button[id=submit-filter]')->form();
577 $form['entry_filter[isArchived]']->untick();
578 $form['entry_filter[isStarred]']->tick();
579
580 $crawler = $client->submit($form);
581 $this->assertCount(1, $crawler->filter('div[class=entry]'));
582 }
583
584 public function testPreviewPictureFilter()
585 {
586 $this->logInAs('admin');
587 $client = $this->getClient();
588
589 $crawler = $client->request('GET', '/unread/list');
590 $form = $crawler->filter('button[id=submit-filter]')->form();
591 $form['entry_filter[previewPicture]']->tick();
592
593 $crawler = $client->submit($form);
594 $this->assertCount(1, $crawler->filter('div[class=entry]'));
595 }
596
597 public function testFilterOnLanguage()
598 {
599 $this->logInAs('admin');
600 $client = $this->getClient();
601
602 $crawler = $client->request('GET', '/unread/list');
603 $form = $crawler->filter('button[id=submit-filter]')->form();
604 $data = [
605 'entry_filter[language]' => 'fr',
606 ];
607
608 $crawler = $client->submit($form, $data);
609 $this->assertCount(2, $crawler->filter('div[class=entry]'));
610
611 $form = $crawler->filter('button[id=submit-filter]')->form();
612 $data = [
613 'entry_filter[language]' => 'en',
614 ];
615
616 $crawler = $client->submit($form, $data);
617 $this->assertCount(2, $crawler->filter('div[class=entry]'));
618 }
619}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php
deleted file mode 100644
index 76c98055..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/ExportControllerTest.php
+++ /dev/null
@@ -1,251 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7class ExportControllerTest extends WallabagCoreTestCase
8{
9 public function testLogin()
10 {
11 $client = $this->getClient();
12
13 $client->request('GET', '/export/unread.csv');
14
15 $this->assertEquals(302, $client->getResponse()->getStatusCode());
16 $this->assertContains('login', $client->getResponse()->headers->get('location'));
17 }
18
19 public function testUnknownCategoryExport()
20 {
21 $this->logInAs('admin');
22 $client = $this->getClient();
23
24 $client->request('GET', '/export/awesomeness.epub');
25
26 $this->assertEquals(404, $client->getResponse()->getStatusCode());
27 }
28
29 public function testUnknownFormatExport()
30 {
31 $this->logInAs('admin');
32 $client = $this->getClient();
33
34 $client->request('GET', '/export/unread.xslx');
35
36 $this->assertEquals(404, $client->getResponse()->getStatusCode());
37 }
38
39 public function testUnsupportedFormatExport()
40 {
41 $this->logInAs('admin');
42 $client = $this->getClient();
43
44 $client->request('GET', '/export/unread.doc');
45 $this->assertEquals(404, $client->getResponse()->getStatusCode());
46
47 $content = $client->getContainer()
48 ->get('doctrine.orm.entity_manager')
49 ->getRepository('WallabagCoreBundle:Entry')
50 ->findOneByUsernameAndNotArchived('admin');
51
52 $client->request('GET', '/export/'.$content->getId().'.doc');
53 $this->assertEquals(404, $client->getResponse()->getStatusCode());
54 }
55
56 public function testBadEntryId()
57 {
58 $this->logInAs('admin');
59 $client = $this->getClient();
60
61 $client->request('GET', '/export/0.mobi');
62
63 $this->assertEquals(404, $client->getResponse()->getStatusCode());
64 }
65
66 public function testEpubExport()
67 {
68 $this->logInAs('admin');
69 $client = $this->getClient();
70
71 ob_start();
72 $crawler = $client->request('GET', '/export/archive.epub');
73 ob_end_clean();
74
75 $this->assertEquals(200, $client->getResponse()->getStatusCode());
76
77 $headers = $client->getResponse()->headers;
78 $this->assertEquals('application/epub+zip', $headers->get('content-type'));
79 $this->assertEquals('attachment; filename="Archive articles.epub"', $headers->get('content-disposition'));
80 $this->assertEquals('binary', $headers->get('content-transfer-encoding'));
81 }
82
83 public function testMobiExport()
84 {
85 $this->logInAs('admin');
86 $client = $this->getClient();
87
88 $content = $client->getContainer()
89 ->get('doctrine.orm.entity_manager')
90 ->getRepository('WallabagCoreBundle:Entry')
91 ->findOneByUsernameAndNotArchived('admin');
92
93 ob_start();
94 $crawler = $client->request('GET', '/export/'.$content->getId().'.mobi');
95 ob_end_clean();
96
97 $this->assertEquals(200, $client->getResponse()->getStatusCode());
98
99 $headers = $client->getResponse()->headers;
100 $this->assertEquals('application/x-mobipocket-ebook', $headers->get('content-type'));
101 $this->assertEquals('attachment; filename="'.preg_replace('/[^A-Za-z0-9\-]/', '', $content->getTitle()).'.mobi"', $headers->get('content-disposition'));
102 $this->assertEquals('binary', $headers->get('content-transfer-encoding'));
103 }
104
105 public function testPdfExport()
106 {
107 $this->logInAs('admin');
108 $client = $this->getClient();
109
110 ob_start();
111 $crawler = $client->request('GET', '/export/all.pdf');
112 ob_end_clean();
113
114 $this->assertEquals(200, $client->getResponse()->getStatusCode());
115
116 $headers = $client->getResponse()->headers;
117 $this->assertEquals('application/pdf', $headers->get('content-type'));
118 $this->assertEquals('attachment; filename="All articles.pdf"', $headers->get('content-disposition'));
119 $this->assertEquals('binary', $headers->get('content-transfer-encoding'));
120 }
121
122 public function testTxtExport()
123 {
124 $this->logInAs('admin');
125 $client = $this->getClient();
126
127 ob_start();
128 $crawler = $client->request('GET', '/export/all.txt');
129 ob_end_clean();
130
131 $this->assertEquals(200, $client->getResponse()->getStatusCode());
132
133 $headers = $client->getResponse()->headers;
134 $this->assertEquals('text/plain; charset=UTF-8', $headers->get('content-type'));
135 $this->assertEquals('attachment; filename="All articles.txt"', $headers->get('content-disposition'));
136 $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding'));
137 }
138
139 public function testCsvExport()
140 {
141 $this->logInAs('admin');
142 $client = $this->getClient();
143
144 // to be sure results are the same
145 $contentInDB = $client->getContainer()
146 ->get('doctrine.orm.entity_manager')
147 ->getRepository('WallabagCoreBundle:Entry')
148 ->createQueryBuilder('e')
149 ->leftJoin('e.user', 'u')
150 ->where('u.username = :username')->setParameter('username', 'admin')
151 ->andWhere('e.isArchived = true')
152 ->getQuery()
153 ->getArrayResult();
154
155 ob_start();
156 $crawler = $client->request('GET', '/export/archive.csv');
157 ob_end_clean();
158
159 $this->assertEquals(200, $client->getResponse()->getStatusCode());
160
161 $headers = $client->getResponse()->headers;
162 $this->assertEquals('application/csv', $headers->get('content-type'));
163 $this->assertEquals('attachment; filename="Archive articles.csv"', $headers->get('content-disposition'));
164 $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding'));
165
166 $csv = str_getcsv($client->getResponse()->getContent(), "\n");
167
168 $this->assertGreaterThan(1, $csv);
169 // +1 for title line
170 $this->assertEquals(count($contentInDB) + 1, count($csv));
171 $this->assertEquals('Title;URL;Content;Tags;"MIME Type";Language', $csv[0]);
172 }
173
174 public function testJsonExport()
175 {
176 $this->logInAs('admin');
177 $client = $this->getClient();
178
179 // to be sure results are the same
180 $contentInDB = $client->getContainer()
181 ->get('doctrine.orm.entity_manager')
182 ->getRepository('WallabagCoreBundle:Entry')
183 ->createQueryBuilder('e')
184 ->leftJoin('e.user', 'u')
185 ->where('u.username = :username')->setParameter('username', 'admin')
186 ->getQuery()
187 ->getArrayResult();
188
189 ob_start();
190 $crawler = $client->request('GET', '/export/all.json');
191 ob_end_clean();
192
193 $this->assertEquals(200, $client->getResponse()->getStatusCode());
194
195 $headers = $client->getResponse()->headers;
196 $this->assertEquals('application/json', $headers->get('content-type'));
197 $this->assertEquals('attachment; filename="All articles.json"', $headers->get('content-disposition'));
198 $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding'));
199
200 $content = json_decode($client->getResponse()->getContent(), true);
201 $this->assertEquals(count($contentInDB), count($content));
202 $this->assertArrayHasKey('id', $content[0]);
203 $this->assertArrayHasKey('title', $content[0]);
204 $this->assertArrayHasKey('url', $content[0]);
205 $this->assertArrayHasKey('is_archived', $content[0]);
206 $this->assertArrayHasKey('is_starred', $content[0]);
207 $this->assertArrayHasKey('content', $content[0]);
208 $this->assertArrayHasKey('mimetype', $content[0]);
209 $this->assertArrayHasKey('language', $content[0]);
210 $this->assertArrayHasKey('reading_time', $content[0]);
211 $this->assertArrayHasKey('domain_name', $content[0]);
212 $this->assertArrayHasKey('tags', $content[0]);
213 }
214
215 public function testXmlExport()
216 {
217 $this->logInAs('admin');
218 $client = $this->getClient();
219
220 // to be sure results are the same
221 $contentInDB = $client->getContainer()
222 ->get('doctrine.orm.entity_manager')
223 ->getRepository('WallabagCoreBundle:Entry')
224 ->createQueryBuilder('e')
225 ->leftJoin('e.user', 'u')
226 ->where('u.username = :username')->setParameter('username', 'admin')
227 ->andWhere('e.isArchived = false')
228 ->getQuery()
229 ->getArrayResult();
230
231 ob_start();
232 $crawler = $client->request('GET', '/export/unread.xml');
233 ob_end_clean();
234
235 $this->assertEquals(200, $client->getResponse()->getStatusCode());
236
237 $headers = $client->getResponse()->headers;
238 $this->assertEquals('application/xml', $headers->get('content-type'));
239 $this->assertEquals('attachment; filename="Unread articles.xml"', $headers->get('content-disposition'));
240 $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding'));
241
242 $content = new \SimpleXMLElement($client->getResponse()->getContent());
243 $this->assertGreaterThan(0, $content->count());
244 $this->assertEquals(count($contentInDB), $content->count());
245 $this->assertNotEmpty('id', (string) $content->entry[0]->id);
246 $this->assertNotEmpty('title', (string) $content->entry[0]->title);
247 $this->assertNotEmpty('url', (string) $content->entry[0]->url);
248 $this->assertNotEmpty('content', (string) $content->entry[0]->content);
249 $this->assertNotEmpty('domain_name', (string) $content->entry[0]->domain_name);
250 }
251}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php
deleted file mode 100644
index 87a01b8e..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php
+++ /dev/null
@@ -1,126 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7class RssControllerTest extends WallabagCoreTestCase
8{
9 public function validateDom($xml, $nb = null)
10 {
11 $doc = new \DOMDocument();
12 $doc->loadXML($xml);
13
14 $xpath = new \DOMXpath($doc);
15
16 if (null === $nb) {
17 $this->assertGreaterThan(0, $xpath->query('//item')->length);
18 } else {
19 $this->assertEquals($nb, $xpath->query('//item')->length);
20 }
21
22 $this->assertEquals(1, $xpath->query('/rss')->length);
23 $this->assertEquals(1, $xpath->query('/rss/channel')->length);
24
25 foreach ($xpath->query('//item') as $item) {
26 $this->assertEquals(1, $xpath->query('title', $item)->length);
27 $this->assertEquals(1, $xpath->query('source', $item)->length);
28 $this->assertEquals(1, $xpath->query('link', $item)->length);
29 $this->assertEquals(1, $xpath->query('guid', $item)->length);
30 $this->assertEquals(1, $xpath->query('pubDate', $item)->length);
31 $this->assertEquals(1, $xpath->query('description', $item)->length);
32 }
33 }
34
35 public function dataForBadUrl()
36 {
37 return [
38 [
39 '/admin/YZIOAUZIAO/unread.xml',
40 ],
41 [
42 '/wallace/YZIOAUZIAO/starred.xml',
43 ],
44 [
45 '/wallace/YZIOAUZIAO/archives.xml',
46 ],
47 ];
48 }
49
50 /**
51 * @dataProvider dataForBadUrl
52 */
53 public function testBadUrl($url)
54 {
55 $client = $this->getClient();
56
57 $client->request('GET', $url);
58
59 $this->assertEquals(404, $client->getResponse()->getStatusCode());
60 }
61
62 public function testUnread()
63 {
64 $client = $this->getClient();
65 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
66 $user = $em
67 ->getRepository('WallabagUserBundle:User')
68 ->findOneByUsername('admin');
69
70 $config = $user->getConfig();
71 $config->setRssToken('SUPERTOKEN');
72 $config->setRssLimit(2);
73 $em->persist($config);
74 $em->flush();
75
76 $client->request('GET', '/admin/SUPERTOKEN/unread.xml');
77
78 $this->assertEquals(200, $client->getResponse()->getStatusCode());
79
80 $this->validateDom($client->getResponse()->getContent(), 2);
81 }
82
83 public function testStarred()
84 {
85 $client = $this->getClient();
86 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
87 $user = $em
88 ->getRepository('WallabagUserBundle:User')
89 ->findOneByUsername('admin');
90
91 $config = $user->getConfig();
92 $config->setRssToken('SUPERTOKEN');
93 $config->setRssLimit(1);
94 $em->persist($config);
95 $em->flush();
96
97 $client = $this->getClient();
98 $client->request('GET', '/admin/SUPERTOKEN/starred.xml');
99
100 $this->assertEquals(200, $client->getResponse()->getStatusCode(), 1);
101
102 $this->validateDom($client->getResponse()->getContent());
103 }
104
105 public function testArchives()
106 {
107 $client = $this->getClient();
108 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
109 $user = $em
110 ->getRepository('WallabagUserBundle:User')
111 ->findOneByUsername('admin');
112
113 $config = $user->getConfig();
114 $config->setRssToken('SUPERTOKEN');
115 $config->setRssLimit(null);
116 $em->persist($config);
117 $em->flush();
118
119 $client = $this->getClient();
120 $client->request('GET', '/admin/SUPERTOKEN/archive.xml');
121
122 $this->assertEquals(200, $client->getResponse()->getStatusCode());
123
124 $this->validateDom($client->getResponse()->getContent());
125 }
126}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php
deleted file mode 100644
index 2910fa4f..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php
+++ /dev/null
@@ -1,72 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7class SecurityControllerTest extends WallabagCoreTestCase
8{
9 public function testLoginWithout2Factor()
10 {
11 $this->logInAs('admin');
12 $client = $this->getClient();
13 $client->followRedirects();
14
15 $crawler = $client->request('GET', '/config');
16 $this->assertContains('config.form_rss.description', $crawler->filter('body')->extract(['_text'])[0]);
17 }
18
19 public function testLoginWith2Factor()
20 {
21 $client = $this->getClient();
22
23 if (!$client->getContainer()->getParameter('twofactor_auth')) {
24 $this->markTestSkipped('twofactor_auth is not enabled.');
25
26 return;
27 }
28
29 $client->followRedirects();
30
31 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
32 $user = $em
33 ->getRepository('WallabagUserBundle:User')
34 ->findOneByUsername('admin');
35 $user->setTwoFactorAuthentication(true);
36 $em->persist($user);
37 $em->flush();
38
39 $this->logInAs('admin');
40 $crawler = $client->request('GET', '/config');
41 $this->assertContains('scheb_two_factor.trusted', $crawler->filter('body')->extract(['_text'])[0]);
42
43 // restore user
44 $user = $em
45 ->getRepository('WallabagUserBundle:User')
46 ->findOneByUsername('admin');
47 $user->setTwoFactorAuthentication(false);
48 $em->persist($user);
49 $em->flush();
50 }
51
52 public function testTrustedComputer()
53 {
54 $client = $this->getClient();
55
56 if (!$client->getContainer()->getParameter('twofactor_auth')) {
57 $this->markTestSkipped('twofactor_auth is not enabled.');
58
59 return;
60 }
61
62 $em = $client->getContainer()->get('doctrine.orm.entity_manager');
63 $user = $em
64 ->getRepository('WallabagUserBundle:User')
65 ->findOneByUsername('admin');
66
67 $date = new \DateTime();
68 $user->addTrustedComputer('ABCDEF', $date->add(new \DateInterval('P1M')));
69 $this->assertTrue($user->isTrustedComputer('ABCDEF'));
70 $this->assertFalse($user->isTrustedComputer('FEDCBA'));
71 }
72}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/SettingsControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/SettingsControllerTest.php
deleted file mode 100644
index fd698b3e..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/SettingsControllerTest.php
+++ /dev/null
@@ -1,32 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7/**
8 * The controller `SettingsController` does not exist.
9 * This test cover security against the internal settings page managed by CraueConfigBundle.
10 */
11class SettingsControllerTest extends WallabagCoreTestCase
12{
13 public function testSettingsWithAdmin()
14 {
15 $this->logInAs('admin');
16 $client = $this->getClient();
17
18 $crawler = $client->request('GET', '/settings');
19
20 $this->assertEquals(200, $client->getResponse()->getStatusCode());
21 }
22
23 public function testSettingsWithNormalUser()
24 {
25 $this->logInAs('bob');
26 $client = $this->getClient();
27
28 $crawler = $client->request('GET', '/settings');
29
30 $this->assertEquals(403, $client->getResponse()->getStatusCode());
31 }
32}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/StaticControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/StaticControllerTest.php
deleted file mode 100644
index 6d7976c4..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/StaticControllerTest.php
+++ /dev/null
@@ -1,28 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7class StaticControllerTest extends WallabagCoreTestCase
8{
9 public function testAbout()
10 {
11 $this->logInAs('admin');
12 $client = $this->getClient();
13
14 $client->request('GET', '/about');
15
16 $this->assertEquals(200, $client->getResponse()->getStatusCode());
17 }
18
19 public function testHowto()
20 {
21 $this->logInAs('admin');
22 $client = $this->getClient();
23
24 $client->request('GET', '/howto');
25
26 $this->assertEquals(200, $client->getResponse()->getStatusCode());
27 }
28}
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php
deleted file mode 100644
index 8af37ea4..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/TagControllerTest.php
+++ /dev/null
@@ -1,128 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6
7class TagControllerTest extends WallabagCoreTestCase
8{
9 public $tagName = 'opensource';
10
11 public function testList()
12 {
13 $this->logInAs('admin');
14 $client = $this->getClient();
15
16 $client->request('GET', '/tag/list');
17
18 $this->assertEquals(200, $client->getResponse()->getStatusCode());
19 }
20
21 public function testAddTagToEntry()
22 {
23 $this->logInAs('admin');
24 $client = $this->getClient();
25
26 $entry = $client->getContainer()
27 ->get('doctrine.orm.entity_manager')
28 ->getRepository('WallabagCoreBundle:Entry')
29 ->findOneByUsernameAndNotArchived('admin');
30
31 $crawler = $client->request('GET', '/view/'.$entry->getId());
32
33 $form = $crawler->filter('form[name=tag]')->form();
34
35 $data = [
36 'tag[label]' => $this->tagName,
37 ];
38
39 $client->submit($form, $data);
40 $this->assertEquals(302, $client->getResponse()->getStatusCode());
41
42 $this->assertEquals(1, count($entry->getTags()));
43
44 # tag already exists and already assigned
45 $client->submit($form, $data);
46 $this->assertEquals(302, $client->getResponse()->getStatusCode());
47
48 $newEntry = $client->getContainer()
49 ->get('doctrine.orm.entity_manager')
50 ->getRepository('WallabagCoreBundle:Entry')
51 ->find($entry->getId());
52
53 $this->assertEquals(1, count($newEntry->getTags()));
54
55 # tag already exists but still not assigned to this entry
56 $data = [
57 'tag[label]' => 'foo',
58 ];
59
60 $client->submit($form, $data);
61 $this->assertEquals(302, $client->getResponse()->getStatusCode());
62
63 $newEntry = $client->getContainer()
64 ->get('doctrine.orm.entity_manager')
65 ->getRepository('WallabagCoreBundle:Entry')
66 ->find($entry->getId());
67
68 $this->assertEquals(2, count($newEntry->getTags()));
69 }
70
71 public function testAddMultipleTagToEntry()
72 {
73 $this->logInAs('admin');
74 $client = $this->getClient();
75
76 $entry = $client->getContainer()
77 ->get('doctrine.orm.entity_manager')
78 ->getRepository('WallabagCoreBundle:Entry')
79 ->findOneByUsernameAndNotArchived('admin');
80
81 $crawler = $client->request('GET', '/view/'.$entry->getId());
82
83 $form = $crawler->filter('form[name=tag]')->form();
84
85 $data = [
86 'tag[label]' => 'foo2, bar2',
87 ];
88
89 $client->submit($form, $data);
90 $this->assertEquals(302, $client->getResponse()->getStatusCode());
91
92 $newEntry = $client->getContainer()
93 ->get('doctrine.orm.entity_manager')
94 ->getRepository('WallabagCoreBundle:Entry')
95 ->find($entry->getId());
96
97 $tags = $newEntry->getTags()->toArray();
98 $this->assertGreaterThanOrEqual(2, count($tags));
99 $this->assertNotEquals(false, array_search('foo2', $tags), 'Tag foo2 is assigned to the entry');
100 $this->assertNotEquals(false, array_search('bar2', $tags), 'Tag bar2 is assigned to the entry');
101 }
102
103 public function testRemoveTagFromEntry()
104 {
105 $this->logInAs('admin');
106 $client = $this->getClient();
107
108 $entry = $client->getContainer()
109 ->get('doctrine.orm.entity_manager')
110 ->getRepository('WallabagCoreBundle:Entry')
111 ->findOneByUsernameAndNotArchived('admin');
112
113 $tag = $client->getContainer()
114 ->get('doctrine.orm.entity_manager')
115 ->getRepository('WallabagCoreBundle:Tag')
116 ->findOneByEntryAndTagLabel($entry, $this->tagName);
117
118 $client->request('GET', '/remove-tag/'.$entry->getId().'/'.$tag->getId());
119
120 $this->assertEquals(302, $client->getResponse()->getStatusCode());
121
122 $this->assertNotContains($this->tagName, $entry->getTags());
123
124 $client->request('GET', '/remove-tag/'.$entry->getId().'/'.$tag->getId());
125
126 $this->assertEquals(404, $client->getResponse()->getStatusCode());
127 }
128}
diff --git a/src/Wallabag/CoreBundle/Tests/EventListener/LocaleListenerTest.php b/src/Wallabag/CoreBundle/Tests/EventListener/LocaleListenerTest.php
deleted file mode 100644
index b4c022d5..00000000
--- a/src/Wallabag/CoreBundle/Tests/EventListener/LocaleListenerTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\EventListener;
4
5use Symfony\Component\EventDispatcher\EventDispatcher;
6use Symfony\Component\HttpFoundation\Request;
7use Symfony\Component\HttpFoundation\Session\Session;
8use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
9use Symfony\Component\HttpKernel\Event\GetResponseEvent;
10use Symfony\Component\HttpKernel\HttpKernelInterface;
11use Symfony\Component\HttpKernel\KernelEvents;
12use Wallabag\CoreBundle\EventListener\LocaleListener;
13
14class LocaleListenerTest extends \PHPUnit_Framework_TestCase
15{
16 private function getEvent(Request $request)
17 {
18 return new GetResponseEvent($this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, HttpKernelInterface::MASTER_REQUEST);
19 }
20
21 public function testWithoutSession()
22 {
23 $request = Request::create('/');
24
25 $listener = new LocaleListener('fr');
26 $event = $this->getEvent($request);
27
28 $listener->onKernelRequest($event);
29 $this->assertEquals('en', $request->getLocale());
30 }
31
32 public function testWithPreviousSession()
33 {
34 $request = Request::create('/');
35 // generate a previous session
36 $request->cookies->set('MOCKSESSID', 'foo');
37 $request->setSession(new Session(new MockArraySessionStorage()));
38
39 $listener = new LocaleListener('fr');
40 $event = $this->getEvent($request);
41
42 $listener->onKernelRequest($event);
43 $this->assertEquals('fr', $request->getLocale());
44 }
45
46 public function testLocaleFromRequestAttribute()
47 {
48 $request = Request::create('/');
49 // generate a previous session
50 $request->cookies->set('MOCKSESSID', 'foo');
51 $request->setSession(new Session(new MockArraySessionStorage()));
52 $request->attributes->set('_locale', 'es');
53
54 $listener = new LocaleListener('fr');
55 $event = $this->getEvent($request);
56
57 $listener->onKernelRequest($event);
58 $this->assertEquals('en', $request->getLocale());
59 $this->assertEquals('es', $request->getSession()->get('_locale'));
60 }
61
62 public function testSubscribedEvents()
63 {
64 $request = Request::create('/');
65 // generate a previous session
66 $request->cookies->set('MOCKSESSID', 'foo');
67 $request->setSession(new Session(new MockArraySessionStorage()));
68
69 $listener = new LocaleListener('fr');
70 $event = $this->getEvent($request);
71
72 $dispatcher = new EventDispatcher();
73 $dispatcher->addSubscriber($listener);
74
75 $dispatcher->dispatch(
76 KernelEvents::REQUEST,
77 $event
78 );
79
80 $this->assertEquals('fr', $request->getLocale());
81 }
82}
diff --git a/src/Wallabag/CoreBundle/Tests/EventListener/RegistrationConfirmedListenerTest.php b/src/Wallabag/CoreBundle/Tests/EventListener/RegistrationConfirmedListenerTest.php
deleted file mode 100644
index 7039dc61..00000000
--- a/src/Wallabag/CoreBundle/Tests/EventListener/RegistrationConfirmedListenerTest.php
+++ /dev/null
@@ -1,91 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\EventListener;
4
5use FOS\UserBundle\Event\FilterUserResponseEvent;
6use FOS\UserBundle\FOSUserEvents;
7use Symfony\Component\EventDispatcher\EventDispatcher;
8use Symfony\Component\HttpFoundation\Request;
9use Symfony\Component\HttpFoundation\Response;
10use Wallabag\CoreBundle\Entity\Config;
11use Wallabag\CoreBundle\EventListener\RegistrationConfirmedListener;
12use Wallabag\UserBundle\Entity\User;
13
14class RegistrationConfirmedListenerTest extends \PHPUnit_Framework_TestCase
15{
16 private $em;
17 private $listener;
18 private $dispatcher;
19 private $request;
20 private $response;
21
22 protected function setUp()
23 {
24 $this->em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
25 ->disableOriginalConstructor()
26 ->getMock();
27
28 $this->listener = new RegistrationConfirmedListener(
29 $this->em,
30 'baggy',
31 20,
32 50,
33 'fr'
34 );
35
36 $this->dispatcher = new EventDispatcher();
37 $this->dispatcher->addSubscriber($this->listener);
38
39 $this->request = Request::create('/');
40 $this->response = Response::create();
41 }
42
43 public function testWithInvalidUser()
44 {
45 $user = new User();
46 $user->setEnabled(false);
47
48 $event = new FilterUserResponseEvent(
49 $user,
50 $this->request,
51 $this->response
52 );
53
54 $this->em->expects($this->never())->method('persist');
55 $this->em->expects($this->never())->method('flush');
56
57 $this->dispatcher->dispatch(
58 FOSUserEvents::REGISTRATION_CONFIRMED,
59 $event
60 );
61 }
62
63 public function testWithValidUser()
64 {
65 $user = new User();
66 $user->setEnabled(true);
67
68 $event = new FilterUserResponseEvent(
69 $user,
70 $this->request,
71 $this->response
72 );
73
74 $config = new Config($user);
75 $config->setTheme('baggy');
76 $config->setItemsPerPage(20);
77 $config->setRssLimit(50);
78 $config->setLanguage('fr');
79
80 $this->em->expects($this->once())
81 ->method('persist')
82 ->will($this->returnValue($config));
83 $this->em->expects($this->once())
84 ->method('flush');
85
86 $this->dispatcher->dispatch(
87 FOSUserEvents::REGISTRATION_CONFIRMED,
88 $event
89 );
90 }
91}
diff --git a/src/Wallabag/CoreBundle/Tests/EventListener/UserLocaleListenerTest.php b/src/Wallabag/CoreBundle/Tests/EventListener/UserLocaleListenerTest.php
deleted file mode 100644
index d9ffe30e..00000000
--- a/src/Wallabag/CoreBundle/Tests/EventListener/UserLocaleListenerTest.php
+++ /dev/null
@@ -1,58 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\EventListener;
4
5use Symfony\Component\HttpFoundation\Request;
6use Symfony\Component\HttpFoundation\Session\Session;
7use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
8use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
9use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
10use Wallabag\CoreBundle\Entity\Config;
11use Wallabag\CoreBundle\EventListener\UserLocaleListener;
12use Wallabag\UserBundle\Entity\User;
13
14class UserLocaleListenerTest extends \PHPUnit_Framework_TestCase
15{
16 public function testWithLanguage()
17 {
18 $session = new Session(new MockArraySessionStorage());
19 $listener = new UserLocaleListener($session);
20
21 $user = new User();
22 $user->setEnabled(true);
23
24 $config = new Config($user);
25 $config->setLanguage('fr');
26
27 $user->setConfig($config);
28
29 $userToken = new UsernamePasswordToken($user, '', 'test');
30 $request = Request::create('/');
31 $event = new InteractiveLoginEvent($request, $userToken);
32
33 $listener->onInteractiveLogin($event);
34
35 $this->assertEquals('fr', $session->get('_locale'));
36 }
37
38 public function testWithoutLanguage()
39 {
40 $session = new Session(new MockArraySessionStorage());
41 $listener = new UserLocaleListener($session);
42
43 $user = new User();
44 $user->setEnabled(true);
45
46 $config = new Config($user);
47
48 $user->setConfig($config);
49
50 $userToken = new UsernamePasswordToken($user, '', 'test');
51 $request = Request::create('/');
52 $event = new InteractiveLoginEvent($request, $userToken);
53
54 $listener->onInteractiveLogin($event);
55
56 $this->assertEquals('', $session->get('_locale'));
57 }
58}
diff --git a/src/Wallabag/CoreBundle/Tests/Form/DataTransformer/StringToListTransformerTest.php b/src/Wallabag/CoreBundle/Tests/Form/DataTransformer/StringToListTransformerTest.php
deleted file mode 100644
index 6b1e8613..00000000
--- a/src/Wallabag/CoreBundle/Tests/Form/DataTransformer/StringToListTransformerTest.php
+++ /dev/null
@@ -1,50 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Form\DataTransformer;
4
5use Wallabag\CoreBundle\Form\DataTransformer\StringToListTransformer;
6
7class StringToListTransformerTest extends \PHPUnit_Framework_TestCase
8{
9 /**
10 * @dataProvider transformProvider
11 */
12 public function testTransformWithValidData($inputData, $expectedResult)
13 {
14 $transformer = new StringToListTransformer();
15
16 $this->assertSame($expectedResult, $transformer->transform($inputData));
17 }
18
19 public function transformProvider()
20 {
21 return [
22 [null, ''],
23 [[], ''],
24 [['single value'], 'single value'],
25 [['first value', 'second value'], 'first value,second value'],
26 ];
27 }
28
29 /**
30 * @dataProvider reverseTransformProvider
31 */
32 public function testReverseTransformWithValidData($inputData, $expectedResult)
33 {
34 $transformer = new StringToListTransformer();
35
36 $this->assertSame($expectedResult, $transformer->reverseTransform($inputData));
37 }
38
39 public function reverseTransformProvider()
40 {
41 return [
42 [null, null],
43 ['', []],
44 ['single value', ['single value']],
45 ['first value,second value', ['first value', 'second value']],
46 ['first value, second value', ['first value', 'second value']],
47 ['first value, , second value', ['first value', 'second value']],
48 ];
49 }
50}
diff --git a/src/Wallabag/CoreBundle/Tests/Helper/ContentProxyTest.php b/src/Wallabag/CoreBundle/Tests/Helper/ContentProxyTest.php
deleted file mode 100644
index 9d7b0f36..00000000
--- a/src/Wallabag/CoreBundle/Tests/Helper/ContentProxyTest.php
+++ /dev/null
@@ -1,318 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Helper;
4
5use Psr\Log\NullLogger;
6use Wallabag\CoreBundle\Helper\ContentProxy;
7use Wallabag\CoreBundle\Entity\Entry;
8use Wallabag\CoreBundle\Entity\Tag;
9use Wallabag\UserBundle\Entity\User;
10
11class ContentProxyTest extends \PHPUnit_Framework_TestCase
12{
13 public function testWithBadUrl()
14 {
15 $tagger = $this->getTaggerMock();
16 $tagger->expects($this->once())
17 ->method('tag');
18
19 $graby = $this->getMockBuilder('Graby\Graby')
20 ->setMethods(['fetchContent'])
21 ->disableOriginalConstructor()
22 ->getMock();
23
24 $graby->expects($this->any())
25 ->method('fetchContent')
26 ->willReturn([
27 'html' => false,
28 'title' => '',
29 'url' => '',
30 'content_type' => '',
31 'language' => '',
32 ]);
33
34 $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger());
35 $entry = $proxy->updateEntry(new Entry(new User()), 'http://user@:80');
36
37 $this->assertEquals('http://user@:80', $entry->getUrl());
38 $this->assertEmpty($entry->getTitle());
39 $this->assertEquals('<p>Unable to retrieve readable content.</p>', $entry->getContent());
40 $this->assertEmpty($entry->getPreviewPicture());
41 $this->assertEmpty($entry->getMimetype());
42 $this->assertEmpty($entry->getLanguage());
43 $this->assertEquals(0.0, $entry->getReadingTime());
44 $this->assertEquals(false, $entry->getDomainName());
45 }
46
47 public function testWithEmptyContent()
48 {
49 $tagger = $this->getTaggerMock();
50 $tagger->expects($this->once())
51 ->method('tag');
52
53 $graby = $this->getMockBuilder('Graby\Graby')
54 ->setMethods(['fetchContent'])
55 ->disableOriginalConstructor()
56 ->getMock();
57
58 $graby->expects($this->any())
59 ->method('fetchContent')
60 ->willReturn([
61 'html' => false,
62 'title' => '',
63 'url' => '',
64 'content_type' => '',
65 'language' => '',
66 ]);
67
68 $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger());
69 $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0');
70
71 $this->assertEquals('http://0.0.0.0', $entry->getUrl());
72 $this->assertEmpty($entry->getTitle());
73 $this->assertEquals('<p>Unable to retrieve readable content.</p>', $entry->getContent());
74 $this->assertEmpty($entry->getPreviewPicture());
75 $this->assertEmpty($entry->getMimetype());
76 $this->assertEmpty($entry->getLanguage());
77 $this->assertEquals(0.0, $entry->getReadingTime());
78 $this->assertEquals('0.0.0.0', $entry->getDomainName());
79 }
80
81 public function testWithEmptyContentButOG()
82 {
83 $tagger = $this->getTaggerMock();
84 $tagger->expects($this->once())
85 ->method('tag');
86
87 $graby = $this->getMockBuilder('Graby\Graby')
88 ->setMethods(['fetchContent'])
89 ->disableOriginalConstructor()
90 ->getMock();
91
92 $graby->expects($this->any())
93 ->method('fetchContent')
94 ->willReturn([
95 'html' => false,
96 'title' => '',
97 'url' => '',
98 'content_type' => '',
99 'language' => '',
100 'open_graph' => [
101 'og_title' => 'my title',
102 'og_description' => 'desc',
103 ],
104 ]);
105
106 $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger());
107 $entry = $proxy->updateEntry(new Entry(new User()), 'http://domain.io');
108
109 $this->assertEquals('http://domain.io', $entry->getUrl());
110 $this->assertEquals('my title', $entry->getTitle());
111 $this->assertEquals('<p>Unable to retrieve readable content.</p><p><i>But we found a short description: </i></p>desc', $entry->getContent());
112 $this->assertEmpty($entry->getPreviewPicture());
113 $this->assertEmpty($entry->getLanguage());
114 $this->assertEmpty($entry->getMimetype());
115 $this->assertEquals(0.0, $entry->getReadingTime());
116 $this->assertEquals('domain.io', $entry->getDomainName());
117 }
118
119 public function testWithContent()
120 {
121 $tagger = $this->getTaggerMock();
122 $tagger->expects($this->once())
123 ->method('tag');
124
125 $graby = $this->getMockBuilder('Graby\Graby')
126 ->setMethods(['fetchContent'])
127 ->disableOriginalConstructor()
128 ->getMock();
129
130 $graby->expects($this->any())
131 ->method('fetchContent')
132 ->willReturn([
133 'html' => str_repeat('this is my content', 325),
134 'title' => 'this is my title',
135 'url' => 'http://1.1.1.1',
136 'content_type' => 'text/html',
137 'language' => 'fr',
138 'open_graph' => [
139 'og_title' => 'my OG title',
140 'og_description' => 'OG desc',
141 'og_image' => 'http://3.3.3.3/cover.jpg',
142 ],
143 ]);
144
145 $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger());
146 $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0');
147
148 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
149 $this->assertEquals('this is my title', $entry->getTitle());
150 $this->assertContains('this is my content', $entry->getContent());
151 $this->assertEquals('http://3.3.3.3/cover.jpg', $entry->getPreviewPicture());
152 $this->assertEquals('text/html', $entry->getMimetype());
153 $this->assertEquals('fr', $entry->getLanguage());
154 $this->assertEquals(4.0, $entry->getReadingTime());
155 $this->assertEquals('1.1.1.1', $entry->getDomainName());
156 }
157
158 public function testWithForcedContent()
159 {
160 $tagger = $this->getTaggerMock();
161 $tagger->expects($this->once())
162 ->method('tag');
163
164 $graby = $this->getMockBuilder('Graby\Graby')->getMock();
165
166 $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger());
167 $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0', [
168 'html' => str_repeat('this is my content', 325),
169 'title' => 'this is my title',
170 'url' => 'http://1.1.1.1',
171 'content_type' => 'text/html',
172 'language' => 'fr',
173 ]);
174
175 $this->assertEquals('http://1.1.1.1', $entry->getUrl());
176 $this->assertEquals('this is my title', $entry->getTitle());
177 $this->assertContains('this is my content', $entry->getContent());
178 $this->assertEquals('text/html', $entry->getMimetype());
179 $this->assertEquals('fr', $entry->getLanguage());
180 $this->assertEquals(4.0, $entry->getReadingTime());
181 $this->assertEquals('1.1.1.1', $entry->getDomainName());
182 }
183
184 public function testTaggerThrowException()
185 {
186 $graby = $this->getMockBuilder('Graby\Graby')
187 ->disableOriginalConstructor()
188 ->getMock();
189
190 $tagger = $this->getTaggerMock();
191 $tagger->expects($this->once())
192 ->method('tag')
193 ->will($this->throwException(new \Exception()));
194
195 $tagRepo = $this->getTagRepositoryMock();
196 $proxy = new ContentProxy($graby, $tagger, $tagRepo, $this->getLogger());
197
198 $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0', [
199 'html' => str_repeat('this is my content', 325),
200 'title' => 'this is my title',
201 'url' => 'http://1.1.1.1',
202 'content_type' => 'text/html',
203 'language' => 'fr',
204 ]);
205
206 $this->assertCount(0, $entry->getTags());
207 }
208
209 public function testAssignTagsWithArrayAndExtraSpaces()
210 {
211 $graby = $this->getMockBuilder('Graby\Graby')
212 ->disableOriginalConstructor()
213 ->getMock();
214
215 $tagRepo = $this->getTagRepositoryMock();
216 $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger());
217
218 $entry = new Entry(new User());
219
220 $proxy->assignTagsToEntry($entry, [' tag1', 'tag2 ']);
221
222 $this->assertCount(2, $entry->getTags());
223 $this->assertEquals('tag1', $entry->getTags()[0]->getLabel());
224 $this->assertEquals('tag2', $entry->getTags()[1]->getLabel());
225 }
226
227 public function testAssignTagsWithString()
228 {
229 $graby = $this->getMockBuilder('Graby\Graby')
230 ->disableOriginalConstructor()
231 ->getMock();
232
233 $tagRepo = $this->getTagRepositoryMock();
234 $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger());
235
236 $entry = new Entry(new User());
237
238 $proxy->assignTagsToEntry($entry, 'tag1, tag2');
239
240 $this->assertCount(2, $entry->getTags());
241 $this->assertEquals('tag1', $entry->getTags()[0]->getLabel());
242 $this->assertEquals('tag2', $entry->getTags()[1]->getLabel());
243 }
244
245 public function testAssignTagsWithEmptyArray()
246 {
247 $graby = $this->getMockBuilder('Graby\Graby')
248 ->disableOriginalConstructor()
249 ->getMock();
250
251 $tagRepo = $this->getTagRepositoryMock();
252 $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger());
253
254 $entry = new Entry(new User());
255
256 $proxy->assignTagsToEntry($entry, []);
257
258 $this->assertCount(0, $entry->getTags());
259 }
260
261 public function testAssignTagsWithEmptyString()
262 {
263 $graby = $this->getMockBuilder('Graby\Graby')
264 ->disableOriginalConstructor()
265 ->getMock();
266
267 $tagRepo = $this->getTagRepositoryMock();
268 $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger());
269
270 $entry = new Entry(new User());
271
272 $proxy->assignTagsToEntry($entry, '');
273
274 $this->assertCount(0, $entry->getTags());
275 }
276
277 public function testAssignTagsAlreadyAssigned()
278 {
279 $graby = $this->getMockBuilder('Graby\Graby')
280 ->disableOriginalConstructor()
281 ->getMock();
282
283 $tagRepo = $this->getTagRepositoryMock();
284 $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger());
285
286 $tagEntity = new Tag();
287 $tagEntity->setLabel('tag1');
288
289 $entry = new Entry(new User());
290 $entry->addTag($tagEntity);
291
292 $proxy->assignTagsToEntry($entry, 'tag1, tag2');
293
294 $this->assertCount(2, $entry->getTags());
295 $this->assertEquals('tag1', $entry->getTags()[0]->getLabel());
296 $this->assertEquals('tag2', $entry->getTags()[1]->getLabel());
297 }
298
299 private function getTaggerMock()
300 {
301 return $this->getMockBuilder('Wallabag\CoreBundle\Helper\RuleBasedTagger')
302 ->setMethods(['tag'])
303 ->disableOriginalConstructor()
304 ->getMock();
305 }
306
307 private function getTagRepositoryMock()
308 {
309 return $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository')
310 ->disableOriginalConstructor()
311 ->getMock();
312 }
313
314 private function getLogger()
315 {
316 return new NullLogger();
317 }
318}
diff --git a/src/Wallabag/CoreBundle/Tests/Helper/RedirectTest.php b/src/Wallabag/CoreBundle/Tests/Helper/RedirectTest.php
deleted file mode 100644
index f4aecc80..00000000
--- a/src/Wallabag/CoreBundle/Tests/Helper/RedirectTest.php
+++ /dev/null
@@ -1,55 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Helper;
4
5use Wallabag\CoreBundle\Helper\Redirect;
6
7class RedirectTest extends \PHPUnit_Framework_TestCase
8{
9 /** @var \PHPUnit_Framework_MockObject_MockObject */
10 private $routerMock;
11
12 /** @var Redirect */
13 private $redirect;
14
15 public function setUp()
16 {
17 $this->routerMock = $this->getRouterMock();
18 $this->redirect = new Redirect($this->routerMock);
19 }
20
21 public function testRedirectToNullWithFallback()
22 {
23 $redirectUrl = $this->redirect->to(null, 'fallback');
24
25 $this->assertEquals('fallback', $redirectUrl);
26 }
27
28 public function testRedirectToNullWithoutFallback()
29 {
30 $redirectUrl = $this->redirect->to(null);
31
32 $this->assertEquals($this->routerMock->generate('homepage'), $redirectUrl);
33 }
34
35 public function testRedirectToValidUrl()
36 {
37 $redirectUrl = $this->redirect->to('/unread/list');
38
39 $this->assertEquals('/unread/list', $redirectUrl);
40 }
41
42 private function getRouterMock()
43 {
44 $mock = $this->getMockBuilder('Symfony\Component\Routing\Router')
45 ->disableOriginalConstructor()
46 ->getMock();
47
48 $mock->expects($this->any())
49 ->method('generate')
50 ->with('homepage')
51 ->willReturn('homepage');
52
53 return $mock;
54 }
55}
diff --git a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php b/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php
deleted file mode 100644
index e9025b45..00000000
--- a/src/Wallabag/CoreBundle/Tests/Helper/RuleBasedTaggerTest.php
+++ /dev/null
@@ -1,212 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Helper;
4
5use Wallabag\CoreBundle\Entity\Config;
6use Wallabag\CoreBundle\Entity\Entry;
7use Wallabag\CoreBundle\Entity\Tag;
8use Wallabag\CoreBundle\Entity\TaggingRule;
9use Wallabag\CoreBundle\Helper\RuleBasedTagger;
10use Wallabag\UserBundle\Entity\User;
11
12class RuleBasedTaggerTest extends \PHPUnit_Framework_TestCase
13{
14 private $rulerz;
15 private $tagRepository;
16 private $entryRepository;
17 private $tagger;
18
19 public function setUp()
20 {
21 $this->rulerz = $this->getRulerZMock();
22 $this->tagRepository = $this->getTagRepositoryMock();
23 $this->entryRepository = $this->getEntryRepositoryMock();
24
25 $this->tagger = new RuleBasedTagger($this->rulerz, $this->tagRepository, $this->entryRepository);
26 }
27
28 public function testTagWithNoRule()
29 {
30 $entry = new Entry($this->getUser());
31
32 $this->tagger->tag($entry);
33
34 $this->assertTrue($entry->getTags()->isEmpty());
35 }
36
37 public function testTagWithNoMatchingRule()
38 {
39 $taggingRule = $this->getTaggingRule('rule as string', ['foo', 'bar']);
40 $user = $this->getUser([$taggingRule]);
41 $entry = new Entry($user);
42
43 $this->rulerz
44 ->expects($this->once())
45 ->method('satisfies')
46 ->with($entry, 'rule as string')
47 ->willReturn(false);
48
49 $this->tagger->tag($entry);
50
51 $this->assertTrue($entry->getTags()->isEmpty());
52 }
53
54 public function testTagWithAMatchingRule()
55 {
56 $taggingRule = $this->getTaggingRule('rule as string', ['foo', 'bar']);
57 $user = $this->getUser([$taggingRule]);
58 $entry = new Entry($user);
59
60 $this->rulerz
61 ->expects($this->once())
62 ->method('satisfies')
63 ->with($entry, 'rule as string')
64 ->willReturn(true);
65
66 $this->tagger->tag($entry);
67
68 $this->assertFalse($entry->getTags()->isEmpty());
69
70 $tags = $entry->getTags();
71 $this->assertSame('foo', $tags[0]->getLabel());
72 $this->assertSame('bar', $tags[1]->getLabel());
73 }
74
75 public function testTagWithAMixOfMatchingRules()
76 {
77 $taggingRule = $this->getTaggingRule('bla bla', ['hey']);
78 $otherTaggingRule = $this->getTaggingRule('rule as string', ['foo']);
79
80 $user = $this->getUser([$taggingRule, $otherTaggingRule]);
81 $entry = new Entry($user);
82
83 $this->rulerz
84 ->method('satisfies')
85 ->will($this->onConsecutiveCalls(false, true));
86
87 $this->tagger->tag($entry);
88
89 $this->assertFalse($entry->getTags()->isEmpty());
90
91 $tags = $entry->getTags();
92 $this->assertSame('foo', $tags[0]->getLabel());
93 }
94
95 public function testWhenTheTagExists()
96 {
97 $taggingRule = $this->getTaggingRule('rule as string', ['foo']);
98 $user = $this->getUser([$taggingRule]);
99 $entry = new Entry($user);
100 $tag = new Tag();
101
102 $this->rulerz
103 ->expects($this->once())
104 ->method('satisfies')
105 ->with($entry, 'rule as string')
106 ->willReturn(true);
107
108 $this->tagRepository
109 ->expects($this->once())
110 // the method `findOneByLabel` doesn't exist, EntityRepository will then call `_call` method
111 // to magically call the `findOneBy` with ['label' => 'foo']
112 ->method('__call')
113 ->willReturn($tag);
114
115 $this->tagger->tag($entry);
116
117 $this->assertFalse($entry->getTags()->isEmpty());
118
119 $tags = $entry->getTags();
120 $this->assertSame($tag, $tags[0]);
121 }
122
123 public function testSameTagWithDifferentfMatchingRules()
124 {
125 $taggingRule = $this->getTaggingRule('bla bla', ['hey']);
126 $otherTaggingRule = $this->getTaggingRule('rule as string', ['hey']);
127
128 $user = $this->getUser([$taggingRule, $otherTaggingRule]);
129 $entry = new Entry($user);
130
131 $this->rulerz
132 ->method('satisfies')
133 ->willReturn(true);
134
135 $this->tagger->tag($entry);
136
137 $this->assertFalse($entry->getTags()->isEmpty());
138
139 $tags = $entry->getTags();
140 $this->assertCount(1, $tags);
141 }
142
143 public function testTagAllEntriesForAUser()
144 {
145 $taggingRule = $this->getTaggingRule('bla bla', ['hey']);
146
147 $user = $this->getUser([$taggingRule]);
148
149 $this->rulerz
150 ->method('satisfies')
151 ->willReturn(true);
152
153 $this->rulerz
154 ->method('filter')
155 ->willReturn([new Entry($user), new Entry($user)]);
156
157 $entries = $this->tagger->tagAllForUser($user);
158
159 $this->assertCount(2, $entries);
160
161 foreach ($entries as $entry) {
162 $tags = $entry->getTags();
163
164 $this->assertCount(1, $tags);
165 $this->assertEquals('hey', $tags[0]->getLabel());
166 }
167 }
168
169 private function getUser(array $taggingRules = [])
170 {
171 $user = new User();
172 $config = new Config($user);
173
174 $user->setConfig($config);
175
176 foreach ($taggingRules as $rule) {
177 $config->addTaggingRule($rule);
178 }
179
180 return $user;
181 }
182
183 private function getTaggingRule($rule, array $tags)
184 {
185 $taggingRule = new TaggingRule();
186 $taggingRule->setRule($rule);
187 $taggingRule->setTags($tags);
188
189 return $taggingRule;
190 }
191
192 private function getRulerZMock()
193 {
194 return $this->getMockBuilder('RulerZ\RulerZ')
195 ->disableOriginalConstructor()
196 ->getMock();
197 }
198
199 private function getTagRepositoryMock()
200 {
201 return $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository')
202 ->disableOriginalConstructor()
203 ->getMock();
204 }
205
206 private function getEntryRepositoryMock()
207 {
208 return $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
209 ->disableOriginalConstructor()
210 ->getMock();
211 }
212}
diff --git a/src/Wallabag/CoreBundle/Tests/Mock/InstallCommandMock.php b/src/Wallabag/CoreBundle/Tests/Mock/InstallCommandMock.php
deleted file mode 100644
index ff9cdafd..00000000
--- a/src/Wallabag/CoreBundle/Tests/Mock/InstallCommandMock.php
+++ /dev/null
@@ -1,22 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Mock;
4
5use Wallabag\CoreBundle\Command\InstallCommand;
6
7/**
8 * This mock aims to speed the test of InstallCommand by avoid calling external command
9 * like all doctrine commands.
10 *
11 * This speed the test but as a downside, it doesn't allow to fully test the InstallCommand
12 *
13 * Launching tests to avoid doctrine command:
14 * phpunit --exclude-group command-doctrine
15 */
16class InstallCommandMock extends InstallCommand
17{
18 protected function runCommand($command, $parameters = [])
19 {
20 return $this;
21 }
22}
diff --git a/src/Wallabag/CoreBundle/Tests/ParamConverter/UsernameRssTokenConverterTest.php b/src/Wallabag/CoreBundle/Tests/ParamConverter/UsernameRssTokenConverterTest.php
deleted file mode 100644
index ee10938a..00000000
--- a/src/Wallabag/CoreBundle/Tests/ParamConverter/UsernameRssTokenConverterTest.php
+++ /dev/null
@@ -1,219 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Command;
4
5use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
6use Symfony\Component\HttpFoundation\Request;
7use Wallabag\CoreBundle\ParamConverter\UsernameRssTokenConverter;
8use Wallabag\UserBundle\Entity\User;
9
10class UsernameRssTokenConverterTest extends \PHPUnit_Framework_TestCase
11{
12 public function testSupportsWithNoRegistry()
13 {
14 $params = new ParamConverter([]);
15 $converter = new UsernameRssTokenConverter();
16
17 $this->assertFalse($converter->supports($params));
18 }
19
20 public function testSupportsWithNoRegistryManagers()
21 {
22 $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')
23 ->disableOriginalConstructor()
24 ->getMock();
25
26 $registry->expects($this->once())
27 ->method('getManagers')
28 ->will($this->returnValue([]));
29
30 $params = new ParamConverter([]);
31 $converter = new UsernameRssTokenConverter($registry);
32
33 $this->assertFalse($converter->supports($params));
34 }
35
36 public function testSupportsWithNoConfigurationClass()
37 {
38 $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')
39 ->disableOriginalConstructor()
40 ->getMock();
41
42 $registry->expects($this->once())
43 ->method('getManagers')
44 ->will($this->returnValue(['default' => null]));
45
46 $params = new ParamConverter([]);
47 $converter = new UsernameRssTokenConverter($registry);
48
49 $this->assertFalse($converter->supports($params));
50 }
51
52 public function testSupportsWithNotTheGoodClass()
53 {
54 $meta = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')
55 ->disableOriginalConstructor()
56 ->getMock();
57
58 $meta->expects($this->once())
59 ->method('getName')
60 ->will($this->returnValue('nothingrelated'));
61
62 $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')
63 ->disableOriginalConstructor()
64 ->getMock();
65
66 $em->expects($this->once())
67 ->method('getClassMetadata')
68 ->with('superclass')
69 ->will($this->returnValue($meta));
70
71 $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')
72 ->disableOriginalConstructor()
73 ->getMock();
74
75 $registry->expects($this->once())
76 ->method('getManagers')
77 ->will($this->returnValue(['default' => null]));
78
79 $registry->expects($this->once())
80 ->method('getManagerForClass')
81 ->with('superclass')
82 ->will($this->returnValue($em));
83
84 $params = new ParamConverter(['class' => 'superclass']);
85 $converter = new UsernameRssTokenConverter($registry);
86
87 $this->assertFalse($converter->supports($params));
88 }
89
90 public function testSupportsWithGoodClass()
91 {
92 $meta = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata')
93 ->disableOriginalConstructor()
94 ->getMock();
95
96 $meta->expects($this->once())
97 ->method('getName')
98 ->will($this->returnValue('Wallabag\UserBundle\Entity\User'));
99
100 $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')
101 ->disableOriginalConstructor()
102 ->getMock();
103
104 $em->expects($this->once())
105 ->method('getClassMetadata')
106 ->with('WallabagUserBundle:User')
107 ->will($this->returnValue($meta));
108
109 $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')
110 ->disableOriginalConstructor()
111 ->getMock();
112
113 $registry->expects($this->once())
114 ->method('getManagers')
115 ->will($this->returnValue(['default' => null]));
116
117 $registry->expects($this->once())
118 ->method('getManagerForClass')
119 ->with('WallabagUserBundle:User')
120 ->will($this->returnValue($em));
121
122 $params = new ParamConverter(['class' => 'WallabagUserBundle:User']);
123 $converter = new UsernameRssTokenConverter($registry);
124
125 $this->assertTrue($converter->supports($params));
126 }
127
128 /**
129 * @expectedException InvalidArgumentException
130 * @expectedExceptionMessage Route attribute is missing
131 */
132 public function testApplyEmptyRequest()
133 {
134 $params = new ParamConverter([]);
135 $converter = new UsernameRssTokenConverter();
136
137 $converter->apply(new Request(), $params);
138 }
139
140 /**
141 * @expectedException Symfony\Component\HttpKernel\Exception\NotFoundHttpException
142 * @expectedExceptionMessage User not found
143 */
144 public function testApplyUserNotFound()
145 {
146 $repo = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository')
147 ->disableOriginalConstructor()
148 ->getMock();
149
150 $repo->expects($this->once())
151 ->method('findOneByUsernameAndRsstoken')
152 ->with('test', 'test')
153 ->will($this->returnValue(null));
154
155 $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')
156 ->disableOriginalConstructor()
157 ->getMock();
158
159 $em->expects($this->once())
160 ->method('getRepository')
161 ->with('WallabagUserBundle:User')
162 ->will($this->returnValue($repo));
163
164 $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')
165 ->disableOriginalConstructor()
166 ->getMock();
167
168 $registry->expects($this->once())
169 ->method('getManagerForClass')
170 ->with('WallabagUserBundle:User')
171 ->will($this->returnValue($em));
172
173 $params = new ParamConverter(['class' => 'WallabagUserBundle:User']);
174 $converter = new UsernameRssTokenConverter($registry);
175 $request = new Request([], [], ['username' => 'test', 'token' => 'test']);
176
177 $converter->apply($request, $params);
178 }
179
180 public function testApplyUserFound()
181 {
182 $user = new User();
183
184 $repo = $this->getMockBuilder('Wallabag\UserBundle\Repository\UserRepository')
185 ->disableOriginalConstructor()
186 ->getMock();
187
188 $repo->expects($this->once())
189 ->method('findOneByUsernameAndRsstoken')
190 ->with('test', 'test')
191 ->will($this->returnValue($user));
192
193 $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager')
194 ->disableOriginalConstructor()
195 ->getMock();
196
197 $em->expects($this->once())
198 ->method('getRepository')
199 ->with('WallabagUserBundle:User')
200 ->will($this->returnValue($repo));
201
202 $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry')
203 ->disableOriginalConstructor()
204 ->getMock();
205
206 $registry->expects($this->once())
207 ->method('getManagerForClass')
208 ->with('WallabagUserBundle:User')
209 ->will($this->returnValue($em));
210
211 $params = new ParamConverter(['class' => 'WallabagUserBundle:User', 'name' => 'user']);
212 $converter = new UsernameRssTokenConverter($registry);
213 $request = new Request([], [], ['username' => 'test', 'token' => 'test']);
214
215 $converter->apply($request, $params);
216
217 $this->assertEquals($user, $request->attributes->get('user'));
218 }
219}
diff --git a/src/Wallabag/CoreBundle/Tests/Subscriber/TablePrefixSubscriberTest.php b/src/Wallabag/CoreBundle/Tests/Subscriber/TablePrefixSubscriberTest.php
deleted file mode 100644
index e5eafab1..00000000
--- a/src/Wallabag/CoreBundle/Tests/Subscriber/TablePrefixSubscriberTest.php
+++ /dev/null
@@ -1,114 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Subscriber;
4
5use Doctrine\Common\EventManager;
6use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
7use Doctrine\ORM\Mapping\ClassMetadata;
8use Wallabag\CoreBundle\Subscriber\TablePrefixSubscriber;
9
10class TablePrefixSubscriberTest extends \PHPUnit_Framework_TestCase
11{
12 public function dataForPrefix()
13 {
14 return [
15 ['wallabag_', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'wallabag_user', '"wallabag_user"', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()],
16 ['wallabag_', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'wallabag_user', '`wallabag_user`', new \Doctrine\DBAL\Platforms\MySqlPlatform()],
17 ['wallabag_', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'wallabag_user', '"wallabag_user"', new \Doctrine\DBAL\Platforms\SqlitePlatform()],
18
19 ['wallabag_', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'wallabag_user', 'wallabag_user', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()],
20 ['wallabag_', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'wallabag_user', 'wallabag_user', new \Doctrine\DBAL\Platforms\MySqlPlatform()],
21 ['wallabag_', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'wallabag_user', 'wallabag_user', new \Doctrine\DBAL\Platforms\SqlitePlatform()],
22
23 ['', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'user', '"user"', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()],
24 ['', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'user', '`user`', new \Doctrine\DBAL\Platforms\MySqlPlatform()],
25 ['', 'Wallabag\UserBundle\Entity\User', '`user`', 'user', 'user', '"user"', new \Doctrine\DBAL\Platforms\SqlitePlatform()],
26
27 ['', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'user', 'user', new \Doctrine\DBAL\Platforms\PostgreSqlPlatform()],
28 ['', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'user', 'user', new \Doctrine\DBAL\Platforms\MySqlPlatform()],
29 ['', 'Wallabag\UserBundle\Entity\User', 'user', 'user', 'user', 'user', new \Doctrine\DBAL\Platforms\SqlitePlatform()],
30 ];
31 }
32
33 /**
34 * @dataProvider dataForPrefix
35 */
36 public function testPrefix($prefix, $entityName, $tableName, $tableNameExpected, $finalTableName, $finalTableNameQuoted, $platform)
37 {
38 $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
39 ->disableOriginalConstructor()
40 ->getMock();
41
42 $subscriber = new TablePrefixSubscriber($prefix);
43
44 $metaClass = new ClassMetadata($entityName);
45 $metaClass->setPrimaryTable(['name' => $tableName]);
46
47 $metaDataEvent = new LoadClassMetadataEventArgs($metaClass, $em);
48
49 $this->assertEquals($tableNameExpected, $metaDataEvent->getClassMetadata()->getTableName());
50
51 $subscriber->loadClassMetadata($metaDataEvent);
52
53 $this->assertEquals($finalTableName, $metaDataEvent->getClassMetadata()->getTableName());
54 $this->assertEquals($finalTableNameQuoted, $metaDataEvent->getClassMetadata()->getQuotedTableName($platform));
55 }
56
57 /**
58 * @dataProvider dataForPrefix
59 */
60 public function testSubscribedEvents($prefix, $entityName, $tableName, $tableNameExpected, $finalTableName, $finalTableNameQuoted, $platform)
61 {
62 $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
63 ->disableOriginalConstructor()
64 ->getMock();
65
66 $metaClass = new ClassMetadata($entityName);
67 $metaClass->setPrimaryTable(['name' => $tableName]);
68
69 $metaDataEvent = new LoadClassMetadataEventArgs($metaClass, $em);
70
71 $subscriber = new TablePrefixSubscriber($prefix);
72
73 $evm = new EventManager();
74 $evm->addEventSubscriber($subscriber);
75
76 $evm->dispatchEvent('loadClassMetadata', $metaDataEvent);
77
78 $this->assertEquals($finalTableName, $metaDataEvent->getClassMetadata()->getTableName());
79 $this->assertEquals($finalTableNameQuoted, $metaDataEvent->getClassMetadata()->getQuotedTableName($platform));
80 }
81
82 public function testPrefixManyToMany()
83 {
84 $em = $this->getMockBuilder('Doctrine\ORM\EntityManager')
85 ->disableOriginalConstructor()
86 ->getMock();
87
88 $subscriber = new TablePrefixSubscriber('yo_');
89
90 $metaClass = new ClassMetadata('Wallabag\UserBundle\Entity\Entry');
91 $metaClass->setPrimaryTable(['name' => 'entry']);
92 $metaClass->mapManyToMany([
93 'fieldName' => 'tags',
94 'joinTable' => ['name' => null, 'schema' => null],
95 'targetEntity' => 'Tag',
96 'mappedBy' => null,
97 'inversedBy' => 'entries',
98 'cascade' => ['persist'],
99 'indexBy' => null,
100 'orphanRemoval' => false,
101 'fetch' => 2,
102 ]);
103
104 $metaDataEvent = new LoadClassMetadataEventArgs($metaClass, $em);
105
106 $this->assertEquals('entry', $metaDataEvent->getClassMetadata()->getTableName());
107
108 $subscriber->loadClassMetadata($metaDataEvent);
109
110 $this->assertEquals('yo_entry', $metaDataEvent->getClassMetadata()->getTableName());
111 $this->assertEquals('yo_entry_tag', $metaDataEvent->getClassMetadata()->associationMappings['tags']['joinTable']['name']);
112 $this->assertEquals('yo_entry', $metaDataEvent->getClassMetadata()->getQuotedTableName(new \Doctrine\DBAL\Platforms\MySqlPlatform()));
113 }
114}
diff --git a/src/Wallabag/CoreBundle/Tests/Twig/WallabagExtensionTest.php b/src/Wallabag/CoreBundle/Tests/Twig/WallabagExtensionTest.php
deleted file mode 100644
index 9af8fad8..00000000
--- a/src/Wallabag/CoreBundle/Tests/Twig/WallabagExtensionTest.php
+++ /dev/null
@@ -1,17 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Twig;
4
5use Wallabag\CoreBundle\Twig\WallabagExtension;
6
7class WallabagExtensionTest extends \PHPUnit_Framework_TestCase
8{
9 public function testRemoveWww()
10 {
11 $extension = new WallabagExtension();
12
13 $this->assertEquals('lemonde.fr', $extension->removeWww('www.lemonde.fr'));
14 $this->assertEquals('lemonde.fr', $extension->removeWww('lemonde.fr'));
15 $this->assertEquals('gist.github.com', $extension->removeWww('gist.github.com'));
16 }
17}
diff --git a/src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php b/src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php
deleted file mode 100644
index 05450c0b..00000000
--- a/src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php
+++ /dev/null
@@ -1,51 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests;
4
5use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
6
7abstract class WallabagCoreTestCase extends WebTestCase
8{
9 private $client = null;
10
11 public function getClient()
12 {
13 return $this->client;
14 }
15
16 public function setUp()
17 {
18 parent::setUp();
19
20 $this->client = static::createClient();
21 }
22
23 public function logInAs($username)
24 {
25 $crawler = $this->client->request('GET', '/login');
26 $form = $crawler->filter('button[type=submit]')->form();
27 $data = [
28 '_username' => $username,
29 '_password' => 'mypassword',
30 ];
31
32 $this->client->submit($form, $data);
33 }
34
35 /**
36 * Return the user id of the logged in user.
37 * You should be sure that you called `logInAs` before.
38 *
39 * @return int
40 */
41 public function getLoggedInUserId()
42 {
43 $token = static::$kernel->getContainer()->get('security.token_storage')->getToken();
44
45 if (null !== $token) {
46 return $token->getUser()->getId();
47 }
48
49 throw new \RuntimeException('No logged in User.');
50 }
51}