fix folder name

This commit is contained in:
2021-03-18 13:37:13 +01:00
parent a2f6773f5a
commit eaa0ad925f
1578 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class CenterControllerTest extends WebTestCase
{
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'admin',
'PHP_AUTH_PW' => 'password',
'HTTP_ACCEPT_LANGUAGE' => 'fr_FR'
));
// Create a new entry in the database
$crawler = $client->request('GET', '/fr/admin/center/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(),
"Unexpected HTTP status code for GET /fr/admin/center/");
$crawler = $client->click($crawler->selectLink('Créer un nouveau centre')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Créer')->form(array(
'chill_mainbundle_center[name]' => 'Test center',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0,
$crawler->filter('td:contains("Test center")')->count(),
'Missing element td:contains("Test center")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Modifier')->link());
$form = $crawler->selectButton('Mettre à jour')->form(array(
'chill_mainbundle_center[name]' => 'Foo',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(),
'Missing element [value="Foo"]');
$crawler = $client->request('GET', '/fr/admin/center/');
// Check the entity has been delete on the list
$this->assertRegExp('/Foo/', $client->getResponse()->getContent());
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class DefaultControllerTest extends WebTestCase
{
public function testIndex()
{
}
}

View File

@@ -0,0 +1,45 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* Test the export
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ExportControllerTest extends WebTestCase
{
public function testIndex()
{
$client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'center a_social',
'PHP_AUTH_PW' => 'password',
'HTTP_ACCEPT_LANGUAGE' => 'fr_FR'
));
$client->request('GET', '/fr/exports/');
$this->assertTrue($client->getResponse()->isSuccessful(),
"assert the list is shown");
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
class LoginControllerTest extends WebTestCase
{
public function testLogin()
{
$client = static::createClient(array(
'framework' => array(
'default_locale' => 'en',
'translator' => array(
'fallback' => 'en'
)
),
));
//load login page and submit form
$crawler = $client->request('GET', '/login');
$this->assertTrue($client->getResponse()->isSuccessful());
$buttonCrawlerNode = $crawler->selectButton('login');
$form = $buttonCrawlerNode->form();
$client->submit($form, array(
'_username' => 'center a_social',
'_password' => 'password'
));
//the response is a redirection
$this->assertTrue($client->getResponse()->isRedirect());
//the response is not a login page, but on a new page
$this->assertNotRegExp('/\/login$/', $client->getResponse()
->headers
->get('location'));
//on the home page, there must be a logout link
$client->followRedirects(true);
$crawler = $client->request('GET', '/');
$this->assertRegExp('/center a_social/', $client->getResponse()
->getContent());
$logoutLinkFilter = $crawler->filter('a:contains("Logout")');
//check there is > 0 logout link
$this->assertGreaterThan(0, $logoutLinkFilter->count(), 'check that a logout link is present');
//click on logout link
$client->followRedirects(false);
$client->click($crawler->selectLink('Logout')->link());
$this->assertTrue($client->getResponse()->isRedirect());
$client->followRedirect(); #redirect to login page
//check we are back on login page
$this->assertRegExp('/\/login$/', $client->getResponse()
->headers
->get('location'));
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PermissionsGroupControllerTest extends WebTestCase
{
public function testEmpty()
{
$this->markTestSkipped();
}
/*
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient();
// Create a new entry in the database
$crawler = $client->request('GET', '/admin/permissionsgroup/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /admin/permissionsgroup/");
$crawler = $client->click($crawler->selectLink('Create a new entry')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
'chill_mainbundle_permissionsgroup[field_name]' => 'Test',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(), 'Missing element td:contains("Test")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
'chill_mainbundle_permissionsgroup[field_name]' => 'Foo',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
// Delete the entity
$client->submit($crawler->selectButton('Delete')->form());
$crawler = $client->followRedirect();
// Check the entity has been delete on the list
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
}
*/
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class ScopeControllerTest extends WebTestCase
{
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'admin',
'PHP_AUTH_PW' => 'password',
'HTTP_ACCEPT_LANGUAGE' => 'fr_FR'
));
// Create a new entry in the database
$crawler = $client->request('GET', '/fr/admin/scope/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(),
"Unexpected HTTP status code for GET /fr/admin/scope/");
$crawler = $client->click($crawler->selectLink('Créer un nouveau cercle')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Créer')->form(array(
'chill_mainbundle_scope[name][fr]' => 'Test en fr',
'chill_mainbundle_scope[name][en]' => 'Test en en'
));
$client->submit($form/*, array(
'chill_mainbundle_scope' => array(
'name' => array(
'fr' => 'test en fr',
'en' => 'test in english',
'nl' => 'test in nl'
)
)
)*/);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test en fr")')->count(),
'Missing element td:contains("Test en fr")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Modifier')->link());
$form = $crawler->selectButton('Mettre à jour')->form(array(
'chill_mainbundle_scope[name][fr]' => 'Foo',
'chill_mainbundle_scope[name][en]' => 'Foo en',
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
}
}

View File

@@ -0,0 +1,139 @@
<?php
/*
* Chill is a software for social workers
* Copyright (C) 2015 Champs-Libres Coopérative <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Chill\MainBundle\Search\SearchInterface;
/**
* Test the search controller
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class SearchControllerTest extends WebTestCase
{
/*
public function setUp()
{
static::bootKernel();
//add a default service
$this->addSearchService(
$this->createDefaultSearchService('<p>I am default</p>', 10), 'default'
);
//add a domain service
$this->addSearchService(
$this->createDefaultSearchService('<p>I am domain bar</p>', 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("<p>I am domain foo</p>", 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',
));
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace Chill\MainBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class UserControllerTest extends WebTestCase
{
private $client;
public function setUp()
{
self::bootKernel();
$this->client = static::createClient(array(), array(
'PHP_AUTH_USER' => 'admin',
'PHP_AUTH_PW' => 'password',
'HTTP_ACCEPT_LANGUAGE' => 'fr_FR'
));
}
public function testList()
{
// get the list
$crawler = $this->client->request('GET', '/fr/admin/user/');
$this->assertEquals(200, $this->client->getResponse()->getStatusCode(),
"Unexpected HTTP status code for GET /admin/user/");
$link = $crawler->selectLink('Ajouter un nouvel utilisateur')->link();
$this->assertInstanceOf('Symfony\Component\DomCrawler\Link', $link);
$this->assertRegExp('|/fr/admin/user/new$|', $link->getUri());
}
public function testNew()
{
$crawler = $this->client->request('GET', '/fr/admin/user/new');
$username = 'Test_user'. uniqid();
$password = 'Password1234!';
// Fill in the form and submit it
$form = $crawler->selectButton('Créer')->form(array(
'chill_mainbundle_user[username]' => $username,
'chill_mainbundle_user[plainPassword][password][first]' => $password,
'chill_mainbundle_user[plainPassword][password][second]' => $password
));
$this->client->submit($form);
$crawler = $this->client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test_user")')->count(),
'Missing element td:contains("Test user")');
$update = $crawler->selectLink('Modifier')->link();
$this->assertInstanceOf('Symfony\Component\DomCrawler\Link', $update);
$this->assertRegExp('|/fr/admin/user/[0-9]{1,}/edit$|', $update->getUri());
//test the auth of the new client
$this->isPasswordValid($username, $password);
return $update;
}
protected function isPasswordValid($username, $password)
{
/* @var $passwordEncoder \Symfony\Component\Security\Core\Encoder\UserPasswordEncoder */
$passwordEncoder = self::$kernel->getContainer()
->get('security.password_encoder');
$user = self::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:User')
->findOneBy(array('username' => $username));
$this->assertTrue($passwordEncoder->isPasswordValid($user, $password));
}
/**
*
* @param \Symfony\Component\DomCrawler\Link $update
* @depends testNew
*/
public function testUpdate(\Symfony\Component\DomCrawler\Link $update)
{
$crawler = $this->client->click($update);
$username = 'Foo bar '.uniqid();
$form = $crawler->selectButton('Mettre à jour')->form(array(
'chill_mainbundle_user[username]' => $username,
));
$this->client->submit($form);
$crawler = $this->client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="'.$username.'"]')->count(),
'Missing element [value="Foo bar"]');
$updatePassword = $crawler->selectLink('Modifier le mot de passe')->link();
$this->assertInstanceOf('Symfony\Component\DomCrawler\Link', $updatePassword);
$this->assertRegExp('|/fr/admin/user/[0-9]{1,}/edit_password$|',
$updatePassword->getUri());
return array('link' => $updatePassword, 'username' => $username);
}
/**
*
* @param \Symfony\Component\DomCrawler\Link $updatePassword
* @depends testUpdate
*/
public function testUpdatePassword(array $params)
{
$link = $params['link'];
$username = $params['username'];
$newPassword = '1234Password!';
$crawler = $this->client->click($link);
$form = $crawler->selectButton('Changer le mot de passe')->form(array(
'chill_mainbundle_user_password[password][first]' => $newPassword,
'chill_mainbundle_user_password[password][second]' => $newPassword,
));
$this->client->submit($form);
$this->assertTrue($this->client->getResponse()->isRedirect(),
"the response is a redirection");
$this->client->followRedirect();
$this->isPasswordValid($username, $newPassword);
}
}

View File

@@ -0,0 +1,179 @@
<?php
/*
* Chill is a software for social workers
* Copyright (C) 2015 Champs-Libres Coopérative <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\DependencyInjection;
use Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilderInterface;
/**
* Description of ConfigConsistencyCompilerPassTest
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ConfigConsistencyCompilerPassTest extends \PHPUnit\Framework\TestCase
{
/**
*
*
* @var \Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass
*/
private $configConsistencyCompilerPass;
public function setUp()
{
$this->configConsistencyCompilerPass = new ConfigConsistencyCompilerPass();
}
/**
* Test that everything is fine is configuration is correct
*
*/
public function testLanguagesArePresent()
{
try {
$this ->configConsistencyCompilerPass
->process(
$this->mockContainer(
$this->mockTranslatorDefinition(array('fr')),
array('fr', 'nl')
)
);
$this->assertTrue(TRUE, 'the config consistency can process');
} catch (\Exception $ex) {
$this->assertTrue(FALSE,
'the config consistency can process');
}
}
/**
* Test that everything is fine is configuration is correct
* if multiple fallback languages are present
*
*/
public function testMultiplesLanguagesArePresent()
{
try {
$this ->configConsistencyCompilerPass
->process(
$this->mockContainer(
$this->mockTranslatorDefinition(array('fr', 'nl')),
array('fr', 'nl', 'en')
)
);
$this->assertTrue(TRUE, 'the config consistency can process');
} catch (\Exception $ex) {
$this->assertTrue(FALSE,
'the config consistency can process');
}
}
/**
* Test that a runtime exception is throw if the available language does
* not contains the fallback locale
*
* @expectedException \RuntimeException
* @expectedExceptionMessageRegExp /The chill_main.available_languages parameter does not contains fallback locales./
*/
public function testLanguageNotPresent()
{
$container = $this->mockContainer(
$this->mockTranslatorDefinition(array('en')), array('fr')
);
$this->configConsistencyCompilerPass->process($container);
}
/**
* Test that a logic exception is thrown if the setFallbackLocale
* method is not defined in translator definition
*
* @expectedException \LogicException
*/
public function testSetFallbackNotDefined()
{
$container = $this->mockContainer(
$this->mockTranslatorDefinition(NULL), array('fr')
);
$this->configConsistencyCompilerPass->process($container);
}
/**
* @return ContainerBuilder
*/
private function mockContainer($definition, $availableLanguages)
{
$container = $this
->getMockBuilder('Symfony\Component\DependencyInjection\ContainerBuilder')
->getMock();
$container->method('getParameter')
->will($this->returnCallback(
function($parameter) use ($availableLanguages) {
if ($parameter === 'chill_main.available_languages') {
return $availableLanguages;
} else {
throw new \LogicException("the parameter '$parameter' "
. "is not defined in stub test");
}
}
));
$container->method('findDefinition')
->will($this->returnCallback(
function($id) use ($definition) {
if (in_array($id, array('translator', 'translator.default'))) {
return $definition;
} else {
throw new \LogicException("the id $id is not defined in test");
}
}));
return $container;
}
/**
*
* @param type $languages
* @return 'Symfony\Component\DependencyInjection\Definition'
*/
private function mockTranslatorDefinition(array $languages = NULL)
{
$definition = $this
->getMockBuilder('Symfony\Component\DependencyInjection\Definition')
->getMock();
if (NULL !== $languages) {
$definition->method('getMethodCalls')
->willReturn(array(
['setFallbackLocales', array($languages)]
));
} else {
$definition->method('getMethodCalls')
->willReturn(array(['nothing', array()]));
}
return $definition;
}
}

View File

@@ -0,0 +1,678 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Export;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\MainBundle\Export\ExportManager;
use Symfony\Component\Security\Core\Role\Role;
use Chill\MainBundle\Export\AggregatorInterface;
use Chill\MainBundle\Export\FilterInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Chill\MainBundle\Export\ExportInterface;
use Prophecy\Argument;
use Doctrine\ORM\QueryBuilder;
use Chill\MainBundle\Form\Type\Export\ExportType;
use Symfony\Component\HttpFoundation\Response;
use Chill\MainBundle\Form\Type\Export\PickCenterType;
/**
* Test the export manager
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ExportManagerTest extends KernelTestCase
{
use \Chill\MainBundle\Test\PrepareCenterTrait;
use \Chill\MainBundle\Test\PrepareUserTrait;
use \Chill\MainBundle\Test\PrepareScopeTrait;
/**
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
private $container;
/**
*
* @var Prophecy\Prophet
*/
private $prophet;
public function setUp()
{
self::bootKernel();
$this->container = self::$kernel->getContainer();
$this->prophet = new \Prophecy\Prophet;
}
public function tearDown()
{
$this->prophet->checkPredictions();
}
/**
* Create an ExportManager where every element may be replaced by a double.
*
* If null is provided for an element, this is replaced by the equivalent
* from the container; if the user provided is null, this is replaced by the
* user 'center a_social' from database.
*
* @param \Psr\Log\LoggerInterface $logger
* @param \Doctrine\ORM\EntityManagerInterface $em
* @param \Symfony\Component\Security\Core\Authorization\AuthorizationChecker $authorizationChecker
* @param \Chill\MainBundle\Security\Authorization\AuthorizationHelper $authorizationHelper
* @param \Symfony\Component\Security\Core\User\UserInterface $user
* @return ExportManager
*/
protected function createExportManager(
\Psr\Log\LoggerInterface $logger = null,
\Doctrine\ORM\EntityManagerInterface $em = null,
\Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface $authorizationChecker = null,
\Chill\MainBundle\Security\Authorization\AuthorizationHelper $authorizationHelper = null,
\Symfony\Component\Security\Core\User\UserInterface $user = null
)
{
$localUser = $user === NULL ? $this->container->get('doctrine.orm.entity_manager')
->getRepository('ChillMainBundle:User')
->findOneBy(array('username' => 'center a_social')) :
$user;
$token = new \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken($localUser, 'password', 'provider');
$tokenStorage = new \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage();
$tokenStorage->setToken($token);
return new ExportManager(
$logger === NULL ? $this->container->get('logger') : $logger,
$em === NULL ? $this->container->get('doctrine.orm.entity_manager') : $em,
$authorizationChecker === NULL ? $this->container->get('security.authorization_checker') : $authorizationChecker,
$authorizationHelper === NULL ? $this->container->get('chill.main.security.authorization.helper') : $authorizationHelper,
$tokenStorage)
;
}
public function testGetExportsWithoutGranting()
{
$exportManager = $this->createExportManager();
//create an export and add it to ExportManager
$export = $this->prophet->prophesize();
$export->willImplement(ExportInterface::class);
$exportManager->addExport($export->reveal(), 'dummy');
$exports = iterator_to_array($exportManager->getExports(false));
$this->assertGreaterThan(0, count($exports));
$this->assertContains($export->reveal(), $exports);
$this->assertContains('dummy', array_keys($exports));
}
public function testGetExistingExportsTypes()
{
$exportManager = $this->createExportManager();
//create an export and add it to ExportManager
$export = $this->prophet->prophesize();
$export->willImplement(ExportInterface::class);
$export->getType()->willReturn('my_type');
$exportManager->addExport($export->reveal(), 'dummy');
$this->assertContains('my_type', $exportManager->getExistingExportsTypes());
}
public function testGetExport()
{
$exportManager = $this->createExportManager();
//create an export and add it to ExportManager
$export = $this->prophet->prophesize();
$export->willImplement(ExportInterface::class);
$exportManager->addExport($export->reveal(), 'dummy');
$obtained = $exportManager->getExport('dummy');
$this->assertInstanceof(ExportInterface::class, $obtained);
}
/**
* @expectedException \RuntimeException
*/
public function testGetExportNonExistant()
{
$exportManager = $this->createExportManager();
$exportManager->getExport('non existing');
}
public function testGetFilter()
{
$exportManager = $this->createExportManager();
//create a filter and add it to ExportManager
$filter = $this->prophet->prophesize();
$filter->willImplement('Chill\MainBundle\Export\FilterInterface');
$exportManager->addFilter($filter->reveal(), 'dummy');
$obtained = $exportManager->getFilter('dummy');
$this->assertInstanceof('Chill\MainBundle\Export\FilterInterface', $obtained);
}
/**
* @expectedException \RuntimeException
*/
public function testGetFilterNonExistant()
{
$exportManager = $this->createExportManager();
$exportManager->getFilter('non existing');
}
public function testGetFilters()
{
$exportManager = $this->createExportManager();
//create three filters and add them to ExportManager
$filterFoo = $this->prophet->prophesize();
$filterFoo->willImplement('Chill\MainBundle\Export\FilterInterface');
$filterBar = $this->prophet->prophesize();
$filterBar->willImplement('Chill\MainBundle\Export\FilterInterface');
$filterFooBar = $this->prophet->prophesize();
$filterFooBar->willImplement('Chill\MainBundle\Export\FilterInterface');
$exportManager->addFilter($filterFoo->reveal(), 'foo');
$exportManager->addFilter($filterBar->reveal(), 'bar');
$exportManager->addFilter($filterFooBar->reveal(), 'foobar');
$obtained = iterator_to_array($exportManager->getFilters(array('foo', 'bar')));
$this->assertContains($filterBar->reveal(), $obtained);
$this->assertContains($filterFoo->reveal(), $obtained);
$this->assertNotContains($filterFooBar->reveal(), $obtained);
}
public function testGetAggregator()
{
$exportManager = $this->createExportManager();
//create a filter and add it to ExportManager
$agg = $this->prophet->prophesize();
$agg->willImplement('Chill\MainBundle\Export\AggregatorInterface');
$exportManager->addAggregator($agg->reveal(), 'dummy');
$obtained = $exportManager->getAggregator('dummy');
$this->assertInstanceof('Chill\MainBundle\Export\AggregatorInterface', $obtained);
}
/**
* @expectedException \RuntimeException
*/
public function testGetAggregatorNonExistant()
{
$exportManager = $this->createExportManager();
$exportManager->getAggregator('non existing');
}
public function testGetAggregators()
{
$exportManager = $this->createExportManager();
//create three filters and add them to ExportManager
$aggFoo = $this->prophet->prophesize();
$aggFoo->willImplement('Chill\MainBundle\Export\AggregatorInterface');
$aggBar = $this->prophet->prophesize();
$aggBar->willImplement('Chill\MainBundle\Export\AggregatorInterface');
$aggFooBar = $this->prophet->prophesize();
$aggFooBar->willImplement('Chill\MainBundle\Export\AggregatorInterface');
$exportManager->addAggregator($aggFoo->reveal(), 'foo');
$exportManager->addAggregator($aggBar->reveal(), 'bar');
$exportManager->addAggregator($aggFooBar->reveal(), 'foobar');
$obtained = iterator_to_array($exportManager->getAggregators(array('foo', 'bar')));
$this->assertContains($aggBar->reveal(), $obtained);
$this->assertContains($aggFoo->reveal(), $obtained);
$this->assertNotContains($aggFooBar->reveal(), $obtained);
}
public function testGetFormatter()
{
$exportManager = $this->createExportManager();
//create a formatter
$formatter = $this->prophet->prophesize();
$formatter->willImplement('Chill\MainBundle\Export\FormatterInterface');
$exportManager->addFormatter($formatter->reveal(), 'dummy');
$obtained = $exportManager->getFormatter('dummy');
$this->assertInstanceOf('Chill\MainBundle\Export\FormatterInterface', $obtained);
}
/**
* @expectedException \RuntimeException
*/
public function testNonExistingFormatter()
{
$exportManager = $this->createExportManager();
$exportManager->getFormatter('non existing');
}
public function testFormattersByTypes()
{
$exportManager = $this->createExportManager();
//create a formatter
$formatterFoo = $this->prophet->prophesize();
$formatterFoo->willImplement('Chill\MainBundle\Export\FormatterInterface');
$formatterFoo->getType()->willReturn('foo');
$formatterBar = $this->prophet->prophesize();
$formatterBar->willImplement('Chill\MainBundle\Export\FormatterInterface');
$formatterBar->getType()->willReturn('bar');
$exportManager->addFormatter($formatterFoo->reveal(), 'foo');
$exportManager->addFormatter($formatterBar->reveal(), 'bar');
$obtained = $exportManager->getFormattersByTypes(array('foo'));
$this->assertContains($formatterFoo->reveal(), $obtained);
$this->assertNotContains($formatterBar->reveal(), $obtained);
}
public function testIsGrantedForElementWithExportAndUserIsGranted()
{
$center = $this->prepareCenter(100, 'center A');
$user = $this->prepareUser(array());
$authorizationChecker = $this->prophet->prophesize();
$authorizationChecker->willImplement('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface');
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $center)
->willReturn(True);
$exportManager = $this->createExportManager(null, null,
$authorizationChecker->reveal(), null, $user);
$export = $this->prophet->prophesize();
$export->willImplement(ExportInterface::class);
$export->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$result = $exportManager->isGrantedForElement($export->reveal(), null, array($center));
$this->assertTrue($result);
}
public function testIsGrantedForElementWithExportAndUserIsGrantedNotForAllCenters()
{
$center = $this->prepareCenter(100, 'center A');
$centerB = $this->prepareCenter(102, 'center B');
$user = $this->prepareUser(array());
$authorizationChecker = $this->prophet->prophesize();
$authorizationChecker->willImplement('Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface');
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $center)
->willReturn(true);
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $centerB)
->willReturn(false);
$exportManager = $this->createExportManager(null, null,
$authorizationChecker->reveal(), null, $user);
$export = $this->prophet->prophesize();
$export->willImplement(ExportInterface::class);
$export->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$result = $exportManager->isGrantedForElement($export->reveal(), null, array($center, $centerB));
$this->assertFalse($result);
}
public function testIsGrantedForElementWithExportEmptyCenters()
{
$user = $this->prepareUser(array());
$exportManager = $this->createExportManager(null, null,
null, null, $user);
$export = $this->prophet->prophesize();
$export->willImplement(\Chill\MainBundle\Export\ExportInterface::class);
$export->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$result = $exportManager->isGrantedForElement($export->reveal(), null, array());
$this->assertFalse($result);
}
public function testIsGrantedForElementWithModifierFallbackToExport()
{
$center = $this->prepareCenter(100, 'center A');
$centerB = $this->prepareCenter(102, 'center B');
$user = $this->prepareUser(array());
$authorizationChecker = $this->prophet->prophesize();
$authorizationChecker->willImplement(AuthorizationCheckerInterface::class);
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $center)
->willReturn(true);
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $centerB)
->willReturn(false);
$exportManager = $this->createExportManager(null, null,
$authorizationChecker->reveal(), null, $user);
$modifier = $this->prophet->prophesize();
$modifier->willImplement(\Chill\MainBundle\Export\ModifierInterface::class);
$modifier->addRole()->willReturn(NULL);
$export = $this->prophet->prophesize();
$export->willImplement(ExportInterface::class);
$export->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$result = $exportManager->isGrantedForElement($modifier->reveal(),
$export->reveal(), array($center, $centerB));
$this->assertFalse($result);
}
public function testAggregatorsApplyingOn()
{
$center = $this->prepareCenter(100, 'center');
$centers = array($center);
$user = $this->prepareUser(array());
$authorizationChecker = $this->prophet->prophesize();
$authorizationChecker->willImplement(AuthorizationCheckerInterface::class);
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $center)
->willReturn(true);
$exportManager = $this->createExportManager(null, null,
$authorizationChecker->reveal(), null, $user);
$exportFooBar = $this->prophet->prophesize();
$exportFooBar->willImplement(ExportInterface::class);
$exportFooBar->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$exportFooBar->supportsModifiers()->willReturn(array('foo', 'bar'));
$aggregatorBar = $this->prophet->prophesize();
$aggregatorBar->willImplement(AggregatorInterface::class);
$aggregatorBar->applyOn()->willReturn('bar');
$aggregatorBar->addRole()->willReturn(null);
$exportManager->addAggregator($aggregatorBar->reveal(), 'bar');
$exportBar = $this->prophet->prophesize();
$exportBar->willImplement(ExportInterface::class);
$exportBar->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$exportBar->supportsModifiers()->willReturn(array('bar'));
$aggregatorFoo = $this->prophet->prophesize();
$aggregatorFoo->willImplement(AggregatorInterface::class);
$aggregatorFoo->applyOn()->willReturn('foo');
$aggregatorFoo->addRole()->willReturn(null);
$exportManager->addAggregator($aggregatorFoo->reveal(), 'foo');
$exportFoo = $this->prophet->prophesize();
$exportFoo->willImplement(ExportInterface::class);
$exportFoo->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$exportFoo->supportsModifiers()->willReturn(array('foo'));
$obtained = iterator_to_array($exportManager->getAggregatorsApplyingOn($exportFoo->reveal(), $centers));
$this->assertEquals(1, count($obtained));
$this->assertContains('foo', array_keys($obtained));
$obtained = iterator_to_array($exportManager->getAggregatorsApplyingOn($exportBar->reveal(), $centers));
$this->assertEquals(1, count($obtained));
$this->assertContains('bar', array_keys($obtained));
$obtained = iterator_to_array($exportManager->getAggregatorsApplyingOn($exportFooBar->reveal(), $centers));
$this->assertEquals(2, count($obtained));
$this->assertContains('bar', array_keys($obtained));
$this->assertContains('foo', array_keys($obtained));
// test with empty centers
$obtained = iterator_to_array($exportManager->getAggregatorsApplyingOn($exportFooBar->reveal(), array()));
$this->assertEquals(0, count($obtained));
}
public function testFiltersApplyingOn()
{
$center = $this->prepareCenter(100, 'center');
$centers = array($center);
$user = $this->prepareUser(array());
$authorizationChecker = $this->prophet->prophesize();
$authorizationChecker->willImplement(AuthorizationCheckerInterface::class);
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $center)
->willReturn(true);
$exportManager = $this->createExportManager(null, null,
$authorizationChecker->reveal(), null, $user);
$exportFooBar = $this->prophet->prophesize();
$exportFooBar->willImplement(ExportInterface::class);
$exportFooBar->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$exportFooBar->supportsModifiers()->willReturn(array('foo', 'bar'));
$filterBar = $this->prophet->prophesize();
$filterBar->willImplement(FilterInterface::class);
$filterBar->applyOn()->willReturn('bar');
$filterBar->addRole()->willReturn(null);
$filterBar->describeAction(Argument::cetera())->willReturn('string');
$exportManager->addFilter($filterBar->reveal(), 'bar');
$exportBar = $this->prophet->prophesize();
$exportBar->willImplement(ExportInterface::class);
$exportBar->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$exportBar->supportsModifiers()->willReturn(array('bar'));
$filterFoo = $this->prophet->prophesize();
$filterFoo->willImplement(FilterInterface::class);
$filterFoo->applyOn()->willReturn('foo');
$filterFoo->addRole()->willReturn(null);
$filterFoo->describeAction(Argument::cetera())->willReturn('string');
$exportManager->addFilter($filterFoo->reveal(), 'foo');
$exportFoo = $this->prophet->prophesize();
$exportFoo->willImplement(ExportInterface::class);
$exportFoo->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$exportFoo->supportsModifiers()->willReturn(array('foo'));
$obtained = iterator_to_array($exportManager->getFiltersApplyingOn($exportFoo->reveal(), $centers));
$this->assertEquals(1, count($obtained));
$this->assertContains('foo', array_keys($obtained));
$obtained = iterator_to_array($exportManager->getFiltersApplyingOn($exportBar->reveal(), $centers));
$this->assertEquals(1, count($obtained));
$this->assertContains('bar', array_keys($obtained));
$obtained = iterator_to_array($exportManager->getFiltersApplyingOn($exportFooBar->reveal(), $centers));
$this->assertEquals(2, count($obtained));
$this->assertContains('bar', array_keys($obtained));
$this->assertContains('foo', array_keys($obtained));
$obtained = iterator_to_array($exportManager->getFiltersApplyingOn($exportFooBar->reveal(), array()));
$this->assertEquals(0, count($obtained));
}
/**
* Test the generation of an export
*/
public function testGenerate()
{
$center = $this->prepareCenter(100, 'center');
$user = $this->prepareUser(array());
$authorizationChecker = $this->prophet->prophesize();
$authorizationChecker->willImplement(AuthorizationCheckerInterface::class);
$authorizationChecker->isGranted('CHILL_STAT_DUMMY', $center)
->willReturn(true);
$exportManager = $this->createExportManager(null, null,
$authorizationChecker->reveal(), null, $user);
$export = $this->prophet->prophesize();
$export->willImplement(ExportInterface::class);
$em = $this->container->get('doctrine.orm.entity_manager');
$export->initiateQuery(
Argument::is(array('foo')),
Argument::Type('array'),
Argument::is(array('a' => 'b'))
)
->will(function () use ($em) {
$qb = $em->createQueryBuilder();
return $qb->addSelect('COUNT(user.id) as export')
->from('ChillMainBundle:User', 'user');
});
//$export->initiateQuery()->shouldBeCalled();
$export->supportsModifiers()->willReturn(array('foo'));
$export->requiredRole()->willReturn(new Role('CHILL_STAT_DUMMY'));
$export->getResult(Argument::Type(QueryBuilder::class), Argument::Type('array'))->willReturn(array(
array(
'aggregator' => 'cat a',
'export' => 0,
),
array(
'aggregator' => 'cat b',
'export' => 1
)
));
$export->getLabels(
Argument::is('export'),
Argument::is(array(0, 1)),
Argument::Type('array')
)
->willReturn(function($value) {
switch($value) {
case 0:
case 1:
return $value;
case '_header':
return 'export';
default: throw new \RuntimeException(sprintf("The value %s is not valid", $value));
}
});
$export->getQueryKeys(Argument::Type('array'))->willReturn(array('export'));
$export->getTitle()->willReturn('dummy title');
$exportManager->addExport($export->reveal(), 'dummy');
$filter = $this->prophet->prophesize();
$filter->willImplement(FilterInterface::class);
//$filter->alterQuery()->shouldBeCalled();
$filter->alterQuery(Argument::Type(QueryBuilder::class), Argument::Type('array'))
->willReturn(null);
$filter->addRole()->shouldBeCalled();
//$filter->addRole()->shouldBeCalled();
$filter->applyOn()->willReturn('foo');
$filter->describeAction(Argument::cetera())->willReturn('filtered string');
$exportManager->addFilter($filter->reveal(), 'filter_foo');
$aggregator = $this->prophet->prophesize();
$aggregator->willImplement(AggregatorInterface::class);
$aggregator->applyOn()->willReturn('foo');
$aggregator->alterQuery(Argument::Type(QueryBuilder::class), Argument::Type('array'))
->willReturn(null);
//$aggregator->alterQuery()->shouldBeCalled();
$aggregator->getQueryKeys(Argument::Type('array'))->willReturn(array('aggregator'));
$aggregator->getLabels(
Argument::is('aggregator'),
Argument::is(array('cat a', 'cat b')),
Argument::is(array())
)
->willReturn(function($value) {
switch ($value) {
case '_header': return 'foo_header';
case 'cat a' : return 'label cat a';
case 'cat b' : return 'label cat b';
default:
throw new \RuntimeException(sprintf("This value (%s) is not valid", $value));
}
});
$aggregator->addRole()->willReturn(null);
//$aggregator->addRole()->shouldBeCalled();
$exportManager->addAggregator($aggregator->reveal(), 'aggregator_foo');
//add formatter interface
$formatter = new \Chill\MainBundle\Export\Formatter\SpreadSheetFormatter(
$this->container->get('translator'), $exportManager);
$exportManager->addFormatter($formatter, 'spreadsheet');
//ob_start();
$response = $exportManager->generate('dummy',
array(PickCenterType::CENTERS_IDENTIFIERS => array($center)),
array(
ExportType::FILTER_KEY => array(
'filter_foo' => array(
'enabled' => true,
'form' => array()
)
),
ExportType::AGGREGATOR_KEY => array(
'aggregator_foo' => array(
'enabled' => true,
'form' => array()
)
),
ExportType::PICK_FORMATTER_KEY => array(
'alias' => 'spreadsheet'
),
ExportType::EXPORT_KEY => array(
'a' => 'b'
)
),
array(
'format' => 'csv',
'aggregator_foo' => array(
'order' => 1
)
)
);
//$content = ob_get_clean();
$this->assertInstanceOf(Response::class, $response);
$expected = <<<EOT
"dummy title",""
"",""
"filtered string",""
"foo_header","_header"
"label cat a",""
"label cat b","1"
EOT;
$this->assertEquals($expected, $response->getContent());
}
}

View File

@@ -0,0 +1,155 @@
<?php
/*
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Form\Type;
use Symfony\Component\Form\Test\TypeTestCase;
use Chill\MainBundle\Form\Type\CenterType;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\GroupCenter;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class CenterTypeTest extends TypeTestCase
{
/**
* Test that a user which can reach only one center
* render as an hidden field
*/
public function testUserCanReachSingleCenter()
{
//prepare user
$center = $this->prepareCenter(1, 'center');
$groupCenter = (new GroupCenter())
->setCenter($center)
;
$user = (new User())
->addGroupCenter($groupCenter);
$type = $this->prepareType($user);
$this->assertEquals(HiddenType::class, $type->getParent());
}
/**
* Test that a user which can reach only one center
* render as an hidden field
*/
public function testUserCanReachMultipleSameCenter()
{
//prepare user
$center = $this->prepareCenter(1, 'center');
$groupCenterA = (new GroupCenter())
->setCenter($center)
;
$groupCenterB = (new GroupCenter())
->setCenter($center)
;
$user = (new User())
->addGroupCenter($groupCenterA)
->addGroupCenter($groupCenterB);
$type = $this->prepareType($user);
$this->assertEquals(HiddenType::class, $type->getParent());
}
/**
* Test that a user which can reach multiple center
* make CenterType render as "entity" type.
*/
public function testUserCanReachMultipleCenters()
{
//prepare user
$centerA = $this->prepareCenter(1, 'centerA');
$centerB = $this->prepareCenter(2, 'centerB');
$groupCenterA = (new GroupCenter())
->setCenter($centerA)
;
$groupCenterB = (new GroupCenter())
->setCenter($centerB)
;
$user = (new User())
->addGroupCenter($groupCenterA)
->addGroupCenter($groupCenterB)
;
$type = $this->prepareType($user);
$this->assertEquals(EntityType::class, $type->getParent());
}
/**
* prepare a mocked center, with and id and name given
*
* @param int $id
* @param string $name
* @return \Chill\MainBundle\Entity\Center
*/
private function prepareCenter($id, $name)
{
$prophet = new \Prophecy\Prophet;
$prophecyCenter = $prophet->prophesize();
$prophecyCenter->willExtend('\Chill\MainBundle\Entity\Center');
$prophecyCenter->getId()->willReturn($id);
$prophecyCenter->getName()->willReturn($name);
return $prophecyCenter->reveal();
}
/**
* prepare the type with mocked center transformer and token storage
*
* @param User $user the user for wich the form will be prepared
* @return CenterType
*/
private function prepareType(User $user)
{
$prophet = new \Prophecy\Prophet;
//create a center transformer
$centerTransformerProphecy = $prophet->prophesize();
$centerTransformerProphecy
->willExtend('Chill\MainBundle\Form\Type\DataTransformer\CenterTransformer');
$transformer = $centerTransformerProphecy->reveal();
$tokenProphecy = $prophet->prophesize();
$tokenProphecy
->willImplement('\Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
$tokenProphecy->getUser()->willReturn($user);
$token = $tokenProphecy->reveal();
$tokenStorageProphecy = $prophet->prophesize();
$tokenStorageProphecy
->willExtend('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage');
$tokenStorageProphecy->getToken()->willReturn($token);
$tokenStorage = $tokenStorageProphecy->reveal();
return new CenterType($tokenStorage, $transformer);
}
}

View File

@@ -0,0 +1,141 @@
<?php
/*
* Chill is a software for social workers
* Copyright (C) 2016 Champs-Libres Coopérative <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Pagination;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Chill\MainBundle\Pagination\Page;
/**
* Test the Page class
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/
class PageTest extends KernelTestCase
{
protected $paginator;
protected $prophet;
public function setUp() {
$this->prophet = new \Prophecy\Prophet;
}
/**
*
* @param int $maxResult
* @param int $itemPerPage
* @param string $route
* @param array $routeParameters
* @return Page
*/
protected function generatePage(
$number = 1,
$itemPerPage = 10,
$route = 'route',
array $routeParameters = array()
) {
$urlGenerator = $this->prophet->prophesize();
$urlGenerator->willImplement(UrlGeneratorInterface::class);
return new Page($number, $itemPerPage, $urlGenerator->reveal(), $route,
$routeParameters);
}
public function testPageNumber() {
$page = $this->generatePage(1);
$this->assertEquals(1, $page->getNumber());
}
/**
* return a set of element to testGetFirstItemNumber
*
* the set contains :
* - the page number ;
* - the number of item per page ;
* - the expected first item number
*
* @return array
*/
public function generateGetFirstItemNumber() {
return array(
[1, 10, 0],
[2, 10, 10]
);
}
/**
*
* @param int $number
* @param int $itemPerPage
* @param int $expectedItemPerPage
* @dataProvider generateGetFirstItemNumber
*/
public function testGetFirstItemNumber(
$number,
$itemPerPage,
$expectedItemPerPage
) {
$page = $this->generatePage($number, $itemPerPage);
$this->assertEquals($expectedItemPerPage, $page->getFirstItemNumber());
}
/**
* return a set of element to testGetLastItemNumber
*
* the set contains :
* - the page number ;
* - the number of item per page ;
* - the expected last item number
*
* @return array
*/
public function generateGetLastItemNumber() {
return array(
[1, 10, 9],
[2, 10, 19]
);
}
/**
*
* @param int $number
* @param int $itemPerPage
* @param int $expectedItemPerPage
* @dataProvider generateGetLastItemNumber
*/
public function testGetLastItemNumber(
$number,
$itemPerPage,
$expectedItemPerPage
) {
$page = $this->generatePage($number, $itemPerPage);
$this->assertEquals($expectedItemPerPage, $page->getLastItemNumber());
}
}

View File

@@ -0,0 +1,237 @@
<?php
/*
* Chill is a software for social workers
* Copyright (C) 2016 Champs-Libres Coopérative <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Pagination;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\MainBundle\Pagination\Paginator;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
/**
* Test the paginator class
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/
class PaginatorTest extends KernelTestCase
{
protected $paginator;
protected $prophet;
public function setUp()
{
$this->prophet = new \Prophecy\Prophet;
}
/**
*
* @param int $maxResult
* @param int $itemPerPage
* @param string $route
* @param array $routeParameters
* @return Paginator
*/
protected function generatePaginator(
$totalItems,
$itemPerPage,
$currentPageNumber = 1,
$route = '',
array $routeParameters = array()
) {
$urlGenerator = $this->prophet->prophesize();
$urlGenerator->willImplement(UrlGeneratorInterface::class);
return new Paginator(
$totalItems,
$itemPerPage,
$currentPageNumber,
$route,
$routeParameters,
$urlGenerator->reveal(),
'page',
'item_per_page'
);
}
/**
* generate a set of pages with different maxItem, itemPerPage, and
* expected page number
*
* @return array
*/
public function generatePageNumber()
{
return array(
[12, 10, 2],
[20, 10, 2],
[21, 10, 3],
[19, 10, 2],
[1, 10, 1],
[0, 10, 1],
[10, 10, 1]
);
}
/**
* Test that the countPages method (and his alias `count`) return
* valid results.
*
* @param int $totalItems
* @param int $itemPerPage
* @param int $expectedPageNumber
* @dataProvider generatePageNumber
*/
public function testPageNumber($totalItems, $itemPerPage, $expectedPageNumber)
{
$paginator = $this->generatePaginator($totalItems, $itemPerPage);
$this->assertEquals($expectedPageNumber, $paginator->countPages());
$this->assertEquals($expectedPageNumber, count($paginator));
}
/**
* generate an array with a set of page with :
* - total items ;
* - item per page ;
* - current page number ;
* - expected hasNextPage result
*
* @return array
*/
public function generateHasNextPage()
{
return array(
[10, 10, 1, false],
[20, 10, 1, true],
[12, 10, 1, true],
[12, 10, 2, false]
);
}
/**
*
* @param int $totalItems
* @param int $itemPerPage
* @param int $currentPage
* @param bool $expectedHasNextPage
* @dataProvider generateHasNextPage
*/
public function testHasNextPage(
$totalItems,
$itemPerPage,
$currentPage,
$expectedHasNextPage
) {
$paginator = $this->generatePaginator($totalItems, $itemPerPage, $currentPage);
$this->assertEquals($expectedHasNextPage, $paginator->hasNextPage());
}
/**
* generate an array with a set of page with :
* - total items ;
* - item per page ;
* - current page number ;
* - expected hasPreviousPage result
*
* @return array
*/
public function generateHasPreviousPage()
{
return array(
[10, 10, 1, false],
[20, 10, 1, false],
[12, 10, 1, false],
[12, 10, 2, true],
);
}
/**
*
* @param int $totalItems
* @param int $itemPerPage
* @param int $currentPage
* @param bool $expectedHasPreviousPage
* @dataProvider generateHasPreviousPage
*/
public function testHasPreviousPage(
$totalItems,
$itemPerPage,
$currentPage,
$expectedHasNextPage
) {
$paginator = $this->generatePaginator($totalItems, $itemPerPage, $currentPage);
$this->assertEquals($expectedHasNextPage, $paginator->hasPreviousPage());
}
public function generateHasPage()
{
return array(
[10, 10, -1, false],
[12, 10, 1, true],
[12, 10, 2, true],
[12, 10, 3, false]
);
}
/**
* test the HasPage function
*
*
* @param int $totalItems
* @param int $itemPerpage
* @param int $pageNumber
* @param bool $expectedHasPage
* @dataProvider generateHasPage
*/
public function testHasPage($totalItems, $itemPerpage, $pageNumber,
$expectedHasPage)
{
$paginator = $this->generatePaginator($totalItems, $itemPerpage);
$this->assertEquals($expectedHasPage, $paginator->hasPage($pageNumber));
}
public function testGetPage()
{
$paginator = $this->generatePaginator(105, 10);
$this->assertEquals(5, $paginator->getPage(5)->getNumber());
}
public function testPagesGenerator()
{
$paginator = $this->generatePaginator(105, 10);
$generator = $paginator->getPagesGenerator();
$i = 1;
foreach($generator as $page) {
$this->assertEquals($i, $page->getNumber(),
"assert that the current page number is $i");
$i++;
}
$this->assertEquals(11, $page->getNumber(),
"assert that the last page number is 11");
}
}

View File

@@ -0,0 +1,52 @@
<?php
/*
* Chill is a software for social workers
* Copyright (C) 2015 Champs-Libres Coopérative <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Routing\Loader;
use Chill\MainBundle\Routing\Loader\ChillRoutesLoader;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
/**
* Test the route loader
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class RouteLoaderTest extends KernelTestCase
{
private $router;
public function setUp()
{
static::bootKernel();
$this->router = static::$kernel->getContainer()->get('router');
}
/**
* Test that the route loader loads at least homepage
*/
public function testRouteFromMainBundleAreLoaded()
{
$homepage = $this->router->getRouteCollection()->get('chill_main_homepage');
$this->assertNotNull($homepage);
}
}

View File

@@ -0,0 +1,54 @@
<?php
/*
* Chill is a suite of a modules, Chill is a software for social workers
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Search;
/**
* Description of AbstractSearch
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AbstractSearchTest extends \PHPUnit\Framework\TestCase
{
/**
* @var \Chill\MainBundle\Search\AbstractSearch
*/
private $stub;
public function setUp()
{
$this->stub = $this->getMockForAbstractClass('Chill\MainBundle\Search\AbstractSearch');
}
public function testParseDateRegular()
{
$date = $this->stub->parseDate('2014-05-01');
$this->assertEquals('2014', $date->format('Y'));
$this->assertEquals('05', $date->format('m'));
$this->assertEquals('01', $date->format('d'));
}
public function testRecompose()
{
$this->markTestSkipped();
}
}

View File

@@ -0,0 +1,314 @@
<?php
/*
*
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Test\Search;
use Chill\MainBundle\Search\SearchProvider;
use Chill\MainBundle\Search\SearchInterface;
class SearchProviderTest extends \PHPUnit\Framework\TestCase
{
/**
*
* @var SearchProvider
*/
private $search;
public function setUp()
{
$this->search = new SearchProvider();
//add a default service
$this->addSearchService(
$this->createDefaultSearchService('I am default', 10), 'default'
);
//add a domain service
$this->addSearchService(
$this->createNonDefaultDomainSearchService('I am domain bar', 20, FALSE), 'bar'
);
}
/**
* @expectedException \Chill\MainBundle\Search\UnknowSearchNameException
*/
public function testInvalidSearchName()
{
$this->search->getByName("invalid name");
}
public function testSimplePattern()
{
$terms = $this->p("@person birthdate:2014-01-02 name:(my name) is not my name");
$this->assertEquals(array(
'_domain' => 'person',
'birthdate' => '2014-01-02',
'_default' => 'is not my name',
'name' => 'my name'
), $terms);
}
public function testWithoutDomain()
{
$terms = $this->p('foo:bar residual');
$this->assertEquals(array(
'_domain' => null,
'foo' => 'bar',
'_default' => 'residual'
), $terms);
}
public function testWithoutDefault()
{
$terms = $this->p('@person foo:bar');
$this->assertEquals(array(
'_domain' => 'person',
'foo' => 'bar',
'_default' => ''
), $terms);
}
public function testCapitalLetters()
{
$terms = $this->p('Foo:Bar LOL marCi @PERSON');
$this->assertEquals(array(
'_domain' => 'person',
'_default' => 'lol marci',
'foo' => 'bar'
), $terms);
}
/**
* @expectedException Chill\MainBundle\Search\ParsingException
*/
public function testMultipleDomainError()
{
$term = $this->p("@person @report");
}
public function testDoubleParenthesis()
{
$terms = $this->p("@papamobile name:(my beautiful name) residual "
. "surname:(i love techno)");
$this->assertEquals(array(
'_domain' => 'papamobile',
'name' => 'my beautiful name',
'_default' => 'residual',
'surname' => 'i love techno'
), $terms);
}
public function testAccentued()
{
//$this->markTestSkipped('accentued characters must be implemented');
$terms = $this->p('manço bélier aztèque à saloù ê');
$this->assertEquals(array(
'_domain' => NULL,
'_default' => 'manco belier azteque a salou e'
), $terms);
}
public function testAccentuedCapitals()
{
//$this->markTestSkipped('accentued characters must be implemented');
$terms = $this->p('MANÉÀ oÛ lÎ À');
$this->assertEquals(array(
'_domain' => null,
'_default' => 'manea ou li a'
), $terms);
}
public function testTrimInParenthesis()
{
$terms = $this->p('foo:(bar )');
$this->assertEquals(array(
'_domain' => null,
'foo' => 'bar',
'_default' => ''
), $terms);
}
public function testTrimInDefault()
{
$terms = $this->p(' foo bar ');
$this->assertEquals(array(
'_domain' => null,
'_default' => 'foo bar'
), $terms);
}
public function testArgumentNameWithTrait()
{
$terms = $this->p('date-from:2016-05-04');
$this->assertEquals(array(
'_domain' => null,
'date-from' => '2016-05-04',
'_default' => ''
), $terms);
}
/**
* Test the behaviour when no domain is provided in the search pattern :
* the default search should be enabled
*/
public function testSearchResultDefault()
{
$response = $this->search->getSearchResults('default search');
//$this->markTestSkipped();
$this->assertEquals(array(
"I am default"
), $response);
}
/**
* @expectedException \Chill\MainBundle\Search\UnknowSearchDomainException
*/
public function testSearchResultDomainUnknow()
{
$response = $this->search->getSearchResults('@unknow domain');
//$this->markTestSkipped();
}
public function testSearchResultDomainSearch()
{
//add a search service which will be supported
$this->addSearchService(
$this->createNonDefaultDomainSearchService("I am domain foo", 100, TRUE), 'foo'
);
$response = $this->search->getSearchResults('@foo default search');
$this->assertEquals(array(
"I am domain foo"
), $response);
}
public function testSearchWithinSpecificSearchName()
{
//add a search service which will be supported
$this->addSearchService(
$this->createNonDefaultDomainSearchService("I am domain foo", 100, TRUE), 'foo'
);
$response = $this->search->getResultByName('@foo search', 'foo');
$this->assertEquals('I am domain foo', $response);
}
/**
* @expectedException \Chill\MainBundle\Search\ParsingException
*/
public function testSearchWithinSpecificSearchNameInConflictWithSupport()
{
$response = $this->search->getResultByName('@foo default search', 'bar');
}
/**
* shortcut for executing parse method
*
* @param unknown $pattern
* @return string[]
*/
private function p($pattern)
{
return $this->search->parse($pattern);
}
/**
* Add a search service to the chill.main.search_provider
*
* Useful for mocking the SearchInterface
*
* @param SearchInterface $search
* @param string $name
*/
private function addSearchService(SearchInterface $search, $name)
{
$this->search
->addSearchService($search, $name);
}
private function createDefaultSearchService($result, $order)
{
$mock = $this
->getMockForAbstractClass('Chill\MainBundle\Search\AbstractSearch');
//set the mock as default
$mock->expects($this->any())
->method('isActiveByDefault')
->will($this->returnValue(TRUE));
$mock->expects($this->any())
->method('getOrder')
->will($this->returnValue($order));
//set the return value
$mock->expects($this->any())
->method('renderResult')
->will($this->returnValue($result));
return $mock;
}
private function createNonDefaultDomainSearchService($result, $order, $domain)
{
$mock = $this
->getMockForAbstractClass('Chill\MainBundle\Search\AbstractSearch');
//set the mock as default
$mock->expects($this->any())
->method('isActiveByDefault')
->will($this->returnValue(FALSE));
$mock->expects($this->any())
->method('getOrder')
->will($this->returnValue($order));
$mock->expects($this->any())
->method('supports')
->will($this->returnValue($domain));
//set the return value
$mock->expects($this->any())
->method('renderResult')
->will($this->returnValue($result));
return $mock;
}
}

View File

@@ -0,0 +1,478 @@
<?php
/*
* Copyright (C) 2015 Julien Fastré <julien.fastre@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Security\Authorization;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\MainBundle\Test\PrepareUserTrait;
use Chill\MainBundle\Test\PrepareCenterTrait;
use Chill\MainBundle\Test\PrepareScopeTrait;
use Chill\MainBundle\Test\ProphecyTrait;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Security\Core\Role\Role;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\Center;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class AuthorizationHelperTest extends KernelTestCase
{
use PrepareUserTrait, PrepareCenterTrait, PrepareScopeTrait, ProphecyTrait;
public function setUp()
{
static::bootKernel();
}
/**
*
* @return \Chill\MainBundle\Security\Authorization\AuthorizationHelper
*/
private function getAuthorizationHelper()
{
return static::$kernel->getContainer()
->get('chill.main.security.authorization.helper')
;
}
/**
* Test function userCanReach of helper.
*
* A user can reach center => the function should return true.
*/
public function testUserCanReachCenter_UserShouldReach()
{
$center = $this->prepareCenter(1, 'center');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $center, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'ANY_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$this->assertTrue($helper->userCanReachCenter($user, $center));
}
/**
* Test function userCanReach of helper
*
* A user can not reachcenter =>W the function should return false
*/
public function testUserCanReachCenter_UserShouldNotReach()
{
$centerA = $this->prepareCenter(1, 'center');
$centerB = $this->prepareCenter(2, 'centerB');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $centerA, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'ANY_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$this->assertFalse($helper->userCanReachCenter($user, $centerB));
}
public function testUserHasAccess_shouldHaveAccess_EntityWithoutScope()
{
$center = $this->prepareCenter(1, 'center');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $center, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'CHILL_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->getCenter()->willReturn($center);
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(),
'CHILL_ROLE'));
}
public function testUserHasAccess_ShouldHaveAccessWithInheritance_EntityWithoutScope()
{
$center = $this->prepareCenter(1, 'center');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $center, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'CHILL_MASTER_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->getCenter()->willReturn($center);
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(),
'CHILL_INHERITED_ROLE_1'));
}
public function testuserHasAccess_UserHasNoRole_EntityWithoutScope()
{
$center = $this->prepareCenter(1, 'center');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $center, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'ANY_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->getCenter()->willReturn($center);
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
}
/**
* test that a user has no access on a entity, but is granted on the same role
* on another center
*/
public function testUserHasAccess_userHasNoRole_UserHasRoleOnAnotherCenter_EntityWithoutScope()
{
$centerA = $this->prepareCenter(1, 'center');
$centerB = $this->prepareCenter(2, 'centerB');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $centerA, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'ANY_ROLE']
),
array(
'centerB' => $centerB, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'ANY_ROLE'],
['scope' => $scope, 'role' => 'CHILL_ROLE']
)
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->getCenter()->willReturn($centerA);
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
}
public function testtestUserHasAccess_UserShouldHaveAccess_EntityWithScope()
{
$center = $this->prepareCenter(1, 'center');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $center, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'CHILL_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
$entity->getCenter()->willReturn($center);
$entity->getScope()->willReturn($scope);
$this->assertTrue($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
}
public function testUserHasAccess_UserHasNoRole_EntityWithScope()
{
$center = $this->prepareCenter(1, 'center');
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $center, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'CHILL_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
$entity->getCenter()->willReturn($center);
$entity->getScope()->willReturn($scope);
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'ANOTHER_ROLE'));
}
public function testUserHasAccess_UserHasNoCenter_EntityWithScope()
{
$centerA = $this->prepareCenter(1, 'center'); //the user will have this center
$centerB = $this->prepareCenter(2, 'centerB'); //the entity will have another center
$scope = $this->prepareScope(1, 'default');
$user = $this->prepareUser(array(
array(
'center' => $centerA, 'permissionsGroup' => array(
['scope' => $scope, 'role' => 'CHILL_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
$entity->getCenter()->willReturn($centerB);
$entity->getScope()->willReturn($scope);
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
}
public function testUserHasAccess_UserHasNoScope_EntityWithScope()
{
$center = $this->prepareCenter(1, 'center');
$scopeA = $this->prepareScope(1, 'default'); //the entity will have this scope
$scopeB = $this->prepareScope(2, 'other'); //the user will be granted this scope
$user = $this->prepareUser(array(
array(
'center' => $center, 'permissionsGroup' => array(
['scope' => $scopeB, 'role' => 'CHILL_ROLE']
)
)
));
$helper = $this->getAuthorizationHelper();
$entity = $this->getProphet()->prophesize();
$entity->willImplement('\Chill\MainBundle\Entity\HasCenterInterface');
$entity->willImplement('\Chill\MainBundle\Entity\HasScopeInterface');
$entity->getCenter()->willReturn($center);
$entity->getScope()->willReturn($scopeA);
$this->assertFalse($helper->userHasAccess($user, $entity->reveal(), 'CHILL_ROLE'));
}
/**
*
* @dataProvider dataProvider_getReachableCenters
* @param Center $shouldHaveCenter
* @param User $user
* @param Role $role
* @param Scope $scope
*/
public function testGetReachableCenters($test, $result, $msg)
{
$this->assertEquals($test, $result, $msg);
}
public function dataProvider_getReachableCenters()
{
$this->setUp();
$centerA = $this->prepareCenter(1, 'center A');
$centerB = $this->prepareCenter(2, 'center B');
$scopeA = $this->prepareScope(1, 'scope default');
$scopeB = $this->prepareScope(2, 'scope B');
$scopeC = $this->prepareScope(3, 'scope C');
$userA = $this->prepareUser(array(
array(
'center' => $centerA,
'permissionsGroup' => array(
['scope' => $scopeB, 'role' => 'CHILL_ROLE_1'],
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2']
)
),
array(
'center' => $centerB,
'permissionsGroup' => array(
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
['scope' => $scopeC, 'role' => 'CHILL_ROLE_2']
)
)
));
$ah = $this->getAuthorizationHelper();
return array(
// without scopes
array(
true,
in_array($centerA, $ah->getReachableCenters($userA,
new Role('CHILL_ROLE_1'), null)),
'center A should be available for userA, with role 1 '
),
array(
true,
in_array($centerA, $ah->getReachableCenters($userA,
new Role('CHILL_ROLE_2'), null)),
'center A should be available for userA, with role 2 '
),
array(
true,
in_array($centerB, $ah->getReachableCenters($userA,
new Role('CHILL_ROLE_2'), null)),
'center A should be available for userA, with role 2 '
),
array(
false,
in_array($centerB, $ah->getReachableCenters($userA,
new Role('CHILL_ROLE_1'), null)),
'center B should NOT be available for userA, with role 1 '
),
// with scope
array(
true,
in_array($centerA, $ah->getReachableCenters($userA,
new Role('CHILL_ROLE_1'), $scopeB)),
'center A should be available for userA, with role 1, scopeC '
),
array(
false,
in_array($centerA, $ah->getReachableCenters($userA,
new Role('CHILL_ROLE_2'), $scopeC)),
'center A should NOT be available for userA, with role 2, scopeA '
),
array(
true,
in_array($centerB, $ah->getReachableCenters($userA,
new Role('CHILL_ROLE_2'), $scopeA)),
'center B should be available for userA, with role 2, scopeA '
),
);
}
/**
*
* @dataProvider dataProvider_getReachableScopes
* @param boolean $expectedResult
* @param Scope $testedScope
* @param User $user
* @param Role $role
* @param Center $center
* @param string $message
*/
public function testGetReachableScopes($expectedResult, Scope $testedScope,
User $user, Role $role, Center $center, $message)
{
$reachableScopes = $this->getAuthorizationHelper()
->getReachableScopes($user, $role, $center);
$this->assertEquals($expectedResult, in_array($testedScope, $reachableScopes),
$message);
}
public function dataProvider_getReachableScopes()
{
$centerA = $this->prepareCenter(1, 'center A');
$centerB = $this->prepareCenter(2, 'center B');
$scopeA = $this->prepareScope(1, 'scope default');
$scopeB = $this->prepareScope(2, 'scope B');
$scopeC = $this->prepareScope(3, 'scope C');
$userA = $this->prepareUser(array(
array(
'center' => $centerA,
'permissionsGroup' => array(
['scope' => $scopeB, 'role' => 'CHILL_ROLE_1'],
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2']
)
),
array(
'center' => $centerB,
'permissionsGroup' => array(
['scope' => $scopeA, 'role' => 'CHILL_ROLE_2'],
['scope' => $scopeC, 'role' => 'CHILL_ROLE_2'],
['scope' => $scopeB, 'role' => 'CHILL_ROLE_2']
)
)
));
return array(
array(
true,
$scopeA,
$userA,
new Role('CHILL_ROLE_2'),
$centerA,
"Assert that a scope is found within accessible scopes"
),
array(
false,
$scopeB,
$userA,
new Role('CHILL_ROLE_2'),
$centerA,
"Assert that a scope not reachable is NOT found within accessible scopes"
),
array(
false,
$scopeB,
$userA,
new Role('CHILL_ROLE_1'),
$centerB,
"Assert that a scope not reachable is not found within accessible scopes."
. " Trying on filter centering"
)
);
}
public function testGetParentRoles()
{
$parentRoles = $this->getAuthorizationHelper()
->getParentRoles(new Role('CHILL_INHERITED_ROLE_1'));
$this->assertContains(
'CHILL_MASTER_ROLE',
\array_map(
function(Role $role) {
return $role->getRole();
},
$parentRoles
),
"Assert that `CHILL_MASTER_ROLE` is a parent of `CHILL_INHERITED_ROLE_1`");
}
public function testFindUsersReaching()
{
$centerA = static::$kernel->getContainer()
->get('doctrine.orm.entity_manager')
->getRepository(Center::class)
->findOneByName('Center A');
$users = $this->getAuthorizationHelper()
->findUsersReaching(new Role('CHILL_PERSON_SEE'),
$centerA);
$usernames = \array_map(function(User $u) { return $u->getUsername(); }, $users);
$this->assertContains('center a_social', $usernames);
}
}

View File

@@ -0,0 +1,117 @@
<?php
/*
* Copyright (C) 2018 Champs Libres Cooperative <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\PasswordRecover;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Chill\MainBundle\Security\PasswordRecover\TokenManager;
use Chill\MainBundle\Entity\User;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class TokenManagerTest extends KernelTestCase
{
protected $tokenManager;
public static function setUpBefore()
{
}
public function setUp()
{
self::bootKernel();
$logger = self::$kernel
->getContainer()
->get('logger');
$this->tokenManager = new TokenManager('secret', $logger);
}
public function testGenerate()
{
$tokenManager = $this->tokenManager;
$user = (new User())->setUsernameCanonical('test');
$expiration = new \DateTimeImmutable('tomorrow');
$tokens = $tokenManager->generate($user, $expiration);
$this->assertInternalType('array', $tokens);
$this->assertArrayHasKey('h', $tokens);
$this->assertArrayHasKey('t', $tokens);
$this->assertNotEmpty($tokens['h']);
$this->assertNotEmpty($tokens['t']);
$this->assertEquals($user->getUsernameCanonical(), $tokens['u']);
}
/**
* @expectedException \UnexpectedValueException
*/
public function testGenerateEmptyUsernameCanonical()
{
$tokenManager = $this->tokenManager;
// set a username, but not a username canonical
$user = (new User())->setUsername('test');
$expiration = new \DateTimeImmutable('tomorrow');
$tokenManager->generate($user, $expiration);
}
public function testVerify()
{
$tokenManager = $this->tokenManager;
$user = (new User())->setUsernameCanonical('test');
$expiration = new \DateTimeImmutable('tomorrow');
$tokens = $tokenManager->generate($user, $expiration);
$hash = $tokens[TokenManager::HASH];
$token = $tokens[TokenManager::TOKEN];
$timestamp = $tokens[TokenManager::TIMESTAMP];
$verification = $tokenManager->verify($hash, $token, $user, $timestamp);
$this->assertTrue($verification);
// test with altering token
$this->assertFalse($tokenManager->verify($hash.'5', $token, $user, $timestamp));
$this->assertFalse($tokenManager->verify($hash, $token.'25', $user, $timestamp));
$this->assertFalse($tokenManager->verify($hash, $token, $user->setUsernameCanonical('test2'), $timestamp));
$this->assertFalse($tokenManager->verify($hash, $token, $user, $timestamp+1));
}
public function testVerifyExpiredFails()
{
$tokenManager = $this->tokenManager;
$user = (new User())->setUsernameCanonical('test');
$expiration = (new \DateTimeImmutable('now'))->sub(new \DateInterval('PT1S'));
$tokens = $tokenManager->generate($user, $expiration);
$hash = $tokens[TokenManager::HASH];
$token = $tokens[TokenManager::TOKEN];
$timestamp = $tokens[TokenManager::TIMESTAMP];
$verification = $tokenManager->verify($hash, $token, $user, $timestamp);
$this->assertFalse($verification);
}
}

View File

@@ -0,0 +1,88 @@
<?php
/*
* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2014, Champs Libres Cooperative SCRLFS, <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests\Services;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\DomCrawler\Crawler;
/**
* Test the Twig function 'chill_menu'
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class ChillMenuTwigFunctionTest extends KernelTestCase
{
private static $templating;
public static function setUpBeforeClass()
{
self::bootKernel(array('environment' => 'test'));
static::$templating = static::$kernel
->getContainer()->get('templating');
//load templates in Tests/Resources/views
static::$kernel->getContainer()->get('twig.loader')
->addPath(static::$kernel->getContainer()->getParameter('kernel.root_dir')
.'/Resources/views/', $namespace = 'tests');
}
public function testNormalMenu()
{
$content = static::$templating->render('@tests/menus/normalMenu.html.twig');
$crawler = new Crawler($content);
$ul = $crawler->filter('ul')->getNode(0);
$this->assertEquals( 'ul', $ul->tagName);
$lis = $crawler->filter('ul')->children();
$this->assertEquals(3, count($lis));
$lis->each(function(Crawler $node, $i) {
$this->assertEquals('li', $node->getNode(0)->tagName);
$a = $node->children()->getNode(0);
$this->assertEquals('a', $a->tagName);
switch($i) {
case 0:
$this->assertEquals('/dummy?param=fake', $a->getAttribute('href'));
$this->assertEquals('active', $a->getAttribute('class'));
$this->assertEquals('test0', $a->nodeValue);
break;
case 1:
$this->assertEquals('/dummy1?param=fake', $a->getAttribute('href'));
$this->assertEmpty($a->getAttribute('class'));
$this->assertEquals('test1', $a->nodeValue);
break;
case 3:
$this->assertEquals('/dummy2/fake', $a->getAttribute('href'));
$this->assertEmpty($a->getAttribute('class'));
$this->assertEquals('test2', $a->nodeValue);
}
});
}
public function testMenuOverrideTemplate()
{
$this->markTestSkipped("this hacks seems not working now");
$content = static::$templating->render('@tests/menus/overrideTemplate.html.twig');
$this->assertEquals('fake template', $content);
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace Chill\MainBundle\Tests\Services;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Routing\RouteCollection;
/**
* This class provide functional test for MenuComposer
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class MenuComposerTest extends KernelTestCase
{
/**
*
* @var \Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader;
*/
private $loader;
/**
*
* @var \Chill\MainBundle\DependencyInjection\Services\MenuComposer;
*/
private $menuComposer;
public function setUp()
{
self::bootKernel(array('environment' => 'test'));
$this->menuComposer = static::$kernel->getContainer()
->get('chill.main.menu_composer');
}
/**
* @covers \Chill\MainBundle\Routing\MenuComposer
*/
public function testMenuComposer()
{
$collection = new RouteCollection();
$routes = $this->menuComposer->getRoutesFor('dummy0');
$this->assertInternalType('array', $routes);
$this->assertCount(3, $routes);
//check that the keys are sorted
$orders = array_keys($routes);
foreach ($orders as $key => $order){
if (array_key_exists($key + 1, $orders)) {
$this->assertGreaterThan($order, $orders[$key + 1],
'Failing to assert that routes are ordered');
}
}
//check that the array are identical, order is not important :
$expected = array(
50 => array(
'key' => 'chill_main_dummy_0',
'label' => 'test0',
'otherkey' => 'othervalue'
),
51 => array(
'key' => 'chill_main_dummy_1',
'label' => 'test1',
'helper'=> 'great helper'
),
52 => array(
'key' => 'chill_main_dummy_2',
'label' => 'test2'
));
foreach ($expected as $order => $route ){
}
//compare arrays
foreach($expected as $order => $route) {
//check the key are the one expected
$this->assertTrue(isset($routes[$order]));
if (isset($routes[$order])){ #avoid an exception if routes with order does not exists
//sort arrays. Order matters for phpunit::assertSame
ksort($route);
ksort($routes[$order]);
$this->assertSame($route, $routes[$order]);
}
}
}
}

View File

@@ -0,0 +1,47 @@
<?php
/*
* Chill is a software for social workers
* Copyright (C) 2015 Champs Libres <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Tests;
use Symfony\Component\BrowserKit\Client;
/**
* Provide useful methods for tests
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/
class TestHelper
{
/**
* create a client authenticated with an user
*
* @param WebTestCase $testCase
* @return \Symfony\Component\BrowserKit\Client authenticated client
*/
public static function getAuthenticatedClientOptions($username = 'center a_social',
$password = 'password')
{
return array(
'PHP_AUTH_USER' => $username,
'PHP_AUTH_PW' => $password,
);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Chill\MainBundle\Tests\Util;
use PHPUnit\Framework\TestCase;
use Chill\MainBundle\Util\CountriesInfo;
/**
* tests for CountriesInfos
*
* @author julien.fastre@champs-libre.coop
*/
class CountriesInfoTest extends TestCase {
public function testGetCountryData()
{
$raw = CountriesInfo::getCountriesData();
$this->assertStringStartsWith("AS AF AFG 004 Afghanistan, Islamic Republic of",
$raw);
}
public function testGetArrayCountriesData()
{
$data = CountriesInfo::getArrayCountriesData();
$this->assertNotNull($data);
$this->assertContains(array(
"AS", "AF", "AFG", "004", "Afghanistan, Islamic Republic of"
), $data);
}
public function testGetCountryCodeByContinents()
{
$countries = CountriesInfo::getCountriesCodeByContinent('EU');
$this->assertContains('BE', $countries);
$this->assertContains('FR', $countries);
$this->assertContains('GB', $countries);
}
public function getGetContinentsCodes()
{
$continents = CountriesInfo::getContinentsCodes();
$this->assertContains('EU', $continents);
}
}

View File

@@ -0,0 +1,8 @@
<?php
if (!is_file($autoloadFile = __DIR__.'/../vendor/autoload.php')) {
throw new \LogicException('Could not find autoload.php in vendor/. Did you run "composer install --dev"?');
}
require $autoloadFile;