diff --git a/.atoum.php b/.atoum.php new file mode 100644 index 000000000..47d94e4e4 --- /dev/null +++ b/.atoum.php @@ -0,0 +1,3 @@ +addTestsFromDirectory(__DIR__ . '/tests/units'); diff --git a/.gitignore b/.gitignore index 37bdd37d8..04e16c983 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ deps.lock !var/sessions/.gitkeep !var/SymfonyRequirements.php /htdocs/bundles/ +/bin/atoum diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index c52827be9..77746533e 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -15,4 +15,8 @@ parameters: # Github connection details github_client_id: id - github_client_secret: secret \ No newline at end of file + github_client_secret: secret + + algolia_app_id: DVB92YWTPE + algolia_backend_api_key: 78e71e5r5c2Rb353f5a03376gb9878779 + algolia_frontend_api_key: 74e71e5r5c2Rb353f5a03376gb9878777 diff --git a/app/config/services.yml b/app/config/services.yml index 7b265ea79..608b042d8 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -83,3 +83,7 @@ services: app.paybox_factory: class: AppBundle\Payment\PayboxFactory + + app.algolia_client: + class: AlgoliaSearch\Client + arguments: [%algolia_app_id%, %algolia_backend_api_key%] diff --git a/composer.json b/composer.json index f54b2659b..40fd36a24 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "sensio/distribution-bundle": "^5.0", "ccmbenchmark/ting_bundle": "^3.0", "knpuniversity/oauth2-client-bundle": "^1.4", - "twig/extensions": "^1.4" + "twig/extensions": "^1.4", + "algolia/algoliasearch-client-php": "^1.12" }, "scripts": { "post-install-cmd": [ @@ -56,5 +57,9 @@ "email": "outils@afup.org" } ], - "minimum-stability": "stable" + "minimum-stability": "stable", + "require-dev": { + "atoum/atoum": "^2.8", + "atoum/stubs": "^2.5" + } } diff --git a/composer.lock b/composer.lock index c17e8ee6c..6edadd2ea 100644 --- a/composer.lock +++ b/composer.lock @@ -4,9 +4,60 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "e1b59538140e102f529021f29cae57d0", - "content-hash": "55d0e227532619609f0ac6344c26f9f7", + "hash": "978c275125b24e670be2ba8cffadefdf", + "content-hash": "39de0f7e93ee769406042cebae3b0e49", "packages": [ + { + "name": "algolia/algoliasearch-client-php", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/algolia/algoliasearch-client-php.git", + "reference": "01dd56a09db7fe6a5609fadbd7ad69d41c131375" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/algolia/algoliasearch-client-php/zipball/01dd56a09db7fe6a5609fadbd7ad69d41c131375", + "reference": "01dd56a09db7fe6a5609fadbd7ad69d41c131375", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.0", + "satooshi/php-coveralls": "0.6.*" + }, + "type": "library", + "autoload": { + "psr-0": { + "AlgoliaSearch": "src/", + "AlgoliaSearch\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Algolia Team", + "email": "contact@algolia.com" + }, + { + "name": "Ryan T. Catlin", + "email": "ryan.catlin@gmail.com" + }, + { + "name": "Jonathan H. Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Algolia Search API Client for PHP", + "homepage": "https://github.com/algolia/algoliasearch-client-php", + "time": "2016-12-09 13:30:25" + }, { "name": "aura/sqlquery", "version": "2.7.0", @@ -1450,58 +1501,6 @@ ], "time": "2016-09-14 20:25:12" }, - { - "name": "sensio/generator-bundle", - "version": "v3.0.8", - "source": { - "type": "git", - "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git", - "reference": "3c20d16512f37d2be159eca0411b99a141b90fa4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/3c20d16512f37d2be159eca0411b99a141b90fa4", - "reference": "3c20d16512f37d2be159eca0411b99a141b90fa4", - "shasum": "" - }, - "require": { - "symfony/console": "~2.7|~3.0", - "symfony/framework-bundle": "~2.7|~3.0", - "symfony/process": "~2.7|~3.0", - "symfony/yaml": "~2.7|~3.0" - }, - "require-dev": { - "doctrine/orm": "~2.4", - "symfony/doctrine-bridge": "~2.7|~3.0", - "twig/twig": "~1.18" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Sensio\\Bundle\\GeneratorBundle\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "This bundle generates code for you", - "time": "2016-09-06 01:30:19" - }, { "name": "sensiolabs/security-checker", "version": "v3.0.2", @@ -1606,61 +1605,6 @@ ], "time": "2016-04-13 16:21:01" }, - { - "name": "symfony/phpunit-bridge", - "version": "v3.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "1f4e2059cf4ecae1053b9c3027b3fc548fd077b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/1f4e2059cf4ecae1053b9c3027b3fc548fd077b9", - "reference": "1f4e2059cf4ecae1053b9c3027b3fc548fd077b9", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" - }, - "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Bridge\\PhpUnit\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony PHPUnit Bridge", - "homepage": "https://symfony.com", - "time": "2016-08-19 06:48:39" - }, { "name": "symfony/polyfill-intl-icu", "version": "v1.2.0", @@ -2200,7 +2144,242 @@ "time": "2016-10-05 18:57:41" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "atoum/atoum", + "version": "2.8.2", + "source": { + "type": "git", + "url": "https://github.com/atoum/atoum.git", + "reference": "4d0136b21185eea5fc2ee638f77b291e6c537100" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/atoum/atoum/zipball/4d0136b21185eea5fc2ee638f77b291e6c537100", + "reference": "4d0136b21185eea5fc2ee638f77b291e6c537100", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": ">=5.3.3" + }, + "replace": { + "mageekguy/atoum": "*" + }, + "suggest": { + "atoum/stubs": "Provides IDE support (like autocompletion) for atoum", + "ext-mbstring": "Provides support for UTF-8 strings" + }, + "bin": [ + "bin/atoum" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "classmap": [ + "classes/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frédéric Hardy", + "email": "frederic.hardy@atoum.org", + "homepage": "http://blog.mageekbox.net" + }, + { + "name": "François Dussert", + "email": "francois.dussert@atoum.org" + }, + { + "name": "Gérald Croes", + "email": "gerald.croes@atoum.org" + }, + { + "name": "Julien Bianchi", + "email": "julien.bianchi@atoum.org" + }, + { + "name": "Ludovic Fleury", + "email": "ludovic.fleury@atoum.org" + } + ], + "description": "Simple modern and intuitive unit testing framework for PHP 5.3+", + "homepage": "http://www.atoum.org", + "keywords": [ + "TDD", + "atoum", + "test", + "unit testing" + ], + "time": "2016-08-12 13:45:10" + }, + { + "name": "atoum/stubs", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/atoum/stubs.git", + "reference": "45babf1aa5042a99c68fe8a17e1229d7c21407cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/atoum/stubs/zipball/45babf1aa5042a99c68fe8a17e1229d7c21407cb", + "reference": "45babf1aa5042a99c68fe8a17e1229d7c21407cb", + "shasum": "" + }, + "suggest": { + "atoum/atoum": "Include atoum in your projet dependencies" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "Julien Bianchi", + "email": "julien.bianchi@atoum.org" + }, + { + "name": "Ludovic Fleury", + "email": "ludovic.fleury@atoum.org" + } + ], + "description": "Stubs for atoum, the simple modern and intuitive unit testing framework for PHP 5.3+", + "homepage": "http://www.atoum.org", + "keywords": [ + "TDD", + "atoum", + "test", + "unit testing" + ], + "time": "2016-01-07 19:57:29" + }, + { + "name": "sensio/generator-bundle", + "version": "v3.0.8", + "source": { + "type": "git", + "url": "https://github.com/sensiolabs/SensioGeneratorBundle.git", + "reference": "3c20d16512f37d2be159eca0411b99a141b90fa4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sensiolabs/SensioGeneratorBundle/zipball/3c20d16512f37d2be159eca0411b99a141b90fa4", + "reference": "3c20d16512f37d2be159eca0411b99a141b90fa4", + "shasum": "" + }, + "require": { + "symfony/console": "~2.7|~3.0", + "symfony/framework-bundle": "~2.7|~3.0", + "symfony/process": "~2.7|~3.0", + "symfony/yaml": "~2.7|~3.0" + }, + "require-dev": { + "doctrine/orm": "~2.4", + "symfony/doctrine-bridge": "~2.7|~3.0", + "twig/twig": "~1.18" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sensio\\Bundle\\GeneratorBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "This bundle generates code for you", + "time": "2016-09-06 01:30:19" + }, + { + "name": "symfony/phpunit-bridge", + "version": "v3.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "1f4e2059cf4ecae1053b9c3027b3fc548fd077b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/1f4e2059cf4ecae1053b9c3027b3fc548fd077b9", + "reference": "1f4e2059cf4ecae1053b9c3027b3fc548fd077b9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony PHPUnit Bridge", + "homepage": "https://symfony.com", + "time": "2016-08-19 06:48:39" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/sources/AppBundle/Command/IndexTalksCommand.php b/sources/AppBundle/Command/IndexTalksCommand.php new file mode 100644 index 000000000..7a8f94616 --- /dev/null +++ b/sources/AppBundle/Command/IndexTalksCommand.php @@ -0,0 +1,30 @@ +setName('indexing:talks') + ; + } + + /** + * @see Command + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $runner = new Runner($this->getContainer()->get('app.algolia_client'), $this->getContainer()->get('ting')); + $runner->run(); + } +} diff --git a/sources/AppBundle/Event/Model/Planning.php b/sources/AppBundle/Event/Model/Planning.php new file mode 100644 index 000000000..2eb0c9c16 --- /dev/null +++ b/sources/AppBundle/Event/Model/Planning.php @@ -0,0 +1,120 @@ +id; + } + + /** + * @param int $id + * + * @return $this + */ + public function setId($id) + { + $id = (int)$id; + $this->propertyChanged('id', $this->id, $id); + $this->id = $id; + return $this; + } + + /** + * @return int + */ + public function getTalkId() + { + return $this->talkId; + } + + /** + * @param int $talkId + * + * @return $this + */ + public function setTalkId($talkId) + { + $talkId = (int)$talkId; + $this->propertyChanged('talkId', $this->talkId, $talkId); + $this->talkId = $talkId; + + return $this; + } + + /** + * @return int + */ + public function getEventId() + { + return $this->eventId; + } + + /** + * @param int $eventId + * + * @return $this + */ + public function setEventId($eventId) + { + $eventId = (int)$eventId; + $this->propertyChanged('eventId', $this->eventId, $eventId); + $this->eventId = $eventId; + + return $this; + } + + /** + * @param int $isKeynote + + * @return $this + */ + public function setIsKeynote($isKeynote) + { + $this->propertyChanged('isKeynote', $this->isKeynote, $isKeynote); + $this->isKeynote = $isKeynote; + + return $this; + } + /** + * @return bool + */ + public function getIsKeynote() + { + return $this->isKeynote; + } +} diff --git a/sources/AppBundle/Event/Model/Repository/PlanningRepository.php b/sources/AppBundle/Event/Model/Repository/PlanningRepository.php new file mode 100644 index 000000000..b85f9b0c6 --- /dev/null +++ b/sources/AppBundle/Event/Model/Repository/PlanningRepository.php @@ -0,0 +1,56 @@ +setEntity(Planning::class); + $metadata->setConnectionName('main'); + $metadata->setDatabase($options['database']); + $metadata->setTable('afup_forum_planning'); + + $metadata + ->addField([ + 'columnName' => 'id', + 'fieldName' => 'id', + 'primary' => true, + 'autoincrement' => true, + 'type' => 'int' + ]) + ->addField([ + 'columnName' => 'id_session', + 'fieldName' => 'talkId', + 'type' => 'int' + ]) + ->addField([ + 'columnName' => 'id_forum', + 'fieldName' => 'eventId', + 'type' => 'int' + ]) + ->addField([ + 'columnName' => 'keynote', + 'fieldName' => 'isKeynote', + 'type' => 'bool', + 'serializer' => Boolean::class + ]) + ; + + return $metadata; + } + +} diff --git a/sources/AppBundle/Event/Model/Repository/TalkRepository.php b/sources/AppBundle/Event/Model/Repository/TalkRepository.php index 6871cbb29..7122437ff 100644 --- a/sources/AppBundle/Event/Model/Repository/TalkRepository.php +++ b/sources/AppBundle/Event/Model/Repository/TalkRepository.php @@ -177,6 +177,11 @@ public static function initMetadata(SerializerFactoryInterface $serializerFactor 'fieldName' => 'blogPostUrl', 'type' => 'string' ]) + ->addField([ + 'columnName' => 'joindin', + 'fieldName' => 'joindinId', + 'type' => 'string' + ]) ; return $metadata; diff --git a/sources/AppBundle/Event/Model/Speaker.php b/sources/AppBundle/Event/Model/Speaker.php index 7826ca1b0..8034d24fd 100644 --- a/sources/AppBundle/Event/Model/Speaker.php +++ b/sources/AppBundle/Event/Model/Speaker.php @@ -198,6 +198,14 @@ public function setLastname($lastname) return $this; } + /** + * @return string + */ + public function getLabel() + { + return $this->getFirstname() . " " . $this->getLastname(); + } + /** * @return string */ diff --git a/sources/AppBundle/Event/Model/Talk.php b/sources/AppBundle/Event/Model/Talk.php index fe182ef3e..5087e8cf8 100644 --- a/sources/AppBundle/Event/Model/Talk.php +++ b/sources/AppBundle/Event/Model/Talk.php @@ -87,6 +87,11 @@ class Talk implements NotifyPropertyInterface */ private $blogPostUrl; + /** + * @var string|null + */ + private $joindinId; + /** * @return int */ @@ -295,6 +300,26 @@ public function setYoutubeId($youtubeId) return $this; } + /** + * @return null|string + */ + public function hasYoutubeId() + { + return null !== $this->youTubeId; + } + + /** + * @return null|string + */ + public function getYoutubeUrl() + { + if (!$this->hasYoutubeId()) { + return null; + } + + return 'https://www.youtube.com/watch?v=' . $this->getYoutubeId(); + } + /** * @return int */ @@ -316,11 +341,64 @@ public function setSlidesUrl($slidesUrl) return $this; } + /** + * @return bool + */ + public function hasSlidesUrl() + { + return null !== $this->slidesUrl; + } + + /** + * @return int + */ + public function getJoindinId() + { + return $this->joindinId; + } + + /** + * @param int $joindInId + * + * @return Talk + */ + public function setJoindinId($joindInId) + { + $this->propertyChanged('joindinId', $this->joindinId, $joindInId); + $this->joindinId = $joindInId; + + return $this; + } + + /** + * @return bool + */ + public function hasJoindinId() + { + return null !== $this->joindinId; + } + + /** + * @return null|string + */ + public function getJoindinUrl() + { + if (!$this->hasJoindinId()) { + return null; + } + + return 'https://legacy.joind.in/talk/view/' . $this->getJoindinId(); + } + /** * @return int */ public function getBlogPostUrl() { + if (0 === strlen($this->blogPostUrl)) { + return null; + } + return $this->blogPostUrl; } @@ -336,4 +414,12 @@ public function setBlogPostUrl($blogPostUrl) return $this; } + + /** + * @return bool + */ + public function hasBlogPostUrl() + { + return null !== $this->getBlogPostUrl(); + } } diff --git a/sources/AppBundle/Indexation/Talks/Runner.php b/sources/AppBundle/Indexation/Talks/Runner.php new file mode 100644 index 000000000..b97778026 --- /dev/null +++ b/sources/AppBundle/Indexation/Talks/Runner.php @@ -0,0 +1,114 @@ +algoliaClient = $algoliaClient; + $this->ting = $ting; + $this->transformer = new Transformer(); + } + + /** + * + */ + public function run() + { + $index = $this->initIndex(); + + $objects = []; + + foreach ($this->getAllPlannings() as $planning) { + + if (null === ($object = $this->prepareObject($planning))) { + continue; + } + + $objects[] = $object; + } + + $index->addObjects($objects, 'planning_id'); + } + + /** + * @return \AlgoliaSearch\Index + */ + protected function initIndex() + { + $index = $this->algoliaClient->initIndex('afup_talks'); + + $index->setSettings([ + 'attributesForFaceting' => [ + 'event.title', + 'speakers.label', + 'has_video', + 'has_slides', + ], + ]); + + return $index; + } + + /** + * @return Planning[] + */ + protected function getAllPlannings() + { + return $this->ting->get(PlanningRepository::class)->getAll(); + } + + /** + * @param Planning $planning + * + * @return array|null + */ + protected function prepareObject(Planning $planning) + { + $talk = $this->ting->get(TalkRepository::class)->get($planning->getTalkId()); + + if (!($talk instanceof Talk)) { + return null; + } + + $event = $this->ting->get(EventRepository::class)->get($planning->getEventId()); + + if (!($event instanceof Event)) { + return null; + } + + $speakers = $this->ting->get(SpeakerRepository::class)->getSpeakersByTalk($talk); + + return $this->transformer->transform($planning, $talk, $event, $speakers); + } +} diff --git a/sources/AppBundle/Indexation/Talks/Transformer.php b/sources/AppBundle/Indexation/Talks/Transformer.php new file mode 100644 index 000000000..ce0681450 --- /dev/null +++ b/sources/AppBundle/Indexation/Talks/Transformer.php @@ -0,0 +1,69 @@ +getLabel(); + } + + $item = [ + 'planning_id' => $planning->getId(), + 'talk_id' => $talk->getId(), + 'title' => $talk->getTitle(), + 'event' => [ + 'id' => $event->getId(), + 'title' => $event->getTitle(), + ], + 'speakers_label' => implode(' et ', $spakersLabels), + 'has_video' => $talk->hasYoutubeId(), + 'has_slides' => $talk->hasSlidesUrl(), + 'has_joindin' => $talk->hasJoindinId(), + 'has_blog_post' => $talk->hasBlogPostUrl(), + ]; + + if (null !== ($youtubeUrl = $talk->getYoutubeUrl())) { + $item['video_url'] = $youtubeUrl; + } + + if (null !== ($slidesUrl = $talk->getSlidesUrl())) { + $item['slides_url'] = $slidesUrl; + } + + if (null !== ($joindinUrl = $talk->getJoindinUrl())) { + $item['joindin_url'] = $joindinUrl; + } + + if (null !== ($blogPostUrl = $talk->getBlogPostUrl())) { + $item['blog_post_url'] = $blogPostUrl; + } + + foreach ($speakers as $speaker) { + $item['speakers'][] = [ + 'id' => $speaker->getId(), + 'first_name' => $speaker->getFirstname(), + 'last_name' => $speaker->getLastname(), + 'label' => $speaker->getLabel(), + ]; + } + + return $item; + } +} diff --git a/tests/units/AppBundle/Event/Model/Talk/Talk.php b/tests/units/AppBundle/Event/Model/Talk/Talk.php new file mode 100644 index 000000000..593bd22de --- /dev/null +++ b/tests/units/AppBundle/Event/Model/Talk/Talk.php @@ -0,0 +1,22 @@ +given($talk = new TestedClass()) + ->then + ->variable($talk->getYoutubeUrl()) + ->isNull() + ->when($talk->setYoutubeId("bWi9h2PmBn0")) + ->string($talk->getYoutubeUrl()) + ->isEqualTo("https://www.youtube.com/watch?v=bWi9h2PmBn0") + ; + } + +} diff --git a/tests/units/AppBundle/Indexation/Talks/Transformer.php b/tests/units/AppBundle/Indexation/Talks/Transformer.php new file mode 100644 index 000000000..050015dad --- /dev/null +++ b/tests/units/AppBundle/Indexation/Talks/Transformer.php @@ -0,0 +1,120 @@ +given( + $talk = new Talk(), + $talk + ->setId(1007) + ->setForumId(10) + ->setSubmittedOn(new \DateTime("2016-01-06 00:00:00.000000")) + ->setTitle('Utiliser PostgreSQL en 2014') + ->setAbstract('
À l\'heure où le NoSQL passe de mode doucement, il est temps de se poser les bonnes questions vis à vis des technologies de bases de données à utiliser, comment et pourquoi. PostgreSQL entre de plein droit dans la case des SGBD relationnels classiques, aussi nous commencerons par étudier ce que de ces outils apportent. Puis nous ferons le tour des fonctionnalités avancées de PostgreSQL, qui le positionnent comme un élément clé de votre architecture d\'application.
') + ->setScheduled(true) + ->setType(1) + ->setSkill(0) + ->setNeedsMentoring(false) + ->setYoutubeId('hzn0ODTMNDk') + ->setSlidesUrl('http://tapoueh.org/images/confs/PHPTour_2014_PostgreSQL.pdf') + ->setJoindinId(11214) + ->setBlogPostUrl('http://tapoueh.org/confs/2014/06/23-PHPTour-Lyon-2014') + ) + ->and( + $planning = new Planning(), + $planning + ->setId(266) + ->setTalkId(1007) + ->setEventId(10) + ->setIsKeynote(false) + ) + ->and( + $event = new Event(), + $event + ->setId(10) + ->setTitle("PHP Tour Lyon 2014") + ->setSeats(300) + ->setDateStart(new \DateTime("2014-06-24")) + ->setDateEnd(new \DateTime('2014-06-25')) + ->setDateEndCallForProjects(new \DateTime('2013-12-31')) + ->setDateEndCallForPapers(new \DateTime("2014-02-28")) + ->setDateEndPreSales(new \DateTime('2014-02-15')) + ->setDateEndSales(new \DateTime('2014-06-22')) + ->setPath('phptourlyon2014') + ) + ->and( + $speaker = new Speaker(), + $speaker + ->setId(800) + ->setEventId(10) + ->setUser(0) + ->setCivility('M.') + ->setFirstname('Dimitri') + ->setLastname('Fontaine') + ->setEmail('example@example.fr') + ->setCompany('2nbQuadrant') + ->setBiography('Dimitri Fontaine travaille sur PostgreSQL, à la fois en tant que Contributeur Majeur du projet au sein d\'une communauté vibrante et en tant qu\'expert PostgreSQL pour 2ndQuadrant.') + ->setTwitter('tapoueh') + ) + ->and($speakers = new \ArrayObject([$speaker])) + ->when($transformer = new TestedClass()) + ->then + ->array($transformer->transform($planning, $talk, $event, $speakers)) + ->isEqualTo([ + 'planning_id' => "266", + 'talk_id' => 1007, + 'title' => "Utiliser PostgreSQL en 2014", + 'event' => [ + 'id' => 10, + 'title' => 'PHP Tour Lyon 2014' + ], + 'speakers_label' => 'Dimitri Fontaine', + 'speakers' => [ + [ + 'id' => 800, + 'first_name' => 'Dimitri', + 'last_name' => 'Fontaine', + 'label' => 'Dimitri Fontaine', + ] + ], + 'has_video' => true, + 'video_url' => 'https://www.youtube.com/watch?v=hzn0ODTMNDk', + 'has_slides' => true, + 'slides_url' => 'http://tapoueh.org/images/confs/PHPTour_2014_PostgreSQL.pdf', + 'has_joindin' => true, + 'joindin_url' => 'https://legacy.joind.in/talk/view/11214', + 'has_blog_post' => true, + 'blog_post_url' => 'http://tapoueh.org/confs/2014/06/23-PHPTour-Lyon-2014', + ]) + ; + } + + public function testTransformEmpty() + { + $this + ->given($talk = new Talk()) + ->and($planning = new Planning()) + ->and($event = new Event()) + ->and($speakers = new \ArrayObject([new Speaker()])) + ->when($transformer = new TestedClass()) + ->then + ->array($object = $transformer->transform($planning, $talk, $event, $speakers)) + ->notHasKey('slides_url') + ->notHasKey('joindin_url') + ->notHasKey('blog_post_url') + ->boolean($object['has_slides'])->isFalse + ->boolean($object['has_joindin'])->isFalse + ->boolean($object['has_blog_post'])->isFalse + ; + } +}