shlink/module/Installer/test/Config/Plugin/ApplicationConfigCustomizerTest.php
2018-11-20 19:30:27 +01:00

171 lines
5 KiB
PHP

<?php
declare(strict_types=1);
namespace ShlinkioTest\Shlink\Installer\Config\Plugin;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Installer\Config\Plugin\ApplicationConfigCustomizer;
use Shlinkio\Shlink\Installer\Exception\InvalidConfigOptionException;
use Shlinkio\Shlink\Installer\Model\CustomizableAppConfig;
use Symfony\Component\Console\Style\SymfonyStyle;
use function array_shift;
use function strpos;
class ApplicationConfigCustomizerTest extends TestCase
{
/** @var ApplicationConfigCustomizer */
private $plugin;
/** @var ObjectProphecy */
private $io;
public function setUp()
{
$this->io = $this->prophesize(SymfonyStyle::class);
$this->io->title(Argument::any())->willReturn(null);
$this->plugin = new ApplicationConfigCustomizer();
}
/**
* @test
*/
public function configIsRequestedToTheUser()
{
$ask = $this->io->ask(Argument::cetera())->willReturn('asked');
$confirm = $this->io->confirm(Argument::cetera())->willReturn(false);
$config = new CustomizableAppConfig();
$this->plugin->process($this->io->reveal(), $config);
$this->assertTrue($config->hasApp());
$this->assertEquals([
'SECRET' => 'asked',
'DISABLE_TRACK_PARAM' => 'asked',
'CHECK_VISITS_THRESHOLD' => false,
], $config->getApp());
$ask->shouldHaveBeenCalledTimes(2);
$confirm->shouldHaveBeenCalledOnce();
}
/**
* @test
*/
public function visitsThresholdIsRequestedIfCheckIsEnabled()
{
$ask = $this->io->ask(Argument::cetera())->will(function (array $args) {
$message = array_shift($args);
return strpos($message, 'What is the amount of visits') === 0 ? 20 : 'asked';
});
$confirm = $this->io->confirm(Argument::cetera())->willReturn(true);
$config = new CustomizableAppConfig();
$this->plugin->process($this->io->reveal(), $config);
$this->assertTrue($config->hasApp());
$this->assertEquals([
'SECRET' => 'asked',
'DISABLE_TRACK_PARAM' => 'asked',
'CHECK_VISITS_THRESHOLD' => true,
'VISITS_THRESHOLD' => 20,
], $config->getApp());
$ask->shouldHaveBeenCalledTimes(3);
$confirm->shouldHaveBeenCalledOnce();
}
/**
* @test
*/
public function onlyMissingOptionsAreAsked()
{
$ask = $this->io->ask(Argument::cetera())->willReturn('disable_param');
$config = new CustomizableAppConfig();
$config->setApp([
'SECRET' => 'foo',
'CHECK_VISITS_THRESHOLD' => true,
'VISITS_THRESHOLD' => 20,
]);
$this->plugin->process($this->io->reveal(), $config);
$this->assertEquals([
'SECRET' => 'foo',
'DISABLE_TRACK_PARAM' => 'disable_param',
'CHECK_VISITS_THRESHOLD' => true,
'VISITS_THRESHOLD' => 20,
], $config->getApp());
$ask->shouldHaveBeenCalledOnce();
}
/**
* @test
*/
public function noQuestionsAskedIfImportedConfigContainsEverything()
{
$ask = $this->io->ask(Argument::cetera())->willReturn('the_new_secret');
$config = new CustomizableAppConfig();
$config->setApp([
'SECRET' => 'foo',
'DISABLE_TRACK_PARAM' => 'the_new_secret',
'CHECK_VISITS_THRESHOLD' => true,
'VISITS_THRESHOLD' => 20,
]);
$this->plugin->process($this->io->reveal(), $config);
$this->assertEquals([
'SECRET' => 'foo',
'DISABLE_TRACK_PARAM' => 'the_new_secret',
'CHECK_VISITS_THRESHOLD' => true,
'VISITS_THRESHOLD' => 20,
], $config->getApp());
$ask->shouldNotHaveBeenCalled();
}
/**
* @test
* @dataProvider provideInvalidValues
* @param mixed $value
*/
public function validateVisitsThresholdThrowsExceptionWhenProvidedValueIsInvalid($value)
{
$this->expectException(InvalidConfigOptionException::class);
$this->plugin->validateVisitsThreshold($value);
}
public function provideInvalidValues(): array
{
return [
'string' => ['foo'],
'empty string' => [''],
'negative number' => [-5],
'negative number as string' => ['-5'],
'zero' => [0],
'zero as string' => ['0'],
];
}
/**
* @test
* @dataProvider provideValidValues
* @param mixed $value
*/
public function validateVisitsThresholdCastsToIntWhenProvidedValueIsValid($value, int $expected)
{
$this->assertEquals($expected, $this->plugin->validateVisitsThreshold($value));
}
public function provideValidValues(): array
{
return [
'positive as string' => ['20', 20],
'positive as integer' => [5, 5],
'one as string' => ['1', 1],
'one as integer' => [1, 1],
];
}
}