diff --git a/config/services/ci/services.yml b/config/services/ci/services.yml index 4c7f06c5f9..6776d87831 100644 --- a/config/services/ci/services.yml +++ b/config/services/ci/services.yml @@ -7,6 +7,7 @@ parameters: engineblock.functional_testing.attribute_aggregation_data_store.file: "/tmp/eb-fixtures/attribute_aggregation.json" engineblock.functional_testing.stepup_gateway_mock_data_store.file: "/tmp/eb-fixtures/stepup_gateway_mock.json" engineblock.functional_testing.translator_mock_data_store.file: "/tmp/eb-fixtures/translator_mock.json" + engineblock.functional_testing.translator_mock_data_store.locale_file: "/tmp/eb-fixtures/translator_mock_%s.json" engineblock.functional_testing.sbs_client_state_manager_data_store.file: "/tmp/eb-fixtures/sbs_client_state_manager.json" engineblock.functional_testing.sbs_controller_data_store.file: "/tmp/eb-fixtures/sbs_server_state.json" @@ -111,6 +112,7 @@ services: arguments: - '@translator' - '@engineblock.function_testing.data_store.translator_mock' + - '%engineblock.functional_testing.translator_mock_data_store.locale_file%' # test stand ins OpenConext\EngineBlockFunctionalTestingBundle\Validator\SsoRequestValidator: @@ -122,6 +124,16 @@ services: OpenConext\EngineBlockBundle\Configuration\ErrorFeedbackConfiguration: arguments: - "@engineblock.functional_testing.mock.translator" + OpenConext\EngineBlock\Metadata\Factory\ValueObject\EngineBlockConfiguration: + public: false + arguments: + - '@engineblock.functional_testing.mock.translator' + - '%email_request_access_address%' + - '%view_default_header%' + - '%hostname%' + - '%view_default_logo%' + - '%view_default_logo_width%' + - '%view_default_logo_height%' OpenConext\EngineBlock\Metadata\Factory\Factory\ServiceProviderFactory: arguments: - '@engineblock.compat.metadata.definitions' diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/IdentityProviderEntity.php b/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/IdentityProviderEntity.php index 01fa458ac8..c1acb6f9c4 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/IdentityProviderEntity.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/IdentityProviderEntity.php @@ -126,10 +126,10 @@ public function hasCompleteOrganizationData(string $locale): bool } /** - * @param $locale + * @param string $locale * @return Organization */ - public function getOrganization($locale): ?Organization + public function getOrganization(string $locale): ?Organization { switch (true) { case ($locale == 'nl'): diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/ServiceProviderEntity.php b/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/ServiceProviderEntity.php index 905d0ebc72..f6def40041 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/ServiceProviderEntity.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/Adapter/ServiceProviderEntity.php @@ -128,10 +128,10 @@ public function hasCompleteOrganizationData(string $locale): bool } /** - * @param $locale + * @param string $locale * @return Organization */ - public function getOrganization($locale): ?Organization + public function getOrganization(string $locale): ?Organization { switch (true) { case ($locale == 'nl'): diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractIdentityProvider.php b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractIdentityProvider.php index d206e91588..ab9cde470e 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractIdentityProvider.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractIdentityProvider.php @@ -115,10 +115,10 @@ public function hasCompleteOrganizationData(string $locale): bool } /** - * @param $locale + * @param string $locale * @return Organization|null */ - public function getOrganization($locale): ?Organization + public function getOrganization(string $locale): ?Organization { return $this->entity->getOrganization($locale); } diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractServiceProvider.php b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractServiceProvider.php index 5cf6e1d26a..ae9d5ef911 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractServiceProvider.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/AbstractServiceProvider.php @@ -107,10 +107,10 @@ public function hasCompleteOrganizationData(string $locale): bool } /** - * @param $locale + * @param string $locale * @return Organization|null */ - public function getOrganization($locale): ?Organization + public function getOrganization(string $locale): ?Organization { return $this->entity->getOrganization($locale); } diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockIdentityProviderInformation.php b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockIdentityProviderInformation.php index d7d7e53b56..e315b00c08 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockIdentityProviderInformation.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockIdentityProviderInformation.php @@ -60,9 +60,9 @@ public function getLogo(): ?Logo return $this->engineBlockConfiguration->getLogo(); } - public function getOrganization($locale): ?Organization + public function getOrganization(string $locale): ?Organization { - return $this->engineBlockConfiguration->getOrganization(); + return $this->engineBlockConfiguration->getOrganization($locale); } /** diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockServiceProviderInformation.php b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockServiceProviderInformation.php index e5d15ccd3b..d969ac5711 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockServiceProviderInformation.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineBlockServiceProviderInformation.php @@ -60,9 +60,9 @@ public function getLogo(): ?Logo return $this->engineBlockConfiguration->getLogo(); } - public function getOrganization($locale): ?Organization + public function getOrganization(string $locale): ?Organization { - return $this->engineBlockConfiguration->getOrganization(); + return $this->engineBlockConfiguration->getOrganization($locale); } /** diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/IdentityProviderEntityInterface.php b/src/OpenConext/EngineBlock/Metadata/Factory/IdentityProviderEntityInterface.php index c0dcf12d9d..ec4865748e 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/IdentityProviderEntityInterface.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/IdentityProviderEntityInterface.php @@ -70,10 +70,10 @@ public function getLogo(): ?Logo; public function hasCompleteOrganizationData(string $locale): bool; /** - * @param $locale + * @param string $locale * @return Organization|null */ - public function getOrganization($locale): ?Organization; + public function getOrganization(string $locale): ?Organization; /** * @param $locale diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/ServiceProviderEntityInterface.php b/src/OpenConext/EngineBlock/Metadata/Factory/ServiceProviderEntityInterface.php index 271390bac0..925062a212 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/ServiceProviderEntityInterface.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/ServiceProviderEntityInterface.php @@ -63,10 +63,10 @@ public function getLogo(): ?Logo; public function hasCompleteOrganizationData(string $locale): bool; /** - * @param $locale + * @param string $locale * @return Organization|null */ - public function getOrganization($locale): ?Organization; + public function getOrganization(string $locale): ?Organization; /** * @param $locale diff --git a/src/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfiguration.php b/src/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfiguration.php index d0b17fa323..5e195adfea 100644 --- a/src/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfiguration.php +++ b/src/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfiguration.php @@ -40,20 +40,13 @@ class EngineBlockConfiguration */ private $engineHostName; - /** - * @var string - */ - private $organizationName; + private string $organizationNameKey; - /** - * @var string - */ - private $organizationDisplayName; + private string $organizationDisplayNameKey; - /** - * @var string - */ - private $organizationUrl; + private string $organizationUrlKey; + + private TranslatorInterface $translator; /** * @var Logo @@ -84,11 +77,12 @@ public function __construct( int $logoWidth, int $logoHeight ) { + $this->translator = $translator; $this->suiteName = $translator->trans('suite_name'); $this->engineHostName = $engineHostName; - $this->organizationName = $translator->trans('metadata_organization_name'); - $this->organizationDisplayName = $translator->trans('metadata_organization_displayname'); - $this->organizationUrl = $translator->trans('metadata_organization_url'); + $this->organizationNameKey = 'metadata_organization_name'; + $this->organizationDisplayNameKey = 'metadata_organization_displayname'; + $this->organizationUrlKey = 'metadata_organization_url'; $this->supportMail = $supportMail; $this->description = $description; @@ -101,9 +95,12 @@ public function __construct( $this->logo->height = $logoHeight; // Create the contact person data for the EB SP entity - $support = ContactPerson::from('support', $this->organizationName, 'Support', $this->supportMail); - $technical = ContactPerson::from('technical', $this->organizationName, 'Support', $this->supportMail); - $administrative = ContactPerson::from('administrative', $this->organizationName, 'Support', $this->supportMail); + // ContactPerson elements have no locale support, + // so resolve the translation once at construction time using the default locale. + $organizationName = $translator->trans($this->organizationNameKey, ['%suiteName%' => $this->suiteName]); + $support = ContactPerson::from('support', $organizationName, 'Support', $this->supportMail); + $technical = ContactPerson::from('technical', $organizationName, 'Support', $this->supportMail); + $administrative = ContactPerson::from('administrative', $organizationName, 'Support', $this->supportMail); $this->contactPersons = [$support, $technical, $administrative]; } @@ -118,9 +115,16 @@ public function getHostname(): string return $this->engineHostName; } - public function getOrganization() : Organization + public function getOrganization(?string $locale = null) : Organization { - return new Organization($this->organizationName, $this->organizationDisplayName, $this->organizationUrl); + $parameters = [ + '%suiteName%' => $this->translator->trans('suite_name', [], null, $locale), + '%supportUrl%' => $this->translator->trans('openconext_support_url', [], null, $locale), + ]; + $organizationName = $this->translator->trans($this->organizationNameKey, $parameters, null, $locale); + $organizationDisplayName = $this->translator->trans($this->organizationDisplayNameKey, $parameters, null, $locale); + $organizationUrl = $this->translator->trans($this->organizationUrlKey, $parameters, null, $locale); + return new Organization($organizationName, $organizationDisplayName, $organizationUrl); } public function getLogo(): Logo diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/MinkContext.php b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/MinkContext.php index 49c536378c..0a8f27aa28 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/MinkContext.php +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/MinkContext.php @@ -66,6 +66,7 @@ public function theResponseShouldMatchXpath($xpath) $xpathObj = new DOMXPath($document); $xpathObj->registerNamespace('ds', XMLSecurityDSig::XMLDSIGNS); + $xpathObj->registerNamespace('md', 'urn:oasis:names:tc:SAML:2.0:metadata'); $xpathObj->registerNamespace('mdui', Common::NS); $xpathObj->registerNamespace('shibmd', Scope::NS); $nodeList = $xpathObj->query($xpath); @@ -201,6 +202,7 @@ public function theResponseShouldNotMatchXpath($xpath) $xpathObj = new DOMXPath($document); $xpathObj->registerNamespace('ds', XMLSecurityDSig::XMLDSIGNS); + $xpathObj->registerNamespace('md', 'urn:oasis:names:tc:SAML:2.0:metadata'); $xpathObj->registerNamespace('mdui', Common::NS); $nodeList = $xpathObj->query($xpath); diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/TranslationContext.php b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/TranslationContext.php index a57bb55d9d..73e855a36f 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/TranslationContext.php +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Context/TranslationContext.php @@ -57,4 +57,14 @@ public function iHaveConfiguredTheFollowingTranslations(TableNode $translations) $this->mockTranslator->setTranslation($translation['Key'], $translation['Value']); } } + + /** + * @Then /^I have configured the following translations for locale "([^"]*)":$/ + */ + public function iHaveConfiguredTheFollowingTranslationsForLocale(string $locale, TableNode $translations) + { + foreach ($translations->getHash() as $translation) { + $this->mockTranslator->setTranslation($translation['Key'], $translation['Value'], $locale); + } + } } diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Metadata.feature b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Metadata.feature index 2213580389..f2f2d3e961 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Metadata.feature +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Metadata.feature @@ -38,6 +38,26 @@ Feature: # Verify the used signing key is EB key And the response should match xpath '//ds:Signature//ds:X509Certificate[starts-with(.,"MIIDuDCCAqCgAwIBAgIJAPdqJ9JQKN6vMA0GCSqGSIb3DQEBBQUAMEYxDzANBgNVBAMT")]' + Scenario: The IdP metadata organization fields are translated per locale without unresolved placeholders + Given I have configured the following translations: + | Key | Value | + | suite_name | OpenConext-EN | + | openconext_support_url | https://openconext.org | + And I have configured the following translations for locale "nl": + | Key | Value | + | suite_name | OpenConext-NL | + | openconext_support_url | https://openconext.org/nl | + When I go to Engineblock URL "/authentication/idp/metadata" + Then the response should match xpath '//md:OrganizationName[@xml:lang="en" and text()="OpenConext-EN"]' + And the response should match xpath '//md:OrganizationName[@xml:lang="nl" and text()="OpenConext-NL"]' + And the response should not match xpath '//md:OrganizationName[contains(text(), "%suiteName%")]' + And the response should match xpath '//md:OrganizationDisplayName[@xml:lang="en" and text()="OpenConext-EN"]' + And the response should match xpath '//md:OrganizationDisplayName[@xml:lang="nl" and text()="OpenConext-NL"]' + And the response should not match xpath '//md:OrganizationDisplayName[contains(text(), "%suiteName%")]' + And the response should match xpath '//md:OrganizationURL[@xml:lang="en" and text()="https://openconext.org"]' + And the response should match xpath '//md:OrganizationURL[@xml:lang="nl" and text()="https://openconext.org/nl"]' + And the response should not match xpath '//md:OrganizationURL[contains(text(), "%supportUrl%")]' + Scenario: A user can request the EngineBlock stepup metadata When I go to Engineblock URL "/authentication/stepup/metadata" # Verify the entity id is correctly set in the metadata diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Mock/MockTranslator.php b/src/OpenConext/EngineBlockFunctionalTestingBundle/Mock/MockTranslator.php index d209de812a..b958dd5e76 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Mock/MockTranslator.php +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Mock/MockTranslator.php @@ -19,6 +19,7 @@ namespace OpenConext\EngineBlockFunctionalTestingBundle\Mock; use OpenConext\EngineBlockFunctionalTestingBundle\Fixtures\DataStore\AbstractDataStore; +use OpenConext\EngineBlockFunctionalTestingBundle\Fixtures\DataStore\JsonDataStore; use Symfony\Component\Translation\DataCollectorTranslator; use Symfony\Contracts\Translation\TranslatorInterface; @@ -28,39 +29,67 @@ final class MockTranslator implements TranslatorInterface * @var DataCollectorTranslator */ private $translator; + /** * @var AbstractDataStore */ private $dataStore; + /** - * @var array + * @var string|null Path template with %s placeholder for locale, e.g. "/tmp/eb-fixtures/translator_mock_%s.json" */ - private $translations; + private $localeDataStoreTemplate; - public function __construct(DataCollectorTranslator $translator, AbstractDataStore $dataStore) - { + /** + * @var JsonDataStore[] Keyed by locale, lazily instantiated + */ + private $localeDataStores = []; + + public function __construct( + DataCollectorTranslator $translator, + AbstractDataStore $dataStore, + string $localeDataStoreTemplate = null + ) { $this->translator = $translator; $this->dataStore = $dataStore; - $this->translations = $dataStore->load(); + $this->localeDataStoreTemplate = $localeDataStoreTemplate; } // Helper methods - public function setTranslation($key, $value) + public function setTranslation(string $key, string $value, string $locale = null): void { - $translations = $this->dataStore->load(); - $translations[$key] = $value; - $this->dataStore->save($translations); + if ($locale !== null) { + $store = $this->getLocaleDataStore($locale); + $translations = $store->load(); + $translations[$key] = $value; + $store->save($translations); + } else { + $translations = $this->dataStore->load(); + $translations[$key] = $value; + $this->dataStore->save($translations); + } } - public function clear() + public function clear(): void { $this->dataStore->save([]); + foreach ($this->localeDataStores as $store) { + $store->save([]); + } + $this->localeDataStores = []; } // Decorated methods public function trans(string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string { - $this->translator->getCatalogue($locale)->add($this->translations); + $translations = $this->dataStore->load(); + + if ($locale !== null) { + $localeTranslations = $this->getLocaleDataStore($locale)->load(); + $translations = array_merge($translations, $localeTranslations); + } + + $this->translator->getCatalogue($locale)->add($translations); return $this->translator->trans($id, $parameters, $domain, $locale); } @@ -73,4 +102,13 @@ public function getLocale(): string { return $this->translator->getLocale(); } + + private function getLocaleDataStore(string $locale): JsonDataStore + { + if (!isset($this->localeDataStores[$locale])) { + $filePath = sprintf($this->localeDataStoreTemplate, $locale); + $this->localeDataStores[$locale] = new JsonDataStore($filePath); + } + return $this->localeDataStores[$locale]; + } } diff --git a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/AbstractEntity.php b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/AbstractEntity.php index 84c81e47a0..0fe4cc3b87 100644 --- a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/AbstractEntity.php +++ b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/AbstractEntity.php @@ -35,6 +35,7 @@ use OpenConext\EngineBlock\Metadata\Service; use OpenConext\EngineBlock\Metadata\ShibMdScope; use OpenConext\EngineBlock\Metadata\X509\X509Certificate; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use ReflectionClass; use ReflectionProperty; @@ -659,6 +660,64 @@ protected function getServiceProviderMockProperties() ]; } + protected function setTranslationExpectancies(MockObject $translator) + { + $translator->expects($this->at(0)) + ->method('trans') + ->with('suite_name') + ->willReturn('test-suite'); + + $translator->expects($this->at(1)) + ->method('trans') + ->with('metadata_organization_name') + ->willReturn('configuredOrganizationName'); + + $translator->expects($this->at(2)) + ->method('trans') + ->with('metadata_organization_name', [], null, 'nl') + ->willReturn('configuredOrganizationName'); + + $translator->expects($this->at(3)) + ->method('trans') + ->with('metadata_organization_displayname', [], null, 'nl') + ->willReturn('configuredOrganizationDisplayName'); + + $translator->expects($this->at(4)) + ->method('trans') + ->with('metadata_organization_url', [], null, 'nl') + ->willReturn('configuredOrganizationUrl'); + + $translator->expects($this->at(5)) + ->method('trans') + ->with('metadata_organization_name', [], null, 'en') + ->willReturn('configuredOrganizationName'); + + $translator->expects($this->at(6)) + ->method('trans') + ->with('metadata_organization_displayname', [], null, 'en') + ->willReturn('configuredOrganizationDisplayName'); + + $translator->expects($this->at(7)) + ->method('trans') + ->with('metadata_organization_url', [], null, 'en') + ->willReturn('configuredOrganizationUrl'); + + $translator->expects($this->at(8)) + ->method('trans') + ->with('metadata_organization_name', [], null, 'pt') + ->willReturn('configuredOrganizationName'); + + $translator->expects($this->at(9)) + ->method('trans') + ->with('metadata_organization_displayname', [], null, 'pt') + ->willReturn('configuredOrganizationDisplayName'); + + $translator->expects($this->at(10)) + ->method('trans') + ->with('metadata_organization_url', [], null, 'pt') + ->willReturn('configuredOrganizationUrl'); + } + private function getParameters($className, $skipParameters = []) { $results = []; diff --git a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockIdentityProviderInformation.php b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockIdentityProviderInformation.php index 060114c76f..67ea7c397b 100644 --- a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockIdentityProviderInformation.php +++ b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockIdentityProviderInformation.php @@ -35,26 +35,16 @@ public function test_methods() $adapter = $this->createIdentityProviderAdapter(); $translator = $this->createMock(TranslatorInterface::class); - $matcher = $this->exactly(4); - $translator->expects($matcher) - ->method('trans')->willReturnCallback(function (...$parameters) use ($matcher) { - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('suite_name', $parameters[0]); - return 'test-suite'; - } - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame('metadata_organization_name', $parameters[0]); - return 'configuredOrganizationName'; - } - if ($matcher->numberOfInvocations() === 3) { - $this->assertSame('metadata_organization_displayname', $parameters[0]); - return 'configuredOrganizationDisplayName'; - } - if ($matcher->numberOfInvocations() === 4) { - $this->assertSame('metadata_organization_url', $parameters[0]); - return 'configuredOrganizationUrl'; - } - }); + $translator->method('trans')->willReturnCallback(function (...$parameters) { + return match ($parameters[0]) { + 'suite_name' => 'test-suite', + 'openconext_support_url' => 'https://example.org', + 'metadata_organization_name' => 'configuredOrganizationName', + 'metadata_organization_displayname' => 'configuredOrganizationDisplayName', + 'metadata_organization_url' => 'configuredOrganizationUrl', + default => '', + }; + }); $configuration = new EngineBlockConfiguration( $translator, diff --git a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockServiceProviderInformation.php b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockServiceProviderInformation.php index 78d55ede2f..c77d414734 100644 --- a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockServiceProviderInformation.php +++ b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/EngineblockServiceProviderInformation.php @@ -35,26 +35,16 @@ public function test_methods() $adapter = $this->createServiceProviderAdapter(); $translator = $this->createMock(TranslatorInterface::class); - $matcher = $this->exactly(4); - $translator->expects($matcher) - ->method('trans')->willReturnCallback(function (...$parameters) use ($matcher) { - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('suite_name', $parameters[0]); - return 'test-suite'; - } - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame('metadata_organization_name', $parameters[0]); - return 'configuredOrganizationName'; - } - if ($matcher->numberOfInvocations() === 3) { - $this->assertSame('metadata_organization_displayname', $parameters[0]); - return 'configuredOrganizationDisplayName'; - } - if ($matcher->numberOfInvocations() === 4) { - $this->assertSame('metadata_organization_url', $parameters[0]); - return 'configuredOrganizationUrl'; - } - }); + $translator->method('trans')->willReturnCallback(function (...$parameters) { + return match ($parameters[0]) { + 'suite_name' => 'test-suite', + 'openconext_support_url' => 'https://example.org', + 'metadata_organization_name' => 'configuredOrganizationName', + 'metadata_organization_displayname' => 'configuredOrganizationDisplayName', + 'metadata_organization_url' => 'configuredOrganizationUrl', + default => '', + }; + }); $configuration = new EngineBlockConfiguration( $translator, diff --git a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/ProxiedIdentityProvider.php b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/ProxiedIdentityProvider.php index f059c59a47..6094976d87 100644 --- a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/ProxiedIdentityProvider.php +++ b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Decorator/ProxiedIdentityProvider.php @@ -101,26 +101,16 @@ public function test_methods() private function createConfiguration(): EngineBlockConfiguration { $translator = $this->createMock(TranslatorInterface::class); - $matcher = $this->exactly(4); - $translator->expects($matcher) - ->method('trans')->willReturnCallback(function (...$parameters) use ($matcher) { - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('suite_name', $parameters[0]); - return 'test-suite'; - } - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame('metadata_organization_name', $parameters[0]); - return 'configuredOrganizationName'; - } - if ($matcher->numberOfInvocations() === 3) { - $this->assertSame('metadata_organization_displayname', $parameters[0]); - return 'configuredOrganizationDisplayName'; - } - if ($matcher->numberOfInvocations() === 4) { - $this->assertSame('metadata_organization_url', $parameters[0]); - return 'configuredOrganizationUrl'; - } - }); + $translator->method('trans')->willReturnCallback(function (...$parameters) { + return match ($parameters[0]) { + 'suite_name' => 'test-suite', + 'openconext_support_url' => 'https://example.org', + 'metadata_organization_name' => 'configuredOrganizationName', + 'metadata_organization_displayname' => 'configuredOrganizationDisplayName', + 'metadata_organization_url' => 'configuredOrganizationUrl', + default => '', + }; + }); $configuration = new EngineBlockConfiguration( $translator, diff --git a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/IdentityProviderFactory.php b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/IdentityProviderFactory.php index 68ca338957..2c44fda442 100644 --- a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/IdentityProviderFactory.php +++ b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/IdentityProviderFactory.php @@ -87,27 +87,16 @@ public function test_create_proxy_from_entity() public function test_create_idp_entity_from_entity_properties() { // Replaced deprecated $this->at(n) expectations with a single batched expectation - $matcher = $this->exactly(4); - // Replaced deprecated $this->at(n) expectations with a single batched expectation - $this->translator->expects($matcher) - ->method('trans')->willReturnCallback(function (...$parameters) use ($matcher) { - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('suite_name', $parameters[0]); - return 'test-suite'; - } - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame('metadata_organization_name', $parameters[0]); - return 'configuredOrganizationName'; - } - if ($matcher->numberOfInvocations() === 3) { - $this->assertSame('metadata_organization_displayname', $parameters[0]); - return 'configuredOrganizationDisplayName'; - } - if ($matcher->numberOfInvocations() === 4) { - $this->assertSame('metadata_organization_url', $parameters[0]); - return 'configuredOrganizationUrl'; - } - }); + $this->translator->method('trans')->willReturnCallback(function (...$parameters) { + return match ($parameters[0]) { + 'suite_name' => 'test-suite', + 'openconext_support_url' => 'https://example.org', + 'metadata_organization_name' => 'configuredOrganizationName', + 'metadata_organization_displayname' => 'configuredOrganizationDisplayName', + 'metadata_organization_url' => 'configuredOrganizationUrl', + default => '', + }; + }); $this->configuration = new EngineBlockConfiguration( $this->translator, diff --git a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/ServiceProviderFactory.php b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/ServiceProviderFactory.php index 91bdd6f3e2..dcc8b1bdfb 100644 --- a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/ServiceProviderFactory.php +++ b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/Factory/ServiceProviderFactory.php @@ -112,26 +112,16 @@ public function test_create_stepup_entity_from() public function test_eb_properties() { - $matcher = $this->exactly(4); - $this->translator->expects($matcher) - ->method('trans')->willReturnCallback(function (...$parameters) use ($matcher) { - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('suite_name', $parameters[0]); - return 'test-suite'; - } - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame('metadata_organization_name', $parameters[0]); - return 'configuredOrganizationName'; - } - if ($matcher->numberOfInvocations() === 3) { - $this->assertSame('metadata_organization_displayname', $parameters[0]); - return 'configuredOrganizationDisplayName'; - } - if ($matcher->numberOfInvocations() === 4) { - $this->assertSame('metadata_organization_url', $parameters[0]); - return 'configuredOrganizationUrl'; - } - }); + $this->translator->method('trans')->willReturnCallback(function (...$parameters) { + return match ($parameters[0]) { + 'suite_name' => 'test-suite', + 'openconext_support_url' => 'https://example.org', + 'metadata_organization_name' => 'configuredOrganizationName', + 'metadata_organization_displayname' => 'configuredOrganizationDisplayName', + 'metadata_organization_url' => 'configuredOrganizationUrl', + default => '', + }; + }); $this->configuration = new EngineBlockConfiguration( $this->translator, @@ -290,26 +280,16 @@ public function test_eb_properties() public function test_stepup_properties() { - $matcher = $this->exactly(4); - $this->translator->expects($matcher) - ->method('trans')->willReturnCallback(function (...$parameters) use ($matcher) { - if ($matcher->numberOfInvocations() === 1) { - $this->assertSame('suite_name', $parameters[0]); - return 'test-suite'; - } - if ($matcher->numberOfInvocations() === 2) { - $this->assertSame('metadata_organization_name', $parameters[0]); - return 'configuredOrganizationName'; - } - if ($matcher->numberOfInvocations() === 3) { - $this->assertSame('metadata_organization_displayname', $parameters[0]); - return 'configuredOrganizationDisplayName'; - } - if ($matcher->numberOfInvocations() === 4) { - $this->assertSame('metadata_organization_url', $parameters[0]); - return 'configuredOrganizationUrl'; - } - }); + $this->translator->method('trans')->willReturnCallback(function (...$parameters) { + return match ($parameters[0]) { + 'suite_name' => 'test-suite', + 'openconext_support_url' => 'https://example.org', + 'metadata_organization_name' => 'configuredOrganizationName', + 'metadata_organization_displayname' => 'configuredOrganizationDisplayName', + 'metadata_organization_url' => 'configuredOrganizationUrl', + default => '', + }; + }); $this->configuration = new EngineBlockConfiguration( $this->translator, diff --git a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfigurationTest.php b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfigurationTest.php index 7613b4f299..c4602a3114 100644 --- a/tests/unit/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfigurationTest.php +++ b/tests/unit/OpenConext/EngineBlock/Metadata/Factory/ValueObject/EngineBlockConfigurationTest.php @@ -32,27 +32,54 @@ class EngineBlockConfigurationTest extends TestCase public function test_configuration_creation() { - $suitName = 'OpenestConext'; + $suiteName = 'OpenestConext'; + $supportUrl = 'https://www.example.org'; $orgUrl = 'https://www.example.org'; $orgName = 'OpenestConext Company'; $orgDisplayName = 'OpenestConext Company Inc.'; $translator = m::mock(TranslatorInterface::class); + + // Called once at construction time to set $this->suiteName $translator ->shouldReceive('trans') - ->with('suite_name')->once() - ->andReturn($suitName); + ->with('suite_name') + ->once() + ->andReturn($suiteName); + + // Called once at construction time for ContactPersons (with %suiteName% parameter) $translator ->shouldReceive('trans') - ->with('metadata_organization_name')->once() + ->with('metadata_organization_name', ['%suiteName%' => $suiteName]) + ->once() ->andReturn($orgName); + + // Called by getOrganization(null) — called once below $translator ->shouldReceive('trans') - ->with('metadata_organization_displayname')->once() + ->with('suite_name', [], null, null) + ->once() + ->andReturn($suiteName); + $translator + ->shouldReceive('trans') + ->with('openconext_support_url', [], null, null) + ->once() + ->andReturn($supportUrl); + $translator + ->shouldReceive('trans') + ->with('metadata_organization_name', ['%suiteName%' => $suiteName, '%supportUrl%' => $supportUrl], null, null) + ->once() + ->andReturn($orgName); + $translator + ->shouldReceive('trans') + ->with('metadata_organization_displayname', ['%suiteName%' => $suiteName, '%supportUrl%' => $supportUrl], null, null) + ->once() ->andReturn($orgDisplayName); + $translator ->shouldReceive('trans') - ->with('metadata_organization_url')->once() + ->with('metadata_organization_url', ['%suiteName%' => $suiteName, '%supportUrl%' => $supportUrl], null, null) + ->once() ->andReturn($orgUrl); $mail = 'mail@example.org'; @@ -98,9 +125,10 @@ public function test_configuration_creation() $this->assertEquals($width, $configuration->getLogo()->width); $this->assertEquals($height, $configuration->getLogo()->height); - $this->assertInstanceOf(Organization::class, $configuration->getOrganization()); - $this->assertEquals($orgUrl, $configuration->getOrganization()->url); - $this->assertEquals($orgName, $configuration->getOrganization()->name); - $this->assertEquals($orgDisplayName, $configuration->getOrganization()->displayName); + $organization = $configuration->getOrganization(); + $this->assertInstanceOf(Organization::class, $organization); + $this->assertEquals($orgUrl, $organization->url); + $this->assertEquals($orgName, $organization->name); + $this->assertEquals($orgDisplayName, $organization->displayName); } } diff --git a/theme/base/templates/modules/Authentication/View/Metadata/partial/organization.xml.twig b/theme/base/templates/modules/Authentication/View/Metadata/partial/organization.xml.twig index bfd57ec6cc..a47f834271 100644 --- a/theme/base/templates/modules/Authentication/View/Metadata/partial/organization.xml.twig +++ b/theme/base/templates/modules/Authentication/View/Metadata/partial/organization.xml.twig @@ -9,17 +9,17 @@ {% for locale in locales %} {% if metadata.hasCompleteOrganizationData(locale) %} - {{ metadata.organizationName(locale)|trans }} + {{ metadata.organizationName(locale) }} {% endif %} {% endfor %} {% for locale in locales %} {% if metadata.hasCompleteOrganizationData(locale) %} - {{ metadata.organizationDisplayName(locale)|trans }} + {{ metadata.organizationDisplayName(locale) }} {% endif %} {% endfor %} {% for locale in locales %} {% if metadata.hasCompleteOrganizationData(locale) %} - {{ metadata.organizationUrl(locale)|trans }} + {{ metadata.organizationUrl(locale) }} {% endif %} {% endfor %}