From dda3caac37a72e868b83e69f19ec64e567fa3c93 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 11 Nov 2023 19:57:12 +0100 Subject: [PATCH 1/2] Add matomo config options --- config/config.php | 8 +++++++ .../AbstractMatomoEnabledConfigOption.php | 20 ++++++++++++++++++ .../Matomo/MatomoApiTokenConfigOption.php | 21 +++++++++++++++++++ .../Matomo/MatomoBaseUrlConfigOption.php | 21 +++++++++++++++++++ .../Matomo/MatomoEnabledConfigOption.php | 21 +++++++++++++++++++ .../Matomo/MatomoSiteIdConfigOption.php | 21 +++++++++++++++++++ src/Util/AskUtilsTrait.php | 6 +++--- 7 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 src/Config/Option/Matomo/AbstractMatomoEnabledConfigOption.php create mode 100644 src/Config/Option/Matomo/MatomoApiTokenConfigOption.php create mode 100644 src/Config/Option/Matomo/MatomoBaseUrlConfigOption.php create mode 100644 src/Config/Option/Matomo/MatomoEnabledConfigOption.php create mode 100644 src/Config/Option/Matomo/MatomoSiteIdConfigOption.php diff --git a/config/config.php b/config/config.php index c7f6da1..103a907 100644 --- a/config/config.php +++ b/config/config.php @@ -110,6 +110,10 @@ 'RabbitMQ > User' => Config\Option\RabbitMq\RabbitMqUserConfigOption::class, 'RabbitMQ > Password' => Config\Option\RabbitMq\RabbitMqPasswordConfigOption::class, 'RabbitMQ > VHost' => Config\Option\RabbitMq\RabbitMqVhostConfigOption::class, + 'Matomo > Enable' => Config\Option\Matomo\MatomoEnabledConfigOption::class, + 'Matomo > Server URL' => Config\Option\Matomo\MatomoBaseUrlConfigOption::class, + 'Matomo > Site ID' => Config\Option\Matomo\MatomoSiteIdConfigOption::class, + 'Matomo > API token' => Config\Option\Matomo\MatomoApiTokenConfigOption::class, ], ], @@ -153,6 +157,10 @@ Config\Option\RabbitMq\RabbitMqUserConfigOption::class => ConfigAbstractFactory::class, Config\Option\RabbitMq\RabbitMqPasswordConfigOption::class => ConfigAbstractFactory::class, Config\Option\RabbitMq\RabbitMqVhostConfigOption::class => ConfigAbstractFactory::class, + Config\Option\Matomo\MatomoEnabledConfigOption::class => InvokableFactory::class, + Config\Option\Matomo\MatomoBaseUrlConfigOption::class => InvokableFactory::class, + Config\Option\Matomo\MatomoSiteIdConfigOption::class => InvokableFactory::class, + Config\Option\Matomo\MatomoApiTokenConfigOption::class => InvokableFactory::class, Config\Option\UrlShortener\GeoLiteLicenseKeyConfigOption::class => InvokableFactory::class, Config\Option\Tracking\OrphanVisitsTrackingConfigOption::class => InvokableFactory::class, Config\Option\Tracking\DisableTrackParamConfigOption::class => InvokableFactory::class, diff --git a/src/Config/Option/Matomo/AbstractMatomoEnabledConfigOption.php b/src/Config/Option/Matomo/AbstractMatomoEnabledConfigOption.php new file mode 100644 index 0000000..3ada3b0 --- /dev/null +++ b/src/Config/Option/Matomo/AbstractMatomoEnabledConfigOption.php @@ -0,0 +1,20 @@ +askRequired($io, 'Matomo API token'); + } +} diff --git a/src/Config/Option/Matomo/MatomoBaseUrlConfigOption.php b/src/Config/Option/Matomo/MatomoBaseUrlConfigOption.php new file mode 100644 index 0000000..bea9a3e --- /dev/null +++ b/src/Config/Option/Matomo/MatomoBaseUrlConfigOption.php @@ -0,0 +1,21 @@ +askRequired($io, 'Matomo server URL'); + } +} diff --git a/src/Config/Option/Matomo/MatomoEnabledConfigOption.php b/src/Config/Option/Matomo/MatomoEnabledConfigOption.php new file mode 100644 index 0000000..dd58c22 --- /dev/null +++ b/src/Config/Option/Matomo/MatomoEnabledConfigOption.php @@ -0,0 +1,21 @@ +confirm('Do you want Shlink to send all visits to an external Matomo server?', false); + } +} diff --git a/src/Config/Option/Matomo/MatomoSiteIdConfigOption.php b/src/Config/Option/Matomo/MatomoSiteIdConfigOption.php new file mode 100644 index 0000000..da6d6ce --- /dev/null +++ b/src/Config/Option/Matomo/MatomoSiteIdConfigOption.php @@ -0,0 +1,21 @@ +askRequired($io, 'Matomo site ID'); + } +} diff --git a/src/Util/AskUtilsTrait.php b/src/Util/AskUtilsTrait.php index 7adc3cc..9078777 100644 --- a/src/Util/AskUtilsTrait.php +++ b/src/Util/AskUtilsTrait.php @@ -9,11 +9,11 @@ trait AskUtilsTrait { - private function askRequired(StyleInterface $io, string $optionNameOrQuestion, ?string $question = null): string + private function askRequired(StyleInterface $io, string $optionName, ?string $question = null): string { - return $io->ask($question ?? $optionNameOrQuestion, null, static function ($value) use ($optionNameOrQuestion) { + return $io->ask($question ?? $optionName, null, static function ($value) use ($optionName) { if (empty($value)) { - throw MissingRequiredOptionException::fromOption($optionNameOrQuestion); + throw MissingRequiredOptionException::fromOption($optionName); } return $value; From 21a3b94c71c6761c0974e59b89b3186361796f69 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 11 Nov 2023 20:05:11 +0100 Subject: [PATCH 2/2] Add tests for matomo config options --- CHANGELOG.md | 1 + .../Matomo/MatomoApiTokenConfigOption.php | 2 +- .../Matomo/MatomoApiTokenConfigOptionTest.php | 38 ++++++++++++ .../Matomo/MatomoBaseUrlConfigOptionTest.php | 59 +++++++++++++++++++ .../Matomo/MatomoEnabledConfigOptionTest.php | 40 +++++++++++++ .../Matomo/MatomoSiteIdConfigOptionTest.php | 38 ++++++++++++ 6 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 test/Config/Option/Matomo/MatomoApiTokenConfigOptionTest.php create mode 100644 test/Config/Option/Matomo/MatomoBaseUrlConfigOptionTest.php create mode 100644 test/Config/Option/Matomo/MatomoEnabledConfigOptionTest.php create mode 100644 test/Config/Option/Matomo/MatomoSiteIdConfigOptionTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0785476..ded4a0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this ### Added * Add `CacheNamespaceConfigOption` to customize the cache namespace. * Add support for PHP 8.3 +* [#200](https://github.com/shlinkio/shlink-installer/issues/200) Add Matomo integration config options. ### Changed * *Nothing* diff --git a/src/Config/Option/Matomo/MatomoApiTokenConfigOption.php b/src/Config/Option/Matomo/MatomoApiTokenConfigOption.php index 3ce51e1..64fca29 100644 --- a/src/Config/Option/Matomo/MatomoApiTokenConfigOption.php +++ b/src/Config/Option/Matomo/MatomoApiTokenConfigOption.php @@ -11,7 +11,7 @@ class MatomoApiTokenConfigOption extends AbstractMatomoEnabledConfigOption public function getEnvVar(): string { - return 'MATOMO_TOKEN'; + return 'MATOMO_API_TOKEN'; } public function ask(StyleInterface $io, array $currentOptions): string diff --git a/test/Config/Option/Matomo/MatomoApiTokenConfigOptionTest.php b/test/Config/Option/Matomo/MatomoApiTokenConfigOptionTest.php new file mode 100644 index 0000000..54056bf --- /dev/null +++ b/test/Config/Option/Matomo/MatomoApiTokenConfigOptionTest.php @@ -0,0 +1,38 @@ +configOption = new MatomoApiTokenConfigOption(); + } + + #[Test] + public function returnsExpectedEnvVar(): void + { + self::assertEquals('MATOMO_API_TOKEN', $this->configOption->getEnvVar()); + } + + #[Test] + public function expectedQuestionIsAsked(): void + { + $expectedAnswer = 'abc123'; + $io = $this->createMock(StyleInterface::class); + $io->expects($this->once())->method('ask')->with('Matomo API token')->willReturn($expectedAnswer); + + $answer = $this->configOption->ask($io, []); + + self::assertEquals($expectedAnswer, $answer); + } +} diff --git a/test/Config/Option/Matomo/MatomoBaseUrlConfigOptionTest.php b/test/Config/Option/Matomo/MatomoBaseUrlConfigOptionTest.php new file mode 100644 index 0000000..a52be70 --- /dev/null +++ b/test/Config/Option/Matomo/MatomoBaseUrlConfigOptionTest.php @@ -0,0 +1,59 @@ +configOption = new MatomoBaseUrlConfigOption(); + } + + #[Test] + public function returnsExpectedEnvVar(): void + { + self::assertEquals('MATOMO_BASE_URL', $this->configOption->getEnvVar()); + } + + #[Test] + public function expectedQuestionIsAsked(): void + { + $expectedAnswer = 'foobar.com'; + $io = $this->createMock(StyleInterface::class); + $io->expects($this->once())->method('ask')->with('Matomo server URL')->willReturn($expectedAnswer); + + $answer = $this->configOption->ask($io, []); + + self::assertEquals($expectedAnswer, $answer); + } + + #[Test] + public function dependsOnMatomoEnabled(): void + { + self::assertEquals(MatomoEnabledConfigOption::class, $this->configOption->getDependentOption()); + } + + #[Test, DataProvider('provideCurrentOptions')] + public function shouldBeAskedOnlyIfMatomoIsEnabled(array $currentOptions, bool $expected): void + { + self::assertEquals($expected, $this->configOption->shouldBeAsked($currentOptions)); + } + + public static function provideCurrentOptions(): iterable + { + yield 'matomo enabled' => [[MatomoEnabledConfigOption::ENV_VAR => true], true]; + yield 'matomo not enabled' => [[MatomoEnabledConfigOption::ENV_VAR => false], false]; + yield 'matomo not set' => [[], false]; + } +} diff --git a/test/Config/Option/Matomo/MatomoEnabledConfigOptionTest.php b/test/Config/Option/Matomo/MatomoEnabledConfigOptionTest.php new file mode 100644 index 0000000..cbc62fa --- /dev/null +++ b/test/Config/Option/Matomo/MatomoEnabledConfigOptionTest.php @@ -0,0 +1,40 @@ +configOption = new MatomoEnabledConfigOption(); + } + + #[Test] + public function returnsExpectedEnvVar(): void + { + self::assertEquals('MATOMO_ENABLED', $this->configOption->getEnvVar()); + } + + #[Test] + public function expectedQuestionIsAsked(): void + { + $io = $this->createMock(StyleInterface::class); + $io->expects($this->once())->method('confirm')->with( + 'Do you want Shlink to send all visits to an external Matomo server?', + false, + )->willReturn(true); + + $answer = $this->configOption->ask($io, []); + + self::assertTrue($answer); + } +} diff --git a/test/Config/Option/Matomo/MatomoSiteIdConfigOptionTest.php b/test/Config/Option/Matomo/MatomoSiteIdConfigOptionTest.php new file mode 100644 index 0000000..d894ff3 --- /dev/null +++ b/test/Config/Option/Matomo/MatomoSiteIdConfigOptionTest.php @@ -0,0 +1,38 @@ +configOption = new MatomoSiteIdConfigOption(); + } + + #[Test] + public function returnsExpectedEnvVar(): void + { + self::assertEquals('MATOMO_SITE_ID', $this->configOption->getEnvVar()); + } + + #[Test] + public function expectedQuestionIsAsked(): void + { + $expectedAnswer = '12345'; + $io = $this->createMock(StyleInterface::class); + $io->expects($this->once())->method('ask')->with('Matomo site ID')->willReturn($expectedAnswer); + + $answer = $this->configOption->ask($io, []); + + self::assertEquals($expectedAnswer, $answer); + } +}