From 55f58c9c5e8c523b7547c5d8199f0efef6941b93 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Wed, 11 Feb 2015 21:06:32 +0100 Subject: Update UserConfig schema --- src/Wallabag/CoreBundle/Command/InstallCommand.php | 12 +++--- src/Wallabag/CoreBundle/Entity/Config.php | 8 ++-- src/Wallabag/CoreBundle/Entity/UsersConfig.php | 50 +++++++++++----------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index feaaebf6..bf2f747d 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php @@ -136,18 +136,18 @@ class InstallCommand extends ContainerAwareCommand $em->persist($user); $pagerConfig = new UsersConfig(); - $pagerConfig->setUserId($user->getId()); + $pagerConfig->setUser($user); $pagerConfig->setName('pager'); $pagerConfig->setValue(10); $em->persist($pagerConfig); - // $languageConfig = new LanguageConfig(); - // $languageConfig->setUserId($user->getId()); - // $languageConfig->setName('language'); - // $languageConfig->setValue('en_EN.UTF8'); + $languageConfig = new LanguageConfig(); + $languageConfig->setUser($user); + $languageConfig->setName('language'); + $languageConfig->setValue('en_EN'); - // $em->persist($languageConfig); + $em->persist($languageConfig); $em->flush(); } diff --git a/src/Wallabag/CoreBundle/Entity/Config.php b/src/Wallabag/CoreBundle/Entity/Config.php index 045ca308..14977d32 100644 --- a/src/Wallabag/CoreBundle/Entity/Config.php +++ b/src/Wallabag/CoreBundle/Entity/Config.php @@ -3,6 +3,7 @@ namespace Wallabag\CoreBundle\Entity; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; /** * Config @@ -15,16 +16,17 @@ class Config /** * @var integer * - * @ORM\Column(name="id", type="integer", nullable=false) + * @ORM\Column(name="id", type="integer") * @ORM\Id - * @ORM\GeneratedValue(strategy="IDENTITY") + * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var string * - * @ORM\Column(name="name", type="string", nullable=true) + * @Assert\NotBlank() + * @ORM\Column(name="name", type="string", nullable=false) */ private $name; diff --git a/src/Wallabag/CoreBundle/Entity/UsersConfig.php b/src/Wallabag/CoreBundle/Entity/UsersConfig.php index 0742edbc..52127631 100644 --- a/src/Wallabag/CoreBundle/Entity/UsersConfig.php +++ b/src/Wallabag/CoreBundle/Entity/UsersConfig.php @@ -22,11 +22,9 @@ class UsersConfig private $id; /** - * @var string - * - * @ORM\Column(name="user_id", type="decimal", precision=10, scale=0, nullable=true) + * @ORM\ManyToOne(targetEntity="User", inversedBy="config") */ - private $userId; + private $user; /** * @var string @@ -53,71 +51,71 @@ class UsersConfig } /** - * Set userId + * Set name * - * @param string $userId + * @param string $name * @return UsersConfig */ - public function setUserId($userId) + public function setName($name) { - $this->userId = $userId; + $this->name = $name; return $this; } /** - * Get userId + * Get name * * @return string */ - public function getUserId() + public function getName() { - return $this->userId; + return $this->name; } /** - * Set name + * Set value * - * @param string $name + * @param string $value * @return UsersConfig */ - public function setName($name) + public function setValue($value) { - $this->name = $name; + $this->value = $value; return $this; } /** - * Get name + * Get value * * @return string */ - public function getName() + public function getValue() { - return $this->name; + return $this->value; } /** - * Set value + * Set user * - * @param string $value + * @param \Wallabag\CoreBundle\Entity\User $user * @return UsersConfig */ - public function setValue($value) + public function setUser(\Wallabag\CoreBundle\Entity\User $user = null) { - $this->value = $value; + $this->user = $user; return $this; } /** - * Get value + * Get user * - * @return string + * @return \Wallabag\CoreBundle\Entity\User */ - public function getValue() + public function getUser() { - return $this->value; + return $this->user; } } -- cgit v1.2.3 From 7a577c519ffc254b6ddecd75c9ee84f656d759e1 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 16 Feb 2015 19:09:47 +0100 Subject: Fix indentation in templates --- .../CoreBundle/Resources/views/_footer.html.twig | 6 +-- .../CoreBundle/Resources/views/_head.html.twig | 60 +++++++++++----------- .../CoreBundle/Resources/views/_menu.html.twig | 28 +++++----- .../Resources/views/_search_form.html.twig | 6 +-- .../CoreBundle/Resources/views/_top.html.twig | 10 ++-- 5 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/Wallabag/CoreBundle/Resources/views/_footer.html.twig b/src/Wallabag/CoreBundle/Resources/views/_footer.html.twig index 26411da9..1b5f9a0f 100644 --- a/src/Wallabag/CoreBundle/Resources/views/_footer.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/_footer.html.twig @@ -1,3 +1,3 @@ -
-

{% trans %}powered by{% endtrans %} wallabag

-
+
+

{% trans %}powered by{% endtrans %} wallabag

+
diff --git a/src/Wallabag/CoreBundle/Resources/views/_head.html.twig b/src/Wallabag/CoreBundle/Resources/views/_head.html.twig index 726b4163..3bdbe812 100755 --- a/src/Wallabag/CoreBundle/Resources/views/_head.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/_head.html.twig @@ -1,40 +1,40 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - - - - + + + + + - - - - - - - - + + + + + + + + diff --git a/src/Wallabag/CoreBundle/Resources/views/_menu.html.twig b/src/Wallabag/CoreBundle/Resources/views/_menu.html.twig index 2e3b6d08..9a3cf053 100644 --- a/src/Wallabag/CoreBundle/Resources/views/_menu.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/_menu.html.twig @@ -1,14 +1,14 @@ - - + + diff --git a/src/Wallabag/CoreBundle/Resources/views/_search_form.html.twig b/src/Wallabag/CoreBundle/Resources/views/_search_form.html.twig index 7eb1b67d..1e6f327d 100644 --- a/src/Wallabag/CoreBundle/Resources/views/_search_form.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/_search_form.html.twig @@ -1,9 +1,9 @@ diff --git a/src/Wallabag/CoreBundle/Resources/views/_top.html.twig b/src/Wallabag/CoreBundle/Resources/views/_top.html.twig index 34d925df..9313071d 100755 --- a/src/Wallabag/CoreBundle/Resources/views/_top.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/_top.html.twig @@ -1,5 +1,5 @@ -
-

- {% block logo %}wallabag logo{% endblock %} -

-
+
+

+ {% block logo %}wallabag logo{% endblock %} +

+
-- cgit v1.2.3 From 4d85d7e9ba676bd5ac3428976ce9227f460eb542 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 16 Feb 2015 21:28:49 +0100 Subject: Implement simple config --- src/Wallabag/CoreBundle/Command/InstallCommand.php | 22 ++-- .../CoreBundle/Controller/ConfigController.php | 58 ++++++++++ src/Wallabag/CoreBundle/Entity/Config.php | 107 +++++++++++++++--- src/Wallabag/CoreBundle/Entity/UsersConfig.php | 121 --------------------- src/Wallabag/CoreBundle/Form/Type/ConfigType.php | 41 +++++++ .../CoreBundle/Repository/ConfigRepository.php | 9 ++ .../CoreBundle/Resources/config/routing.yml | 6 +- .../Resources/views/Config/index.html.twig | 41 +++++++ .../Tests/Controller/ConfigControllerTest.php | 96 ++++++++++++++++ src/Wallabag/CoreBundle/Tests/WallabagTestCase.php | 2 +- 10 files changed, 347 insertions(+), 156 deletions(-) create mode 100644 src/Wallabag/CoreBundle/Controller/ConfigController.php delete mode 100644 src/Wallabag/CoreBundle/Entity/UsersConfig.php create mode 100644 src/Wallabag/CoreBundle/Form/Type/ConfigType.php create mode 100644 src/Wallabag/CoreBundle/Repository/ConfigRepository.php create mode 100644 src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig create mode 100644 src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index bf2f747d..a4301958 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php @@ -6,7 +6,7 @@ use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Wallabag\CoreBundle\Entity\User; -use Wallabag\CoreBundle\Entity\UsersConfig; +use Wallabag\CoreBundle\Entity\Config; class InstallCommand extends ContainerAwareCommand { @@ -135,21 +135,13 @@ class InstallCommand extends ContainerAwareCommand $em->persist($user); - $pagerConfig = new UsersConfig(); - $pagerConfig->setUser($user); - $pagerConfig->setName('pager'); - $pagerConfig->setValue(10); + $config = new Config(); + $config->setUser($user); + $config->setTheme('baggy'); + $config->setItemsPerPage(10); + $config->setLanguage('en_US'); - $em->persist($pagerConfig); - - $languageConfig = new LanguageConfig(); - $languageConfig->setUser($user); - $languageConfig->setName('language'); - $languageConfig->setValue('en_EN'); - - $em->persist($languageConfig); - - $em->flush(); + $em->persist($config); } protected function runCommand($command, InputInterface $input, OutputInterface $output) diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php new file mode 100644 index 00000000..f48a9cb1 --- /dev/null +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -0,0 +1,58 @@ +getConfig(); + + $form = $this->createForm(new ConfigType(), $config); + + $form->handleRequest($request); + + if ($form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->persist($config); + $em->flush(); + + $this->get('session')->getFlashBag()->add( + 'notice', + 'Config saved' + ); + + return $this->redirect($this->generateUrl('config')); + } + + return $this->render('WallabagCoreBundle:Config:index.html.twig', array( + 'form' => $form->createView(), + )); + } + + private function getConfig() + { + $config = $this->getDoctrine() + ->getRepository('WallabagCoreBundle:Config') + ->findOneByUser($this->getUser()); + + if (!$config) { + $config = new Config($this->getUser()); + } + + return $config; + } +} diff --git a/src/Wallabag/CoreBundle/Entity/Config.php b/src/Wallabag/CoreBundle/Entity/Config.php index 14977d32..7b4464a1 100644 --- a/src/Wallabag/CoreBundle/Entity/Config.php +++ b/src/Wallabag/CoreBundle/Entity/Config.php @@ -8,6 +8,7 @@ use Symfony\Component\Validator\Constraints as Assert; /** * Config * + * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\ConfigRepository") * @ORM\Table(name="config") * @ORM\Entity */ @@ -26,16 +27,40 @@ class Config * @var string * * @Assert\NotBlank() - * @ORM\Column(name="name", type="string", nullable=false) + * @ORM\Column(name="theme", type="string", nullable=false) */ - private $name; + private $theme; /** * @var string * - * @ORM\Column(name="value", type="blob", nullable=true) + * @Assert\NotBlank() + * @ORM\Column(name="items_per_page", type="integer", nullable=false) + */ + private $items_per_page; + + /** + * @var string + * + * @Assert\NotBlank() + * @ORM\Column(name="language", type="string", nullable=false) */ - private $value; + private $language; + + /** + * @ORM\ManyToOne(targetEntity="User", inversedBy="config") + */ + private $user; + + /* + * @param User $user + */ + public function __construct(User $user) + { + $this->user = $user; + $this->items_per_page = 12; + $this->language = 'en_US'; + } /** * Get id @@ -48,48 +73,94 @@ class Config } /** - * Set name + * Set theme * - * @param string $name + * @param string $theme * @return Config */ - public function setName($name) + public function setTheme($theme) { - $this->name = $name; + $this->theme = $theme; return $this; } /** - * Get name + * Get theme * * @return string */ - public function getName() + public function getTheme() { - return $this->name; + return $this->theme; } /** - * Set value + * Set items_per_page * - * @param string $value + * @param integer $itemsPerPage * @return Config */ - public function setValue($value) + public function setItemsPerPage($itemsPerPage) { - $this->value = $value; + $this->items_per_page = $itemsPerPage; return $this; } /** - * Get value + * Get items_per_page + * + * @return integer + */ + public function getItemsPerPage() + { + return $this->items_per_page; + } + + /** + * Set language + * + * @param string $language + * @return Config + */ + public function setLanguage($language) + { + $this->language = $language; + + return $this; + } + + /** + * Get language * * @return string */ - public function getValue() + public function getLanguage() + { + return $this->language; + } + + /** + * Set user + * + * @param \Wallabag\CoreBundle\Entity\User $user + * @return Config + */ + public function setUser(\Wallabag\CoreBundle\Entity\User $user = null) + { + $this->user = $user; + + return $this; + } + + /** + * Get user + * + * @return \Wallabag\CoreBundle\Entity\User + */ + public function getUser() { - return $this->value; + return $this->user; } } diff --git a/src/Wallabag/CoreBundle/Entity/UsersConfig.php b/src/Wallabag/CoreBundle/Entity/UsersConfig.php deleted file mode 100644 index 52127631..00000000 --- a/src/Wallabag/CoreBundle/Entity/UsersConfig.php +++ /dev/null @@ -1,121 +0,0 @@ -id; - } - - /** - * Set name - * - * @param string $name - * @return UsersConfig - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * Get name - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Set value - * - * @param string $value - * @return UsersConfig - */ - public function setValue($value) - { - $this->value = $value; - - return $this; - } - - /** - * Get value - * - * @return string - */ - public function getValue() - { - return $this->value; - } - - /** - * Set user - * - * @param \Wallabag\CoreBundle\Entity\User $user - * @return UsersConfig - */ - public function setUser(\Wallabag\CoreBundle\Entity\User $user = null) - { - $this->user = $user; - - return $this; - } - - /** - * Get user - * - * @return \Wallabag\CoreBundle\Entity\User - */ - public function getUser() - { - return $this->user; - } -} diff --git a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php new file mode 100644 index 00000000..74e2a6f1 --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php @@ -0,0 +1,41 @@ +add('theme', 'choice', array( + 'choices' => array( + 'baggy' => 'Baggy', + 'courgette' => 'Courgette', + 'dark' => 'Dark', + 'default' => 'Default', + 'dmagenta' => 'Dmagenta', + 'solarized' => 'Solarized', + 'solarized_dark' => 'Solarized Dark', + ), + )) + ->add('items_per_page') + ->add('language') + ->add('save', 'submit') + ; + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Wallabag\CoreBundle\Entity\Config', + )); + } + + public function getName() + { + return 'config'; + } +} diff --git a/src/Wallabag/CoreBundle/Repository/ConfigRepository.php b/src/Wallabag/CoreBundle/Repository/ConfigRepository.php new file mode 100644 index 00000000..b2b1f627 --- /dev/null +++ b/src/Wallabag/CoreBundle/Repository/ConfigRepository.php @@ -0,0 +1,9 @@ +Basic config + +
+ {{ form_errors(form) }} + +
+
+ {{ form_label(form.theme) }} + {{ form_errors(form.theme) }} + {{ form_widget(form.theme) }} +
+
+ +
+
+ {{ form_label(form.items_per_page) }} + {{ form_errors(form.items_per_page) }} + {{ form_widget(form.items_per_page) }} +
+
+ +
+
+ {{ form_label(form.language) }} + {{ form_errors(form.language) }} + {{ form_widget(form.language) }} +
+
+ + {{ form_rest(form) }} +
+{% endblock %} diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php new file mode 100644 index 00000000..30809a04 --- /dev/null +++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php @@ -0,0 +1,96 @@ +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('input[type=number]')); + $this->assertCount(1, $crawler->filter('button[type=submit]')); + } + + public function testUpdate() + { + $this->logInAs('admin'); + $client = $this->getClient(); + + $crawler = $client->request('GET', '/config'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $form = $crawler->filter('button[type=submit]')->form(); + + $data = array( + 'config[theme]' => 'baggy', + 'config[items_per_page]' => '30', + 'config[language]' => 'fr_FR', + ); + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text'))); + $this->assertContains('Config saved', $alert[0]); + } + + public function dataForUpdateFailed() + { + return array( + array(array( + 'config[theme]' => 'baggy', + 'config[items_per_page]' => '', + 'config[language]' => 'fr_FR', + )), + array(array( + 'config[theme]' => 'baggy', + 'config[items_per_page]' => '12', + 'config[language]' => '', + )), + ); + } + + /** + * @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[type=submit]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text'))); + $this->assertContains('This value should not be blank', $alert[0]); + } +} diff --git a/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php b/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php index a80b8bac..39794545 100644 --- a/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php +++ b/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php @@ -4,7 +4,7 @@ namespace Wallabag\CoreBundle\Tests; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; -class WallabagTestCase extends WebTestCase +abstract class WallabagTestCase extends WebTestCase { private $client = null; -- cgit v1.2.3 From 78cedc2262fa6d13904915cacd546389d3f453fc Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 16 Feb 2015 21:31:16 +0100 Subject: Cleanup --- app/config/config.yml | 4 ++-- app/config/global.inc.php | 25 ------------------------- app/config/parameters.yml.dist | 2 +- 3 files changed, 3 insertions(+), 28 deletions(-) delete mode 100755 app/config/global.inc.php diff --git a/app/config/config.yml b/app/config/config.yml index 7dc1bf51..33db2458 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -5,7 +5,7 @@ imports: framework: #esi: ~ - #translator: { fallback: "%locale%" } + translator: { fallback: "%locale%" } secret: "%secret%" router: resource: "%kernel.root_dir%/config/routing.yml" @@ -103,4 +103,4 @@ fos_rest: routing_loader: default_format: json -nelmio_api_doc: ~ \ No newline at end of file +nelmio_api_doc: ~ diff --git a/app/config/global.inc.php b/app/config/global.inc.php deleted file mode 100755 index 8e62818b..00000000 --- a/app/config/global.inc.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2013 - * @license http://opensource.org/licenses/MIT see COPYING file - */ - -define('ROOT', dirname(__FILE__) . '/../..'); - -require_once ROOT . '/vendor/autoload.php'; - -# system configuration -require_once __DIR__ . '/config.inc.php'; -require_once __DIR__ . '/config.inc.default.php'; - -if (!ini_get('date.timezone') || !@date_default_timezone_set(ini_get('date.timezone'))) { - date_default_timezone_set('UTC'); -} - -if (defined('ERROR_REPORTING')) { - error_reporting(ERROR_REPORTING); -} diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index e1be2e6e..e936911c 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -38,4 +38,4 @@ parameters: export_pdf: true # List view - items_on_page: 12 \ No newline at end of file + items_on_page: 12 -- cgit v1.2.3 From 7781faa0b0749b0d9842fddec3e337db04d44a10 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 16 Feb 2015 21:31:42 +0100 Subject: Use a form type for entry --- .../CoreBundle/Controller/EntryController.php | 7 ++---- src/Wallabag/CoreBundle/Form/Type/EntryType.php | 29 ++++++++++++++++++++++ .../Tests/Controller/EntryControllerTest.php | 2 +- 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 src/Wallabag/CoreBundle/Form/Type/EntryType.php diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php index 89677bef..81ab7788 100644 --- a/src/Wallabag/CoreBundle/Controller/EntryController.php +++ b/src/Wallabag/CoreBundle/Controller/EntryController.php @@ -7,7 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Wallabag\CoreBundle\Entity\Entry; use Wallabag\CoreBundle\Service\Extractor; -use Wallabag\CoreBundle\Helper\Url; +use Wallabag\CoreBundle\Form\Type\EntryType; class EntryController extends Controller { @@ -22,10 +22,7 @@ class EntryController extends Controller { $entry = new Entry($this->getUser()); - $form = $this->createFormBuilder($entry) - ->add('url', 'url') - ->add('save', 'submit') - ->getForm(); + $form = $this->createForm(new EntryType(), $entry); $form->handleRequest($request); diff --git a/src/Wallabag/CoreBundle/Form/Type/EntryType.php b/src/Wallabag/CoreBundle/Form/Type/EntryType.php new file mode 100644 index 00000000..cfd64473 --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/EntryType.php @@ -0,0 +1,29 @@ +add('url', 'url') + ->add('save', 'submit') + ; + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Wallabag\CoreBundle\Entity\Entry', + )); + } + + public function getName() + { + return 'entry'; + } +} diff --git a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php index 7276f8e4..2634141e 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php @@ -60,7 +60,7 @@ class EntryControllerTest extends WallabagTestCase $form = $crawler->filter('button[type=submit]')->form(); $data = array( - 'form[url]' => 'https://www.mailjet.com/blog/mailjet-zapier-integrations-made-easy/', + 'entry[url]' => 'https://www.mailjet.com/blog/mailjet-zapier-integrations-made-easy/', ); $client->submit($form, $data); -- cgit v1.2.3 From d9085c63e35bb708f560722fff5f4f5ad322c27b Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 17 Feb 2015 21:03:23 +0100 Subject: Handle password change --- app/config/services.yml | 1 + .../CoreBundle/Controller/ConfigController.php | 39 +++++++-- .../CoreBundle/DataFixtures/ORM/LoadUserData.php | 4 +- .../CoreBundle/Form/Type/ChangePasswordType.php | 40 +++++++++ .../Resources/views/Config/index.html.twig | 58 ++++++++++--- .../Encoder/WallabagPasswordEncoder.php | 8 +- .../Validator/WallabagUserPasswordValidator.php | 48 +++++++++++ .../Tests/Controller/ConfigControllerTest.php | 94 +++++++++++++++++++++- .../Controller/WallabagRestControllerTest.php | 8 +- src/Wallabag/CoreBundle/Tests/WallabagTestCase.php | 2 +- 10 files changed, 268 insertions(+), 34 deletions(-) create mode 100644 src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php create mode 100644 src/Wallabag/CoreBundle/Security/Validator/WallabagUserPasswordValidator.php diff --git a/app/config/services.yml b/app/config/services.yml index d4485e42..91a03e10 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -3,6 +3,7 @@ parameters: security.authentication.provider.dao.class: Wallabag\CoreBundle\Security\Authentication\Provider\WallabagAuthenticationProvider security.encoder.digest.class: Wallabag\CoreBundle\Security\Authentication\Encoder\WallabagPasswordEncoder + security.validator.user_password.class: Wallabag\CoreBundle\Security\Validator\WallabagUserPasswordValidator services: # service_name: diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index f48a9cb1..7540f756 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -7,6 +7,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Form\Type\ConfigType; +use Wallabag\CoreBundle\Form\Type\ChangePasswordType; class ConfigController extends Controller { @@ -14,19 +15,18 @@ class ConfigController extends Controller * @param Request $request * * @Route("/config", name="config") - * - * @return \Symfony\Component\HttpFoundation\Response */ public function indexAction(Request $request) { + $em = $this->getDoctrine()->getManager(); $config = $this->getConfig(); - $form = $this->createForm(new ConfigType(), $config); + // handle basic config detail + $configForm = $this->createForm(new ConfigType(), $config); + $configForm->handleRequest($request); - $form->handleRequest($request); + if ($configForm->isValid()) { - if ($form->isValid()) { - $em = $this->getDoctrine()->getManager(); $em->persist($config); $em->flush(); @@ -38,11 +38,36 @@ class ConfigController extends Controller return $this->redirect($this->generateUrl('config')); } + // handle changing password + $pwdForm = $this->createForm(new ChangePasswordType()); + $pwdForm->handleRequest($request); + + if ($pwdForm->isValid()) { + $user = $this->getUser(); + $user->setPassword($pwdForm->get('new_password')->getData()); + $em->persist($user); + $em->flush(); + + $this->get('session')->getFlashBag()->add( + 'notice', + 'Password updated' + ); + + return $this->redirect($this->generateUrl('config')); + } + return $this->render('WallabagCoreBundle:Config:index.html.twig', array( - 'form' => $form->createView(), + 'configForm' => $configForm->createView(), + 'pwdForm' => $pwdForm->createView(), )); } + /** + * Retrieve config for the current user. + * If no config were found, create a new one. + * + * @return Wallabag\CoreBundle\Entity\Config + */ private function getConfig() { $config = $this->getDoctrine() diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadUserData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadUserData.php index e4751f20..d99412f4 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadUserData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadUserData.php @@ -18,7 +18,7 @@ class LoadUserData extends AbstractFixture implements OrderedFixtureInterface $userAdmin->setName('Big boss'); $userAdmin->setEmail('bigboss@wallabag.org'); $userAdmin->setUsername('admin'); - $userAdmin->setPassword('test'); + $userAdmin->setPassword('mypassword'); $manager->persist($userAdmin); @@ -28,7 +28,7 @@ class LoadUserData extends AbstractFixture implements OrderedFixtureInterface $bobUser->setName('Bobby'); $bobUser->setEmail('bobby@wallabag.org'); $bobUser->setUsername('bob'); - $bobUser->setPassword('test'); + $bobUser->setPassword('mypassword'); $manager->persist($bobUser); diff --git a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php new file mode 100644 index 00000000..8bf4ca1e --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php @@ -0,0 +1,40 @@ +add('old_password', 'password', array( + 'constraints' => new UserPassword(array('message' => 'Wrong value for your current password')), + )) + ->add('new_password', 'repeated', array( + 'type' => 'password', + 'invalid_message' => 'The password fields must match.', + 'required' => true, + 'first_options' => array('label' => 'New password'), + 'second_options' => array('label' => 'Repeat new password'), + 'constraints' => array( + new Constraints\Length(array( + 'min' => 6, + 'minMessage' => 'Password should by at least 6 chars long' + )), + new Constraints\NotBlank() + ) + )) + ->add('save', 'submit') + ; + } + + public function getName() + { + return 'change_passwd'; + } +} diff --git a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig index 9c04ff20..94145177 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig @@ -7,35 +7,67 @@ {% endblock %} {% block content %} -

Basic config

+

{% trans %}Basic config{% endtrans %}

-
- {{ form_errors(form) }} + + {{ form_errors(configForm) }}
- {{ form_label(form.theme) }} - {{ form_errors(form.theme) }} - {{ form_widget(form.theme) }} + {{ form_label(configForm.theme) }} + {{ form_errors(configForm.theme) }} + {{ form_widget(configForm.theme) }}
- {{ form_label(form.items_per_page) }} - {{ form_errors(form.items_per_page) }} - {{ form_widget(form.items_per_page) }} + {{ form_label(configForm.items_per_page) }} + {{ form_errors(configForm.items_per_page) }} + {{ form_widget(configForm.items_per_page) }}
- {{ form_label(form.language) }} - {{ form_errors(form.language) }} - {{ form_widget(form.language) }} + {{ form_label(configForm.language) }} + {{ form_errors(configForm.language) }} + {{ form_widget(configForm.language) }}
- {{ form_rest(form) }} + {{ form_rest(configForm) }} +
+ +

{% trans %}Change your password{% endtrans %}

+ +
+ {{ form_errors(pwdForm) }} + +
+
+ {{ form_label(pwdForm.old_password) }} + {{ form_errors(pwdForm.old_password) }} + {{ form_widget(pwdForm.old_password) }} +
+
+ +
+
+ {{ form_label(pwdForm.new_password.first) }} + {{ form_errors(pwdForm.new_password.first) }} + {{ form_widget(pwdForm.new_password.first) }} +
+
+ +
+
+ {{ form_label(pwdForm.new_password.second) }} + {{ form_errors(pwdForm.new_password.second) }} + {{ form_widget(pwdForm.new_password.second) }} +
+
+ + {{ form_rest(pwdForm) }}
{% endblock %} diff --git a/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php b/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php index 56f1affe..fcfe418b 100644 --- a/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php +++ b/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php @@ -41,10 +41,6 @@ class WallabagPasswordEncoder extends BasePasswordEncoder */ public function encodePassword($raw, $salt) { - if (null === $this->username) { - throw new \LogicException('We can not check the password without a username.'); - } - if ($this->isPasswordTooLong($raw)) { throw new BadCredentialsException('Invalid password.'); } @@ -71,6 +67,10 @@ class WallabagPasswordEncoder extends BasePasswordEncoder */ protected function mergePasswordAndSalt($password, $salt) { + if (null === $this->username) { + throw new \LogicException('We can not check the password without a username.'); + } + if (empty($salt)) { return $password; } diff --git a/src/Wallabag/CoreBundle/Security/Validator/WallabagUserPasswordValidator.php b/src/Wallabag/CoreBundle/Security/Validator/WallabagUserPasswordValidator.php new file mode 100644 index 00000000..5586f976 --- /dev/null +++ b/src/Wallabag/CoreBundle/Security/Validator/WallabagUserPasswordValidator.php @@ -0,0 +1,48 @@ +securityContext = $securityContext; + $this->encoderFactory = $encoderFactory; + } + + /** + * {@inheritdoc} + */ + public function validate($password, Constraint $constraint) + { + if (!$constraint instanceof UserPassword) { + throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UserPassword'); + } + + $user = $this->securityContext->getToken()->getUser(); + + if (!$user instanceof UserInterface) { + throw new ConstraintDefinitionException('The User object must implement the UserInterface interface.'); + } + + // give username, it's used to hash the password + $encoder = $this->encoderFactory->getEncoder($user); + $encoder->setUsername($user->getUsername()); + + if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) { + $this->context->addViolation($constraint->message); + } + } +} diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php index 30809a04..4aceed15 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php @@ -26,7 +26,8 @@ class ConfigControllerTest extends WallabagTestCase $this->assertEquals(200, $client->getResponse()->getStatusCode()); $this->assertCount(1, $crawler->filter('input[type=number]')); - $this->assertCount(1, $crawler->filter('button[type=submit]')); + $this->assertCount(1, $crawler->filter('button[id=config_save]')); + $this->assertCount(1, $crawler->filter('button[id=change_passwd_save]')); } public function testUpdate() @@ -38,7 +39,7 @@ class ConfigControllerTest extends WallabagTestCase $this->assertEquals(200, $client->getResponse()->getStatusCode()); - $form = $crawler->filter('button[type=submit]')->form(); + $form = $crawler->filter('button[id=config_save]')->form(); $data = array( 'config[theme]' => 'baggy', @@ -84,7 +85,7 @@ class ConfigControllerTest extends WallabagTestCase $this->assertEquals(200, $client->getResponse()->getStatusCode()); - $form = $crawler->filter('button[type=submit]')->form(); + $form = $crawler->filter('button[id=config_save]')->form(); $crawler = $client->submit($form, $data); @@ -93,4 +94,91 @@ class ConfigControllerTest extends WallabagTestCase $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text'))); $this->assertContains('This value should not be blank', $alert[0]); } + + public function dataForChangePasswordFailed() + { + return array( + array( + array( + 'change_passwd[old_password]' => 'baggy', + 'change_passwd[new_password][first]' => '', + 'change_passwd[new_password][second]' => '', + ), + 'Wrong value for your current password' + ), + array( + array( + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => '', + 'change_passwd[new_password][second]' => '', + ), + 'This value should not be blank' + ), + array( + array( + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => 'hop', + 'change_passwd[new_password][second]' => '', + ), + 'The password fields must match' + ), + array( + array( + 'change_passwd[old_password]' => 'mypassword', + 'change_passwd[new_password][first]' => 'hop', + 'change_passwd[new_password][second]' => 'hop', + ), + 'Password should by at least 6 chars long' + ), + ); + } + + /** + * @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(array('_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 = array( + '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.flash-notice')->extract(array('_text'))); + $this->assertContains('Password updated', $alert[0]); + } } diff --git a/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php index d77e2303..fcfa8ccf 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php @@ -47,7 +47,7 @@ class WallabagRestControllerTest extends WallabagTestCase $client->request('GET', '/api/salts/admin.json'); $salt = json_decode($client->getResponse()->getContent()); - $headers = $this->generateHeaders('admin', 'test', $salt[0]); + $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]); $entry = $client->getContainer() ->get('doctrine.orm.entity_manager') @@ -73,7 +73,7 @@ class WallabagRestControllerTest extends WallabagTestCase $client->request('GET', '/api/salts/admin.json'); $salt = json_decode($client->getResponse()->getContent()); - $headers = $this->generateHeaders('admin', 'test', $salt[0]); + $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]); $entry = $client->getContainer() ->get('doctrine.orm.entity_manager') @@ -101,7 +101,7 @@ class WallabagRestControllerTest extends WallabagTestCase $client->request('GET', '/api/salts/admin.json'); $salt = json_decode($client->getResponse()->getContent()); - $headers = $this->generateHeaders('admin', 'test', $salt[0]); + $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]); $client->request('GET', '/api/entries', array(), array(), $headers); @@ -125,7 +125,7 @@ class WallabagRestControllerTest extends WallabagTestCase $client->request('GET', '/api/salts/admin.json'); $salt = json_decode($client->getResponse()->getContent()); - $headers = $this->generateHeaders('admin', 'test', $salt[0]); + $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]); $entry = $client->getContainer() ->get('doctrine.orm.entity_manager') diff --git a/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php b/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php index 39794545..22016d8e 100644 --- a/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php +++ b/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php @@ -24,7 +24,7 @@ abstract class WallabagTestCase extends WebTestCase $form = $crawler->filter('button[type=submit]')->form(); $data = array( '_username' => $username, - '_password' => 'test', + '_password' => 'mypassword', ); $this->client->submit($form, $data); -- cgit v1.2.3 From c0d9eba07f40a52bdfcfca3e7a926163b17d83ab Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 17 Feb 2015 22:45:20 +0100 Subject: Updating logged in user (email, name, etc ..) --- .../CoreBundle/Controller/ConfigController.php | 21 ++++- src/Wallabag/CoreBundle/Entity/User.php | 19 +++-- .../CoreBundle/Form/Type/ChangePasswordType.php | 9 +-- src/Wallabag/CoreBundle/Form/Type/ConfigType.php | 2 +- src/Wallabag/CoreBundle/Form/Type/UserType.php | 31 ++++++++ .../Resources/views/Config/index.html.twig | 34 ++++++++- .../Tests/Controller/ConfigControllerTest.php | 89 ++++++++++++++++++++-- 7 files changed, 185 insertions(+), 20 deletions(-) create mode 100644 src/Wallabag/CoreBundle/Form/Type/UserType.php diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index 7540f756..b3236e3c 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -8,6 +8,7 @@ use Symfony\Component\HttpFoundation\Request; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Form\Type\ConfigType; use Wallabag\CoreBundle\Form\Type\ChangePasswordType; +use Wallabag\CoreBundle\Form\Type\UserType; class ConfigController extends Controller { @@ -20,13 +21,13 @@ class ConfigController extends Controller { $em = $this->getDoctrine()->getManager(); $config = $this->getConfig(); + $user = $this->getUser(); // handle basic config detail $configForm = $this->createForm(new ConfigType(), $config); $configForm->handleRequest($request); if ($configForm->isValid()) { - $em->persist($config); $em->flush(); @@ -43,7 +44,6 @@ class ConfigController extends Controller $pwdForm->handleRequest($request); if ($pwdForm->isValid()) { - $user = $this->getUser(); $user->setPassword($pwdForm->get('new_password')->getData()); $em->persist($user); $em->flush(); @@ -56,9 +56,26 @@ class ConfigController extends Controller return $this->redirect($this->generateUrl('config')); } + // handle changing user information + $userForm = $this->createForm(new UserType(), $user); + $userForm->handleRequest($request); + + if ($userForm->isValid()) { + $em->persist($user); + $em->flush(); + + $this->get('session')->getFlashBag()->add( + 'notice', + 'Information updated' + ); + + return $this->redirect($this->generateUrl('config')); + } + return $this->render('WallabagCoreBundle:Config:index.html.twig', array( 'configForm' => $configForm->createView(), 'pwdForm' => $pwdForm->createView(), + 'userForm' => $userForm->createView(), )); } diff --git a/src/Wallabag/CoreBundle/Entity/User.php b/src/Wallabag/CoreBundle/Entity/User.php index c83250c3..193dfebc 100644 --- a/src/Wallabag/CoreBundle/Entity/User.php +++ b/src/Wallabag/CoreBundle/Entity/User.php @@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\AdvancedUserInterface; +use Symfony\Component\Validator\Constraints as Assert; /** * User @@ -29,6 +30,11 @@ class User implements AdvancedUserInterface, \Serializable * @var string * * @ORM\Column(name="username", type="text") + * @Assert\NotBlank() + * @Assert\Length( + * min = "3", + * max = "255" + * ) */ private $username; @@ -56,14 +62,16 @@ class User implements AdvancedUserInterface, \Serializable /** * @var string * - * @ORM\Column(name="email", type="text", nullable=true) + * @ORM\Column(name="email", type="text", nullable=false) + * @Assert\Email() + * @Assert\NotBlank() */ private $email; /** - * @ORM\Column(name="is_active", type="boolean") + * @ORM\Column(name="is_active", type="boolean", nullable=false) */ - private $isActive; + private $isActive = true; /** * @var date @@ -86,9 +94,8 @@ class User implements AdvancedUserInterface, \Serializable public function __construct() { - $this->isActive = true; - $this->salt = md5(uniqid(null, true)); - $this->entries = new ArrayCollection(); + $this->salt = md5(uniqid(null, true)); + $this->entries = new ArrayCollection(); } /** diff --git a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php index 8bf4ca1e..de0ad537 100644 --- a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php +++ b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php @@ -3,7 +3,6 @@ namespace Wallabag\CoreBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolverInterface; use Symfony\Component\Security\Core\Validator\Constraints\UserPassword; use Symfony\Component\Validator\Constraints; @@ -23,11 +22,11 @@ class ChangePasswordType extends AbstractType 'second_options' => array('label' => 'Repeat new password'), 'constraints' => array( new Constraints\Length(array( - 'min' => 6, - 'minMessage' => 'Password should by at least 6 chars long' + 'min' => 8, + 'minMessage' => 'Password should by at least 6 chars long', )), - new Constraints\NotBlank() - ) + new Constraints\NotBlank(), + ), )) ->add('save', 'submit') ; diff --git a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php index 74e2a6f1..a1e0ce47 100644 --- a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php +++ b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php @@ -21,7 +21,7 @@ class ConfigType extends AbstractType 'solarized_dark' => 'Solarized Dark', ), )) - ->add('items_per_page') + ->add('items_per_page', 'text') ->add('language') ->add('save', 'submit') ; diff --git a/src/Wallabag/CoreBundle/Form/Type/UserType.php b/src/Wallabag/CoreBundle/Form/Type/UserType.php new file mode 100644 index 00000000..b479a0b5 --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/UserType.php @@ -0,0 +1,31 @@ +add('username', 'text') + ->add('name', 'text') + ->add('email', 'text') + ->add('save', 'submit') + ; + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Wallabag\CoreBundle\Entity\User', + )); + } + + public function getName() + { + return 'user'; + } +} diff --git a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig index 94145177..7a45ec1f 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig @@ -7,7 +7,7 @@ {% endblock %} {% block content %} -

{% trans %}Basic config{% endtrans %}

+

{% trans %}Wallabag configuration{% endtrans %}

{{ form_errors(configForm) }} @@ -39,6 +39,38 @@ {{ form_rest(configForm) }}
+

{% trans %}User information{% endtrans %}

+ +
+ {{ form_errors(userForm) }} + +
+
+ {{ form_label(userForm.username) }} + {{ form_errors(userForm.username) }} + {{ form_widget(userForm.username) }} +
+
+ +
+
+ {{ form_label(userForm.name) }} + {{ form_errors(userForm.name) }} + {{ form_widget(userForm.name) }} +
+
+ +
+
+ {{ form_label(userForm.email) }} + {{ form_errors(userForm.email) }} + {{ form_widget(userForm.email) }} +
+
+ + {{ form_rest(userForm) }} +
+

{% trans %}Change your password{% endtrans %}

diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php index 4aceed15..519b4ba2 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php @@ -25,9 +25,9 @@ class ConfigControllerTest extends WallabagTestCase $this->assertEquals(200, $client->getResponse()->getStatusCode()); - $this->assertCount(1, $crawler->filter('input[type=number]')); $this->assertCount(1, $crawler->filter('button[id=config_save]')); $this->assertCount(1, $crawler->filter('button[id=change_passwd_save]')); + $this->assertCount(1, $crawler->filter('button[id=user_save]')); } public function testUpdate() @@ -104,7 +104,7 @@ class ConfigControllerTest extends WallabagTestCase 'change_passwd[new_password][first]' => '', 'change_passwd[new_password][second]' => '', ), - 'Wrong value for your current password' + 'Wrong value for your current password', ), array( array( @@ -112,7 +112,7 @@ class ConfigControllerTest extends WallabagTestCase 'change_passwd[new_password][first]' => '', 'change_passwd[new_password][second]' => '', ), - 'This value should not be blank' + 'This value should not be blank', ), array( array( @@ -120,7 +120,7 @@ class ConfigControllerTest extends WallabagTestCase 'change_passwd[new_password][first]' => 'hop', 'change_passwd[new_password][second]' => '', ), - 'The password fields must match' + 'The password fields must match', ), array( array( @@ -128,7 +128,7 @@ class ConfigControllerTest extends WallabagTestCase 'change_passwd[new_password][first]' => 'hop', 'change_passwd[new_password][second]' => 'hop', ), - 'Password should by at least 6 chars long' + 'Password should by at least 6 chars long', ), ); } @@ -181,4 +181,83 @@ class ConfigControllerTest extends WallabagTestCase $this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text'))); $this->assertContains('Password updated', $alert[0]); } + + public function dataForUserFailed() + { + return array( + array( + array( + 'user[username]' => '', + 'user[name]' => '', + 'user[email]' => '', + ), + 'This value should not be blank.', + ), + array( + array( + 'user[username]' => 'ad', + 'user[name]' => '', + 'user[email]' => '', + ), + 'This value is too short.', + ), + array( + array( + 'user[username]' => 'admin', + 'user[name]' => '', + 'user[email]' => 'test', + ), + 'This value is not a valid email address.', + ), + ); + } + + /** + * @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=user_save]')->form(); + + $crawler = $client->submit($form, $data); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->assertGreaterThan(1, $alert = $crawler->filter('body')->extract(array('_text'))); + $this->assertContains($expectedMessage, $alert[0]); + } + + 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=user_save]')->form(); + + $data = array( + 'user[username]' => 'admin', + 'user[name]' => 'new name', + 'user[email]' => 'admin@wallabag.io', + ); + + $client->submit($form, $data); + + $this->assertEquals(302, $client->getResponse()->getStatusCode()); + + $crawler = $client->followRedirect(); + + $this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text'))); + $this->assertContains('Information updated', $alert[0]); + } } -- cgit v1.2.3 From e4977b8a866f84f65f08c55c050a62f40170fdbf Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 22 Feb 2015 09:30:25 +0100 Subject: Adding new user --- .../CoreBundle/Controller/ConfigController.php | 20 +++++ .../CoreBundle/Form/Type/ChangePasswordType.php | 2 +- src/Wallabag/CoreBundle/Form/Type/NewUserType.php | 40 ++++++++++ .../Resources/views/Config/index.html.twig | 32 ++++++++ .../Tests/Controller/ConfigControllerTest.php | 89 +++++++++++++++++++++- 5 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 src/Wallabag/CoreBundle/Form/Type/NewUserType.php diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index b3236e3c..aedbc999 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -6,9 +6,11 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Wallabag\CoreBundle\Entity\Config; +use Wallabag\CoreBundle\Entity\User; use Wallabag\CoreBundle\Form\Type\ConfigType; use Wallabag\CoreBundle\Form\Type\ChangePasswordType; use Wallabag\CoreBundle\Form\Type\UserType; +use Wallabag\CoreBundle\Form\Type\NewUserType; class ConfigController extends Controller { @@ -72,10 +74,28 @@ class ConfigController extends Controller return $this->redirect($this->generateUrl('config')); } + // handle adding new user + $newUser = new User(); + $newUserForm = $this->createForm(new NewUserType(), $newUser); + $newUserForm->handleRequest($request); + + if ($newUserForm->isValid()) { + $em->persist($newUser); + $em->flush(); + + $this->get('session')->getFlashBag()->add( + 'notice', + sprintf('User "%s" added', $newUser->getUsername()) + ); + + return $this->redirect($this->generateUrl('config')); + } + return $this->render('WallabagCoreBundle:Config:index.html.twig', array( 'configForm' => $configForm->createView(), 'pwdForm' => $pwdForm->createView(), 'userForm' => $userForm->createView(), + 'newUserForm' => $newUserForm->createView(), )); } diff --git a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php index de0ad537..e141789f 100644 --- a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php +++ b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php @@ -23,7 +23,7 @@ class ChangePasswordType extends AbstractType 'constraints' => array( new Constraints\Length(array( 'min' => 8, - 'minMessage' => 'Password should by at least 6 chars long', + 'minMessage' => 'Password should by at least 8 chars long', )), new Constraints\NotBlank(), ), diff --git a/src/Wallabag/CoreBundle/Form/Type/NewUserType.php b/src/Wallabag/CoreBundle/Form/Type/NewUserType.php new file mode 100644 index 00000000..313a9aae --- /dev/null +++ b/src/Wallabag/CoreBundle/Form/Type/NewUserType.php @@ -0,0 +1,40 @@ +add('username', 'text') + ->add('password', 'password', array( + 'constraints' => array( + new Constraints\Length(array( + 'min' => 8, + 'minMessage' => 'Password should by at least 8 chars long', + )), + new Constraints\NotBlank(), + ), + )) + ->add('email', 'text') + ->add('save', 'submit') + ; + } + + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => 'Wallabag\CoreBundle\Entity\User', + )); + } + + public function getName() + { + return 'new_user'; + } +} diff --git a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig index 7a45ec1f..051dafd6 100644 --- a/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig +++ b/src/Wallabag/CoreBundle/Resources/views/Config/index.html.twig @@ -102,4 +102,36 @@ {{ form_rest(pwdForm) }} + +

{% trans %}Add a user{% endtrans %}

+ +
+ {{ form_errors(newUserForm) }} + +
+
+ {{ form_label(newUserForm.username) }} + {{ form_errors(newUserForm.username) }} + {{ form_widget(newUserForm.username) }} +
+
+ +
+
+ {{ form_label(newUserForm.password) }} + {{ form_errors(newUserForm.password) }} + {{ form_widget(newUserForm.password) }} +
+
+ +
+
+ {{ form_label(newUserForm.email) }} + {{ form_errors(newUserForm.email) }} + {{ form_widget(newUserForm.email) }} +
+
+ + {{ form_rest(newUserForm) }} +
{% endblock %} diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php index 519b4ba2..9b1a0986 100644 --- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php +++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php @@ -128,7 +128,7 @@ class ConfigControllerTest extends WallabagTestCase 'change_passwd[new_password][first]' => 'hop', 'change_passwd[new_password][second]' => 'hop', ), - 'Password should by at least 6 chars long', + 'Password should by at least', ), ); } @@ -260,4 +260,91 @@ class ConfigControllerTest extends WallabagTestCase $this->assertGreaterThan(1, $alert = $crawler->filter('div.flash-notice')->extract(array('_text'))); $this->assertContains('Information updated', $alert[0]); } + + public function dataForNewUserFailed() + { + return array( + array( + array( + 'new_user[username]' => '', + 'new_user[password]' => '', + 'new_user[email]' => '', + ), + 'This value should not be blank.', + ), + array( + array( + 'new_user[username]' => 'ad', + 'new_user[password]' => '', + 'new_user[email]' => '', + ), + 'This value is too short.', + ), + array( + array( + 'new_user[username]' => 'wallace', + 'new_user[password]' => '', + 'new_user[email]' => 'test', + ), + 'This value is not a valid email address.', + ), + array( + array( + 'new_user[username]' => 'wallace', + 'new_user[password]' => 'admin', + 'new_user[email]' => 'wallace@wallace.me', + ), + 'Password should by at least', + ), + ); + } + + /** + * @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(array('_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 = array( + 'new_user[username]' => 'wallace', + 'new_user[password]' => '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.flash-notice')->extract(array('_text'))); + $this->assertContains('User "wallace" added', $alert[0]); + } } -- cgit v1.2.3 From 0bd2cb1ecd2f9194735af77142390a94723d1b39 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 22 Feb 2015 10:50:27 +0100 Subject: Handle default value for new user --- app/config/parameters.yml.dist | 4 +++- src/Wallabag/CoreBundle/Command/InstallCommand.php | 9 ++++----- src/Wallabag/CoreBundle/Controller/ConfigController.php | 8 ++++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index e936911c..258a585f 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -37,5 +37,7 @@ parameters: export_mobi: true export_pdf: true - # List view + # default user config items_on_page: 12 + theme: baggy + language: en_US diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index a4301958..c1b72604 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php @@ -135,11 +135,10 @@ class InstallCommand extends ContainerAwareCommand $em->persist($user); - $config = new Config(); - $config->setUser($user); - $config->setTheme('baggy'); - $config->setItemsPerPage(10); - $config->setLanguage('en_US'); + $config = new Config($user); + $config->setTheme($this->getContainer()->getParameter('theme')); + $config->setItemsPerPage($this->getContainer()->getParameter('items_on_page')); + $config->setLanguage($this->getContainer()->getParameter('language')); $em->persist($config); } diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php index aedbc999..68e034fa 100644 --- a/src/Wallabag/CoreBundle/Controller/ConfigController.php +++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php @@ -81,6 +81,14 @@ class ConfigController extends Controller if ($newUserForm->isValid()) { $em->persist($newUser); + + $config = new Config($newUser); + $config->setTheme($this->container->getParameter('theme')); + $config->setItemsPerPage($this->container->getParameter('items_on_page')); + $config->setLanguage($this->container->getParameter('language')); + + $em->persist($config); + $em->flush(); $this->get('session')->getFlashBag()->add( -- cgit v1.2.3 From 0bf99bb144561525a34a50315b95efd6f543fe35 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 22 Feb 2015 14:35:36 +0100 Subject: Improve install command & add test Also add fixtures for Config InstallCommand now check if database, schema are here and ask the user what to do (keep or trash & re-create) --- src/Wallabag/CoreBundle/Command/InstallCommand.php | 270 ++++++++++++++++----- .../CoreBundle/DataFixtures/ORM/LoadConfigData.php | 45 ++++ .../CoreBundle/DataFixtures/ORM/LoadEntryData.php | 2 +- .../Tests/Command/InstallCommandTest.php | 61 +++++ 4 files changed, 314 insertions(+), 64 deletions(-) create mode 100644 src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php create mode 100644 src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index c1b72604..a528c309 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php @@ -4,134 +4,194 @@ namespace Wallabag\CoreBundle\Command; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\NullOutput; use Wallabag\CoreBundle\Entity\User; use Wallabag\CoreBundle\Entity\Config; class InstallCommand extends ContainerAwareCommand { + /** + * @var InputInterface + */ + protected $defaultInput; + + /** + * @var OutputInterface + */ + protected $defaultOutput; + protected function configure() { $this ->setName('wallabag:install') ->setDescription('Wallabag installer.') + ->addOption( + 'reset', + null, + InputOption::VALUE_NONE, + 'Reset current database' + ) ; } protected function execute(InputInterface $input, OutputInterface $output) { - $output->writeln('Installing Wallabag.'); + $this->defaultInput = $input; + $this->defaultOutput = $output; + + $output->writeln('Installing Wallabag...'); $output->writeln(''); $this - ->checkStep($output) - ->setupStep($input, $output) + ->checkRequirements() + ->setupDatabase() + ->setupAdmin() + ->setupAsset() ; $output->writeln('Wallabag has been successfully installed.'); $output->writeln('Just execute `php app/console server:run` for using wallabag: http://localhost:8000'); } - protected function checkStep(OutputInterface $output) + protected function checkRequirements() { - $output->writeln('Checking system requirements.'); + $this->defaultOutput->writeln('Step 1 of 4. Checking system requirements.'); $fulfilled = true; // @TODO: find a better way to check requirements - $output->writeln('Check PCRE'); + $label = 'PCRE'; if (extension_loaded('pcre')) { - $output->writeln(' OK'); + $status = 'OK!'; + $help = ''; } else { $fulfilled = false; - $output->writeln(' ERROR'); - $output->writeln('You should enabled PCRE extension'); + $status = 'ERROR!'; + $help = 'You should enabled PCRE extension'; } + $rows[] = array($label, $status, $help); - $output->writeln('Check DOM'); + $label = 'DOM'; if (extension_loaded('DOM')) { - $output->writeln(' OK'); + $status = 'OK!'; + $help = ''; } else { $fulfilled = false; - $output->writeln(' ERROR'); - $output->writeln('You should enabled DOM extension'); + $status = 'ERROR!'; + $help = 'You should enabled DOM extension'; } + $rows[] = array($label, $status, $help); + + $this->getHelper('table') + ->setHeaders(array('Checked', 'Status', 'Recommendation')) + ->setRows($rows) + ->render($this->defaultOutput); if (!$fulfilled) { - throw new RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); + throw new \RuntimeException('Some system requirements are not fulfilled. Please check output messages and fix them.'); + } else { + $this->defaultOutput->writeln('Success! Your system can run Wallabag properly.'); } - $output->writeln(''); + $this->defaultOutput->writeln(''); return $this; } - protected function setupStep(InputInterface $input, OutputInterface $output) + protected function setupDatabase() { - $output->writeln('Setting up database.'); + $this->defaultOutput->writeln('Step 2 of 4. Setting up database.'); - $this->setupDatabase($input, $output); + // user want to reset everything? Don't care about what is already here + if (true === $this->defaultInput->getOption('reset')) { + $this->defaultOutput->writeln('Droping database, creating database and schema'); - // if ($this->getHelperSet()->get('dialog')->askConfirmation($output, 'Load fixtures (Y/N)?', false)) { - // $this->setupFixtures($input, $output); - // } + $this + ->runCommand('doctrine:database:drop', array('--force' => true)) + ->runCommand('doctrine:database:create') + ->runCommand('doctrine:schema:create') + ; - $output->writeln(''); - $output->writeln('Administration setup.'); + return $this; + } - $this->setupAdmin($output); + if (!$this->isDatabasePresent()) { + $this->defaultOutput->writeln('Creating database and schema, clearing the cache'); - $output->writeln(''); + $this + ->runCommand('doctrine:database:create') + ->runCommand('doctrine:schema:create') + ->runCommand('cache:clear') + ; - return $this; - } + return $this; + } - protected function setupDatabase(InputInterface $input, OutputInterface $output) - { - if ($this->getHelperSet()->get('dialog')->askConfirmation($output, 'Drop current database (Y/N)?', true)) { - $connection = $this->getContainer()->get('doctrine')->getConnection(); - $params = $connection->getParams(); + $dialog = $this->getHelper('dialog'); - $name = isset($params['path']) ? $params['path'] : (isset($params['dbname']) ? $params['dbname'] : false); - unset($params['dbname']); + if ($dialog->askConfirmation($this->defaultOutput, 'It appears that your database already exists. Would you like to reset it? (y/N) ', false)) { + $this->defaultOutput->writeln('Droping database, creating database and schema'); - if (!isset($params['path'])) { - $name = $connection->getDatabasePlatform()->quoteSingleIdentifier($name); - } + $this + ->runCommand('doctrine:database:drop', array('--force' => true)) + ->runCommand('doctrine:database:create') + ->runCommand('doctrine:schema:create') + ; + } elseif ($this->isSchemaPresent()) { + if ($dialog->askConfirmation($this->defaultOutput, 'Seems like your database contains schema. Do you want to reset it? (y/N) ', false)) { + $this->defaultOutput->writeln('Droping schema and creating schema'); - $connection->getSchemaManager()->dropDatabase($name); + $this + ->runCommand('doctrine:schema:drop', array('--force' => true)) + ->runCommand('doctrine:schema:create') + ; + } } else { - throw new \Exception("Install setup stopped, database need to be dropped. Please backup your current one and re-launch the install command."); + $this->defaultOutput->writeln('Creating schema'); + + $this + ->runCommand('doctrine:schema:create') + ; } - $this - ->runCommand('doctrine:database:create', $input, $output) - ->runCommand('doctrine:schema:create', $input, $output) - ->runCommand('cache:clear', $input, $output) - ->runCommand('assets:install', $input, $output) - ->runCommand('assetic:dump', $input, $output) - ; - } + $this->defaultOutput->writeln('Clearing the cache'); + $this->runCommand('cache:clear'); + + /* + if ($this->getHelperSet()->get('dialog')->askConfirmation($this->defaultOutput, 'Load fixtures (Y/N)?', false)) { + $doctrineConfig = $this->getContainer()->get('doctrine.orm.entity_manager')->getConnection()->getConfiguration(); + $logger = $doctrineConfig->getSQLLogger(); + // speed up fixture load + $doctrineConfig->setSQLLogger(null); + $this->runCommand('doctrine:fixtures:load'); + $doctrineConfig->setSQLLogger($logger); + } + */ - protected function setupFixtures(InputInterface $input, OutputInterface $output) - { - $doctrineConfig = $this->getContainer()->get('doctrine.orm.entity_manager')->getConnection()->getConfiguration(); - $logger = $doctrineConfig->getSQLLogger(); - // speed up fixture load - $doctrineConfig->setSQLLogger(null); - $this->runCommand('doctrine:fixtures:load', $input, $output); - $doctrineConfig->setSQLLogger($logger); + $this->defaultOutput->writeln(''); + + return $this; } - protected function setupAdmin(OutputInterface $output) + protected function setupAdmin() { + $this->defaultOutput->writeln('Step 3 of 4. Administration setup.'); + $dialog = $this->getHelperSet()->get('dialog'); + + if (false === $dialog->askConfirmation($this->defaultOutput, 'Would you like to create a new user ? (y/N)', true)) { + return $this; + } + $em = $this->getContainer()->get('doctrine.orm.entity_manager'); $user = new User(); - $user->setUsername($dialog->ask($output, 'Username (default: wallabag) :', 'wallabag')); - $user->setPassword($dialog->ask($output, 'Password (default: wallabag) :', 'wallabag')); - $user->setEmail($dialog->ask($output, 'Email:', '')); + $user->setUsername($dialog->ask($this->defaultOutput, 'Username (default: wallabag) :', 'wallabag')); + $user->setPassword($dialog->ask($this->defaultOutput, 'Password (default: wallabag) :', 'wallabag')); + $user->setEmail($dialog->ask($this->defaultOutput, 'Email:', '')); $em->persist($user); @@ -141,16 +201,100 @@ class InstallCommand extends ContainerAwareCommand $config->setLanguage($this->getContainer()->getParameter('language')); $em->persist($config); + + $em->flush(); + + $this->defaultOutput->writeln(''); + + return $this; } - protected function runCommand($command, InputInterface $input, OutputInterface $output) + protected function setupAsset() { + $this->defaultOutput->writeln('Step 4 of 4. Installing assets.'); + $this - ->getApplication() - ->find($command) - ->run($input, $output) + ->runCommand('assets:install') + ->runCommand('assetic:dump') ; + $this->defaultOutput->writeln(''); + + return $this; + } + + /** + * Run a command + * + * @param string $command + * @param array $parameters Parameters to this command (usually 'force' => true) + */ + protected function runCommand($command, $parameters = array()) + { + $parameters = array_merge( + array('command' => $command), + $parameters, + array( + '--no-debug' => true, + '--env' => $this->defaultInput->getOption('env') ?: 'dev', + ) + ); + + if ($this->defaultInput->getOption('no-interaction')) { + $parameters = array_merge($parameters, array('--no-interaction' => true)); + } + + $this->getApplication()->setAutoExit(false); + $exitCode = $this->getApplication()->run(new ArrayInput($parameters), new NullOutput()); + + if (0 !== $exitCode) { + $this->getApplication()->setAutoExit(true); + + $errorMessage = sprintf('The command "%s" terminated with an error code: %u.', $command, $exitCode); + $this->defaultOutput->writeln("$errorMessage"); + $exception = new \Exception($errorMessage, $exitCode); + + throw $exception; + } + + // PDO does not always close the connection after Doctrine commands. + // See https://github.com/symfony/symfony/issues/11750. + $this->getContainer()->get('doctrine')->getManager()->getConnection()->close(); + return $this; } + + /** + * Check if the database already exists + * + * @return boolean + */ + private function isDatabasePresent() + { + $databaseName = $this->getContainer()->getParameter('database_name'); + + try { + $schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager(); + } catch (\Exception $exception) { + if (false !== strpos($exception->getMessage(), sprintf("Unknown database '%s'", $databaseName))) { + return false; + } + + throw $exception; + } + + return in_array($databaseName, $schemaManager->listDatabases()); + } + + /** + * Check if the schema is already created + * + * @return boolean + */ + private function isSchemaPresent() + { + $schemaManager = $this->getContainer()->get('doctrine')->getManager()->getConnection()->getSchemaManager(); + + return $schemaManager->tablesExist(array('entry')); + } } diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php new file mode 100644 index 00000000..900e151d --- /dev/null +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadConfigData.php @@ -0,0 +1,45 @@ +getReference('admin-user')); + $adminConfig->setTheme('baggy'); + $adminConfig->setItemsPerPage(30); + $adminConfig->setLanguage('en_US'); + + $manager->persist($adminConfig); + + $this->addReference('admin-config', $adminConfig); + + $bobConfig = new Config($this->getReference('bob-user')); + $bobConfig->setTheme('default'); + $bobConfig->setItemsPerPage(10); + $bobConfig->setLanguage('fr_FR'); + + $manager->persist($bobConfig); + + $this->addReference('bob-config', $bobConfig); + + $manager->flush(); + } + + /** + * {@inheritDoc} + */ + public function getOrder() + { + return 20; + } +} diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php index 520b44b8..3be323ed 100644 --- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php +++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php @@ -49,6 +49,6 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface */ public function getOrder() { - return 20; + return 30; } } diff --git a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php new file mode 100644 index 00000000..6bcc9707 --- /dev/null +++ b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php @@ -0,0 +1,61 @@ +setAutoExit(false); + + $code = $application->run(new ArrayInput(array( + 'command' => 'doctrine:fixtures:load', + '--no-interaction' => true, + '--env' => 'test', + )), new NullOutput()); + } + + public function testRunInstallCommand() + { + $this->container = static::$kernel->getContainer(); + + $application = new Application(static::$kernel); + $application->add(new InstallCommand()); + + $command = $application->find('wallabag:install'); + + // We mock the DialogHelper + $dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper') + ->disableOriginalConstructor() + ->getMock(); + $dialog->expects($this->any()) + ->method('ask') + ->will($this->returnValue('test')); + $dialog->expects($this->any()) + ->method('askConfirmation') + ->will($this->returnValue(true)); + + // We override the standard helper with our mock + $command->getHelperSet()->set($dialog, 'dialog'); + + $tester = new CommandTester($command); + $tester->execute(array( + 'command' => $command->getName() + )); + + $this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay()); + $this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay()); + $this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay()); + } +} -- cgit v1.2.3 From 732c2ad8971f427ec196acfac53dad034cefdef4 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 22 Feb 2015 17:18:54 +0100 Subject: sqlite doesn't support getListDatabasesSQL --- app/config/parameters.yml.dist | 2 +- src/Wallabag/CoreBundle/Command/InstallCommand.php | 11 +++++++++++ src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index 258a585f..44969750 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -6,7 +6,7 @@ parameters: database_name: symfony database_user: root database_password: ~ - database_path: "%kernel.root_dir%/../data/db/poche.sqlite" + database_path: "%kernel.root_dir%/../data/db/wallabag.sqlite" mailer_transport: smtp mailer_host: 127.0.0.1 diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php index a528c309..ac7583ea 100644 --- a/src/Wallabag/CoreBundle/Command/InstallCommand.php +++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php @@ -283,6 +283,17 @@ class InstallCommand extends ContainerAwareCommand throw $exception; } + // custom verification for sqlite, since `getListDatabasesSQL` doesn't work for sqlite + if ('sqlite' == $schemaManager->getDatabasePlatform()->getName()) { + $params = $this->getContainer()->get('doctrine.dbal.default_connection')->getParams(); + + if (isset($params['path']) && file_exists($params['path'])) { + return true; + } + + return false; + } + return in_array($databaseName, $schemaManager->listDatabases()); } diff --git a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php index 6bcc9707..a091d66f 100644 --- a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php +++ b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php @@ -50,7 +50,7 @@ class InstallCommandTest extends WallabagTestCase $tester = new CommandTester($command); $tester->execute(array( - 'command' => $command->getName() + 'command' => $command->getName(), )); $this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay()); -- cgit v1.2.3 From c641baad0ec52198d77f2018c7bf8acdfe5957ce Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 22 Feb 2015 23:29:48 +0100 Subject: More tests on the install command --- .../Tests/Command/InstallCommandTest.php | 219 ++++++++++++++++++++- 1 file changed, 216 insertions(+), 3 deletions(-) diff --git a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php index a091d66f..64f6c329 100644 --- a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php +++ b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php @@ -8,13 +8,13 @@ use Symfony\Bundle\FrameworkBundle\Console\Application; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; +use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; +use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; class InstallCommandTest extends WallabagTestCase { - public function tearDown() + public static function tearDownAfterClass() { - parent::tearDown(); - $application = new Application(static::$kernel); $application->setAutoExit(false); @@ -58,4 +58,217 @@ class InstallCommandTest extends WallabagTestCase $this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay()); $this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay()); } + + public function testRunInstallCommandWithReset() + { + $this->container = static::$kernel->getContainer(); + + $application = new Application(static::$kernel); + $application->add(new InstallCommand()); + + $command = $application->find('wallabag:install'); + + // We mock the DialogHelper + $dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper') + ->disableOriginalConstructor() + ->getMock(); + $dialog->expects($this->any()) + ->method('ask') + ->will($this->returnValue('test')); + $dialog->expects($this->any()) + ->method('askConfirmation') + ->will($this->returnValue(true)); + + // We override the standard helper with our mock + $command->getHelperSet()->set($dialog, 'dialog'); + + $tester = new CommandTester($command); + $tester->execute(array( + 'command' => $command->getName(), + '--reset' => true, + )); + + $this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay()); + $this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay()); + $this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay()); + + // we force to reset everything + $this->assertContains('Droping database, creating database and schema', $tester->getDisplay()); + } + + public function testRunInstallCommandWithDatabaseRemoved() + { + $this->container = static::$kernel->getContainer(); + + $application = new Application(static::$kernel); + $application->add(new InstallCommand()); + $application->add(new DropDatabaseDoctrineCommand()); + + // drop database first, so the install command won't ask to reset things + $command = new DropDatabaseDoctrineCommand(); + $command->setApplication($application); + $command->run(new ArrayInput(array( + 'command' => 'doctrine:database:drop', + '--force' => true, + )), new NullOutput()); + + $command = $application->find('wallabag:install'); + + // We mock the DialogHelper + $dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper') + ->disableOriginalConstructor() + ->getMock(); + $dialog->expects($this->any()) + ->method('ask') + ->will($this->returnValue('test')); + $dialog->expects($this->any()) + ->method('askConfirmation') + ->will($this->returnValue(true)); + + // We override the standard helper with our mock + $command->getHelperSet()->set($dialog, 'dialog'); + + $tester = new CommandTester($command); + $tester->execute(array( + 'command' => $command->getName(), + )); + + $this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay()); + $this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay()); + $this->assertContains('Step 4 of 4. 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() + { + $this->container = static::$kernel->getContainer(); + + $application = new Application(static::$kernel); + $application->add(new InstallCommand()); + + $command = $application->find('wallabag:install'); + + // We mock the DialogHelper + $dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper') + ->disableOriginalConstructor() + ->getMock(); + + $dialog->expects($this->exactly(3)) + ->method('askConfirmation') + ->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($dialog, 'dialog'); + + $tester = new CommandTester($command); + $tester->execute(array( + 'command' => $command->getName(), + )); + + $this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay()); + $this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay()); + $this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay()); + + $this->assertContains('Droping schema and creating schema', $tester->getDisplay()); + } + + public function testRunInstallCommandChooseNothing() + { + $this->container = static::$kernel->getContainer(); + + $application = new Application(static::$kernel); + $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(array( + 'command' => 'doctrine:database:drop', + '--force' => true, + )), new NullOutput()); + + $this->container->get('doctrine')->getManager()->getConnection()->close(); + + $command = new CreateDatabaseDoctrineCommand(); + $command->setApplication($application); + $command->run(new ArrayInput(array( + 'command' => 'doctrine:database:create', + '--env' => 'test', + )), new NullOutput()); + + $command = $application->find('wallabag:install'); + + // We mock the DialogHelper + $dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper') + ->disableOriginalConstructor() + ->getMock(); + + $dialog->expects($this->exactly(2)) + ->method('askConfirmation') + ->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($dialog, 'dialog'); + + $tester = new CommandTester($command); + $tester->execute(array( + 'command' => $command->getName(), + )); + + $this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay()); + $this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay()); + $this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay()); + + $this->assertContains('Creating schema', $tester->getDisplay()); + } + + public function testRunInstallCommandNoInteraction() + { + $this->container = static::$kernel->getContainer(); + + $application = new Application(static::$kernel); + $application->add(new InstallCommand()); + + $command = $application->find('wallabag:install'); + + // We mock the DialogHelper + $dialog = $this->getMockBuilder('Symfony\Component\Console\Helper\DialogHelper') + ->disableOriginalConstructor() + ->getMock(); + $dialog->expects($this->any()) + ->method('ask') + ->will($this->returnValue('test')); + $dialog->expects($this->any()) + ->method('askConfirmation') + ->will($this->returnValue(true)); + + // We override the standard helper with our mock + $command->getHelperSet()->set($dialog, 'dialog'); + + $tester = new CommandTester($command); + $tester->execute(array( + 'command' => $command->getName(), + '--no-interaction' => true, + )); + + $this->assertContains('Step 1 of 4. Checking system requirements.', $tester->getDisplay()); + $this->assertContains('Step 2 of 4. Setting up database.', $tester->getDisplay()); + $this->assertContains('Step 3 of 4. Administration setup.', $tester->getDisplay()); + $this->assertContains('Step 4 of 4. Installing assets.', $tester->getDisplay()); + } } -- cgit v1.2.3