Improved test covering ListSHortUrlsCommand with optional tags

This commit is contained in:
Alejandro Celaya 2021-04-11 11:29:42 +02:00
parent 5ddac7866b
commit 334d95c843
2 changed files with 105 additions and 35 deletions

View File

@ -123,30 +123,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
$startDate = $this->getStartDateOption($input, $output);
$endDate = $this->getEndDateOption($input, $output);
$orderBy = $this->processOrderBy($input);
$pickProp = static fn (string $prop): callable => static fn (array $shortUrl) => $shortUrl[$prop];
$columnMap = [
'Short Code' => $pickProp('shortCode'),
'Title' => $pickProp('title'),
'Short URL' => $pickProp('shortUrl'),
'Long URL' => $pickProp('longUrl'),
'Date created' => $pickProp('dateCreated'),
'Visits count' => $pickProp('visitsCount'),
];
if ($this->getOptionWithDeprecatedFallback($input, 'show-tags')) {
$columnMap['Tags'] = static fn (array $shortUrl): string => implode(', ', $shortUrl['tags']);
}
if ($input->getOption('show-api-key')) {
$columnMap['API Key'] = static fn (array $_, ShortUrl $shortUrl): string =>
(string) $shortUrl->authorApiKey();
}
if ($input->getOption('show-api-key-name')) {
$columnMap['API Key Name'] = static function (array $_, ShortUrl $shortUrl): ?string {
$apiKey = $shortUrl->authorApiKey();
return $apiKey !== null ? $apiKey->name() : null;
};
}
$columnsMap = $this->resolveColumnsMap($input);
$data = [
ShortUrlsParamsInputFilter::SEARCH_TERM => $searchTerm,
@ -162,7 +139,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
do {
$data[ShortUrlsParamsInputFilter::PAGE] = $page;
$result = $this->renderPage($output, $columnMap, ShortUrlsParams::fromRawData($data), $all);
$result = $this->renderPage($output, $columnsMap, ShortUrlsParams::fromRawData($data), $all);
$page++;
$continue = $result->hasNextPage() && $io->confirm(
@ -179,19 +156,19 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
private function renderPage(
OutputInterface $output,
array $columnMap,
array $columnsMap,
ShortUrlsParams $params,
bool $all
): Paginator {
$shortUrls = $this->shortUrlService->listShortUrls($params);
$rows = map($shortUrls, function (ShortUrl $shortUrl) use ($columnMap) {
$rows = map($shortUrls, function (ShortUrl $shortUrl) use ($columnsMap) {
$rawShortUrl = $this->transformer->transform($shortUrl);
return map($columnMap, fn (callable $call) => $call($rawShortUrl, $shortUrl));
return map($columnsMap, fn (callable $call) => $call($rawShortUrl, $shortUrl));
});
ShlinkTable::fromOutput($output)->render(
array_keys($columnMap),
array_keys($columnsMap),
$rows,
$all ? null : $this->formatCurrentPageMessage($shortUrls, 'Page %s of %s'),
);
@ -209,4 +186,33 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
[$field, $dir] = array_pad(explode(',', $orderBy), 2, null);
return $dir === null ? $field : sprintf('%s-%s', $field, $dir);
}
private function resolveColumnsMap(InputInterface $input): array
{
$pickProp = static fn (string $prop): callable => static fn (array $shortUrl) => $shortUrl[$prop];
$columnsMap = [
'Short Code' => $pickProp('shortCode'),
'Title' => $pickProp('title'),
'Short URL' => $pickProp('shortUrl'),
'Long URL' => $pickProp('longUrl'),
'Date created' => $pickProp('dateCreated'),
'Visits count' => $pickProp('visitsCount'),
];
if ($this->getOptionWithDeprecatedFallback($input, 'show-tags')) {
$columnsMap['Tags'] = static fn (array $shortUrl): string => implode(', ', $shortUrl['tags']);
}
if ($input->getOption('show-api-key')) {
$columnsMap['API Key'] = static fn (array $_, ShortUrl $shortUrl): string =>
(string) $shortUrl->authorApiKey();
}
if ($input->getOption('show-api-key-name')) {
$columnsMap['API Key Name'] = static function (array $_, ShortUrl $shortUrl): ?string {
$apiKey = $shortUrl->authorApiKey();
return $apiKey !== null ? $apiKey->name() : null;
};
}
return $columnsMap;
}
}

View File

@ -12,13 +12,17 @@ use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\ListShortUrlsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer;
use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
use Symfony\Component\Console\Tester\CommandTester;
use function count;
use function explode;
class ListShortUrlsCommandTest extends TestCase
@ -98,17 +102,77 @@ class ListShortUrlsCommandTest extends TestCase
$this->commandTester->execute(['--page' => $page]);
}
/** @test */
public function ifTagsFlagIsProvidedTagsColumnIsIncluded(): void
{
/**
* @test
* @dataProvider provideOptionalFlags
*/
public function provideOptionalFlagsMakesNewColumnsToBeIncluded(
array $input,
array $expectedContents,
array $notExpectedContents,
ApiKey $apiKey
): void {
$this->shortUrlService->listShortUrls(ShortUrlsParams::emptyInstance())
->willReturn(new Paginator(new ArrayAdapter([])))
->willReturn(new Paginator(new ArrayAdapter([
ShortUrl::fromMeta(ShortUrlMeta::fromRawData([
'longUrl' => 'foo.com',
'tags' => ['foo', 'bar', 'baz'],
'apiKey' => $apiKey,
])),
])))
->shouldBeCalledOnce();
$this->commandTester->setInputs(['y']);
$this->commandTester->execute(['--show-tags' => true]);
$this->commandTester->execute($input);
$output = $this->commandTester->getDisplay();
self::assertStringContainsString('Tags', $output);
if (count($expectedContents) === 0 && count($notExpectedContents) === 0) {
self::fail('No expectations were run');
}
foreach ($expectedContents as $column) {
self::assertStringContainsString($column, $output);
}
foreach ($notExpectedContents as $column) {
self::assertStringNotContainsString($column, $output);
}
}
public function provideOptionalFlags(): iterable
{
$apiKey = ApiKey::fromMeta(ApiKeyMeta::withName('my api key'));
$key = $apiKey->toString();
yield 'tags only' => [
['--show-tags' => true],
['| Tags ', '| foo, bar, baz'],
['| API Key ', '| API Key Name |', $key, '| my api key'],
$apiKey,
];
yield 'api key only' => [
['--show-api-key' => true],
['| API Key ', $key],
['| Tags ', '| foo, bar, baz', '| API Key Name |', '| my api key'],
$apiKey,
];
yield 'api key name only' => [
['--show-api-key-name' => true],
['| API Key Name |', '| my api key'],
['| Tags ', '| foo, bar, baz', '| API Key ', $key],
$apiKey,
];
yield 'tags and api key' => [
['--show-tags' => true, '--show-api-key' => true],
['| API Key ', '| Tags ', '| foo, bar, baz', $key],
['| API Key Name |', '| my api key'],
$apiKey,
];
yield 'all' => [
['--show-tags' => true, '--show-api-key' => true, '--show-api-key-name' => true],
['| API Key ', '| Tags ', '| API Key Name |', '| foo, bar, baz', $key, '| my api key'],
[],
$apiKey,
];
}
/**