diff --git a/DataFixtures/ORM/LoadPeople.php b/DataFixtures/ORM/LoadPeople.php index c2d562501..5a143af54 100644 --- a/DataFixtures/ORM/LoadPeople.php +++ b/DataFixtures/ORM/LoadPeople.php @@ -25,6 +25,7 @@ use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Chill\PersonBundle\Entity\Person; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; /** * Load people into database @@ -32,8 +33,11 @@ use Chill\PersonBundle\Entity\Person; * @author Julien Fastré * @author Marc Ducobu */ -class LoadPeople extends AbstractFixture implements OrderedFixtureInterface +class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface { + + use \Symfony\Component\DependencyInjection\ContainerAwareTrait; + public function prepare() { //prepare days, month, years @@ -63,7 +67,24 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface public function load(ObjectManager $manager) { - echo "loading people...\n"; + $this->loadRandPeople($manager); + $this->loadExpectedPeople($manager); + + $manager->flush(); + } + + public function loadExpectedPeople(ObjectManager $manager) + { + echo "loading expected people...\n"; + + foreach ($this->peoples as $person) { + $this->addAPerson($this->fillWithDefault($person), $manager); + } + } + + public function loadRandPeople(ObjectManager $manager) + { + echo "loading rand people...\n"; $this->prepare(); @@ -96,38 +117,66 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface $person = array( 'FirstName' => $firstName, 'LastName' => $lastName, - 'DateOfBirth' => "1960-10-12", - 'PlaceOfBirth' => "Ottignies Louvain-La-Neuve", 'Genre' => $sex, - 'Email' => "Email d'un ami: roger@tt.com", - 'CountryOfBirth' => 'France', - 'Nationality' => 'Russie', - 'CFData' => array() + 'Nationality' => (rand(0,100) > 50) ? NULL: 'BE' ); - $p = new Person(); - - foreach ($person as $key => $value) { - switch ($key) { - case 'CountryOfBirth': - break; - case 'Nationality': - break; - case 'DateOfBirth': - $value = new \DateTime($value); - - - default: - call_user_func(array($p, 'set'.$key), $value); - } - } - - $manager->persist($p); - echo "add person'".$p->__toString()."'\n"; + $this->addAPerson($this->fillWithDefault($person), $manager); } while ($i <= 100); - - $manager->flush(); + } + + /** + * fill a person array with default value + * + * @param string[] $specific + */ + private function fillWithDefault(array $specific) + { + return array_merge(array( + 'DateOfBirth' => "1960-10-12", + 'PlaceOfBirth' => "Ottignies Louvain-La-Neuve", + 'Genre' => Person::GENRE_MAN, + 'Email' => "Email d'un ami: roger@tt.com", + 'CountryOfBirth' => 'BE', + 'Nationality' => 'BE', + 'CFData' => array() + ), $specific); + } + + private function addAPerson(array $person, ObjectManager $manager) + { + $p = new Person(); + + foreach ($person as $key => $value) { + switch ($key) { + case 'CountryOfBirth': + $p->setCountryOfBirth($this->getCountry($value)); + break; + case 'Nationality': + $p->setNationality($this->getCountry($value)); + break; + case 'DateOfBirth': + $value = new \DateTime($value); + + + default: + call_user_func(array($p, 'set'.$key), $value); + } + } + + $manager->persist($p); + echo "add person'".$p->__toString()."'\n"; + } + + private function getCountry($countryCode) + { + if ($countryCode === NULL) { + return NULL; + } + return $this->container->get('doctrine.orm.entity_manager') + ->getRepository('ChillMainBundle:Country') + ->findOneByCountryCode($countryCode); } private $firstNamesMale = array("Jean", "Mohamed", "Alfred", "Robert", @@ -155,14 +204,38 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface private $peoples = array( array( + 'FirstName' => "Depardieu", + 'LastName' => "Gérard", + 'DateOfBirth' => "1948-12-27", + 'PlaceOfBirth' => "Châteauroux", + 'Genre' => Person::GENRE_MAN, + 'CountryOfBirth' => 'FR', + 'Nationality' => 'RU' + ), + array( + //to have a person with same firstname as Gérard Depardieu 'FirstName' => "Depardieu", 'LastName' => "Jean", 'DateOfBirth' => "1960-10-12", - 'PlaceOfBirth' => "Ottignies Louvain-La-Neuve", - 'Genre' => Person::GENRE_MAN, - 'Email' => "Email d'un ami: roger@tt.com", - 'CountryOfBirth' => 'France', - 'Nationality' => 'Russie' - ) + 'CountryOfBirth' => 'FR', + 'Nationality' => 'FR' + ), + array( + //to have a person with same birthdate of Gérard Depardieu + 'FirstName' => 'Van Snick', + 'LastName' => 'Bart', + 'DateOfBirth' => '1948-12-27' + ), + array( + //to have a woman with Depardieu as FirstName + 'FirstName' => 'Depardieu', + 'LastName' => 'Charline', + 'Genre' => Person::GENRE_WOMAN + ), + array( + //to have a special character in lastName + 'FirstName' => 'Manço', + 'LastName' => 'Étienne' + ) ); } diff --git a/Resources/config/services.yml b/Resources/config/services.yml index d52e89cc2..22e13c32f 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -22,4 +22,4 @@ services: calls: - ['setContainer', ["@service_container"]] tags: - - { name: chill.search, alias: 'person_search' } + - { name: chill.search, alias: 'person_regular' } diff --git a/Search/PersonSearch.php b/Search/PersonSearch.php index f15f9e322..98e7c19a4 100644 --- a/Search/PersonSearch.php +++ b/Search/PersonSearch.php @@ -192,8 +192,8 @@ class PersonSearch extends AbstractSearch foreach($grams as $key => $gram) { $qb->andWhere($qb->expr() - ->like('LOWER(CONCAT(p.firstName, \' \', p.lastName))', ':default')) - ->setParameter('default', '%'.$gram.'%'); + ->like('LOWER(CONCAT(p.firstName, \' \', p.lastName))', ':default_'.$key)) + ->setParameter('default_'.$key, '%'.$gram.'%'); } } diff --git a/Tests/Search/PersonSearchTest.php b/Tests/Search/PersonSearchTest.php new file mode 100644 index 000000000..07cb1e825 --- /dev/null +++ b/Tests/Search/PersonSearchTest.php @@ -0,0 +1,202 @@ + + * + * 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\PersonBundle\Tests\Search; + +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; + + +/** + * Test Person search + * + * @author Julien Fastré + */ +class PersonSearchTest extends WebTestCase +{ + public function testExpected() + { + $client = $this->getAuthenticatedClient(); + + $crawler = $client->request('GET', '/fr/search', array( + 'q' => '@person Depardieu' + )); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testExpectedNamed() + { + $client = $this->getAuthenticatedClient(); + + $crawler = $client->request('GET', '/fr/search', array( + 'q' => '@person Depardieu', 'name' => 'person_regular' + )); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testSearchByFirstName() + { + $crawler = $this->generateCrawlerForSearch('@person firstname:Depardieu'); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testSearchByFirstNameLower() + { + $crawler = $this->generateCrawlerForSearch('@person firstname:depardieu'); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testSearchByFirstNamePartim() + { + $crawler = $this->generateCrawlerForSearch('@person firstname:Dep'); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testFirstNameAccentued() + { + $this->markTestSkipped(); + $crawlerSpecial = $this->generateCrawlerForSearch('@person firstname:manço'); + + $this->assertRegExp('/Manço/', $crawlerSpecial->text()); + + + $crawlerNoSpecial = $this->generateCrawlerForSearch('@person firstname:manco'); + + $this->assertRegExp('/Manço/', $crawlerNoSpecial->text()); + } + + public function testSearchByLastName() + { + $crawler = $this->generateCrawlerForSearch('@person lastname:Jean'); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testSearchByLastNameLower() + { + $crawler = $this->generateCrawlerForSearch('@person lastname:jean'); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testSearchByLastNamePartim() + { + $crawler = $this->generateCrawlerForSearch('@person lastname:ean'); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + } + + public function testSearchByLastNameAccented() + { + $this->markTestSkipped(); + $crawlerSpecial = $this->generateCrawlerForSearch('@person lastname:Gérard'); + + $this->assertRegExp('/Gérard/', $crawlerSpecial->text()); + + + $crawlerNoSpecial = $this->generateCrawlerForSearch('@person lastname:Gerard'); + + $this->assertRegExp('/Gérard/', $crawlerNoSpecial->text()); + } + + public function testSearchCombineFirstnameAndNationality() + { + $crawler = $this->generateCrawlerForSearch('@person firstname:Depardieu nationality:RU'); + + $this->assertRegExp('/Gérard/', $crawler->text()); + //if this is a AND clause, Jean Depardieu should not appears + $this->assertNotRegExp('/Jean/', $crawler->text(), + "assert clause firstname and nationality are AND"); + } + + public function testSearchCombineLastnameAndFirstName() + { + $crawler = $this->generateCrawlerForSearch('@person firstname:Depardieu lastname:Jean'); + + $this->assertRegExp('/Depardieu/', $crawler->text()); + //if this is a AND clause, Jean Depardieu should not appears + $this->assertNotRegExp('/Gérard/', $crawler->text(), + "assert clause firstname and nationality are AND"); + } + + public function testSearchDateOfBirth() + { + $crawler = $this->generateCrawlerForSearch('@person birthdate:1948-12-27'); + + $this->assertRegExp('/Gérard/', $crawler->text()); + $this->assertRegExp('/Bart/', $crawler->text()); + } + + public function testSearchCombineDateOfBirthAndFirstName() + { + $crawler = $this->generateCrawlerForSearch('@person birthdate:1948-12-27 firstname:(Van Snick)'); + + $this->assertRegExp('/Bart/', $crawler->text()); + $this->assertNotRegExp('/Depardieu/', $crawler->text()); + } + + public function testSearchCombineGenreAndFirstName() + { + $crawler = $this->generateCrawlerForSearch('@person gender:woman firstname:(Depardieu)'); + + $this->assertRegExp('/Charline/', $crawler->text()); + $this->assertNotRegExp('/Gérard/', $crawler->text()); + } + + public function testSearchMultipleTrigramUseAndClauseInDefault() + { + $crawler = $this->generateCrawlerForSearch('@person cha dep'); + + $this->assertRegExp('/Charline/', $crawler->text()); + $this->assertNotRegExp('/Gérard/', $crawler->text()); + $this->assertNotRegExp('/Jean/', $crawler->text()); + } + + + + private function generateCrawlerForSearch($pattern) + { + $client = $this->getAuthenticatedClient(); + + $crawler = $client->request('GET', '/fr/search', array( + 'q' => $pattern + )); + + $this->assertTrue($client->getResponse()->isSuccessful()); + + return $crawler; + } + + /** + * + * @return \Symfony\Component\BrowserKit\Client + */ + private function getAuthenticatedClient() + { + return static::createClient(array(), array( + 'PHP_AUTH_USER' => 'center a_social', + 'PHP_AUTH_PW' => 'password', + )); + } +}