Completed
Pull Request — develop (#809)
by Alejandro
12:25
created

requestingAllElementsWillSetItemsPerPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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