From 23634d5d842dabcf5d7475e2becb7e127824239e Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Wed, 1 Jun 2016 21:27:35 +0200 Subject: Jump to Symfony 3.1 --- .../CoreBundle/Command/InstallCommandTest.php | 279 +++++++++ .../CoreBundle/Command/TagAllCommandTest.php | 60 ++ .../CoreBundle/Controller/ConfigControllerTest.php | 652 ++++++++++++++++++++ .../Controller/DeveloperControllerTest.php | 71 +++ .../CoreBundle/Controller/EntryControllerTest.php | 665 +++++++++++++++++++++ .../CoreBundle/Controller/ExportControllerTest.php | 251 ++++++++ .../CoreBundle/Controller/RssControllerTest.php | 126 ++++ .../Controller/SecurityControllerTest.php | 72 +++ .../Controller/SettingsControllerTest.php | 32 + .../CoreBundle/Controller/StaticControllerTest.php | 28 + .../CoreBundle/Controller/TagControllerTest.php | 128 ++++ .../EventListener/LocaleListenerTest.php | 82 +++ .../RegistrationConfirmedListenerTest.php | 91 +++ .../EventListener/UserLocaleListenerTest.php | 58 ++ .../StringToListTransformerTest.php | 50 ++ .../CoreBundle/Helper/ContentProxyTest.php | 318 ++++++++++ tests/Wallabag/CoreBundle/Helper/RedirectTest.php | 55 ++ .../CoreBundle/Helper/RuleBasedTaggerTest.php | 212 +++++++ .../CoreBundle/Mock/InstallCommandMock.php | 22 + .../UsernameRssTokenConverterTest.php | 219 +++++++ .../Subscriber/TablePrefixSubscriberTest.php | 114 ++++ .../CoreBundle/Twig/WallabagExtensionTest.php | 17 + tests/Wallabag/CoreBundle/WallabagCoreTestCase.php | 51 ++ 23 files changed, 3653 insertions(+) create mode 100644 tests/Wallabag/CoreBundle/Command/InstallCommandTest.php create mode 100644 tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/DeveloperControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/RssControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/SettingsControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/StaticControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/Controller/TagControllerTest.php create mode 100644 tests/Wallabag/CoreBundle/EventListener/LocaleListenerTest.php create mode 100644 tests/Wallabag/CoreBundle/EventListener/RegistrationConfirmedListenerTest.php create mode 100644 tests/Wallabag/CoreBundle/EventListener/UserLocaleListenerTest.php create mode 100644 tests/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformerTest.php create mode 100644 tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php create mode 100644 tests/Wallabag/CoreBundle/Helper/RedirectTest.php create mode 100644 tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php create mode 100644 tests/Wallabag/CoreBundle/Mock/InstallCommandMock.php create mode 100644 tests/Wallabag/CoreBundle/ParamConverter/UsernameRssTokenConverterTest.php create mode 100644 tests/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriberTest.php create mode 100644 tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php create mode 100644 tests/Wallabag/CoreBundle/WallabagCoreTestCase.php (limited to 'tests/Wallabag/CoreBundle') diff --git a/tests/Wallabag/CoreBundle/Command/InstallCommandTest.php b/tests/Wallabag/CoreBundle/Command/InstallCommandTest.php new file mode 100644 index 00000000..6c6ce087 --- /dev/null +++ b/tests/Wallabag/CoreBundle/Command/InstallCommandTest.php @@ -0,0 +1,279 @@ +getClient()->getContainer()->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOPgSql\Driver) { + /* + * LOG: statement: CREATE DATABASE "wallabag" + * ERROR: source database "template1" is being accessed by other users + * DETAIL: There is 1 other session using the database. + * STATEMENT: CREATE DATABASE "wallabag" + * FATAL: database "wallabag" does not exist + * + * http://stackoverflow.com/a/14374832/569101 + */ + $this->markTestSkipped('PostgreSQL spotted: can find a good way to drop current database, skipping.'); + } + } + + public static function tearDownAfterClass() + { + $application = new Application(static::$kernel); + $application->setAutoExit(false); + + $code = $application->run(new ArrayInput([ + 'command' => 'doctrine:fixtures:load', + '--no-interaction' => true, + '--env' => 'test', + ]), new NullOutput()); + } + + public function testRunInstallCommand() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new InstallCommandMock()); + + $command = $application->find('wallabag:install'); + + // We mock the QuestionHelper + $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper') + ->disableOriginalConstructor() + ->getMock(); + $question->expects($this->any()) + ->method('ask') + ->will($this->returnValue('yes_'.uniqid('', true))); + + // We override the standard helper with our mock + $command->getHelperSet()->set($question, 'question'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + ]); + + $this->assertContains('Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Setting up database.', $tester->getDisplay()); + $this->assertContains('Administration setup.', $tester->getDisplay()); + $this->assertContains('Config setup.', $tester->getDisplay()); + $this->assertContains('Installing assets.', $tester->getDisplay()); + } + + public function testRunInstallCommandWithReset() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new InstallCommandMock()); + + $command = $application->find('wallabag:install'); + + // We mock the QuestionHelper + $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper') + ->disableOriginalConstructor() + ->getMock(); + $question->expects($this->any()) + ->method('ask') + ->will($this->returnValue('yes_'.uniqid('', true))); + + // We override the standard helper with our mock + $command->getHelperSet()->set($question, 'question'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + '--reset' => true, + ]); + + $this->assertContains('Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Setting up database.', $tester->getDisplay()); + $this->assertContains('Droping database, creating database and schema, clearing the cache', $tester->getDisplay()); + $this->assertContains('Administration setup.', $tester->getDisplay()); + $this->assertContains('Config setup.', $tester->getDisplay()); + $this->assertContains('Installing assets.', $tester->getDisplay()); + + // we force to reset everything + $this->assertContains('Droping database, creating database and schema, clearing the cache', $tester->getDisplay()); + } + + public function testRunInstallCommandWithDatabaseRemoved() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new DropDatabaseDoctrineCommand()); + + // drop database first, so the install command won't ask to reset things + $command = $application->find('doctrine:database:drop'); + $command->run(new ArrayInput([ + 'command' => 'doctrine:database:drop', + '--force' => true, + ]), new NullOutput()); + + // start a new application to avoid lagging connexion to pgsql + $client = static::createClient(); + $application = new Application($client->getKernel()); + $application->add(new InstallCommand()); + + $command = $application->find('wallabag:install'); + + // We mock the QuestionHelper + $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper') + ->disableOriginalConstructor() + ->getMock(); + $question->expects($this->any()) + ->method('ask') + ->will($this->returnValue('yes_'.uniqid('', true))); + + // We override the standard helper with our mock + $command->getHelperSet()->set($question, 'question'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + ]); + + $this->assertContains('Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Setting up database.', $tester->getDisplay()); + $this->assertContains('Administration setup.', $tester->getDisplay()); + $this->assertContains('Config setup.', $tester->getDisplay()); + $this->assertContains('Installing assets.', $tester->getDisplay()); + + // the current database doesn't already exist + $this->assertContains('Creating database and schema, clearing the cache', $tester->getDisplay()); + } + + public function testRunInstallCommandChooseResetSchema() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new InstallCommandMock()); + + $command = $application->find('wallabag:install'); + + // We mock the QuestionHelper + $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper') + ->disableOriginalConstructor() + ->getMock(); + + $question->expects($this->exactly(3)) + ->method('ask') + ->will($this->onConsecutiveCalls( + false, // don't want to reset the entire database + true, // do want to reset the schema + false // don't want to create a new user + )); + + // We override the standard helper with our mock + $command->getHelperSet()->set($question, 'question'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + ]); + + $this->assertContains('Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Setting up database.', $tester->getDisplay()); + $this->assertContains('Administration setup.', $tester->getDisplay()); + $this->assertContains('Config setup.', $tester->getDisplay()); + $this->assertContains('Installing assets.', $tester->getDisplay()); + + $this->assertContains('Droping schema and creating schema', $tester->getDisplay()); + } + + public function testRunInstallCommandChooseNothing() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new InstallCommand()); + $application->add(new DropDatabaseDoctrineCommand()); + $application->add(new CreateDatabaseDoctrineCommand()); + + // drop database first, so the install command won't ask to reset things + $command = new DropDatabaseDoctrineCommand(); + $command->setApplication($application); + $command->run(new ArrayInput([ + 'command' => 'doctrine:database:drop', + '--force' => true, + ]), new NullOutput()); + + $this->getClient()->getContainer()->get('doctrine')->getConnection()->close(); + + $command = new CreateDatabaseDoctrineCommand(); + $command->setApplication($application); + $command->run(new ArrayInput([ + 'command' => 'doctrine:database:create', + '--env' => 'test', + ]), new NullOutput()); + + $command = $application->find('wallabag:install'); + + // We mock the QuestionHelper + $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper') + ->disableOriginalConstructor() + ->getMock(); + + $question->expects($this->exactly(2)) + ->method('ask') + ->will($this->onConsecutiveCalls( + false, // don't want to reset the entire database + false // don't want to create a new user + )); + + // We override the standard helper with our mock + $command->getHelperSet()->set($question, 'question'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + ]); + + $this->assertContains('Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Setting up database.', $tester->getDisplay()); + $this->assertContains('Administration setup.', $tester->getDisplay()); + $this->assertContains('Config setup.', $tester->getDisplay()); + $this->assertContains('Installing assets.', $tester->getDisplay()); + + $this->assertContains('Creating schema', $tester->getDisplay()); + } + + public function testRunInstallCommandNoInteraction() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new InstallCommandMock()); + + $command = $application->find('wallabag:install'); + + // We mock the QuestionHelper + $question = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper') + ->disableOriginalConstructor() + ->getMock(); + $question->expects($this->any()) + ->method('ask') + ->will($this->returnValue('yes_'.uniqid('', true))); + + // We override the standard helper with our mock + $command->getHelperSet()->set($question, 'question'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + '--no-interaction' => true, + ]); + + $this->assertContains('Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Setting up database.', $tester->getDisplay()); + $this->assertContains('Administration setup.', $tester->getDisplay()); + $this->assertContains('Config setup.', $tester->getDisplay()); + $this->assertContains('Installing assets.', $tester->getDisplay()); + } +} diff --git a/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php b/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php new file mode 100644 index 00000000..ec31708f --- /dev/null +++ b/tests/Wallabag/CoreBundle/Command/TagAllCommandTest.php @@ -0,0 +1,60 @@ +getClient()->getKernel()); + $application->add(new TagAllCommand()); + + $command = $application->find('wallabag:tag:all'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + ]); + } + + public function testRunTagAllCommandWithBadUsername() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new TagAllCommand()); + + $command = $application->find('wallabag:tag:all'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + 'username' => 'unknown', + ]); + + $this->assertContains('User "unknown" not found', $tester->getDisplay()); + } + + public function testRunTagAllCommand() + { + $application = new Application($this->getClient()->getKernel()); + $application->add(new TagAllCommand()); + + $command = $application->find('wallabag:tag:all'); + + $tester = new CommandTester($command); + $tester->execute([ + 'command' => $command->getName(), + 'username' => 'admin', + ]); + + $this->assertContains('Tagging entries for user « admin »... Done', $tester->getDisplay()); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php new file mode 100644 index 00000000..7193f9b0 --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/ConfigControllerTest.php @@ -0,0 +1,652 @@ +getClient(); + + $client->request('GET', '/new'); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertContains('login', $client->getResponse()->headers->get('location')); + } + + public function testIndex() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $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=update_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() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=config_save]')->form(); + + $data = [ + 'config[theme]' => 'baggy', + 'config[items_per_page]' => '30', + 'config[reading_speed]' => '0.5', + 'config[language]' => 'en', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text'])); + $this->assertContains('flashes.config.notice.config_saved', $alert[0]); + } + + public function testChangeReadingSpeed() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + $form = $crawler->filter('button[id=submit-filter]')->form(); + $dataFilters = [ + 'entry_filter[readingTime][right_number]' => 22, + 'entry_filter[readingTime][left_number]' => 22, + ]; + $crawler = $client->submit($form, $dataFilters); + $this->assertCount(1, $crawler->filter('div[class=entry]')); + + // Change reading speed + $crawler = $client->request('GET', '/config'); + $form = $crawler->filter('button[id=config_save]')->form(); + $data = [ + 'config[reading_speed]' => '2', + ]; + $client->submit($form, $data); + + // Is the entry still available via filters? + $crawler = $client->request('GET', '/unread/list'); + $form = $crawler->filter('button[id=submit-filter]')->form(); + $crawler = $client->submit($form, $dataFilters); + $this->assertCount(0, $crawler->filter('div[class=entry]')); + + // Restore old configuration + $crawler = $client->request('GET', '/config'); + $form = $crawler->filter('button[id=config_save]')->form(); + $data = [ + 'config[reading_speed]' => '0.5', + ]; + $client->submit($form, $data); + } + + public function dataForUpdateFailed() + { + return [ + [[ + 'config[theme]' => 'baggy', + 'config[items_per_page]' => '', + 'config[language]' => 'en', + ]], + ]; + } + + /** + * @dataProvider dataForUpdateFailed + */ + public function testUpdateFailed($data) + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=config_save]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text'])); + $this->assertContains('This value should not be blank', $alert[0]); + } + + public function dataForChangePasswordFailed() + { + return [ + [ + [ + 'change_passwd[old_password]' => 'material', + 'change_passwd[new_password][first]' => '', + 'change_passwd[new_password][second]' => '', + ], + 'validator.password_wrong_value', + ], + [ + [ + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => '', + 'change_passwd[new_password][second]' => '', + ], + 'This value should not be blank', + ], + [ + [ + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => 'hop', + 'change_passwd[new_password][second]' => '', + ], + 'validator.password_must_match', + ], + [ + [ + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => 'hop', + 'change_passwd[new_password][second]' => 'hop', + ], + 'validator.password_too_short', + ], + ]; + } + + /** + * @dataProvider dataForChangePasswordFailed + */ + public function testChangePasswordFailed($data, $expectedMessage) + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=change_passwd_save]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text'])); + $this->assertContains($expectedMessage, $alert[0]); + } + + public function testChangePassword() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=change_passwd_save]')->form(); + + $data = [ + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => 'mypassword', + 'change_passwd[new_password][second]' => 'mypassword', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text'])); + $this->assertContains('flashes.config.notice.password_updated', $alert[0]); + } + + public function dataForUserFailed() + { + return [ + [ + [ + 'update_user[name]' => '', + 'update_user[email]' => '', + ], + 'fos_user.email.blank', + ], + [ + [ + 'update_user[name]' => '', + 'update_user[email]' => 'test', + ], + 'fos_user.email.invalid', + ], + ]; + } + + /** + * @dataProvider dataForUserFailed + */ + public function testUserFailed($data, $expectedMessage) + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=update_user_save]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text'])); + $this->assertContains($expectedMessage, $alert[0]); + } + + public function testUserUpdate() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=update_user_save]')->form(); + + $data = [ + 'update_user[name]' => 'new name', + 'update_user[email]' => 'admin@wallabag.io', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text'])); + $this->assertContains('flashes.config.notice.user_updated', $alert[0]); + } + + public function dataForNewUserFailed() + { + return [ + [ + [ + 'new_user[username]' => '', + 'new_user[plainPassword][first]' => '', + 'new_user[plainPassword][second]' => '', + 'new_user[email]' => '', + ], + 'fos_user.username.blank', + ], + [ + [ + 'new_user[username]' => 'a', + 'new_user[plainPassword][first]' => 'mypassword', + 'new_user[plainPassword][second]' => 'mypassword', + 'new_user[email]' => '', + ], + 'fos_user.username.short', + ], + [ + [ + 'new_user[username]' => 'wallace', + 'new_user[plainPassword][first]' => 'mypassword', + 'new_user[plainPassword][second]' => 'mypassword', + 'new_user[email]' => 'test', + ], + 'fos_user.email.invalid', + ], + [ + [ + 'new_user[username]' => 'admin', + 'new_user[plainPassword][first]' => 'wallacewallace', + 'new_user[plainPassword][second]' => 'wallacewallace', + 'new_user[email]' => 'wallace@wallace.me', + ], + 'fos_user.username.already_used', + ], + [ + [ + 'new_user[username]' => 'wallace', + 'new_user[plainPassword][first]' => 'mypassword1', + 'new_user[plainPassword][second]' => 'mypassword2', + 'new_user[email]' => 'wallace@wallace.me', + ], + 'validator.password_must_match', + ], + ]; + } + + /** + * @dataProvider dataForNewUserFailed + */ + public function testNewUserFailed($data, $expectedMessage) + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=new_user_save]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(['_text'])); + $this->assertContains($expectedMessage, $alert[0]); + } + + public function testNewUserCreated() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=new_user_save]')->form(); + + $data = [ + 'new_user[username]' => 'wallace', + 'new_user[plainPassword][first]' => 'wallace1', + 'new_user[plainPassword][second]' => 'wallace1', + 'new_user[email]' => 'wallace@wallace.me', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text'])); + $this->assertContains('flashes.config.notice.user_added', $alert[0]); + + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagUserBundle:User') + ->findOneByUsername('wallace'); + + $this->assertTrue(false !== $user); + $this->assertTrue($user->isEnabled()); + $this->assertEquals('material', $user->getConfig()->getTheme()); + $this->assertEquals(12, $user->getConfig()->getItemsPerPage()); + $this->assertEquals(50, $user->getConfig()->getRssLimit()); + $this->assertEquals('en', $user->getConfig()->getLanguage()); + $this->assertEquals(1, $user->getConfig()->getReadingSpeed()); + } + + public function testRssUpdateResetToken() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + // reset the token + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagUserBundle: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(['_text'])); + $this->assertContains('config.form_rss.no_token', $body[0]); + + $client->request('GET', '/generate-token'); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); + $this->assertNotContains('config.form_rss.no_token', $body[0]); + } + + public function testGenerateTokenAjax() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request( + 'GET', + '/generate-token', + [], + [], + ['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'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=rss_config_save]')->form(); + + $data = [ + '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(['_text'])); + $this->assertContains('flashes.config.notice.rss_updated', $alert[0]); + } + + public function dataForRssFailed() + { + return [ + [ + [ + 'rss_config[rss_limit]' => 0, + ], + 'This value should be 1 or more.', + ], + [ + [ + 'rss_config[rss_limit]' => 1000000000000, + ], + 'validator.rss_limit_too_hight', + ], + ]; + } + + /** + * @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(['_text'])); + $this->assertContains($expectedMessage, $alert[0]); + } + + public function testTaggingRuleCreation() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertTrue($client->getResponse()->isSuccessful()); + + $form = $crawler->filter('button[id=tagging_rule_save]')->form(); + + $data = [ + 'tagging_rule[rule]' => 'readingTime <= 3', + 'tagging_rule[tags]' => 'short reading', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text'])); + $this->assertContains('flashes.config.notice.tagging_rules_updated', $alert[0]); + + $deleteLink = $crawler->filter('.delete')->last()->link(); + + $crawler = $client->click($deleteLink); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + $this->assertGreaterThan(1, $alert = $crawler->filter('div.messages.success')->extract(['_text'])); + $this->assertContains('flashes.config.notice.tagging_rules_deleted', $alert[0]); + } + + public function dataForTaggingRuleFailed() + { + return [ + [ + [ + 'tagging_rule[rule]' => 'unknownVar <= 3', + 'tagging_rule[tags]' => 'cool tag', + ], + [ + 'The variable', + 'does not exist.', + ], + ], + [ + [ + 'tagging_rule[rule]' => 'length(domainName) <= 42', + 'tagging_rule[tags]' => 'cool tag', + ], + [ + 'The operator', + 'does not exist.', + ], + ], + ]; + } + + /** + * @dataProvider dataForTaggingRuleFailed + */ + public function testTaggingRuleCreationFail($data, $messages) + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertTrue($client->getResponse()->isSuccessful()); + + $form = $crawler->filter('button[id=tagging_rule_save]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); + + foreach ($messages as $message) { + $this->assertContains($message, $body[0]); + } + } + + public function testDeletingTaggingRuleFromAnOtherUser() + { + $this->logInAs('bob'); + $client = $this->getClient(); + + $rule = $client->getContainer()->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:TaggingRule') + ->findAll()[0]; + + $crawler = $client->request('GET', '/tagging-rule/delete/'.$rule->getId()); + + $this->assertEquals(403, $client->getResponse()->getStatusCode()); + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); + $this->assertContains('You can not access this tagging rule', $body[0]); + } + + public function testDemoMode() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $config = $client->getContainer()->get('craue_config'); + $config->set('demo_mode_enabled', 1); + $config->set('demo_mode_username', 'admin'); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[id=change_passwd_save]')->form(); + + $data = [ + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => 'mypassword', + 'change_passwd[new_password][second]' => 'mypassword', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertContains('flashes.config.notice.password_not_updated_demo', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]); + + $config->set('demo_mode_enabled', 0); + $config->set('demo_mode_username', 'wallabag'); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/DeveloperControllerTest.php b/tests/Wallabag/CoreBundle/Controller/DeveloperControllerTest.php new file mode 100644 index 00000000..79452ace --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/DeveloperControllerTest.php @@ -0,0 +1,71 @@ +logInAs('admin'); + $client = $this->getClient(); + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + + $crawler = $client->request('GET', '/developer/client/create'); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[type=submit]')->form(); + + $client->submit($form); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + $this->assertGreaterThan(count($nbClients), count($newNbClients)); + } + + public function testListingClient() + { + $this->logInAs('admin'); + $client = $this->getClient(); + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + + $crawler = $client->request('GET', '/developer'); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->assertEquals(count($nbClients), $crawler->filter('ul[class=collapsible] li')->count()); + } + + public function testDeveloperHowto() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/developer/howto/first-app'); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testRemoveClient() + { + $this->logInAs('admin'); + $client = $this->getClient(); + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $nbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + + $crawler = $client->request('GET', '/developer'); + + $link = $crawler + ->filter('div[class=collapsible-body] p a') + ->eq(0) + ->link() + ; + + $client->click($link); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $newNbClients = $em->getRepository('WallabagApiBundle:Client')->findAll(); + $this->assertGreaterThan(count($newNbClients), count($nbClients)); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php new file mode 100644 index 00000000..bea771bc --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php @@ -0,0 +1,665 @@ +getClient(); + + $client->request('GET', '/new'); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertContains('login', $client->getResponse()->headers->get('location')); + } + + public function testQuickstart() + { + $this->logInAs('empty'); + $client = $this->getClient(); + + $client->request('GET', '/unread/list'); + $crawler = $client->followRedirect(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); + $this->assertContains('quickstart.intro.paragraph_1', $body[0]); + + // Test if quickstart is disabled when user has 1 entry + $crawler = $client->request('GET', '/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('form[name=entry]')->form(); + + $data = [ + 'entry[url]' => $this->url, + ]; + + $client->submit($form, $data); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $client->followRedirect(); + + $crawler = $client->request('GET', '/unread/list'); + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); + $this->assertContains('entry.list.number_on_the_page', $body[0]); + } + + public function testGetNew() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertCount(1, $crawler->filter('input[type=url]')); + $this->assertCount(1, $crawler->filter('form[name=entry]')); + } + + public function testPostNewViaBookmarklet() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/'); + + $this->assertCount(4, $crawler->filter('div[class=entry]')); + + // Good URL + $client->request('GET', '/bookmarklet', ['url' => $this->url]); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $client->followRedirect(); + $crawler = $client->request('GET', '/'); + $this->assertCount(5, $crawler->filter('div[class=entry]')); + + $em = $client->getContainer() + ->get('doctrine.orm.entity_manager'); + $entry = $em + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + $em->remove($entry); + $em->flush(); + } + + public function testPostNewEmpty() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('form[name=entry]')->form(); + + $crawler = $client->submit($form); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->assertCount(1, $alert = $crawler->filter('form ul li')->extract(['_text'])); + $this->assertEquals('This value should not be blank.', $alert[0]); + } + + /** + * This test will require an internet connection. + */ + public function testPostNewOk() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('form[name=entry]')->form(); + + $data = [ + 'entry[url]' => $this->url, + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content); + $this->assertEquals($this->url, $content->getUrl()); + $this->assertContains('Google', $content->getTitle()); + } + + public function testPostNewOkUrlExist() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('form[name=entry]')->form(); + + $data = [ + 'entry[url]' => $this->url, + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertContains('/view/', $client->getResponse()->getTargetUrl()); + } + + /** + * This test will require an internet connection. + */ + public function testPostNewThatWillBeTagged() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('form[name=entry]')->form(); + + $data = [ + 'entry[url]' => $url = 'https://github.com/wallabag/wallabag', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertContains('/', $client->getResponse()->getTargetUrl()); + + $em = $client->getContainer() + ->get('doctrine.orm.entity_manager'); + $entry = $em + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUrl($url); + $tags = $entry->getTags(); + + $this->assertCount(1, $tags); + $this->assertEquals('wallabag', $tags[0]->getLabel()); + + $em->remove($entry); + $em->flush(); + + // and now re-submit it to test the cascade persistence for tags after entry removal + // related https://github.com/wallabag/wallabag/issues/2121 + $crawler = $client->request('GET', '/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('form[name=entry]')->form(); + + $data = [ + 'entry[url]' => $url = 'https://github.com/wallabag/wallabag/tree/master', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertContains('/', $client->getResponse()->getTargetUrl()); + + $entry = $em + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUrl($url); + + $tags = $entry->getTags(); + + $this->assertCount(1, $tags); + $this->assertEquals('wallabag', $tags[0]->getLabel()); + + $em->remove($entry); + $em->flush(); + } + + public function testArchive() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/archive/list'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testStarred() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/starred/list'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testRangeException() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/all/list/900'); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertEquals('/all/list', $client->getResponse()->getTargetUrl()); + } + + /** + * @depends testPostNewOk + */ + public function testView() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $crawler = $client->request('GET', '/view/'.$content->getId()); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->assertGreaterThan(1, $body = $crawler->filter('body')->extract(['_text'])); + $this->assertContains($content->getTitle(), $body[0]); + } + + /** + * @depends testPostNewOk + * + * This test will require an internet connection. + */ + public function testReload() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + // empty content + $content->setContent(''); + $client->getContainer()->get('doctrine.orm.entity_manager')->persist($content); + $client->getContainer()->get('doctrine.orm.entity_manager')->flush(); + + $client->request('GET', '/reload/'.$content->getId()); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $this->assertNotEmpty($content->getContent()); + } + + public function testEdit() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $crawler = $client->request('GET', '/edit/'.$content->getId()); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertCount(1, $crawler->filter('input[id=entry_title]')); + $this->assertCount(1, $crawler->filter('button[id=entry_save]')); + } + + public function testEditUpdate() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $crawler = $client->request('GET', '/edit/'.$content->getId()); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[type=submit]')->form(); + + $data = [ + 'entry[title]' => 'My updated title hehe :)', + ]; + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div[id=article] h1')->extract(['_text'])); + $this->assertContains('My updated title hehe :)', $alert[0]); + } + + public function testToggleArchive() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $client->request('GET', '/archive/'.$content->getId()); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $res = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->find($content->getId()); + + $this->assertEquals($res->isArchived(), true); + } + + public function testToggleStar() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $client->request('GET', '/star/'.$content->getId()); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $res = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneById($content->getId()); + + $this->assertEquals($res->isStarred(), true); + } + + public function testDelete() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findByUrlAndUserId($this->url, $this->getLoggedInUserId()); + + $client->request('GET', '/delete/'.$content->getId()); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $client->request('GET', '/delete/'.$content->getId()); + + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + } + + /** + * It will create a new entry. + * Browse to it. + * Then remove it. + * + * And it'll check that user won't be redirected to the view page of the content when it had been removed + */ + public function testViewAndDelete() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + // add a new content to be removed later + $user = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagUserBundle:User') + ->findOneByUserName('admin'); + + $content = new Entry($user); + $content->setUrl('http://1.1.1.1/entry'); + $content->setReadingTime(12); + $content->setDomainName('domain.io'); + $content->setMimetype('text/html'); + $content->setTitle('test title entry'); + $content->setContent('This is my content /o/'); + $content->setArchived(true); + $content->setLanguage('fr'); + + $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->persist($content); + $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->flush(); + + $client->request('GET', '/view/'.$content->getId()); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $client->request('GET', '/delete/'.$content->getId()); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $client->followRedirect(); + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testViewOtherUserEntry() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUsernameAndNotArchived('bob'); + + $client->request('GET', '/view/'.$content->getId()); + + $this->assertEquals(403, $client->getResponse()->getStatusCode()); + } + + public function testFilterOnReadingTime() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + + $data = [ + 'entry_filter[readingTime][right_number]' => 22, + 'entry_filter[readingTime][left_number]' => 22, + ]; + + $crawler = $client->submit($form, $data); + + $this->assertCount(1, $crawler->filter('div[class=entry]')); + } + + public function testFilterOnUnreadStatus() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/all/list'); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + + $data = [ + 'entry_filter[isUnread]' => true, + ]; + + $crawler = $client->submit($form, $data); + + $this->assertCount(4, $crawler->filter('div[class=entry]')); + } + + public function testFilterOnCreationDate() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + + $data = [ + 'entry_filter[createdAt][left_date]' => date('d/m/Y'), + 'entry_filter[createdAt][right_date]' => date('d/m/Y', strtotime('+1 day')), + ]; + + $crawler = $client->submit($form, $data); + + $this->assertCount(5, $crawler->filter('div[class=entry]')); + + $data = [ + 'entry_filter[createdAt][left_date]' => date('d/m/Y'), + 'entry_filter[createdAt][right_date]' => date('d/m/Y'), + ]; + + $crawler = $client->submit($form, $data); + + $this->assertCount(5, $crawler->filter('div[class=entry]')); + + $data = [ + 'entry_filter[createdAt][left_date]' => '01/01/1970', + 'entry_filter[createdAt][right_date]' => '01/01/1970', + ]; + + $crawler = $client->submit($form, $data); + + $this->assertCount(0, $crawler->filter('div[class=entry]')); + } + + public function testPaginationWithFilter() + { + $this->logInAs('admin'); + $client = $this->getClient(); + $crawler = $client->request('GET', '/config'); + + $form = $crawler->filter('button[id=config_save]')->form(); + + $data = [ + 'config[items_per_page]' => '1', + ]; + + $client->submit($form, $data); + + $parameters = '?entry_filter%5BreadingTime%5D%5Bleft_number%5D=&entry_filter%5BreadingTime%5D%5Bright_number%5D='; + + $client->request('GET', 'unread/list'.$parameters); + + $this->assertContains($parameters, $client->getResponse()->getContent()); + + // reset pagination + $crawler = $client->request('GET', '/config'); + $form = $crawler->filter('button[id=config_save]')->form(); + $data = [ + 'config[items_per_page]' => '12', + ]; + $client->submit($form, $data); + } + + public function testFilterOnDomainName() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + $form = $crawler->filter('button[id=submit-filter]')->form(); + $data = [ + 'entry_filter[domainName]' => 'domain', + ]; + + $crawler = $client->submit($form, $data); + $this->assertCount(5, $crawler->filter('div[class=entry]')); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + $data = [ + 'entry_filter[domainName]' => 'wallabag', + ]; + + $crawler = $client->submit($form, $data); + $this->assertCount(0, $crawler->filter('div[class=entry]')); + } + + public function testFilterOnStatus() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + $form = $crawler->filter('button[id=submit-filter]')->form(); + $form['entry_filter[isArchived]']->tick(); + $form['entry_filter[isStarred]']->untick(); + + $crawler = $client->submit($form); + $this->assertCount(1, $crawler->filter('div[class=entry]')); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + $form['entry_filter[isArchived]']->untick(); + $form['entry_filter[isStarred]']->tick(); + + $crawler = $client->submit($form); + $this->assertCount(1, $crawler->filter('div[class=entry]')); + } + + public function testPreviewPictureFilter() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + $form = $crawler->filter('button[id=submit-filter]')->form(); + $form['entry_filter[previewPicture]']->tick(); + + $crawler = $client->submit($form); + $this->assertCount(1, $crawler->filter('div[class=entry]')); + } + + public function testFilterOnLanguage() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + $form = $crawler->filter('button[id=submit-filter]')->form(); + $data = [ + 'entry_filter[language]' => 'fr', + ]; + + $crawler = $client->submit($form, $data); + $this->assertCount(2, $crawler->filter('div[class=entry]')); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + $data = [ + 'entry_filter[language]' => 'en', + ]; + + $crawler = $client->submit($form, $data); + $this->assertCount(2, $crawler->filter('div[class=entry]')); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php b/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php new file mode 100644 index 00000000..b22156c3 --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/ExportControllerTest.php @@ -0,0 +1,251 @@ +getClient(); + + $client->request('GET', '/export/unread.csv'); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + $this->assertContains('login', $client->getResponse()->headers->get('location')); + } + + public function testUnknownCategoryExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/export/awesomeness.epub'); + + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + } + + public function testUnknownFormatExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/export/unread.xslx'); + + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + } + + public function testUnsupportedFormatExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/export/unread.doc'); + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUsernameAndNotArchived('admin'); + + $client->request('GET', '/export/'.$content->getId().'.doc'); + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + } + + public function testBadEntryId() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/export/0.mobi'); + + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + } + + public function testEpubExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + ob_start(); + $crawler = $client->request('GET', '/export/archive.epub'); + ob_end_clean(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $headers = $client->getResponse()->headers; + $this->assertEquals('application/epub+zip', $headers->get('content-type')); + $this->assertEquals('attachment; filename="Archive articles.epub"', $headers->get('content-disposition')); + $this->assertEquals('binary', $headers->get('content-transfer-encoding')); + } + + public function testMobiExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $content = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUsernameAndNotArchived('admin'); + + ob_start(); + $crawler = $client->request('GET', '/export/'.$content->getId().'.mobi'); + ob_end_clean(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $headers = $client->getResponse()->headers; + $this->assertEquals('application/x-mobipocket-ebook', $headers->get('content-type')); + $this->assertEquals('attachment; filename="'.preg_replace('/[^A-Za-z0-9\-]/', '', $content->getTitle()).'.mobi"', $headers->get('content-disposition')); + $this->assertEquals('binary', $headers->get('content-transfer-encoding')); + } + + public function testPdfExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + ob_start(); + $crawler = $client->request('GET', '/export/all.pdf'); + ob_end_clean(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $headers = $client->getResponse()->headers; + $this->assertEquals('application/pdf', $headers->get('content-type')); + $this->assertEquals('attachment; filename="All articles.pdf"', $headers->get('content-disposition')); + $this->assertEquals('binary', $headers->get('content-transfer-encoding')); + } + + public function testTxtExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + ob_start(); + $crawler = $client->request('GET', '/export/all.txt'); + ob_end_clean(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $headers = $client->getResponse()->headers; + $this->assertEquals('text/plain; charset=UTF-8', $headers->get('content-type')); + $this->assertEquals('attachment; filename="All articles.txt"', $headers->get('content-disposition')); + $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding')); + } + + public function testCsvExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + // to be sure results are the same + $contentInDB = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->createQueryBuilder('e') + ->leftJoin('e.user', 'u') + ->where('u.username = :username')->setParameter('username', 'admin') + ->andWhere('e.isArchived = true') + ->getQuery() + ->getArrayResult(); + + ob_start(); + $crawler = $client->request('GET', '/export/archive.csv'); + ob_end_clean(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $headers = $client->getResponse()->headers; + $this->assertEquals('application/csv', $headers->get('content-type')); + $this->assertEquals('attachment; filename="Archive articles.csv"', $headers->get('content-disposition')); + $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding')); + + $csv = str_getcsv($client->getResponse()->getContent(), "\n"); + + $this->assertGreaterThan(1, $csv); + // +1 for title line + $this->assertEquals(count($contentInDB) + 1, count($csv)); + $this->assertEquals('Title;URL;Content;Tags;"MIME Type";Language', $csv[0]); + } + + public function testJsonExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + // to be sure results are the same + $contentInDB = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->createQueryBuilder('e') + ->leftJoin('e.user', 'u') + ->where('u.username = :username')->setParameter('username', 'admin') + ->getQuery() + ->getArrayResult(); + + ob_start(); + $crawler = $client->request('GET', '/export/all.json'); + ob_end_clean(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $headers = $client->getResponse()->headers; + $this->assertEquals('application/json', $headers->get('content-type')); + $this->assertEquals('attachment; filename="All articles.json"', $headers->get('content-disposition')); + $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding')); + + $content = json_decode($client->getResponse()->getContent(), true); + $this->assertEquals(count($contentInDB), count($content)); + $this->assertArrayHasKey('id', $content[0]); + $this->assertArrayHasKey('title', $content[0]); + $this->assertArrayHasKey('url', $content[0]); + $this->assertArrayHasKey('is_archived', $content[0]); + $this->assertArrayHasKey('is_starred', $content[0]); + $this->assertArrayHasKey('content', $content[0]); + $this->assertArrayHasKey('mimetype', $content[0]); + $this->assertArrayHasKey('language', $content[0]); + $this->assertArrayHasKey('reading_time', $content[0]); + $this->assertArrayHasKey('domain_name', $content[0]); + $this->assertArrayHasKey('tags', $content[0]); + } + + public function testXmlExport() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + // to be sure results are the same + $contentInDB = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->createQueryBuilder('e') + ->leftJoin('e.user', 'u') + ->where('u.username = :username')->setParameter('username', 'admin') + ->andWhere('e.isArchived = false') + ->getQuery() + ->getArrayResult(); + + ob_start(); + $crawler = $client->request('GET', '/export/unread.xml'); + ob_end_clean(); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $headers = $client->getResponse()->headers; + $this->assertEquals('application/xml', $headers->get('content-type')); + $this->assertEquals('attachment; filename="Unread articles.xml"', $headers->get('content-disposition')); + $this->assertEquals('UTF-8', $headers->get('content-transfer-encoding')); + + $content = new \SimpleXMLElement($client->getResponse()->getContent()); + $this->assertGreaterThan(0, $content->count()); + $this->assertEquals(count($contentInDB), $content->count()); + $this->assertNotEmpty('id', (string) $content->entry[0]->id); + $this->assertNotEmpty('title', (string) $content->entry[0]->title); + $this->assertNotEmpty('url', (string) $content->entry[0]->url); + $this->assertNotEmpty('content', (string) $content->entry[0]->content); + $this->assertNotEmpty('domain_name', (string) $content->entry[0]->domain_name); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/RssControllerTest.php b/tests/Wallabag/CoreBundle/Controller/RssControllerTest.php new file mode 100644 index 00000000..fb6fe06a --- /dev/null +++ b/tests/Wallabag/CoreBundle/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 [ + [ + '/admin/YZIOAUZIAO/unread.xml', + ], + [ + '/wallace/YZIOAUZIAO/starred.xml', + ], + [ + '/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('WallabagUserBundle: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('WallabagUserBundle: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('WallabagUserBundle: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/tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php b/tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php new file mode 100644 index 00000000..f503ff4b --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/SecurityControllerTest.php @@ -0,0 +1,72 @@ +logInAs('admin'); + $client = $this->getClient(); + $client->followRedirects(); + + $crawler = $client->request('GET', '/config'); + $this->assertContains('config.form_rss.description', $crawler->filter('body')->extract(['_text'])[0]); + } + + public function testLoginWith2Factor() + { + $client = $this->getClient(); + + if (!$client->getContainer()->getParameter('twofactor_auth')) { + $this->markTestSkipped('twofactor_auth is not enabled.'); + + return; + } + + $client->followRedirects(); + + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagUserBundle:User') + ->findOneByUsername('admin'); + $user->setTwoFactorAuthentication(true); + $em->persist($user); + $em->flush(); + + $this->logInAs('admin'); + $crawler = $client->request('GET', '/config'); + $this->assertContains('scheb_two_factor.trusted', $crawler->filter('body')->extract(['_text'])[0]); + + // restore user + $user = $em + ->getRepository('WallabagUserBundle:User') + ->findOneByUsername('admin'); + $user->setTwoFactorAuthentication(false); + $em->persist($user); + $em->flush(); + } + + public function testTrustedComputer() + { + $client = $this->getClient(); + + if (!$client->getContainer()->getParameter('twofactor_auth')) { + $this->markTestSkipped('twofactor_auth is not enabled.'); + + return; + } + + $em = $client->getContainer()->get('doctrine.orm.entity_manager'); + $user = $em + ->getRepository('WallabagUserBundle:User') + ->findOneByUsername('admin'); + + $date = new \DateTime(); + $user->addTrustedComputer('ABCDEF', $date->add(new \DateInterval('P1M'))); + $this->assertTrue($user->isTrustedComputer('ABCDEF')); + $this->assertFalse($user->isTrustedComputer('FEDCBA')); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/SettingsControllerTest.php b/tests/Wallabag/CoreBundle/Controller/SettingsControllerTest.php new file mode 100644 index 00000000..9b8b5702 --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/SettingsControllerTest.php @@ -0,0 +1,32 @@ +logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/settings'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testSettingsWithNormalUser() + { + $this->logInAs('bob'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/settings'); + + $this->assertEquals(403, $client->getResponse()->getStatusCode()); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/StaticControllerTest.php b/tests/Wallabag/CoreBundle/Controller/StaticControllerTest.php new file mode 100644 index 00000000..98a37b50 --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/StaticControllerTest.php @@ -0,0 +1,28 @@ +logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/about'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testHowto() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/howto'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } +} diff --git a/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php new file mode 100644 index 00000000..a019d36c --- /dev/null +++ b/tests/Wallabag/CoreBundle/Controller/TagControllerTest.php @@ -0,0 +1,128 @@ +logInAs('admin'); + $client = $this->getClient(); + + $client->request('GET', '/tag/list'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + } + + public function testAddTagToEntry() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $entry = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUsernameAndNotArchived('admin'); + + $crawler = $client->request('GET', '/view/'.$entry->getId()); + + $form = $crawler->filter('form[name=tag]')->form(); + + $data = [ + 'tag[label]' => $this->tagName, + ]; + + $client->submit($form, $data); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $this->assertEquals(1, count($entry->getTags())); + + # tag already exists and already assigned + $client->submit($form, $data); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $newEntry = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->find($entry->getId()); + + $this->assertEquals(1, count($newEntry->getTags())); + + # tag already exists but still not assigned to this entry + $data = [ + 'tag[label]' => 'foo', + ]; + + $client->submit($form, $data); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $newEntry = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->find($entry->getId()); + + $this->assertEquals(2, count($newEntry->getTags())); + } + + public function testAddMultipleTagToEntry() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $entry = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUsernameAndNotArchived('admin'); + + $crawler = $client->request('GET', '/view/'.$entry->getId()); + + $form = $crawler->filter('form[name=tag]')->form(); + + $data = [ + 'tag[label]' => 'foo2, bar2', + ]; + + $client->submit($form, $data); + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $newEntry = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->find($entry->getId()); + + $tags = $newEntry->getTags()->toArray(); + $this->assertGreaterThanOrEqual(2, count($tags)); + $this->assertNotEquals(false, array_search('foo2', $tags), 'Tag foo2 is assigned to the entry'); + $this->assertNotEquals(false, array_search('bar2', $tags), 'Tag bar2 is assigned to the entry'); + } + + public function testRemoveTagFromEntry() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $entry = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Entry') + ->findOneByUsernameAndNotArchived('admin'); + + $tag = $client->getContainer() + ->get('doctrine.orm.entity_manager') + ->getRepository('WallabagCoreBundle:Tag') + ->findOneByEntryAndTagLabel($entry, $this->tagName); + + $client->request('GET', '/remove-tag/'.$entry->getId().'/'.$tag->getId()); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $this->assertNotContains($this->tagName, $entry->getTags()); + + $client->request('GET', '/remove-tag/'.$entry->getId().'/'.$tag->getId()); + + $this->assertEquals(404, $client->getResponse()->getStatusCode()); + } +} diff --git a/tests/Wallabag/CoreBundle/EventListener/LocaleListenerTest.php b/tests/Wallabag/CoreBundle/EventListener/LocaleListenerTest.php new file mode 100644 index 00000000..2a7f9390 --- /dev/null +++ b/tests/Wallabag/CoreBundle/EventListener/LocaleListenerTest.php @@ -0,0 +1,82 @@ +getMock('Symfony\Component\HttpKernel\HttpKernelInterface'), $request, HttpKernelInterface::MASTER_REQUEST); + } + + public function testWithoutSession() + { + $request = Request::create('/'); + + $listener = new LocaleListener('fr'); + $event = $this->getEvent($request); + + $listener->onKernelRequest($event); + $this->assertEquals('en', $request->getLocale()); + } + + public function testWithPreviousSession() + { + $request = Request::create('/'); + // generate a previous session + $request->cookies->set('MOCKSESSID', 'foo'); + $request->setSession(new Session(new MockArraySessionStorage())); + + $listener = new LocaleListener('fr'); + $event = $this->getEvent($request); + + $listener->onKernelRequest($event); + $this->assertEquals('fr', $request->getLocale()); + } + + public function testLocaleFromRequestAttribute() + { + $request = Request::create('/'); + // generate a previous session + $request->cookies->set('MOCKSESSID', 'foo'); + $request->setSession(new Session(new MockArraySessionStorage())); + $request->attributes->set('_locale', 'es'); + + $listener = new LocaleListener('fr'); + $event = $this->getEvent($request); + + $listener->onKernelRequest($event); + $this->assertEquals('en', $request->getLocale()); + $this->assertEquals('es', $request->getSession()->get('_locale')); + } + + public function testSubscribedEvents() + { + $request = Request::create('/'); + // generate a previous session + $request->cookies->set('MOCKSESSID', 'foo'); + $request->setSession(new Session(new MockArraySessionStorage())); + + $listener = new LocaleListener('fr'); + $event = $this->getEvent($request); + + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber($listener); + + $dispatcher->dispatch( + KernelEvents::REQUEST, + $event + ); + + $this->assertEquals('fr', $request->getLocale()); + } +} diff --git a/tests/Wallabag/CoreBundle/EventListener/RegistrationConfirmedListenerTest.php b/tests/Wallabag/CoreBundle/EventListener/RegistrationConfirmedListenerTest.php new file mode 100644 index 00000000..e45722fa --- /dev/null +++ b/tests/Wallabag/CoreBundle/EventListener/RegistrationConfirmedListenerTest.php @@ -0,0 +1,91 @@ +em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor() + ->getMock(); + + $this->listener = new RegistrationConfirmedListener( + $this->em, + 'baggy', + 20, + 50, + 'fr' + ); + + $this->dispatcher = new EventDispatcher(); + $this->dispatcher->addSubscriber($this->listener); + + $this->request = Request::create('/'); + $this->response = Response::create(); + } + + public function testWithInvalidUser() + { + $user = new User(); + $user->setEnabled(false); + + $event = new FilterUserResponseEvent( + $user, + $this->request, + $this->response + ); + + $this->em->expects($this->never())->method('persist'); + $this->em->expects($this->never())->method('flush'); + + $this->dispatcher->dispatch( + FOSUserEvents::REGISTRATION_CONFIRMED, + $event + ); + } + + public function testWithValidUser() + { + $user = new User(); + $user->setEnabled(true); + + $event = new FilterUserResponseEvent( + $user, + $this->request, + $this->response + ); + + $config = new Config($user); + $config->setTheme('baggy'); + $config->setItemsPerPage(20); + $config->setRssLimit(50); + $config->setLanguage('fr'); + + $this->em->expects($this->once()) + ->method('persist') + ->will($this->returnValue($config)); + $this->em->expects($this->once()) + ->method('flush'); + + $this->dispatcher->dispatch( + FOSUserEvents::REGISTRATION_CONFIRMED, + $event + ); + } +} diff --git a/tests/Wallabag/CoreBundle/EventListener/UserLocaleListenerTest.php b/tests/Wallabag/CoreBundle/EventListener/UserLocaleListenerTest.php new file mode 100644 index 00000000..e9ac7c1d --- /dev/null +++ b/tests/Wallabag/CoreBundle/EventListener/UserLocaleListenerTest.php @@ -0,0 +1,58 @@ +setEnabled(true); + + $config = new Config($user); + $config->setLanguage('fr'); + + $user->setConfig($config); + + $userToken = new UsernamePasswordToken($user, '', 'test'); + $request = Request::create('/'); + $event = new InteractiveLoginEvent($request, $userToken); + + $listener->onInteractiveLogin($event); + + $this->assertEquals('fr', $session->get('_locale')); + } + + public function testWithoutLanguage() + { + $session = new Session(new MockArraySessionStorage()); + $listener = new UserLocaleListener($session); + + $user = new User(); + $user->setEnabled(true); + + $config = new Config($user); + + $user->setConfig($config); + + $userToken = new UsernamePasswordToken($user, '', 'test'); + $request = Request::create('/'); + $event = new InteractiveLoginEvent($request, $userToken); + + $listener->onInteractiveLogin($event); + + $this->assertEquals('', $session->get('_locale')); + } +} diff --git a/tests/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformerTest.php b/tests/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformerTest.php new file mode 100644 index 00000000..0ec98c1f --- /dev/null +++ b/tests/Wallabag/CoreBundle/Form/DataTransformer/StringToListTransformerTest.php @@ -0,0 +1,50 @@ +assertSame($expectedResult, $transformer->transform($inputData)); + } + + public function transformProvider() + { + return [ + [null, ''], + [[], ''], + [['single value'], 'single value'], + [['first value', 'second value'], 'first value,second value'], + ]; + } + + /** + * @dataProvider reverseTransformProvider + */ + public function testReverseTransformWithValidData($inputData, $expectedResult) + { + $transformer = new StringToListTransformer(); + + $this->assertSame($expectedResult, $transformer->reverseTransform($inputData)); + } + + public function reverseTransformProvider() + { + return [ + [null, null], + ['', []], + ['single value', ['single value']], + ['first value,second value', ['first value', 'second value']], + ['first value, second value', ['first value', 'second value']], + ['first value, , second value', ['first value', 'second value']], + ]; + } +} diff --git a/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php b/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php new file mode 100644 index 00000000..7abb0737 --- /dev/null +++ b/tests/Wallabag/CoreBundle/Helper/ContentProxyTest.php @@ -0,0 +1,318 @@ +getTaggerMock(); + $tagger->expects($this->once()) + ->method('tag'); + + $graby = $this->getMockBuilder('Graby\Graby') + ->setMethods(['fetchContent']) + ->disableOriginalConstructor() + ->getMock(); + + $graby->expects($this->any()) + ->method('fetchContent') + ->willReturn([ + 'html' => false, + 'title' => '', + 'url' => '', + 'content_type' => '', + 'language' => '', + ]); + + $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger()); + $entry = $proxy->updateEntry(new Entry(new User()), 'http://user@:80'); + + $this->assertEquals('http://user@:80', $entry->getUrl()); + $this->assertEmpty($entry->getTitle()); + $this->assertEquals('

Unable to retrieve readable content.

', $entry->getContent()); + $this->assertEmpty($entry->getPreviewPicture()); + $this->assertEmpty($entry->getMimetype()); + $this->assertEmpty($entry->getLanguage()); + $this->assertEquals(0.0, $entry->getReadingTime()); + $this->assertEquals(false, $entry->getDomainName()); + } + + public function testWithEmptyContent() + { + $tagger = $this->getTaggerMock(); + $tagger->expects($this->once()) + ->method('tag'); + + $graby = $this->getMockBuilder('Graby\Graby') + ->setMethods(['fetchContent']) + ->disableOriginalConstructor() + ->getMock(); + + $graby->expects($this->any()) + ->method('fetchContent') + ->willReturn([ + 'html' => false, + 'title' => '', + 'url' => '', + 'content_type' => '', + 'language' => '', + ]); + + $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger()); + $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0'); + + $this->assertEquals('http://0.0.0.0', $entry->getUrl()); + $this->assertEmpty($entry->getTitle()); + $this->assertEquals('

Unable to retrieve readable content.

', $entry->getContent()); + $this->assertEmpty($entry->getPreviewPicture()); + $this->assertEmpty($entry->getMimetype()); + $this->assertEmpty($entry->getLanguage()); + $this->assertEquals(0.0, $entry->getReadingTime()); + $this->assertEquals('0.0.0.0', $entry->getDomainName()); + } + + public function testWithEmptyContentButOG() + { + $tagger = $this->getTaggerMock(); + $tagger->expects($this->once()) + ->method('tag'); + + $graby = $this->getMockBuilder('Graby\Graby') + ->setMethods(['fetchContent']) + ->disableOriginalConstructor() + ->getMock(); + + $graby->expects($this->any()) + ->method('fetchContent') + ->willReturn([ + 'html' => false, + 'title' => '', + 'url' => '', + 'content_type' => '', + 'language' => '', + 'open_graph' => [ + 'og_title' => 'my title', + 'og_description' => 'desc', + ], + ]); + + $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger()); + $entry = $proxy->updateEntry(new Entry(new User()), 'http://domain.io'); + + $this->assertEquals('http://domain.io', $entry->getUrl()); + $this->assertEquals('my title', $entry->getTitle()); + $this->assertEquals('

Unable to retrieve readable content.

But we found a short description:

desc', $entry->getContent()); + $this->assertEmpty($entry->getPreviewPicture()); + $this->assertEmpty($entry->getLanguage()); + $this->assertEmpty($entry->getMimetype()); + $this->assertEquals(0.0, $entry->getReadingTime()); + $this->assertEquals('domain.io', $entry->getDomainName()); + } + + public function testWithContent() + { + $tagger = $this->getTaggerMock(); + $tagger->expects($this->once()) + ->method('tag'); + + $graby = $this->getMockBuilder('Graby\Graby') + ->setMethods(['fetchContent']) + ->disableOriginalConstructor() + ->getMock(); + + $graby->expects($this->any()) + ->method('fetchContent') + ->willReturn([ + 'html' => str_repeat('this is my content', 325), + 'title' => 'this is my title', + 'url' => 'http://1.1.1.1', + 'content_type' => 'text/html', + 'language' => 'fr', + 'open_graph' => [ + 'og_title' => 'my OG title', + 'og_description' => 'OG desc', + 'og_image' => 'http://3.3.3.3/cover.jpg', + ], + ]); + + $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger()); + $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0'); + + $this->assertEquals('http://1.1.1.1', $entry->getUrl()); + $this->assertEquals('this is my title', $entry->getTitle()); + $this->assertContains('this is my content', $entry->getContent()); + $this->assertEquals('http://3.3.3.3/cover.jpg', $entry->getPreviewPicture()); + $this->assertEquals('text/html', $entry->getMimetype()); + $this->assertEquals('fr', $entry->getLanguage()); + $this->assertEquals(4.0, $entry->getReadingTime()); + $this->assertEquals('1.1.1.1', $entry->getDomainName()); + } + + public function testWithForcedContent() + { + $tagger = $this->getTaggerMock(); + $tagger->expects($this->once()) + ->method('tag'); + + $graby = $this->getMockBuilder('Graby\Graby')->getMock(); + + $proxy = new ContentProxy($graby, $tagger, $this->getTagRepositoryMock(), $this->getLogger()); + $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0', [ + 'html' => str_repeat('this is my content', 325), + 'title' => 'this is my title', + 'url' => 'http://1.1.1.1', + 'content_type' => 'text/html', + 'language' => 'fr', + ]); + + $this->assertEquals('http://1.1.1.1', $entry->getUrl()); + $this->assertEquals('this is my title', $entry->getTitle()); + $this->assertContains('this is my content', $entry->getContent()); + $this->assertEquals('text/html', $entry->getMimetype()); + $this->assertEquals('fr', $entry->getLanguage()); + $this->assertEquals(4.0, $entry->getReadingTime()); + $this->assertEquals('1.1.1.1', $entry->getDomainName()); + } + + public function testTaggerThrowException() + { + $graby = $this->getMockBuilder('Graby\Graby') + ->disableOriginalConstructor() + ->getMock(); + + $tagger = $this->getTaggerMock(); + $tagger->expects($this->once()) + ->method('tag') + ->will($this->throwException(new \Exception())); + + $tagRepo = $this->getTagRepositoryMock(); + $proxy = new ContentProxy($graby, $tagger, $tagRepo, $this->getLogger()); + + $entry = $proxy->updateEntry(new Entry(new User()), 'http://0.0.0.0', [ + 'html' => str_repeat('this is my content', 325), + 'title' => 'this is my title', + 'url' => 'http://1.1.1.1', + 'content_type' => 'text/html', + 'language' => 'fr', + ]); + + $this->assertCount(0, $entry->getTags()); + } + + public function testAssignTagsWithArrayAndExtraSpaces() + { + $graby = $this->getMockBuilder('Graby\Graby') + ->disableOriginalConstructor() + ->getMock(); + + $tagRepo = $this->getTagRepositoryMock(); + $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger()); + + $entry = new Entry(new User()); + + $proxy->assignTagsToEntry($entry, [' tag1', 'tag2 ']); + + $this->assertCount(2, $entry->getTags()); + $this->assertEquals('tag1', $entry->getTags()[0]->getLabel()); + $this->assertEquals('tag2', $entry->getTags()[1]->getLabel()); + } + + public function testAssignTagsWithString() + { + $graby = $this->getMockBuilder('Graby\Graby') + ->disableOriginalConstructor() + ->getMock(); + + $tagRepo = $this->getTagRepositoryMock(); + $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger()); + + $entry = new Entry(new User()); + + $proxy->assignTagsToEntry($entry, 'tag1, tag2'); + + $this->assertCount(2, $entry->getTags()); + $this->assertEquals('tag1', $entry->getTags()[0]->getLabel()); + $this->assertEquals('tag2', $entry->getTags()[1]->getLabel()); + } + + public function testAssignTagsWithEmptyArray() + { + $graby = $this->getMockBuilder('Graby\Graby') + ->disableOriginalConstructor() + ->getMock(); + + $tagRepo = $this->getTagRepositoryMock(); + $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger()); + + $entry = new Entry(new User()); + + $proxy->assignTagsToEntry($entry, []); + + $this->assertCount(0, $entry->getTags()); + } + + public function testAssignTagsWithEmptyString() + { + $graby = $this->getMockBuilder('Graby\Graby') + ->disableOriginalConstructor() + ->getMock(); + + $tagRepo = $this->getTagRepositoryMock(); + $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger()); + + $entry = new Entry(new User()); + + $proxy->assignTagsToEntry($entry, ''); + + $this->assertCount(0, $entry->getTags()); + } + + public function testAssignTagsAlreadyAssigned() + { + $graby = $this->getMockBuilder('Graby\Graby') + ->disableOriginalConstructor() + ->getMock(); + + $tagRepo = $this->getTagRepositoryMock(); + $proxy = new ContentProxy($graby, $this->getTaggerMock(), $tagRepo, $this->getLogger()); + + $tagEntity = new Tag(); + $tagEntity->setLabel('tag1'); + + $entry = new Entry(new User()); + $entry->addTag($tagEntity); + + $proxy->assignTagsToEntry($entry, 'tag1, tag2'); + + $this->assertCount(2, $entry->getTags()); + $this->assertEquals('tag1', $entry->getTags()[0]->getLabel()); + $this->assertEquals('tag2', $entry->getTags()[1]->getLabel()); + } + + private function getTaggerMock() + { + return $this->getMockBuilder('Wallabag\CoreBundle\Helper\RuleBasedTagger') + ->setMethods(['tag']) + ->disableOriginalConstructor() + ->getMock(); + } + + private function getTagRepositoryMock() + { + return $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository') + ->disableOriginalConstructor() + ->getMock(); + } + + private function getLogger() + { + return new NullLogger(); + } +} diff --git a/tests/Wallabag/CoreBundle/Helper/RedirectTest.php b/tests/Wallabag/CoreBundle/Helper/RedirectTest.php new file mode 100644 index 00000000..f339f75e --- /dev/null +++ b/tests/Wallabag/CoreBundle/Helper/RedirectTest.php @@ -0,0 +1,55 @@ +routerMock = $this->getRouterMock(); + $this->redirect = new Redirect($this->routerMock); + } + + public function testRedirectToNullWithFallback() + { + $redirectUrl = $this->redirect->to(null, 'fallback'); + + $this->assertEquals('fallback', $redirectUrl); + } + + public function testRedirectToNullWithoutFallback() + { + $redirectUrl = $this->redirect->to(null); + + $this->assertEquals($this->routerMock->generate('homepage'), $redirectUrl); + } + + public function testRedirectToValidUrl() + { + $redirectUrl = $this->redirect->to('/unread/list'); + + $this->assertEquals('/unread/list', $redirectUrl); + } + + private function getRouterMock() + { + $mock = $this->getMockBuilder('Symfony\Component\Routing\Router') + ->disableOriginalConstructor() + ->getMock(); + + $mock->expects($this->any()) + ->method('generate') + ->with('homepage') + ->willReturn('homepage'); + + return $mock; + } +} diff --git a/tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php b/tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php new file mode 100644 index 00000000..17b08c2a --- /dev/null +++ b/tests/Wallabag/CoreBundle/Helper/RuleBasedTaggerTest.php @@ -0,0 +1,212 @@ +rulerz = $this->getRulerZMock(); + $this->tagRepository = $this->getTagRepositoryMock(); + $this->entryRepository = $this->getEntryRepositoryMock(); + + $this->tagger = new RuleBasedTagger($this->rulerz, $this->tagRepository, $this->entryRepository); + } + + public function testTagWithNoRule() + { + $entry = new Entry($this->getUser()); + + $this->tagger->tag($entry); + + $this->assertTrue($entry->getTags()->isEmpty()); + } + + public function testTagWithNoMatchingRule() + { + $taggingRule = $this->getTaggingRule('rule as string', ['foo', 'bar']); + $user = $this->getUser([$taggingRule]); + $entry = new Entry($user); + + $this->rulerz + ->expects($this->once()) + ->method('satisfies') + ->with($entry, 'rule as string') + ->willReturn(false); + + $this->tagger->tag($entry); + + $this->assertTrue($entry->getTags()->isEmpty()); + } + + public function testTagWithAMatchingRule() + { + $taggingRule = $this->getTaggingRule('rule as string', ['foo', 'bar']); + $user = $this->getUser([$taggingRule]); + $entry = new Entry($user); + + $this->rulerz + ->expects($this->once()) + ->method('satisfies') + ->with($entry, 'rule as string') + ->willReturn(true); + + $this->tagger->tag($entry); + + $this->assertFalse($entry->getTags()->isEmpty()); + + $tags = $entry->getTags(); + $this->assertSame('foo', $tags[0]->getLabel()); + $this->assertSame('bar', $tags[1]->getLabel()); + } + + public function testTagWithAMixOfMatchingRules() + { + $taggingRule = $this->getTaggingRule('bla bla', ['hey']); + $otherTaggingRule = $this->getTaggingRule('rule as string', ['foo']); + + $user = $this->getUser([$taggingRule, $otherTaggingRule]); + $entry = new Entry($user); + + $this->rulerz + ->method('satisfies') + ->will($this->onConsecutiveCalls(false, true)); + + $this->tagger->tag($entry); + + $this->assertFalse($entry->getTags()->isEmpty()); + + $tags = $entry->getTags(); + $this->assertSame('foo', $tags[0]->getLabel()); + } + + public function testWhenTheTagExists() + { + $taggingRule = $this->getTaggingRule('rule as string', ['foo']); + $user = $this->getUser([$taggingRule]); + $entry = new Entry($user); + $tag = new Tag(); + + $this->rulerz + ->expects($this->once()) + ->method('satisfies') + ->with($entry, 'rule as string') + ->willReturn(true); + + $this->tagRepository + ->expects($this->once()) + // the method `findOneByLabel` doesn't exist, EntityRepository will then call `_call` method + // to magically call the `findOneBy` with ['label' => 'foo'] + ->method('__call') + ->willReturn($tag); + + $this->tagger->tag($entry); + + $this->assertFalse($entry->getTags()->isEmpty()); + + $tags = $entry->getTags(); + $this->assertSame($tag, $tags[0]); + } + + public function testSameTagWithDifferentfMatchingRules() + { + $taggingRule = $this->getTaggingRule('bla bla', ['hey']); + $otherTaggingRule = $this->getTaggingRule('rule as string', ['hey']); + + $user = $this->getUser([$taggingRule, $otherTaggingRule]); + $entry = new Entry($user); + + $this->rulerz + ->method('satisfies') + ->willReturn(true); + + $this->tagger->tag($entry); + + $this->assertFalse($entry->getTags()->isEmpty()); + + $tags = $entry->getTags(); + $this->assertCount(1, $tags); + } + + public function testTagAllEntriesForAUser() + { + $taggingRule = $this->getTaggingRule('bla bla', ['hey']); + + $user = $this->getUser([$taggingRule]); + + $this->rulerz + ->method('satisfies') + ->willReturn(true); + + $this->rulerz + ->method('filter') + ->willReturn([new Entry($user), new Entry($user)]); + + $entries = $this->tagger->tagAllForUser($user); + + $this->assertCount(2, $entries); + + foreach ($entries as $entry) { + $tags = $entry->getTags(); + + $this->assertCount(1, $tags); + $this->assertEquals('hey', $tags[0]->getLabel()); + } + } + + private function getUser(array $taggingRules = []) + { + $user = new User(); + $config = new Config($user); + + $user->setConfig($config); + + foreach ($taggingRules as $rule) { + $config->addTaggingRule($rule); + } + + return $user; + } + + private function getTaggingRule($rule, array $tags) + { + $taggingRule = new TaggingRule(); + $taggingRule->setRule($rule); + $taggingRule->setTags($tags); + + return $taggingRule; + } + + private function getRulerZMock() + { + return $this->getMockBuilder('RulerZ\RulerZ') + ->disableOriginalConstructor() + ->getMock(); + } + + private function getTagRepositoryMock() + { + return $this->getMockBuilder('Wallabag\CoreBundle\Repository\TagRepository') + ->disableOriginalConstructor() + ->getMock(); + } + + private function getEntryRepositoryMock() + { + return $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository') + ->disableOriginalConstructor() + ->getMock(); + } +} diff --git a/tests/Wallabag/CoreBundle/Mock/InstallCommandMock.php b/tests/Wallabag/CoreBundle/Mock/InstallCommandMock.php new file mode 100644 index 00000000..5806bd4d --- /dev/null +++ b/tests/Wallabag/CoreBundle/Mock/InstallCommandMock.php @@ -0,0 +1,22 @@ +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([])); + + $params = new ParamConverter([]); + $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(['default' => null])); + + $params = new ParamConverter([]); + $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(['default' => null])); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('superclass') + ->will($this->returnValue($em)); + + $params = new ParamConverter(['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\UserBundle\Entity\User')); + + $em = $this->getMockBuilder('Doctrine\Common\Persistence\ObjectManager') + ->disableOriginalConstructor() + ->getMock(); + + $em->expects($this->once()) + ->method('getClassMetadata') + ->with('WallabagUserBundle:User') + ->will($this->returnValue($meta)); + + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagers') + ->will($this->returnValue(['default' => null])); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('WallabagUserBundle:User') + ->will($this->returnValue($em)); + + $params = new ParamConverter(['class' => 'WallabagUserBundle:User']); + $converter = new UsernameRssTokenConverter($registry); + + $this->assertTrue($converter->supports($params)); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Route attribute is missing + */ + public function testApplyEmptyRequest() + { + $params = new ParamConverter([]); + $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\UserBundle\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('WallabagUserBundle:User') + ->will($this->returnValue($repo)); + + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('WallabagUserBundle:User') + ->will($this->returnValue($em)); + + $params = new ParamConverter(['class' => 'WallabagUserBundle:User']); + $converter = new UsernameRssTokenConverter($registry); + $request = new Request([], [], ['username' => 'test', 'token' => 'test']); + + $converter->apply($request, $params); + } + + public function testApplyUserFound() + { + $user = new User(); + + $repo = $this->getMockBuilder('Wallabag\UserBundle\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('WallabagUserBundle:User') + ->will($this->returnValue($repo)); + + $registry = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); + + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with('WallabagUserBundle:User') + ->will($this->returnValue($em)); + + $params = new ParamConverter(['class' => 'WallabagUserBundle:User', 'name' => 'user']); + $converter = new UsernameRssTokenConverter($registry); + $request = new Request([], [], ['username' => 'test', 'token' => 'test']); + + $converter->apply($request, $params); + + $this->assertEquals($user, $request->attributes->get('user')); + } +} diff --git a/tests/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriberTest.php b/tests/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriberTest.php new file mode 100644 index 00000000..4ae76703 --- /dev/null +++ b/tests/Wallabag/CoreBundle/Subscriber/TablePrefixSubscriberTest.php @@ -0,0 +1,114 @@ +getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor() + ->getMock(); + + $subscriber = new TablePrefixSubscriber($prefix); + + $metaClass = new ClassMetadata($entityName); + $metaClass->setPrimaryTable(['name' => $tableName]); + + $metaDataEvent = new LoadClassMetadataEventArgs($metaClass, $em); + + $this->assertEquals($tableNameExpected, $metaDataEvent->getClassMetadata()->getTableName()); + + $subscriber->loadClassMetadata($metaDataEvent); + + $this->assertEquals($finalTableName, $metaDataEvent->getClassMetadata()->getTableName()); + $this->assertEquals($finalTableNameQuoted, $metaDataEvent->getClassMetadata()->getQuotedTableName($platform)); + } + + /** + * @dataProvider dataForPrefix + */ + public function testSubscribedEvents($prefix, $entityName, $tableName, $tableNameExpected, $finalTableName, $finalTableNameQuoted, $platform) + { + $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor() + ->getMock(); + + $metaClass = new ClassMetadata($entityName); + $metaClass->setPrimaryTable(['name' => $tableName]); + + $metaDataEvent = new LoadClassMetadataEventArgs($metaClass, $em); + + $subscriber = new TablePrefixSubscriber($prefix); + + $evm = new EventManager(); + $evm->addEventSubscriber($subscriber); + + $evm->dispatchEvent('loadClassMetadata', $metaDataEvent); + + $this->assertEquals($finalTableName, $metaDataEvent->getClassMetadata()->getTableName()); + $this->assertEquals($finalTableNameQuoted, $metaDataEvent->getClassMetadata()->getQuotedTableName($platform)); + } + + public function testPrefixManyToMany() + { + $em = $this->getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor() + ->getMock(); + + $subscriber = new TablePrefixSubscriber('yo_'); + + $metaClass = new ClassMetadata('Wallabag\UserBundle\Entity\Entry'); + $metaClass->setPrimaryTable(['name' => 'entry']); + $metaClass->mapManyToMany([ + 'fieldName' => 'tags', + 'joinTable' => ['name' => null, 'schema' => null], + 'targetEntity' => 'Tag', + 'mappedBy' => null, + 'inversedBy' => 'entries', + 'cascade' => ['persist'], + 'indexBy' => null, + 'orphanRemoval' => false, + 'fetch' => 2, + ]); + + $metaDataEvent = new LoadClassMetadataEventArgs($metaClass, $em); + + $this->assertEquals('entry', $metaDataEvent->getClassMetadata()->getTableName()); + + $subscriber->loadClassMetadata($metaDataEvent); + + $this->assertEquals('yo_entry', $metaDataEvent->getClassMetadata()->getTableName()); + $this->assertEquals('yo_entry_tag', $metaDataEvent->getClassMetadata()->associationMappings['tags']['joinTable']['name']); + $this->assertEquals('yo_entry', $metaDataEvent->getClassMetadata()->getQuotedTableName(new \Doctrine\DBAL\Platforms\MySqlPlatform())); + } +} diff --git a/tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php b/tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php new file mode 100644 index 00000000..8ec2a75a --- /dev/null +++ b/tests/Wallabag/CoreBundle/Twig/WallabagExtensionTest.php @@ -0,0 +1,17 @@ +assertEquals('lemonde.fr', $extension->removeWww('www.lemonde.fr')); + $this->assertEquals('lemonde.fr', $extension->removeWww('lemonde.fr')); + $this->assertEquals('gist.github.com', $extension->removeWww('gist.github.com')); + } +} diff --git a/tests/Wallabag/CoreBundle/WallabagCoreTestCase.php b/tests/Wallabag/CoreBundle/WallabagCoreTestCase.php new file mode 100644 index 00000000..c69e8330 --- /dev/null +++ b/tests/Wallabag/CoreBundle/WallabagCoreTestCase.php @@ -0,0 +1,51 @@ +client; + } + + public function setUp() + { + parent::setUp(); + + $this->client = static::createClient(); + } + + public function logInAs($username) + { + $crawler = $this->client->request('GET', '/login'); + $form = $crawler->filter('button[type=submit]')->form(); + $data = [ + '_username' => $username, + '_password' => 'mypassword', + ]; + + $this->client->submit($form, $data); + } + + /** + * Return the user id of the logged in user. + * You should be sure that you called `logInAs` before. + * + * @return int + */ + public function getLoggedInUserId() + { + $token = static::$kernel->getContainer()->get('security.token_storage')->getToken(); + + if (null !== $token) { + return $token->getUser()->getId(); + } + + throw new \RuntimeException('No logged in User.'); + } +} -- cgit v1.2.3 From 95859e54c512ec4a3ee1c28404981f5c4b9481df Mon Sep 17 00:00:00 2001 From: Jeremy Benoist Date: Thu, 23 Jun 2016 10:46:47 +0200 Subject: Add some tests about readingTime --- .../CoreBundle/Controller/EntryControllerTest.php | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'tests/Wallabag/CoreBundle') diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php index bea771bc..5c739c78 100644 --- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php @@ -499,6 +499,42 @@ class EntryControllerTest extends WallabagCoreTestCase $this->assertCount(1, $crawler->filter('div[class=entry]')); } + public function testFilterOnReadingTimeOnlyUpper() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + + $data = [ + 'entry_filter[readingTime][right_number]' => 22, + ]; + + $crawler = $client->submit($form, $data); + + $this->assertCount(2, $crawler->filter('div[class=entry]')); + } + + public function testFilterOnReadingTimeOnlyLower() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/unread/list'); + + $form = $crawler->filter('button[id=submit-filter]')->form(); + + $data = [ + 'entry_filter[readingTime][left_number]' => 22, + ]; + + $crawler = $client->submit($form, $data); + + $this->assertCount(4, $crawler->filter('div[class=entry]')); + } + public function testFilterOnUnreadStatus() { $this->logInAs('admin'); -- cgit v1.2.3