diff --git a/lib/Alchemy/Phrasea/Application/Helper/AclAware.php b/lib/Alchemy/Phrasea/Application/Helper/AclAware.php index 2e72c9264f..5113f7ac47 100644 --- a/lib/Alchemy/Phrasea/Application/Helper/AclAware.php +++ b/lib/Alchemy/Phrasea/Application/Helper/AclAware.php @@ -14,7 +14,6 @@ use Alchemy\Phrasea\Model\Entities\User; trait AclAware { - /** @var ACLProvider */ private $aclProvider; /** @@ -45,17 +44,20 @@ trait AclAware return $this->aclProvider; } - if (null === $this->aclProvider && $this instanceof \Pimple && $this->offsetExists('acl')) { - $this->aclProvider = function () { + $locator = $this->aclProvider; + + if (null === $locator && $this instanceof \Pimple && $this->offsetExists('acl')) { + $locator = function () { return $this['acl']; }; } - if (null === $this->aclProvider) { + if (null === $locator) { throw new \LogicException(ACLProvider::class . ' instance or locator was not set'); } - $instance = call_user_func($this->aclProvider); + $instance = $locator(); + if (!$instance instanceof ACLProvider) { throw new \LogicException(sprintf( 'Expects locator to return instance of "%s", got "%s"', diff --git a/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php b/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php index a2b71a1813..8716d6d80b 100644 --- a/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php +++ b/lib/Alchemy/Phrasea/Authentication/Phrasea/FailureManager.php @@ -13,24 +13,35 @@ namespace Alchemy\Phrasea\Authentication\Phrasea; use Alchemy\Phrasea\Exception\InvalidArgumentException; use Alchemy\Phrasea\Authentication\Exception\RequireCaptchaException; +use Alchemy\Phrasea\Model\Repositories\AuthFailureRepository; use Doctrine\ORM\EntityManager; use Alchemy\Phrasea\Model\Entities\AuthFailure; -use Doctrine\ORM\EntityRepository; use Neutron\ReCaptcha\ReCaptcha; use Symfony\Component\HttpFoundation\Request; class FailureManager { - /** @var ReCaptcha */ + /** + * @var ReCaptcha + */ private $captcha; - /** @var EntityManager */ + + /** + * @var EntityManager + */ private $em; - /** @var EntityRepository */ + + /** + * @var AuthFailureRepository + */ private $repository; - /** @var integer */ + + /** + * @var int + */ private $trials; - public function __construct(EntityRepository $repo, EntityManager $em, ReCaptcha $captcha, $trials) + public function __construct(AuthFailureRepository $repo, EntityManager $em, ReCaptcha $captcha, $trials) { $this->captcha = $captcha; $this->em = $em; @@ -40,9 +51,12 @@ class FailureManager throw new InvalidArgumentException('Trials number must be a positive integer'); } - $this->trials = $trials; + $this->trials = (int)$trials; } + /** + * @return int + */ public function getTrials() { return $this->trials; @@ -86,36 +100,38 @@ class FailureManager $failures = $this->repository->findLockedFailuresMatching($username, $request->getClientIp()); if (0 === count($failures)) { - return; + return $this; } if ($this->trials < count($failures) && $this->captcha->isSetup()) { $response = $this->captcha->bind($request); - if ($response->isValid()) { - foreach ($failures as $failure) { - $failure->setLocked(false); - } - $this->em->flush(); - } else { - throw new RequireCaptchaException('Too much failure, require captcha'); + if (!$response->isValid()) { + throw new RequireCaptchaException('Too many failures, require captcha'); } + + foreach ($failures as $failure) { + $failure->setLocked(false); + } + + $this->em->flush($failures); } return $this; } - /** - * Removes failures older than 2 monthes - */ private function removeOldFailures() { $failures = $this->repository->findOldFailures('-2 months'); - if (0 < count($failures)) { - foreach ($failures as $failure) { - $this->em->remove($failure); - } + if (empty($failures)) { + return; } + + foreach ($failures as $failure) { + $this->em->remove($failure); + } + + $this->em->flush($failures); } } diff --git a/lib/Alchemy/Phrasea/Authentication/SuggestionFinder.php b/lib/Alchemy/Phrasea/Authentication/SuggestionFinder.php index f4c0c22045..3f328a5943 100644 --- a/lib/Alchemy/Phrasea/Authentication/SuggestionFinder.php +++ b/lib/Alchemy/Phrasea/Authentication/SuggestionFinder.php @@ -15,13 +15,13 @@ use Alchemy\Phrasea\Authentication\Exception\NotAuthenticatedException; use Alchemy\Phrasea\Authentication\Provider\Token\Token; use Alchemy\Phrasea\Authentication\Provider\Token\Identity; use Alchemy\Phrasea\Model\Entities\User; -use Doctrine\Common\Persistence\ObjectRepository; +use Alchemy\Phrasea\Model\Repositories\UserRepository; class SuggestionFinder { private $repository; - public function __construct(ObjectRepository $repository) + public function __construct(UserRepository $repository) { $this->repository = $repository; } diff --git a/lib/Alchemy/Phrasea/Border/Attribute/Factory.php b/lib/Alchemy/Phrasea/Border/Attribute/Factory.php index e3e684fc6f..5f9cbd288f 100644 --- a/lib/Alchemy/Phrasea/Border/Attribute/Factory.php +++ b/lib/Alchemy/Phrasea/Border/Attribute/Factory.php @@ -33,19 +33,16 @@ class Factory */ public static function getFileAttribute(Application $app, $name, $serialized) { - switch ($name) { + switch ($name) + { case AttributeInterface::NAME_METADATA: return Metadata::loadFromString($app, $serialized); - break; case AttributeInterface::NAME_STORY: return Story::loadFromString($app, $serialized); - break; case AttributeInterface::NAME_METAFIELD: return MetaField::loadFromString($app, $serialized); - break; case AttributeInterface::NAME_STATUS: return Status::loadFromString($app, $serialized); - break; } throw new \InvalidArgumentException(sprintf('Unknown attribute %s', $name)); diff --git a/lib/Alchemy/Phrasea/Border/Attribute/MetaField.php b/lib/Alchemy/Phrasea/Border/Attribute/MetaField.php index 4a27607e24..1121220f00 100644 --- a/lib/Alchemy/Phrasea/Border/Attribute/MetaField.php +++ b/lib/Alchemy/Phrasea/Border/Attribute/MetaField.php @@ -12,7 +12,6 @@ namespace Alchemy\Phrasea\Border\Attribute; use Alchemy\Phrasea\Application; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Phraseanet Border MetaField Attribute @@ -23,13 +22,11 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class MetaField implements AttributeInterface { /** - * * @var \databox_field */ protected $databox_field; /** - * * @var array */ protected $value; @@ -46,14 +43,6 @@ class MetaField implements AttributeInterface $this->value = $value; } - /** - * Destructor - */ - public function __destruct() - { - $this->metadata = $this->databox_field = null; - } - /** * {@inheritdoc} */ @@ -101,15 +90,18 @@ class MetaField implements AttributeInterface */ public static function loadFromString(Application $app, $string) { - if (!$datas = @unserialize($string)) { + $data = @unserialize($string); + + if (!is_array($data) || !isset($data['sbas_id']) || !isset($data['id']) || !isset($data['value'])) { throw new \InvalidArgumentException('Unable to load metadata from string'); } try { - return new static($app->findDataboxById($datas['sbas_id']) - ->get_meta_structure()->get_element($datas['id']), $datas['value']); - } catch (NotFoundHttpException $e) { - throw new \InvalidArgumentException('Field does not exist anymore'); + $field = $app->findDataboxById($data['sbas_id'])->get_meta_structure()->get_element($data['id']); + + return new static($field, $data['value']); + } catch (\Exception $exception) { + throw new \InvalidArgumentException('Field does not exist anymore', 0, $exception); } } } diff --git a/lib/Alchemy/Phrasea/Border/Manager.php b/lib/Alchemy/Phrasea/Border/Manager.php index d2301f4a6e..295d46db87 100644 --- a/lib/Alchemy/Phrasea/Border/Manager.php +++ b/lib/Alchemy/Phrasea/Border/Manager.php @@ -129,8 +129,6 @@ class Manager $callable($element, $visa, $code); } - $visa = null; - return $code; } diff --git a/lib/Alchemy/Phrasea/CLI.php b/lib/Alchemy/Phrasea/CLI.php index 6ea074566c..e5a10eac5e 100644 --- a/lib/Alchemy/Phrasea/CLI.php +++ b/lib/Alchemy/Phrasea/CLI.php @@ -45,8 +45,6 @@ class CLI extends Application { parent::__construct($environment); - $app = $this; - $this['session.test'] = true; $this['console'] = $this->share(function () use ($name, $version) { diff --git a/lib/Alchemy/Phrasea/Collection/Collection.php b/lib/Alchemy/Phrasea/Collection/Collection.php index adce9e1705..d9ee19910a 100644 --- a/lib/Alchemy/Phrasea/Collection/Collection.php +++ b/lib/Alchemy/Phrasea/Collection/Collection.php @@ -92,7 +92,7 @@ EOT; } /** - * @param $collectionId + * @param int $collectionId */ public function setCollectionId($collectionId) { @@ -126,7 +126,7 @@ EOT; } /** - * @return \string[] + * @return string[] */ public function getLabels() { @@ -134,7 +134,7 @@ EOT; } /** - * @param \string[] $labels + * @param string[] $labels */ public function setLabels($labels) { @@ -142,7 +142,7 @@ EOT; } /** - * @param $lang + * @param string $lang * @param bool $substitute * @return string */ @@ -154,14 +154,14 @@ EOT; if ($substitute) { return isset($this->labels[$lang]) ? $this->labels[$lang] : $this->name; - } else { - return $this->labels[$lang]; } + + return $this->labels[$lang]; } /** - * @param $lang - * @param $label + * @param string $lang + * @param string $label */ public function setLabel($lang, $label) { @@ -173,7 +173,7 @@ EOT; } /** - * @return \int[]|string|null + * @return int[]|string|null */ public function getLogo() { @@ -181,7 +181,7 @@ EOT; } /** - * @param \int[]|string $logo + * @param int[]|string $logo */ public function setLogo($logo) { diff --git a/lib/Alchemy/Phrasea/Collection/Repository/ArrayCacheCollectionRepository.php b/lib/Alchemy/Phrasea/Collection/Repository/ArrayCacheCollectionRepository.php index 3a5bc69951..29283148e0 100644 --- a/lib/Alchemy/Phrasea/Collection/Repository/ArrayCacheCollectionRepository.php +++ b/lib/Alchemy/Phrasea/Collection/Repository/ArrayCacheCollectionRepository.php @@ -13,7 +13,7 @@ class ArrayCacheCollectionRepository implements CollectionRepository private $collectionRepository; /** - * @var \collection[] + * @var \collection[]|null */ private $collectionCache = null; diff --git a/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php index 8f6c565a18..3d8d63f3d9 100644 --- a/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php +++ b/lib/Alchemy/Phrasea/Command/BuildMissingSubdefs.php @@ -18,16 +18,13 @@ use Symfony\Component\Console\Output\OutputInterface; class BuildMissingSubdefs extends Command { - /** - * Constructor - */ + private $generator; + public function __construct($name = null) { parent::__construct($name); $this->setDescription('Builds subviews that previously failed to be generated / did not exist when records were added'); - - return $this; } /** @@ -37,48 +34,61 @@ class BuildMissingSubdefs extends Command { $start = microtime(true); $progressBar = new ProgressBar($output); - $n = 0; - - /** @var SubdefGenerator $subdefGenerator */ - $subdefGenerator = $this->container['subdef.generator']; + $generatedSubdefs = 0; foreach ($this->container->getDataboxes() as $databox) { $sql = 'SELECT record_id FROM record WHERE parent_record_id = 0'; - $stmt = $databox->get_connection()->prepare($sql); - $stmt->execute(); - $rs = $stmt->fetchAll(\PDO::FETCH_ASSOC); - $stmt->closeCursor(); - $progressBar->start(count($rs)); + $result = $databox->get_connection()->executeQuery($sql)->fetchAll(\PDO::FETCH_ASSOC); + $progressBar->start(count($result)); - foreach ($rs as $row) { + foreach ($result as $row) { $record = $databox->get_record($row['record_id']); - $wanted_subdefs = $record->get_missing_subdefs(); + $generatedSubdefs += $this->generateRecordMissingSubdefs($record); - if (count($wanted_subdefs) > 0) { - $subdefGenerator->generateSubdefs($record, $wanted_subdefs); - - foreach ($wanted_subdefs as $subdef) { - $this->container['monolog']->addInfo("generate " . $subdef . " for record " . $record->get_record_id()); - $n++; - } - } - - unset($record); $progressBar->advance(); } $progressBar->finish(); } - $this->container['monolog']->addInfo($n . " subdefs done"); + $this->container['monolog']->addInfo($generatedSubdefs . " subdefs done"); $stop = microtime(true); $duration = $stop - $start; - $this->container['monolog']->addInfo(sprintf("process took %s, (%f sd/s.)", $this->getFormattedDuration($duration), round($n / $duration, 3))); + $this->container['monolog']->addInfo(sprintf("process took %s, (%f sd/s.)", $this->getFormattedDuration($duration), round($generatedSubdefs / $duration, 3))); $progressBar->finish(); - - return; } + /** + * Generate subdef generation and return number of subdef + * @param \record_adapter $record + * @return int + */ + protected function generateRecordMissingSubdefs(\record_adapter $record) + { + $wanted_subdefs = $record->get_missing_subdefs(); + + if (!empty($wanted_subdefs)) { + $this->getSubdefGenerator()->generateSubdefs($record, $wanted_subdefs); + + foreach ($wanted_subdefs as $subdef) { + $this->container['monolog']->addInfo("generate " . $subdef . " for record " . $record->getRecordId()); + } + } + + return count($wanted_subdefs); + } + + /** + * @return SubdefGenerator + */ + protected function getSubdefGenerator() + { + if (null === $this->generator) { + $this->generator = $this->container['subdef.generator']; + } + + return $this->generator; + } } diff --git a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php index 700bb719bf..92718e056b 100644 --- a/lib/Alchemy/Phrasea/Command/BuildSubdefs.php +++ b/lib/Alchemy/Phrasea/Command/BuildSubdefs.php @@ -1,9 +1,8 @@ addOption('min_record', 'min', InputOption::VALUE_OPTIONAL, 'Min record id'); $this->addOption('with-substitution', 'wsubstit', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records as well'); $this->addOption('substitution-only', 'substito', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records only'); - - return $this; } /** @@ -70,111 +63,46 @@ class BuildSubdefs extends Command return; } - $sqlCount = "SELECT COUNT(DISTINCT(r.record_id)) AS nb_records" - . " FROM record r LEFT JOIN subdef s ON (r.record_id = s.record_id AND s.name IN (?))" - . " WHERE r.type IN (?)"; - - $types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY); - $params = array($subdefsName, $recordsType); - - if (null !== $min = $input->getOption('min_record')) { - $sqlCount .= " AND (r.record_id >= ?)"; - - $params[] = (int) $min; - $types[] = \PDO::PARAM_INT; - } - - if (null !== $max = $input->getOption('max_record')) { - $sqlCount .= " AND (r.record_id <= ?)"; - - $params[] = (int) $max; - $types[] = \PDO::PARAM_INT; - } - + $min = $input->getOption('min_record'); + $max = $input->getOption('max_record'); $substitutionOnly = $input->getOption('substitution-only'); $withSubstitution = $input->getOption('with-substitution'); - if (false === $withSubstitution) { - if (true === $substitutionOnly) { - $sqlCount .= " AND (ISNULL(s.substit) OR s.substit = 1)"; - } else { - $sqlCount .= " AND (ISNULL(s.substit) OR s.substit = 0)"; - } - } elseif ($substitutionOnly) { + if (false !== $withSubstitution && false !== $substitutionOnly) { throw new InvalidArgumentException('Conflict, you can not ask for --substitution-only && --with-substitution parameters at the same time'); } - list($sqlCount, $stmtParams) = SQLParserUtils::expandListParameters($sqlCount, $params, $types); + list($sql, $params, $types) = $this->generateSQL($subdefsName, $recordsType, $min, $max, $withSubstitution, $substitutionOnly); $databox = $this->container->findDataboxById($input->getArgument('databox')); - - $output->writeln($sqlCount); - $connection = $databox->get_connection(); - $stmt = $connection->prepare($sqlCount); - $stmt->execute($stmtParams); - $row = $stmt->fetch(); - $totalRecords = $row['nb_records']; + + $sqlCount = sprintf('SELECT COUNT(*) FROM (%s)', $sql); + $output->writeln($sqlCount); + $totalRecords = (int)$connection->executeQuery($sqlCount, $params, $types)->fetchColumn(); if ($totalRecords === 0) { return; } - /** @var HelperSet $helperSet */ - $helperSet = $this->getHelperSet(); + $progress = new ProgressBar($output, $totalRecords); - /** @var ProgressBar $progress */ - $progress = $helperSet->get('progress'); - - $progress->start($output, $totalRecords); + $progress->start(); $progress->display(); - $sql = "SELECT DISTINCT(r.record_id)" - . " FROM record r LEFT JOIN subdef s ON (r.record_id = s.record_id AND s.name IN (?))" - . " WHERE r.type IN (?)"; - - $types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY); - $params = array($subdefsName, $recordsType); - - if ($min) { - $sql .= " AND (r.record_id >= ?)"; - - $params[] = (int) $min; - $types[] = \PDO::PARAM_INT; - } - if ($max) { - $sql .= " AND (r.record_id <= ?)"; - - $params[] = (int) $max; - $types[] = \PDO::PARAM_INT; - } - - if (false === $withSubstitution) { - if (true === $substitutionOnly) { - $sql .= " AND (ISNULL(s.substit) OR s.substit = 1)"; - } else { - $sql .= " AND (ISNULL(s.substit) OR s.substit = 0)"; - } - } - - list($sql, $stmtParams) = SQLParserUtils::expandListParameters($sql, $params, $types); - - $connection = $databox->get_connection(); - $stmt = $connection->prepare($sql); - $stmt->execute($stmtParams); - $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC); + $rows = $connection->executeQuery($sql, $params, $types)->fetchAll(\PDO::FETCH_ASSOC); foreach ($rows as $row) { $output->write(sprintf(' (#%s)', $row['record_id'])); - $record = new \record_adapter($this->container, $databox->get_sbas_id(), $row['record_id']); + $record = $databox->get_record($row['record_id']); - /** @var media_subdef[] $subdefs */ $subdefs = array_filter($record->get_subdefs(), function(media_subdef $subdef) use ($subdefsName) { return in_array($subdef->get_name(), $subdefsName); }); + /** @var media_subdef $subdef */ foreach ($subdefs as $subdef) { $subdef->remove_file(); if (($withSubstitution && $subdef->is_substituted()) || $substitutionOnly) { @@ -186,13 +114,49 @@ class BuildSubdefs extends Command $subdefGenerator = $this->container['subdef.generator']; $subdefGenerator->generateSubdefs($record, $subdefsName); - $stmt->closeCursor(); - $progress->advance(); } - unset($rows, $record, $stmt, $connection); - $progress->finish(); } + + /** + * @param string[] $subdefNames + * @param string[] $recordTypes + * @param null|int $min + * @param null|int $max + * @param bool $withSubstitution + * @param bool $substitutionOnly + * @return array + */ + protected function generateSQL(array $subdefNames, array $recordTypes, $min, $max, $withSubstitution, $substitutionOnly) + { + $sql = "SELECT DISTINCT(r.record_id) AS record_id" + . " FROM record r LEFT JOIN subdef s ON (r.record_id = s.record_id AND s.name IN (?))" + . " WHERE r.type IN (?)"; + + $types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY); + $params = array($subdefNames, $recordTypes); + + if (null !== $min) { + $sql .= " AND (r.record_id >= ?)"; + + $params[] = (int)$min; + $types[] = \PDO::PARAM_INT; + } + if (null !== $max) { + $sql .= " AND (r.record_id <= ?)"; + + $params[] = (int)$max; + $types[] = \PDO::PARAM_INT; + } + + if (false === $withSubstitution) { + $sql .= " AND (ISNULL(s.substit) OR s.substit = ?)"; + $params[] = $substitutionOnly ? 1 : 0; + $types[] = \PDO::PARAM_INT; + } + + return array($sql, $params, $types); + } } diff --git a/lib/Alchemy/Phrasea/Model/Repositories/AuthFailureRepository.php b/lib/Alchemy/Phrasea/Model/Repositories/AuthFailureRepository.php index 783620a8c9..90f51df3ff 100644 --- a/lib/Alchemy/Phrasea/Model/Repositories/AuthFailureRepository.php +++ b/lib/Alchemy/Phrasea/Model/Repositories/AuthFailureRepository.php @@ -1,9 +1,8 @@ getResult(); } + /** + * @param string $username + * @param string $ip + * @return AuthFailure[] + */ public function findLockedFailuresMatching($username, $ip) { $dql = 'SELECT f @@ -46,7 +49,7 @@ class AuthFailureRepository extends EntityRepository $params = [ 'username' => $username, - 'ip' => $ip, + 'ip' => $ip, ]; $query = $this->_em->createQuery($dql); diff --git a/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php b/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php index bba5c5ba3c..fb385e688c 100644 --- a/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php +++ b/tests/Alchemy/Tests/Phrasea/Authentication/Phrasea/FailureManagerTest.php @@ -4,6 +4,7 @@ namespace Alchemy\Tests\Phrasea\Authentication\Phrasea; use Alchemy\Phrasea\Authentication\Phrasea\FailureManager; use Alchemy\Phrasea\Model\Entities\AuthFailure; +use Alchemy\Phrasea\Model\Repositories\AuthFailureRepository; use Gedmo\Timestampable\TimestampableListener; use Symfony\Component\HttpFoundation\Request; @@ -18,7 +19,7 @@ class FailureManagerTest extends \PhraseanetTestCase */ public function testSaveFailure() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $recaptcha = $this->getReCaptchaMock(null); @@ -31,8 +32,8 @@ class FailureManagerTest extends \PhraseanetTestCase ->will($this->returnValue($ip)); $oldFailures = [ - $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'), - $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure') + $this->getMock(AuthFailure::class), + $this->getMock(AuthFailure::class) ]; $repo->expects($this->once()) @@ -41,12 +42,12 @@ class FailureManagerTest extends \PhraseanetTestCase $em->expects($this->exactly(count($oldFailures))) ->method('remove') - ->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\AuthFailure')); + ->with($this->isInstanceOf(AuthFailure::class)); $catchFailure = null; $em->expects($this->once()) ->method('persist') - ->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\AuthFailure')) + ->with($this->isInstanceOf(AuthFailure::class)) ->will($this->returnCallback(function ($failure) use (&$catchFailure) { $catchFailure = $failure; })); @@ -54,6 +55,8 @@ class FailureManagerTest extends \PhraseanetTestCase $manager = new FailureManager($repo, $em, $recaptcha, 9); $manager->saveFailure($username, $request); + /** @var null|AuthFailure $catchFailure */ + $this->assertInstanceOf(AuthFailure::class, $catchFailure); $this->assertEquals($ip, $catchFailure->getIp()); $this->assertEquals(true, $catchFailure->getLocked()); $this->assertEquals($username, $catchFailure->getUsername()); @@ -64,7 +67,7 @@ class FailureManagerTest extends \PhraseanetTestCase */ public function testCheckFailures() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $recaptcha = $this->getReCaptchaMock(null); $request = $this->getRequestMock(); @@ -86,7 +89,7 @@ class FailureManagerTest extends \PhraseanetTestCase */ public function testCheckFailuresLessThan9() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $recaptcha = $this->getReCaptchaMock(null); $request = $this->getRequestMock(); @@ -94,7 +97,7 @@ class FailureManagerTest extends \PhraseanetTestCase $username = 'romainneutron'; $oldFailures = $this->ArrayIze(function () { - return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'); + return $this->getMock(AuthFailure::class); }, 8); $repo->expects($this->once()) @@ -110,7 +113,7 @@ class FailureManagerTest extends \PhraseanetTestCase */ public function testCheckFailuresMoreThan9WithoutCaptcha() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $recaptcha = $this->getReCaptchaMock(false); $request = $this->getRequestMock(); @@ -118,7 +121,7 @@ class FailureManagerTest extends \PhraseanetTestCase $username = 'romainneutron'; $oldFailures = $this->ArrayIze(function () { - return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'); + return $this->getMock(AuthFailure::class); }, 10); $repo->expects($this->once()) @@ -134,7 +137,7 @@ class FailureManagerTest extends \PhraseanetTestCase */ public function testCheckFailuresMoreThan9WithCorrectCaptcha() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $request = $this->getRequestMock(); $recaptcha = $this->getReCaptchaMock(true, $request, true); @@ -142,7 +145,7 @@ class FailureManagerTest extends \PhraseanetTestCase $username = 'romainneutron'; $oldFailures = $this->ArrayIze(function () { - $failure = $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'); + $failure = $this->getMock(AuthFailure::class); $failure->expects($this->once()) ->method('setLocked') ->with($this->equalTo(false)); @@ -164,7 +167,7 @@ class FailureManagerTest extends \PhraseanetTestCase */ public function testCheckFailuresMoreThan9WithIncorrectCaptcha() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $request = $this->getRequestMock(); $recaptcha = $this->getReCaptchaMock(true, $request, false); @@ -172,7 +175,7 @@ class FailureManagerTest extends \PhraseanetTestCase $username = 'romainneutron'; $oldFailures = $this->ArrayIze(function () { - return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'); + return $this->getMock(AuthFailure::class); }, 10); $repo->expects($this->once()) @@ -185,7 +188,7 @@ class FailureManagerTest extends \PhraseanetTestCase public function testCheckFailuresTrialsIsConfigurableUnderThreshold() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $recaptcha = $this->getReCaptchaMock(null); $request = $this->getRequestMock(); @@ -193,7 +196,7 @@ class FailureManagerTest extends \PhraseanetTestCase $username = 'romainneutron'; $oldFailures = $this->ArrayIze(function () { - return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'); + return $this->getMock(AuthFailure::class); }, 2); $repo->expects($this->once()) @@ -207,10 +210,9 @@ class FailureManagerTest extends \PhraseanetTestCase public function testTrialsIsConfigurable() { $em = $this->createEntityManagerMock(); - $recaptcha = $this->getReCaptchaMock(null); - $manager = new FailureManager($this->createEntityRepositoryMock(), $em, $recaptcha, 2); + $manager = new FailureManager($this->createAuthFailureRepositoryMock(), $em, $recaptcha, 2); $this->assertEquals(2, $manager->getTrials()); } @@ -220,7 +222,7 @@ class FailureManagerTest extends \PhraseanetTestCase */ public function testCheckFailuresTrialsIsConfigurableOverThreshold() { - $repo = $this->getRepo(); + $repo = $this->createAuthFailureRepositoryMock(); $em = $this->createEntityManagerMock(); $request = $this->getRequestMock(); $recaptcha = $this->getReCaptchaMock(true, $request, false); @@ -228,7 +230,7 @@ class FailureManagerTest extends \PhraseanetTestCase $username = 'romainneutron'; $oldFailures = $this->ArrayIze(function () { - return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'); + return $this->getMock(AuthFailure::class); }, 3); $repo->expects($this->once()) @@ -311,14 +313,17 @@ class FailureManagerTest extends \PhraseanetTestCase private function getRequestMock() { - return $this->getMockBuilder('Symfony\Component\HttpFoundation\Request') + return $this->getMockBuilder(Request::class) ->disableOriginalConstructor() ->getMock(); } - private function getRepo() + /** + * @return AuthFailureRepository|\PHPUnit_Framework_MockObject_MockObject + */ + private function createAuthFailureRepositoryMock() { - return $this->getMockBuilder('Alchemy\Phrasea\Model\Repositories\AuthFailureRepository') + return $this->getMockBuilder(AuthFailureRepository::class) ->disableOriginalConstructor() ->getMock(); } diff --git a/tests/Alchemy/Tests/Phrasea/Core/Provider/AuthenticationManagerServiceProviderTest.php b/tests/Alchemy/Tests/Phrasea/Core/Provider/AuthenticationManagerServiceProviderTest.php index 765dfbbc2c..fb128260f8 100644 --- a/tests/Alchemy/Tests/Phrasea/Core/Provider/AuthenticationManagerServiceProviderTest.php +++ b/tests/Alchemy/Tests/Phrasea/Core/Provider/AuthenticationManagerServiceProviderTest.php @@ -2,11 +2,26 @@ namespace Alchemy\Tests\Phrasea\Core\Provider; +use Alchemy\Phrasea\Authentication\AccountCreator; +use Alchemy\Phrasea\Authentication\Authenticator; +use Alchemy\Phrasea\Authentication\Manager as AuthenticationManager; +use Alchemy\Phrasea\Authentication\PersistentCookie\Manager as PersistentCookieManager; +use Alchemy\Phrasea\Authentication\Phrasea\FailureHandledNativeAuthentication; +use Alchemy\Phrasea\Authentication\Phrasea\FailureManager; +use Alchemy\Phrasea\Authentication\Phrasea\NativeAuthentication; +use Alchemy\Phrasea\Authentication\Phrasea\OldPasswordEncoder; +use Alchemy\Phrasea\Authentication\Phrasea\PasswordAuthenticationInterface; +use Alchemy\Phrasea\Authentication\Phrasea\PasswordEncoder; +use Alchemy\Phrasea\Authentication\Provider\Factory; +use Alchemy\Phrasea\Authentication\ProvidersCollection; +use Alchemy\Phrasea\Authentication\SuggestionFinder; use Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider; -use Alchemy\Phrasea\Core\Provider\TokensServiceProvider; use Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider; use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider; +use Alchemy\Phrasea\Model\Entities\User; +use Alchemy\Phrasea\Model\Repositories\AuthFailureRepository; use Alchemy\Phrasea\Model\Repositories\UserRepository; +use Neutron\ReCaptcha\ReCaptcha; /** * @group functional @@ -19,59 +34,59 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase { return [ [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'authentication', - 'Alchemy\\Phrasea\\Authentication\\Authenticator', + Authenticator::class, ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'authentication.persistent-manager', - 'Alchemy\Phrasea\Authentication\PersistentCookie\Manager' + PersistentCookieManager::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'authentication.suggestion-finder', - 'Alchemy\Phrasea\Authentication\SuggestionFinder' + SuggestionFinder::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'authentication.providers.factory', - 'Alchemy\Phrasea\Authentication\Provider\Factory' + Factory::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'authentication.providers', - 'Alchemy\Phrasea\Authentication\ProvidersCollection' + ProvidersCollection::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'authentication.manager', - 'Alchemy\Phrasea\Authentication\Manager' + AuthenticationManager::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'auth.password-encoder', - 'Alchemy\Phrasea\Authentication\Phrasea\PasswordEncoder' + PasswordEncoder::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'auth.old-password-encoder', - 'Alchemy\Phrasea\Authentication\Phrasea\OldPasswordEncoder' + OldPasswordEncoder::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'auth.native.failure-manager', - 'Alchemy\Phrasea\Authentication\Phrasea\FailureManager' + FailureManager::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'auth.native', - 'Alchemy\Phrasea\Authentication\Phrasea\PasswordAuthenticationInterface' + PasswordAuthenticationInterface::class ], [ - 'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider', + AuthenticationManagerServiceProvider::class, 'authentication.providers.account-creator', - 'Alchemy\Phrasea\Authentication\AccountCreator' + AccountCreator::class ], ]; } @@ -83,9 +98,7 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase $app['conf']->set(['authentication', 'captcha', 'trials-before-display'], 42); //$app['orm.em'] = $this->createEntityManagerMock(); - $app['recaptcha'] = $this->getMockBuilder('Neutron\ReCaptcha\ReCaptcha') - ->disableOriginalConstructor() - ->getMock(); + $app['recaptcha'] = $this->createReCaptchaMock(); $manager = $app['auth.native.failure-manager']; $this->assertEquals(42, $manager->getTrials()); @@ -93,9 +106,10 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase public function testFailureAccountCreator() { - self::$DI['app']->register(new ConfigurationServiceProvider()); - self::$DI['app']['conf']->set(['authentication', 'auto-create'], ['templates' => []]); - self::$DI['app']['authentication.providers.account-creator']; + $app = $this->getApplication(); + $app->register(new ConfigurationServiceProvider()); + $app['conf']->set(['authentication', 'auto-create'], ['templates' => []]); + $app['authentication.providers.account-creator']; } public function testAuthNativeWithCaptchaEnabled() @@ -111,12 +125,12 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase $app['orm.em'] = $this->createEntityManagerMock(); $app['repo.users'] = $this->createUserRepositoryMock(); - $app['repo.auth-failures'] = $this->createEntityRepositoryMock(); - $app['recaptcha'] = $this->getMockBuilder('Neutron\ReCaptcha\ReCaptcha') + $app['repo.auth-failures'] = $this->getMockBuilder(AuthFailureRepository::class) ->disableOriginalConstructor() ->getMock(); + $app['recaptcha'] = $this->createReCaptchaMock(); - $this->assertInstanceOf('Alchemy\Phrasea\Authentication\Phrasea\FailureHandledNativeAuthentication', $app['auth.native']); + $this->assertInstanceOf(FailureHandledNativeAuthentication::class, $app['auth.native']); } public function testAuthNativeWithCaptchaDisabled() @@ -131,26 +145,25 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase $app['orm.em'] = $this->createEntityManagerMock(); $app['repo.users'] = $this->createUserRepositoryMock(); - $app['recaptcha'] = $this->getMockBuilder('Neutron\ReCaptcha\ReCaptcha') - ->disableOriginalConstructor() - ->getMock(); + $app['recaptcha'] = $this->createReCaptchaMock(); - $this->assertInstanceOf('Alchemy\Phrasea\Authentication\Phrasea\NativeAuthentication', $app['auth.native']); + $this->assertInstanceOf(NativeAuthentication::class, $app['auth.native']); } public function testAccountCreator() { - $template1 = $user = self::$DI['app']['manipulator.user']->createTemplate('template1', self::$DI['user']); - $template2 = $user = self::$DI['app']['manipulator.user']->createTemplate('template2', self::$DI['user']); + $app = $this->getApplication(); + $template1 = $user = $app['manipulator.user']->createTemplate('template1', self::$DI['user']); + $template2 = $user = $app['manipulator.user']->createTemplate('template2', self::$DI['user']); - self::$DI['app']['conf']->set(['authentication', 'auto-create'], ['templates' => [$template1->getId(), $template2->getId()]]); + $app['conf']->set(['authentication', 'auto-create'], ['templates' => [$template1->getId(), $template2->getId()]]); - $this->assertEquals([$template1->getLogin(), $template2->getLogin()], array_map(function ($u) { - return $u->getLogin(); - }, self::$DI['app']['authentication.providers.account-creator']->getTemplates())); + $this->assertEquals([$template1->getLogin(), $template2->getLogin()], array_map(function (User $user) { + return $user->getLogin(); + }, $app['authentication.providers.account-creator']->getTemplates())); - $this->removeUser(self::$DI['app'], $template1); - $this->removeUser(self::$DI['app'], $template2); + $this->removeUser($app, $template1); + $this->removeUser($app, $template2); } private function createUserRepositoryMock() @@ -159,4 +172,14 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase ->disableOriginalConstructor() ->getMock(); } + + /** + * @return ReCaptcha|\PHPUnit_Framework_MockObject_MockObject + */ + protected function createReCaptchaMock() + { + return $this->getMockBuilder(ReCaptcha::class) + ->disableOriginalConstructor() + ->getMock(); + } } diff --git a/tests/classes/PhraseanetTestCase.php b/tests/classes/PhraseanetTestCase.php index 3a57ad97f7..207cec250f 100644 --- a/tests/classes/PhraseanetTestCase.php +++ b/tests/classes/PhraseanetTestCase.php @@ -336,6 +336,11 @@ abstract class PhraseanetTestCase extends WebTestCase return $cli; } + /** + * @param null|string $path + * @param string $environment + * @return Application + */ protected function loadApp($path = null, $environment = Application::ENV_TEST) { if (null !== $path) {