From 01d25e4c49591361f3af06fd19c2ff9b319f224f Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Fri, 22 Jan 2021 11:29:38 +0100 Subject: [PATCH 1/3] Allow creation of content elements Content elements could not be created, since they needed campaigns. In order to retrieve campaigns, the API needs to be created. The API needs settings from current site, which is not available in that context. Therefore the factory is extended to also fetch site and their settings based on page uid. The page uid is available in the context. Since we now interact with guzzle, we add the dependency. Wouldn't be necessary if SDK would have PSR compatible type hints. Also tests were added for code, to keep code coverage. Fixes: #5 --- Classes/CampaignsFactory.php | 55 +++++++++++++ Classes/SettingsFactory.php | 25 ++++++ Classes/TcaEnhancer.php | 19 ++++- Configuration/Services.yaml | 3 + Tests/Unit/CampaignsFactoryTest.php | 75 ++++++++++++++++++ Tests/Unit/SettingsFactoryTest.php | 66 ++++++++++++++-- Tests/Unit/TcaEnhancerTest.php | 118 ++++++++++++++++++++++++++++ composer.json | 3 +- 8 files changed, 354 insertions(+), 10 deletions(-) create mode 100644 Classes/CampaignsFactory.php create mode 100644 Tests/Unit/CampaignsFactoryTest.php create mode 100644 Tests/Unit/TcaEnhancerTest.php diff --git a/Classes/CampaignsFactory.php b/Classes/CampaignsFactory.php new file mode 100644 index 0000000..86d3726 --- /dev/null +++ b/Classes/CampaignsFactory.php @@ -0,0 +1,55 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use GuzzleHttp\Client; +use SkillDisplay\PHPToolKit\Api\Campaigns; +use SkillDisplay\Typo3Extension\SettingsFactory; + +class CampaignsFactory +{ + /** + * @var SettingsFactory + */ + private $settingsFactory; + + /** + * @var Client + */ + private $client; + + public function __construct( + SettingsFactory $settingsFactory, + Client $client + ) { + $this->settingsFactory = $settingsFactory; + $this->client = $client; + } + + public function createFromPageUid(int $pageUid): Campaigns + { + return new Campaigns( + $this->settingsFactory->createFromPageUid($pageUid), + $this->client + ); + } +} diff --git a/Classes/SettingsFactory.php b/Classes/SettingsFactory.php index 2faebfa..3bd487e 100644 --- a/Classes/SettingsFactory.php +++ b/Classes/SettingsFactory.php @@ -25,9 +25,22 @@ namespace SkillDisplay\Typo3Extension; use SkillDisplay\PHPToolKit\Configuration\Settings; use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\Site\Entity\Site; +use TYPO3\CMS\Core\Site\SiteFinder; class SettingsFactory { + /** + * @var SiteFinder + */ + private $siteFinder; + + public function __construct( + SiteFinder $siteFinder + ) { + $this->siteFinder = $siteFinder; + } + public function createFromCurrentSiteConfiguration(): Settings { $site = $this->getRequest()->getAttribute('site'); @@ -35,6 +48,18 @@ class SettingsFactory throw new \Exception('Could not determine current site.', 1599721652); } + return $this->createFromSite($site); + } + + public function createFromPageUid(int $pageUid): Settings + { + $site = $this->siteFinder->getSiteByPageId($pageUid); + + return $this->createFromSite($site); + } + + private function createFromSite(Site $site): Settings + { $config = $site->getConfiguration(); return new Settings( diff --git a/Classes/TcaEnhancer.php b/Classes/TcaEnhancer.php index 7d3bc4e..6ff554c 100644 --- a/Classes/TcaEnhancer.php +++ b/Classes/TcaEnhancer.php @@ -4,19 +4,30 @@ declare(strict_types=1); namespace SkillDisplay\Typo3Extension; -use SkillDisplay\PHPToolKit\Api\Campaigns; use SkillDisplay\PHPToolKit\Entity\Campaign; -use TYPO3\CMS\Core\Utility\GeneralUtility; class TcaEnhancer { - public function getCampaignsForTCA(array $params): void + /** + * @var CampaignsFactory + */ + private $campaignsFactory; + + public function __construct( + CampaignsFactory $campaignsFactory + ) { + $this->campaignsFactory = $campaignsFactory; + } + + public function getCampaignsForTCA(array &$params): void { $params['items'] = [ ['', 0], ]; - $campaigns = GeneralUtility::makeInstance(Campaigns::class)->getForUser(); + $campaigns = $this->campaignsFactory + ->createFromPageUid($params['row']['pid']) + ->getForUser(); /** @var Campaign $campaign */ foreach ($campaigns as $campaign) { $params['items'][] = [ diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index ec5baba..fda843a 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -39,3 +39,6 @@ services: SkillDisplay\Typo3Extension\Backend\Preview: public: true + + SkillDisplay\Typo3Extension\TcaEnhancer: + public: true diff --git a/Tests/Unit/CampaignsFactoryTest.php b/Tests/Unit/CampaignsFactoryTest.php new file mode 100644 index 0000000..f166ad4 --- /dev/null +++ b/Tests/Unit/CampaignsFactoryTest.php @@ -0,0 +1,75 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use GuzzleHttp\Client; +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; +use SkillDisplay\PHPToolKit\Api\Campaigns; +use SkillDisplay\PHPToolKit\Configuration\Settings; +use SkillDisplay\Typo3Extension\CampaignsFactory; +use SkillDisplay\Typo3Extension\SettingsFactory; + +/** + * @covers SkillDisplay\Typo3Extension\CampaignsFactory + */ +class CampaignsFactoryTest extends TestCase +{ + use ProphecyTrait; + + /** + * @test + */ + public function instanceCanBeCreated(): void + { + $settingsFactory = $this->prophesize(SettingsFactory::class); + $client = $this->prophesize(Client::class); + + $subject = new CampaignsFactory( + $settingsFactory->reveal(), + $client->reveal() + ); + + self::assertInstanceOf(CampaignsFactory::class, $subject); + } + + /** + * @test + */ + public function returnsCampaignsFromPageUid(): void + { + $settingsFactory = $this->prophesize(SettingsFactory::class); + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + + $settingsFactory->createFromPageUid(10)->willReturn($settings->reveal()); + + $subject = new CampaignsFactory( + $settingsFactory->reveal(), + $client->reveal() + ); + + $result = $subject->createFromPageUid(10); + + self::assertInstanceOf(Campaigns::class, $result); + } +} diff --git a/Tests/Unit/SettingsFactoryTest.php b/Tests/Unit/SettingsFactoryTest.php index ecc6a84..a9955e2 100644 --- a/Tests/Unit/SettingsFactoryTest.php +++ b/Tests/Unit/SettingsFactoryTest.php @@ -28,6 +28,7 @@ use SkillDisplay\PHPToolKit\Configuration\Settings; use SkillDisplay\Typo3Extension\SettingsFactory; use TYPO3\CMS\Core\Http\ServerRequest; use TYPO3\CMS\Core\Site\Entity\Site; +use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\TestingFramework\Core\Unit\UnitTestCase as TestCase; /** @@ -42,15 +43,18 @@ class SettingsFactoryTest extends TestCase */ public function instanceCanBeCreated(): void { - $subject = new SettingsFactory(); + $siteFinder = $this->prophesize(SiteFinder::class); + $subject = new SettingsFactory($siteFinder->reveal()); static::assertInstanceOf(SettingsFactory::class, $subject); } /** * @test */ - public function returnsDefaultSettingsIfNothingIsConfigured(): void + public function returnsDefaultSettingsIfNothingIsConfiguredInCurrentSite(): void { + $siteFinder = $this->prophesize(SiteFinder::class); + $site = $this->prophesize(Site::class); $site->getConfiguration()->willReturn([]); @@ -58,7 +62,7 @@ class SettingsFactoryTest extends TestCase $request->getAttribute('site')->willReturn($site->reveal()); $GLOBALS['TYPO3_REQUEST'] = $request->reveal(); - $subject = new SettingsFactory(); + $subject = new SettingsFactory($siteFinder->reveal()); $settings = $subject->createFromCurrentSiteConfiguration(); static::assertInstanceOf(Settings::class, $settings); @@ -74,6 +78,8 @@ class SettingsFactoryTest extends TestCase */ public function returnsSettingsFromCurrentSite(): void { + $siteFinder = $this->prophesize(SiteFinder::class); + $site = $this->prophesize(Site::class); $site->getConfiguration()->willReturn([ 'skilldisplay_api_key' => '---YOUR-API-KEY---', @@ -85,7 +91,7 @@ class SettingsFactoryTest extends TestCase $request->getAttribute('site')->willReturn($site->reveal()); $GLOBALS['TYPO3_REQUEST'] = $request->reveal(); - $subject = new SettingsFactory(); + $subject = new SettingsFactory($siteFinder->reveal()); $settings = $subject->createFromCurrentSiteConfiguration(); static::assertInstanceOf(Settings::class, $settings); @@ -101,14 +107,64 @@ class SettingsFactoryTest extends TestCase */ public function throwsExceptionIfCurrentSiteCanNotBeFetched(): void { + $siteFinder = $this->prophesize(SiteFinder::class); + $request = $this->prophesize(ServerRequest::class); $request->getAttribute('site')->willReturn(null); $GLOBALS['TYPO3_REQUEST'] = $request->reveal(); - $subject = new SettingsFactory(); + $subject = new SettingsFactory($siteFinder->reveal()); $this->expectExceptionMessage('Could not determine current site.'); $this->expectExceptionCode(1599721652); $subject->createFromCurrentSiteConfiguration(); } + + /** + * @test + */ + public function returnsDefaultSettingsIfNothingIsConfiguredForPageUidBasesSite(): void + { + $site = $this->prophesize(Site::class); + $site->getConfiguration()->willReturn([]); + + $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder->getSiteByPageId(10)->willReturn($site->reveal()); + + $subject = new SettingsFactory($siteFinder->reveal()); + + $settings = $subject->createFromPageUid(10); + static::assertInstanceOf(Settings::class, $settings); + static::assertSame(0, $settings->getVerifierID()); + static::assertSame('', $settings->getUserSecret()); + static::assertSame('', $settings->getApiKey()); + static::assertSame('https://www.skilldisplay.eu', $settings->getAPIUrl()); + static::assertSame('https://my.skilldisplay.eu', $settings->getMySkillDisplayUrl()); + } + + /** + * @test + */ + public function returnsSettingsFromPageUidBasedSite(): void + { + $site = $this->prophesize(Site::class); + $site->getConfiguration()->willReturn([ + 'skilldisplay_api_key' => '---YOUR-API-KEY---', + 'skilldisplay_verifier_id' => 10, + 'skilldisplay_user_secret' => '---USER-SECRET---', + ]); + + $siteFinder = $this->prophesize(SiteFinder::class); + $siteFinder->getSiteByPageId(10)->willReturn($site->reveal()); + + $subject = new SettingsFactory($siteFinder->reveal()); + + $settings = $subject->createFromPageUid(10); + static::assertInstanceOf(Settings::class, $settings); + static::assertSame(10, $settings->getVerifierID()); + static::assertSame('---USER-SECRET---', $settings->getUserSecret()); + static::assertSame('---YOUR-API-KEY---', $settings->getApiKey()); + static::assertSame('https://www.skilldisplay.eu', $settings->getAPIUrl()); + static::assertSame('https://my.skilldisplay.eu', $settings->getMySkillDisplayUrl()); + } } diff --git a/Tests/Unit/TcaEnhancerTest.php b/Tests/Unit/TcaEnhancerTest.php new file mode 100644 index 0000000..f42941f --- /dev/null +++ b/Tests/Unit/TcaEnhancerTest.php @@ -0,0 +1,118 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; +use SkillDisplay\PHPToolKit\Api\Campaigns; +use SkillDisplay\PHPToolKit\Entity\Campaign; +use SkillDisplay\Typo3Extension\CampaignsFactory; +use SkillDisplay\Typo3Extension\TcaEnhancer; + +/** + * @covers SkillDisplay\Typo3Extension\TcaEnhancer + */ +class TcaEnhancerTest extends TestCase +{ + use ProphecyTrait; + + /** + * @test + */ + public function instanceCanBeCreated(): void + { + $campaignsFactory = $this->prophesize(CampaignsFactory::class); + $subject = new TcaEnhancer( + $campaignsFactory->reveal() + ); + + self::assertInstanceOf(TcaEnhancer::class, $subject); + } + + /** + * @test + */ + public function addsDefaultItemOnlyWhenNoCampaignsAreAvailable(): void + { + $parameters = [ + 'row' => [ + 'pid' => 10, + ], + ]; + + $campaigns = $this->prophesize(Campaigns::class); + $campaigns->getForUser()->willReturn([]); + + $campaignsFactory = $this->prophesize(CampaignsFactory::class); + $campaignsFactory->createFromPageUid(10)->willReturn($campaigns->reveal()); + + $subject = new TcaEnhancer( + $campaignsFactory->reveal() + ); + $subject->getCampaignsForTCA($parameters); + + self::assertArrayHasKey('items', $parameters); + self::assertSame([ + ['', 0], + ], $parameters['items']); + } + + /** + * @test + */ + public function addsFetchedCampaignsBesideDefault(): void + { + $parameters = [ + 'row' => [ + 'pid' => 10, + ], + ]; + + $campaign1 = $this->prophesize(Campaign::class); + $campaign1->getTitle()->willReturn('Campaign Title 1'); + $campaign1->getId()->willReturn(10); + $campaign2 = $this->prophesize(Campaign::class); + $campaign2->getTitle()->willReturn('Campaign Title 2'); + $campaign2->getId()->willReturn(20); + + $campaigns = $this->prophesize(Campaigns::class); + $campaigns->getForUser()->willReturn([ + $campaign1->reveal(), + $campaign2->reveal(), + ]); + + $campaignsFactory = $this->prophesize(CampaignsFactory::class); + $campaignsFactory->createFromPageUid(10)->willReturn($campaigns->reveal()); + + $subject = new TcaEnhancer( + $campaignsFactory->reveal() + ); + $subject->getCampaignsForTCA($parameters); + + self::assertArrayHasKey('items', $parameters); + self::assertSame([ + ['', 0], + ['Campaign Title 1', 10], + ['Campaign Title 2', 20], + ], $parameters['items']); + } +} diff --git a/composer.json b/composer.json index a421078..c760f6b 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,8 @@ "skilldisplay/phptoolkit": "^1.2", "typo3/cms-backend": "^10.4", "typo3/cms-frontend": "^10.4", - "typo3fluid/fluid": "^2.6" + "typo3fluid/fluid": "^2.6", + "guzzlehttp/guzzle": "^6.5" }, "require-dev": { "squizlabs/php_codesniffer": "^3.5", From 0adaafa182a515bb7289ffc0819fc7979045c403 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Fri, 22 Jan 2021 11:33:38 +0100 Subject: [PATCH 2/3] Add missing translation to new field The new field was introduced without any label. That label is added, together with description and exclude. This keeps consistency and explanation to editors. --- Configuration/TCA/Overrides/tt_content.php | 2 ++ Resources/Private/Language/locallang_tca.xlf | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php index 5911056..b2d0716 100644 --- a/Configuration/TCA/Overrides/tt_content.php +++ b/Configuration/TCA/Overrides/tt_content.php @@ -33,7 +33,9 @@ ], ], 'skilldisplay_campaign' => [ + 'exclude' => 1, 'label' => $languagePath . 'skilldisplay_campaign', + 'description' => $languagePath . 'skilldisplay_campaign.description', 'config' => [ 'type' => 'select', 'renderType' => 'selectSingle', diff --git a/Resources/Private/Language/locallang_tca.xlf b/Resources/Private/Language/locallang_tca.xlf index 3a541c9..943f16b 100644 --- a/Resources/Private/Language/locallang_tca.xlf +++ b/Resources/Private/Language/locallang_tca.xlf @@ -17,6 +17,12 @@ UID of SkillSet + + Campaign + + + Fetched from API. + From 1e3646e1057ef7dfdbcf21f20d169c9a93971578 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Sat, 23 Jan 2021 15:53:56 +0100 Subject: [PATCH 3/3] Follow new strict_types enforecement --- Classes/CampaignsFactory.php | 2 ++ Tests/Unit/CampaignsFactoryTest.php | 2 ++ Tests/Unit/TcaEnhancerTest.php | 2 ++ 3 files changed, 6 insertions(+) diff --git a/Classes/CampaignsFactory.php b/Classes/CampaignsFactory.php index 86d3726..1d616c2 100644 --- a/Classes/CampaignsFactory.php +++ b/Classes/CampaignsFactory.php @@ -1,5 +1,7 @@