diff --git a/Controller/SearchController.php b/Controller/SearchController.php index 110cc98dc..63439e8ce 100644 --- a/Controller/SearchController.php +++ b/Controller/SearchController.php @@ -24,6 +24,9 @@ namespace Chill\MainBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; +use Chill\MainBundle\Search\UnknowSearchDomainException; +use Chill\MainBundle\Search\UnknowSearchNameException; +use Chill\MainBundle\Search\ParsingException; /** * @@ -31,16 +34,52 @@ use Symfony\Component\HttpFoundation\Request; * @author julien.fastre@champs-libres.coop * @author marc@champs-libres.coop */ - class SearchController extends Controller { + public function searchAction(Request $request) { - $results = $this->get('chill.main.search_provider') - ->getResults($request->query->get('q')); + $pattern = $request->query->get('q', ''); + + if ($pattern === ''){ + return $this->render('ChillMainBundle:Search:error.html.twig', + array( + 'message' => $this->get('translator')->trans("Your search is empty. " + . "Please provide search terms.") + )); + + } + + $name = $request->query->get('name', NULL); + + try { + if ($name === NULL) { + $results = $this->get('chill.main.search_provider') + ->getSearchResults($request->query->get('q')); + } else { + $results = [$this->get('chill.main.search_provider') + ->getResultByName($pattern, $name)]; + } + } catch (UnknowSearchDomainException $ex) { + return $this->render('ChillMainBundle:Search:error.html.twig', + array( + "message" => $this->get('translator')->trans("The domain %domain% " + . "is unknow. Please check your search.", array('%domain%' => $ex->getDomain())) + )); + } catch (UnknowSearchNameException $ex) { + throw $this->createNotFoundException("The name ".$ex->getName()." is not found"); + } catch (ParsingException $ex) { + return $this->render('ChillMainBundle:Search:error.html.twig', + array( + "message" => $this->get('translator')->trans('Invalid terms'). + ": ".$this->get('translator')->trans($ex->getMessage()) + )); + } + return $this->render('ChillMainBundle:Search:list.html.twig', array('results' => $results) ); } + } \ No newline at end of file diff --git a/Resources/config/routing.yml b/Resources/config/routing.yml index 331f4ae21..e61546ea6 100644 --- a/Resources/config/routing.yml +++ b/Resources/config/routing.yml @@ -30,7 +30,7 @@ chill_main_admin_central: icons: [gears] chill_main_search: - pattern: /{_locale}/person/search + pattern: /{_locale}/search defaults: { _controller: ChillMainBundle:Search:search } login: diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml index 7a9c752ed..da328d76f 100644 --- a/Resources/translations/messages.fr.yml +++ b/Resources/translations/messages.fr.yml @@ -8,4 +8,10 @@ Invalid CSRF token.: Votre session a expirée ou est devenue invalide. Username: Nom d'utilisateur Password: Mot de passe Welcome to %installation_name%: Bienvenue à %installation_name% -Login to %installation_name%: Connexion à %installation_name% \ No newline at end of file +Login to %installation_name%: Connexion à %installation_name% + +#serach +Your search is empty. Please provide search terms.: La recherche est vide. Merci de fournir des termes de recherche. +The domain %domain% is unknow. Please check your search.: Le domaine de recherche "%domain%" est inconnu. Merci de vérifier votre recherche. +Invalid terms : Recherche invalide +You should not have more than one domain. : Vous ne devriez pas avoir plus d'un domaine de recherche. \ No newline at end of file diff --git a/Resources/views/Search/error.html.twig b/Resources/views/Search/error.html.twig new file mode 100644 index 000000000..690d40de9 --- /dev/null +++ b/Resources/views/Search/error.html.twig @@ -0,0 +1,23 @@ +{# + * Copyright (C) 2014, Champs Libres Cooperative SCRLFS, + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +#} +{% extends "ChillMainBundle::layout.html.twig" %} + +{% block content %} + +

{{ message }}

+ +{% endblock %} diff --git a/Search/SearchProvider.php b/Search/SearchProvider.php index 3a5c3c977..b6aa6178e 100644 --- a/Search/SearchProvider.php +++ b/Search/SearchProvider.php @@ -68,7 +68,7 @@ class SearchProvider preg_match_all('/@([a-z]+)/', $subject, $terms); if (count($terms[0]) > 1) { - throw new ParsingException('You should not have more than one domain'); + throw new ParsingException('You should not have more than one domain.'); } //add pattern to be extracted diff --git a/Search/UnknowSearchNameException.php b/Search/UnknowSearchNameException.php index d3e75a5dd..0bd0989d1 100644 --- a/Search/UnknowSearchNameException.php +++ b/Search/UnknowSearchNameException.php @@ -27,8 +27,17 @@ namespace Chill\MainBundle\Search; */ class UnknowSearchNameException extends \Exception { + + private $name; + public function __construct($name) { parent::__construct( "No module search supports with the name $name"); + $this->name = $name; + } + + public function getName() + { + return $this->name; } } diff --git a/Tests/Controller/SearchControllerTest.php b/Tests/Controller/SearchControllerTest.php new file mode 100644 index 000000000..62be5d0f5 --- /dev/null +++ b/Tests/Controller/SearchControllerTest.php @@ -0,0 +1,139 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +namespace Chill\MainBundle\Tests\Controller; + +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use Chill\MainBundle\Search\SearchInterface; + + + +/** + * Test the search controller + * + * @author Julien Fastré + */ +class SearchControllerTest extends WebTestCase +{ + /* + public function setUp() + { + static::bootKernel(); + + //add a default service + $this->addSearchService( + $this->createDefaultSearchService('

I am default

', 10), 'default' + ); + //add a domain service + $this->addSearchService( + $this->createDefaultSearchService('

I am domain bar

', 20), 'bar' + ); + } + + /** + * Test the behaviour when no domain is provided in the search pattern : + * the default search should be enabled + */ + public function testSearchPath() + { + $client = $this->getAuthenticatedClient(); + + $crawler = $client->request('GET', '/fr/search', array('q' => 'default search')); + + $this->assertTrue($client->getResponse()->isSuccessful(), + "The page is loaded without errors"); + + } + + public function testSearchPathEmpty() + { + $client = $this->getAuthenticatedClient(); + + $crawler = $client->request('GET', '/fr/search?q='); + + $this->assertGreaterThan(0, $crawler->filter('*:contains("Merci de fournir des termes de recherche.")')->count()); + } + + public function testDomainUnknow() + { + $client = $this->getAuthenticatedClient(); + + $crawler = $client->request('GET', '/fr/search', array('q' => '@unknow domain')); + + $this->assertTrue($client->getResponse()->isSuccessful(), + "The page is loaded without errors"); + $this->assertGreaterThan(0, $crawler->filter('*:contains("Le domaine de recherche "unknow" est inconnu.")')->count(), + "Message domain unknow is shown"); + + } + + public function testParsingIncorrect() + { + $client = $this->getAuthenticatedClient(); + + $crawler = $client->request('GET', '/fr/search', + array('q' => '@domaine @domain double domaine')); + + $this->assertGreaterThan(0, $crawler->filter('*:contains("Recherche invalide")') + ->count()); + } + + public function testUnknowName() + { + $client = $this->getAuthenticatedClient(); + + $client->request('GET', '/fr/search', + array('q' => 'default search', 'name' => 'unknow')); + + $this->assertTrue($client->getResponse()->isNotFound()); + } + + + public function testSearchWithinSpecificSearchName() + { + /* + //add a search service which will be supported + $this->addSearchService( + $this->createNonDefaultDomainSearchService("

I am domain foo

", 100, TRUE), 'foo' + ); + + $client = $this->getAuthenticatedClient(); + $crawler = $client->request('GET', '/fr/search', + array('q' => '@foo default search', 'name' => 'foo')); + + //$this->markTestSkipped(); + $this->assertEquals(0, $crawler->filter('p:contains("I am default")')->count(), + "The mocked default results are not shown"); + $this->assertEquals(0, $crawler->filter('p:contains("I am domain bar")')->count(), + "The mocked non-default results are not shown"); + $this->assertEquals(1, $crawler->filter('p:contains("I am domain foo")')->count(), + "The mocked nnon default results for foo are shown"); + */ + } + + private function getAuthenticatedClient() + { + return static::createClient(array(), array( + 'PHP_AUTH_USER' => 'center b_social', + 'PHP_AUTH_PW' => 'password', + )); + } + +} diff --git a/Tests/Fixtures/App/config/config_test.yml b/Tests/Fixtures/App/config/config_test.yml index 190ea71c5..652a26975 100644 --- a/Tests/Fixtures/App/config/config_test.yml +++ b/Tests/Fixtures/App/config/config_test.yml @@ -26,7 +26,7 @@ security: default: anonymous: ~ - + http_basic: ~ form_login: csrf_parameter: _csrf_token intention: authenticate