loadingMorePagesCallsListMoreTimes()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 0
dl 0
loc 19
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\CLI\Command\ShortUrl;
6
7
use Cake\Chronos\Chronos;
8
use Laminas\Paginator\Adapter\ArrayAdapter;
9
use Laminas\Paginator\Paginator;
10
use PHPUnit\Framework\TestCase;
11
use Prophecy\Argument;
12
use Prophecy\PhpUnit\ProphecyTrait;
13
use Prophecy\Prophecy\ObjectProphecy;
14
use Shlinkio\Shlink\CLI\Command\ShortUrl\ListShortUrlsCommand;
15
use Shlinkio\Shlink\Core\Entity\ShortUrl;
16
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
17
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
18
use Symfony\Component\Console\Application;
19
use Symfony\Component\Console\Tester\CommandTester;
20
21
use function explode;
22
23
class ListShortUrlsCommandTest extends TestCase
24
{
25
    use ProphecyTrait;
26
27
    private CommandTester $commandTester;
28
    private ObjectProphecy $shortUrlService;
29
30
    public function setUp(): void
31
    {
32
        $this->shortUrlService = $this->prophesize(ShortUrlServiceInterface::class);
33
        $app = new Application();
34
        $command = new ListShortUrlsCommand($this->shortUrlService->reveal(), []);
35
        $app->add($command);
36
        $this->commandTester = new CommandTester($command);
37
    }
38
39
    /** @test */
40
    public function loadingMorePagesCallsListMoreTimes(): void
41
    {
42
        // The paginator will return more than one page
43
        $data = [];
44
        for ($i = 0; $i < 50; $i++) {
45
            $data[] = new ShortUrl('url_' . $i);
46
        }
47
48
        $this->shortUrlService->listShortUrls(Argument::cetera())
49
            ->will(fn () => new Paginator(new ArrayAdapter($data)))
50
            ->shouldBeCalledTimes(3);
51
52
        $this->commandTester->setInputs(['y', 'y', 'n']);
53
        $this->commandTester->execute([]);
54
        $output = $this->commandTester->getDisplay();
55
56
        self::assertStringContainsString('Continue with page 2?', $output);
57
        self::assertStringContainsString('Continue with page 3?', $output);
58
        self::assertStringContainsString('Continue with page 4?', $output);
59
    }
60
61
    /** @test */
62
    public function havingMorePagesButAnsweringNoCallsListJustOnce(): void
63
    {
64
        // The paginator will return more than one page
65
        $data = [];
66
        for ($i = 0; $i < 30; $i++) {
67
            $data[] = new ShortUrl('url_' . $i);
68
        }
69
70
        $this->shortUrlService->listShortUrls(ShortUrlsParams::emptyInstance())
71
            ->willReturn(new Paginator(new ArrayAdapter($data)))
72
            ->shouldBeCalledOnce();
73
74
        $this->commandTester->setInputs(['n']);
75
        $this->commandTester->execute([]);
76
        $output = $this->commandTester->getDisplay();
77
78
        self::assertStringContainsString('url_1', $output);
79
        self::assertStringContainsString('url_9', $output);
80
        self::assertStringNotContainsString('url_10', $output);
81
        self::assertStringNotContainsString('url_20', $output);
82
        self::assertStringNotContainsString('url_30', $output);
83
        self::assertStringContainsString('Continue with page 2?', $output);
84
        self::assertStringNotContainsString('Continue with page 3?', $output);
85
    }
86
87
    /** @test */
88
    public function passingPageWillMakeListStartOnThatPage(): void
89
    {
90
        $page = 5;
91
        $this->shortUrlService->listShortUrls(ShortUrlsParams::fromRawData(['page' => $page]))
92
            ->willReturn(new Paginator(new ArrayAdapter()))
93
            ->shouldBeCalledOnce();
94
95
        $this->commandTester->setInputs(['y']);
96
        $this->commandTester->execute(['--page' => $page]);
97
    }
98
99
    /** @test */
100
    public function ifTagsFlagIsProvidedTagsColumnIsIncluded(): void
101
    {
102
        $this->shortUrlService->listShortUrls(ShortUrlsParams::emptyInstance())
103
            ->willReturn(new Paginator(new ArrayAdapter()))
104
            ->shouldBeCalledOnce();
105
106
        $this->commandTester->setInputs(['y']);
107
        $this->commandTester->execute(['--showTags' => true]);
108
        $output = $this->commandTester->getDisplay();
109
        self::assertStringContainsString('Tags', $output);
110
    }
111
112
    /**
113
     * @test
114
     * @dataProvider provideArgs
115
     */
116
    public function serviceIsInvokedWithProvidedArgs(
117
        array $commandArgs,
118
        ?int $page,
119
        ?string $searchTerm,
120
        array $tags,
121
        ?string $startDate = null,
122
        ?string $endDate = null
123
    ): void {
124
        $listShortUrls = $this->shortUrlService->listShortUrls(ShortUrlsParams::fromRawData([
125
            'page' => $page,
126
            'searchTerm' => $searchTerm,
127
            'tags' => $tags,
128
            'startDate' => $startDate !== null ? Chronos::parse($startDate)->toAtomString() : null,
129
            'endDate' => $endDate !== null ? Chronos::parse($endDate)->toAtomString() : null,
130
        ]))->willReturn(new Paginator(new ArrayAdapter()));
131
132
        $this->commandTester->setInputs(['n']);
133
        $this->commandTester->execute($commandArgs);
134
135
        $listShortUrls->shouldHaveBeenCalledOnce();
136
    }
137
138
    public function provideArgs(): iterable
139
    {
140
        yield [[], 1, null, []];
141
        yield [['--page' => $page = 3], $page, null, []];
142
        yield [['--searchTerm' => $searchTerm = 'search this'], 1, $searchTerm, []];
143
        yield [
144
            ['--page' => $page = 3, '--searchTerm' => $searchTerm = 'search this', '--tags' => $tags = 'foo,bar'],
145
            $page,
146
            $searchTerm,
147
            explode(',', $tags),
148
        ];
149
        yield [
150
            ['--startDate' => $startDate = '2019-01-01'],
151
            1,
152
            null,
153
            [],
154
            $startDate,
155
        ];
156
        yield [
157
            ['--endDate' => $endDate = '2020-05-23'],
158
            1,
159
            null,
160
            [],
161
            null,
162
            $endDate,
163
        ];
164
        yield [
165
            ['--startDate' => $startDate = '2019-01-01', '--endDate' => $endDate = '2020-05-23'],
166
            1,
167
            null,
168
            [],
169
            $startDate,
170
            $endDate,
171
        ];
172
    }
173
174
    /**
175
     * @param string|array|null $expectedOrderBy
176
     * @test
177
     * @dataProvider provideOrderBy
178
     */
179
    public function orderByIsProperlyComputed(array $commandArgs, $expectedOrderBy): void
180
    {
181
        $listShortUrls = $this->shortUrlService->listShortUrls(ShortUrlsParams::fromRawData([
182
            'orderBy' => $expectedOrderBy,
183
        ]))->willReturn(new Paginator(new ArrayAdapter()));
184
185
        $this->commandTester->setInputs(['n']);
186
        $this->commandTester->execute($commandArgs);
187
188
        $listShortUrls->shouldHaveBeenCalledOnce();
189
    }
190
191
    public function provideOrderBy(): iterable
192
    {
193
        yield [[], null];
194
        yield [['--orderBy' => 'foo'], 'foo'];
195
        yield [['--orderBy' => 'foo,ASC'], ['foo' => 'ASC']];
196
        yield [['--orderBy' => 'bar,DESC'], ['bar' => 'DESC']];
197
    }
198
199
    /** @test */
200
    public function requestingAllElementsWillSetItemsPerPage(): void
201
    {
202
        $listShortUrls = $this->shortUrlService->listShortUrls(ShortUrlsParams::fromRawData([
203
            'page' => 1,
204
            'searchTerm' => null,
205
            'tags' => [],
206
            'startDate' => null,
207
            'endDate' => null,
208
            'orderBy' => null,
209
            'itemsPerPage' => -1,
210
        ]))->willReturn(new Paginator(new ArrayAdapter()));
211
212
        $this->commandTester->execute(['--all' => true]);
213
214
        $listShortUrls->shouldHaveBeenCalledOnce();
215
    }
216
}
217