From: Jeremy Date: Sat, 28 Mar 2015 20:43:49 +0000 (+0100) Subject: Add tests X-Git-Tag: 2.0.0-alpha.0~70^2~4 X-Git-Url: https://git.immae.eu/?a=commitdiff_plain;h=371ac69a6bd6325929e4efee7958682a6b1666f7;p=github%2Fwallabag%2Fwallabag.git Add tests and fix few mistakes --- diff --git a/app/config/security.yml b/app/config/security.yml index 90903f31..37236d40 100644 --- a/app/config/security.yml +++ b/app/config/security.yml @@ -60,4 +60,5 @@ security: - { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/forgot-password, roles: IS_AUTHENTICATED_ANONYMOUSLY } + - { path: /(unread|starred|archive).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/, roles: ROLE_USER } diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index 1622f348..dbae3ea7 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -107,7 +107,7 @@ class ConfigController extends Controller $config = new Config($newUser); $config->setTheme($this->container->getParameter('theme')); $config->setItemsPerPage($this->container->getParameter('items_on_page')); - $config->setRssLimit($this->getContainer()->getParameter('rss_limit')); + $config->setRssLimit($this->container->getParameter('rss_limit')); $config->setLanguage($this->container->getParameter('language')); $em->persist($config); diff --git a/src/Wallabag/CoreBundle/Controller/RssController.php b/src/Wallabag/CoreBundle/Controller/RssController.php index f2f8dd65..14f1dcb2 100644 --- a/src/Wallabag/CoreBundle/Controller/RssController.php +++ b/src/Wallabag/CoreBundle/Controller/RssController.php @@ -25,7 +25,7 @@ class RssController extends Controller ->findUnreadByUser( $user->getId(), 0, - $user->getConfig()->getRssLimit() ?: $this->getContainer()->getParameter('rss_limit') + $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit') ); return $this->render('WallabagCoreBundle:Entry:entries.xml.twig', array( @@ -49,7 +49,7 @@ class RssController extends Controller ->findArchiveByUser( $user->getId(), 0, - $user->getConfig()->getRssLimit() ?: $this->getContainer()->getParameter('rss_limit') + $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit') ); return $this->render('WallabagCoreBundle:Entry:entries.xml.twig', array( @@ -73,7 +73,7 @@ class RssController extends Controller ->findStarredByUser( $user->getId(), 0, - $user->getConfig()->getRssLimit() ?: $this->getContainer()->getParameter('rss_limit') + $user->getConfig()->getRssLimit() ?: $this->container->getParameter('rss_limit') ); return $this->render('WallabagCoreBundle:Entry:entries.xml.twig', array( diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php index ce12ec5d..54d0d6b6 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php @@ -67,6 +67,26 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface $this->addReference('entry4', $entry4); + $entry5 = new Entry($this->getReference('admin-user')); + $entry5->setUrl('http://0.0.0.0'); + $entry5->setTitle('test title entry5'); + $entry5->setContent('This is my content /o/'); + $entry5->setStarred(true); + + $manager->persist($entry5); + + $this->addReference('entry5', $entry5); + + $entry6 = new Entry($this->getReference('admin-user')); + $entry6->setUrl('http://0.0.0.0'); + $entry6->setTitle('test title entry6'); + $entry6->setContent('This is my content /o/'); + $entry6->setArchived(true); + + $manager->persist($entry6); + + $this->addReference('entry6', $entry6); + $manager->flush(); } diff --git a/src/Wallabag/CoreBundle/Entity/Config.php b/src/Wallabag/CoreBundle/Entity/Config.php index 56eff30c..9f079656 100644 --- a/src/Wallabag/CoreBundle/Entity/Config.php +++ b/src/Wallabag/CoreBundle/Entity/Config.php @@ -35,6 +35,11 @@ class Config * @var integer * * @Assert\NotBlank() + * @Assert\Range( + * min = 1, + * max = 100000, + * maxMessage = "This will certainly kill the app" + * ) * @ORM\Column(name="items_per_page", type="integer", nullable=false) */ private $itemsPerPage; @@ -58,6 +63,11 @@ class Config * @var integer * * @ORM\Column(name="rss_limit", type="integer", nullable=true) + * @Assert\Range( + * min = 1, + * max = 100000, + * maxMessage = "This will certainly kill the app" + * ) */ private $rssLimit; diff --git a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php index 0c8706e2..0fcf020a 100644 --- a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php +++ b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php @@ -24,7 +24,7 @@ class ConfigType extends AbstractType { $builder ->add('theme', 'choice', array('choices' => $this->themes)) - ->add('items_per_page', 'text') + ->add('items_per_page') ->add('language') ->add('save', 'submit') ; diff --git a/src/Wallabag/CoreBundle/Form/Type/RssType.php b/src/Wallabag/CoreBundle/Form/Type/RssType.php index 5edb38ba..a1ab990f 100644 --- a/src/Wallabag/CoreBundle/Form/Type/RssType.php +++ b/src/Wallabag/CoreBundle/Form/Type/RssType.php @@ -10,7 +10,7 @@ class RssType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('rss_limit', 'text') + ->add('rss_limit') ->add('save', 'submit') ; } diff --git a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig index b134b6ca..f2a98dfb 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig @@ -56,11 +56,15 @@
- + {% if rss.token %} + + {% else %} + You need to generate a token first. + {% endif %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig index 6eebc80d..f1039f5d 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Entry/entries.xml.twig @@ -17,11 +17,11 @@ {{ entry.createdAt|date('D, d M Y H:i:s') }} 0 %} + {%- if entry.content| readingTime > 0 -%} {% trans %}estimated reading time :{% endtrans %} {{ entry.content| readingTime }} min - {% else -%} + {%- else -%} {% trans %}estimated reading time :{% endtrans %} < 1 min - {% endif -%} + {%- endif %} {{ entry.content -}} ]]> diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css index 1df82910..ff1a36a1 100755 --- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css +++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/public/css/main.css @@ -7,7 +7,7 @@ 4 = Messages 5 = Article 6 = Media queries - + ========================================================================== */ html { @@ -42,17 +42,17 @@ body { position: absolute; top: 2em; left: 50%; - margin-left: -55px; + margin-left: -55px; } /* ========================================================================== 1 = Style Guide ========================================================================== */ -::selection { - color: #FFF; +::selection { + color: #FFF; background-color: #000; -} +} .desktopHide { display: none; @@ -62,7 +62,7 @@ body { position: fixed; z-index: 20; top: 0.4em; - left: 0.6em; + left: 0.6em; } h2, h3, h4 { @@ -89,7 +89,7 @@ form fieldset { margin: 0; } -form input[type="text"], select, form input[type="password"], form input[type="url"], form input[type="email"] { +form input[type="text"], form input[type="number"], select, form input[type="password"], form input[type="url"], form input[type="email"] { border: 1px solid #999; padding: 0.5em 1em; min-width: 12em; @@ -149,7 +149,7 @@ form button, input[type="submit"] { #bookmarklet { cursor: move; -} +} h2:after { content: ""; @@ -296,7 +296,7 @@ h2:after { /* ========================================================================== 2 = Layout ========================================================================== */ - + #content { margin-top: 5em; min-height: 30em; @@ -653,7 +653,7 @@ a.add-to-wallabag-link-after:after { /* ========================================================================== 3 = Pictos ========================================================================== */ - + @font-face { font-family: 'icomoon'; src:url('../fonts/icomoon.eot?-s0mcsx'); @@ -866,7 +866,7 @@ blockquote { color: #FFF; text-decoration: none; } - + #article_toolbar a:hover, #article_toolbar a:focus { background-color: #999; } @@ -1052,7 +1052,7 @@ pre code { #article_toolbar a { padding: 0.3em 0.4em 0.2em; } - + #display-mode { display: none; } diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php index d7d341aa..11c86423 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php @@ -28,6 +28,8 @@ class ConfigControllerTest extends WallabagTestCase $this->assertCount(1, $crawler->filter('button[id=config_save]')); $this->assertCount(1, $crawler->filter('button[id=change_passwd_save]')); $this->assertCount(1, $crawler->filter('button[id=user_save]')); + $this->assertCount(1, $crawler->filter('button[id=new_user_save]')); + $this->assertCount(1, $crawler->filter('button[id=rss_config_save]')); } public function testUpdate() @@ -347,4 +349,128 @@ class ConfigControllerTest extends WallabagTestCase $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(array('_text'))); $this->assertContains('User "wallace" added', $alert[0]); } + + public function testRssUpdateResetToken() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + // reset the token + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagCoreBundle:User') + ->findOneByUsername('admin'); + + if (!$user) { + $this->markTestSkipped('No user found in db.'); + } + + $config = $user->getConfig(); + $config->setRssToken(null); + $em->persist($config); + $em->flush(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(array('_text'))); + $this->assertContains('You need to generate a token first.', $body[0]); + + $client->request('GET', '/generate-token'); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(array('_text'))); + $this->assertNotContains('You need to generate a token first.', $body[0]); + } + + public function testGenerateTokenAjax() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request( + 'GET', + '/generate-token', + array(), + array(), + array('HTTP_X-Requested-With' => 'XMLHttpRequest') + ); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $content = json_decode($client->getResponse()->getContent(), true);; + $this->assertArrayHasKey('token', $content); + } + + public function testRssUpdate() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + if (500 == $client->getResponse()->getStatusCode()) { + var_export($client->getResponse()->getContent()); + die(); + } + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=rss_config_save]')->form(); + + $data = array( + 'rss_config[rss_limit]' => 12, + ); + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(array('_text'))); + $this->assertContains('RSS information updated', $alert[0]); + } + + public function dataForRssFailed() + { + return array( + array( + array( + 'rss_config[rss_limit]' => 0, + ), + 'This value should be 1 or more.', + ), + array( + array( + 'rss_config[rss_limit]' => 1000000000000, + ), + 'This will certainly kill the app', + ), + ); + } + + /** + * @dataProvider dataForRssFailed + */ + public function testRssFailed($data, $expectedMessage) + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=rss_config_save]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text'))); + $this->assertContains($expectedMessage, $alert[0]); + } } diff --git a/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php new file mode 100644 index 00000000..8f627b4b --- /dev/null +++ b/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php @@ -0,0 +1,126 @@ +loadXML($xml); + + $xpath = new \DOMXpath($doc); + + if (null === $nb) { + $this->assertGreaterThan(0, $xpath->query('//item')->length); + } else { + $this->assertEquals($nb, $xpath->query('//item')->length); + } + + $this->assertEquals(1, $xpath->query('/rss')->length); + $this->assertEquals(1, $xpath->query('/rss/channel')->length); + + foreach ($xpath->query('//item') as $item) { + $this->assertEquals(1, $xpath->query('title', $item)->length); + $this->assertEquals(1, $xpath->query('source', $item)->length); + $this->assertEquals(1, $xpath->query('link', $item)->length); + $this->assertEquals(1, $xpath->query('guid', $item)->length); + $this->assertEquals(1, $xpath->query('pubDate', $item)->length); + $this->assertEquals(1, $xpath->query('description', $item)->length); + } + } + + public function dataForBadUrl() + { + return array( + array( + '/admin/YZIOAUZIAO/unread.xml' + ), + array( + '/wallace/YZIOAUZIAO/starred.xml' + ), + array( + '/wallace/YZIOAUZIAO/archives.xml' + ), + ); + } + + /** + * @dataProvider dataForBadUrl + */ + public function testBadUrl($url) + { + $client = $this->getClient(); + + $client->request('GET', $url); + + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + } + + public function testUnread() + { + $client = $this->getClient(); + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagCoreBundle:User') + ->findOneByUsername('admin'); + + $config = $user->getConfig(); + $config->setRssToken('SUPERTOKEN'); + $config->setRssLimit(2); + $em->persist($config); + $em->flush(); + + $client->request('GET', '/admin/SUPERTOKEN/unread.xml'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->validateDom($client->getResponse()->getContent(), 2); + } + + public function testStarred() + { + $client = $this->getClient(); + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagCoreBundle:User') + ->findOneByUsername('admin'); + + $config = $user->getConfig(); + $config->setRssToken('SUPERTOKEN'); + $config->setRssLimit(1); + $em->persist($config); + $em->flush(); + + $client = $this->getClient(); + $client->request('GET', '/admin/SUPERTOKEN/starred.xml'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode(), 1); + + $this->validateDom($client->getResponse()->getContent()); + } + + public function testArchives() + { + $client = $this->getClient(); + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagCoreBundle:User') + ->findOneByUsername('admin'); + + $config = $user->getConfig(); + $config->setRssToken('SUPERTOKEN'); + $config->setRssLimit(null); + $em->persist($config); + $em->flush(); + + $client = $this->getClient(); + $client->request('GET', '/admin/SUPERTOKEN/archive.xml'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->validateDom($client->getResponse()->getContent()); + } +} diff --git a/src/Wallabag/CoreBundle/Tests/ParamConverter/UsernameRssTokenConverterTest.php b/src/Wallabag/CoreBundle/Tests/ParamConverter/UsernameRssTokenConverterTest.php new file mode 100644 index 00000000..ebb550b5 --- /dev/null +++ b/src/Wallabag/CoreBundle/Tests/ParamConverter/UsernameRssTokenConverterTest.php @@ -0,0 +1,220 @@ +assertFalse($converter->supports($params)); + } + + public function testSupportsWithNoRegistryManagers() + { + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagers') + ->will($this->returnValue(array())); + + $params = new ParamConverter(array()); + $converter = new UsernameRssTokenConverter($registry); + + $this->assertFalse($converter->supports($params)); + } + + public function testSupportsWithNoConfigurationClass() + { + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagers') + ->will($this->returnValue(array('default' => null))); + + $params = new ParamConverter(array()); + $converter = new UsernameRssTokenConverter($registry); + + $this->assertFalse($converter->supports($params)); + } + + public function testSupportsWithNotTheGoodClass() + { + $meta = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata') + ->disableOriginalConstructor() + ->getMock(); + + $meta->expects($this->once()) + ->method('getName') + ->will($this->returnValue('nothingrelated')); + + $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + ->disableOriginalConstructor() + ->getMock(); + + $em->expects($this->once()) + ->method('getClassMetadata') + ->with('superclass') + ->will($this->returnValue($meta)); + + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagers') + ->will($this->returnValue(array('default' => null))); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('superclass') + ->will($this->returnValue($em)); + + $params = new ParamConverter(array('class' => 'superclass')); + $converter = new UsernameRssTokenConverter($registry); + + $this->assertFalse($converter->supports($params)); + } + + public function testSupportsWithGoodClass() + { + $meta = $this->getMockBuilder('Doctrine\Common\Persistence\Mapping\ClassMetadata') + ->disableOriginalConstructor() + ->getMock(); + + $meta->expects($this->once()) + ->method('getName') + ->will($this->returnValue('Wallabag\CoreBundle\Entity\User')); + + $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + ->disableOriginalConstructor() + ->getMock(); + + $em->expects($this->once()) + ->method('getClassMetadata') + ->with('WallabagCoreBundle:User') + ->will($this->returnValue($meta)); + + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagers') + ->will($this->returnValue(array('default' => null))); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('WallabagCoreBundle:User') + ->will($this->returnValue($em)); + + $params = new ParamConverter(array('class' => 'WallabagCoreBundle:User')); + $converter = new UsernameRssTokenConverter($registry); + + $this->assertTrue($converter->supports($params)); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Route attribute is missing + */ + public function testApplyEmptyRequest() + { + $params = new ParamConverter(array()); + $converter = new UsernameRssTokenConverter(); + + $converter->apply(new Request(), $params); + } + + /** + * @expectedException Symfony\Component\HttpKernel\Exception\NotFoundHttpException + * @expectedExceptionMessage User not found + */ + public function testApplyUserNotFound() + { + $repo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\UserRepository') + ->disableOriginalConstructor() + ->getMock(); + + $repo->expects($this->once()) + ->method('findOneByUsernameAndRsstoken') + ->with('test', 'test') + ->will($this->returnValue(null)); + + $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + ->disableOriginalConstructor() + ->getMock(); + + $em->expects($this->once()) + ->method('getRepository') + ->with('WallabagCoreBundle:User') + ->will($this->returnValue($repo)); + + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('WallabagCoreBundle:User') + ->will($this->returnValue($em)); + + $params = new ParamConverter(array('class' => 'WallabagCoreBundle:User')); + $converter = new UsernameRssTokenConverter($registry); + $request = new Request(array(), array(), array('username' => 'test', 'token' => 'test')); + + $converter->apply($request, $params); + } + + public function testApplyUserFound() + { + $user = new User(); + + $repo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\UserRepository') + ->disableOriginalConstructor() + ->getMock(); + + $repo->expects($this->once()) + ->method('findOneByUsernameAndRsstoken') + ->with('test', 'test') + ->will($this->returnValue($user)); + + $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + ->disableOriginalConstructor() + ->getMock(); + + $em->expects($this->once()) + ->method('getRepository') + ->with('WallabagCoreBundle:User') + ->will($this->returnValue($repo)); + + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('WallabagCoreBundle:User') + ->will($this->returnValue($em)); + + $params = new ParamConverter(array('class' => 'WallabagCoreBundle:User', 'name' => 'user')); + $converter = new UsernameRssTokenConverter($registry); + $request = new Request(array(), array(), array('username' => 'test', 'token' => 'test')); + + $converter->apply($request, $params); + + $this->assertEquals($user, $request->attributes->get('user')); + } +}