Passed
Pull Request — master (#343)
by Alejandro
05:42
created

CreateShortUrlActionTest::provideMatchingBodies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 0
dl 0
loc 13
rs 9.9332
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace ShlinkioApiTest\Shlink\Rest\Action;
5
6
use Cake\Chronos\Chronos;
7
use GuzzleHttp\RequestOptions;
8
use ShlinkioTest\Shlink\Common\ApiTest\ApiTestCase;
9
10
class CreateShortUrlActionTest extends ApiTestCase
11
{
12
    /**
13
     * @test
14
     */
15
    public function createsNewShortUrlWhenOnlyLongUrlIsProvided(): void
16
    {
17
        $expectedKeys = ['shortCode', 'shortUrl', 'longUrl', 'dateCreated', 'visitsCount', 'tags'];
18
        [$statusCode, $payload] = $this->createShortUrl();
19
20
        $this->assertEquals(self::STATUS_OK, $statusCode);
21
        foreach ($expectedKeys as $key) {
22
            $this->assertArrayHasKey($key, $payload);
23
        }
24
    }
25
26
    /**
27
     * @test
28
     */
29
    public function createsNewShortUrlWithCustomSlug(): void
30
    {
31
        [$statusCode, $payload] = $this->createShortUrl(['customSlug' => 'my cool slug']);
32
33
        $this->assertEquals(self::STATUS_OK, $statusCode);
34
        $this->assertEquals('my-cool-slug', $payload['shortCode']);
35
    }
36
37
    /**
38
     * @test
39
     */
40
    public function createsNewShortUrlWithTags(): void
41
    {
42
        [$statusCode, $payload] = $this->createShortUrl(['tags' => ['foo', 'bar', 'baz']]);
43
44
        $this->assertEquals(self::STATUS_OK, $statusCode);
45
        $this->assertEquals(['foo', 'bar', 'baz'], $payload['tags']);
46
    }
47
48
    /**
49
     * @test
50
     * @dataProvider provideMaxVisits
51
     */
52
    public function createsNewShortUrlWithVisitsLimit(int $maxVisits): void
53
    {
54
        [$statusCode, ['shortCode' => $shortCode]] = $this->createShortUrl(['maxVisits' => $maxVisits]);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $shortCode seems to be never defined.
Loading history...
55
56
        $this->assertEquals(self::STATUS_OK, $statusCode);
57
58
        // Last request to the short URL will return a 404, and the rest, a 302
59
        for ($i = 0; $i < $maxVisits; $i++) {
60
            $this->assertEquals(self::STATUS_FOUND, $this->callShortUrl($shortCode)->getStatusCode());
61
        }
62
        $lastResp = $this->callShortUrl($shortCode);
63
        $this->assertEquals(self::STATUS_NOT_FOUND, $lastResp->getStatusCode());
64
    }
65
66
    public function provideMaxVisits(): array
67
    {
68
        return [
69
            [1],
70
            [5],
71
            [3],
72
        ];
73
    }
74
75
    /**
76
     * @test
77
     */
78
    public function createsShortUrlWithValidSince(): void
79
    {
80
        [$statusCode, ['shortCode' => $shortCode]] = $this->createShortUrl([
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $shortCode seems to be never defined.
Loading history...
81
            'validSince' => Chronos::now()->addDay()->toAtomString(),
82
        ]);
83
84
        $this->assertEquals(self::STATUS_OK, $statusCode);
85
86
        // Request to the short URL will return a 404 since ist' not valid yet
87
        $lastResp = $this->callShortUrl($shortCode);
88
        $this->assertEquals(self::STATUS_NOT_FOUND, $lastResp->getStatusCode());
89
    }
90
91
    /**
92
     * @test
93
     */
94
    public function createsShortUrlWithValidUntil(): void
95
    {
96
        [$statusCode, ['shortCode' => $shortCode]] = $this->createShortUrl([
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $shortCode seems to be never defined.
Loading history...
97
            'validUntil' => Chronos::now()->subDay()->toAtomString(),
98
        ]);
99
100
        $this->assertEquals(self::STATUS_OK, $statusCode);
101
102
        // Request to the short URL will return a 404 since it's no longer valid
103
        $lastResp = $this->callShortUrl($shortCode);
104
        $this->assertEquals(self::STATUS_NOT_FOUND, $lastResp->getStatusCode());
105
    }
106
107
    /**
108
     * @test
109
     * @dataProvider provideMatchingBodies
110
     */
111
    public function returnsAnExistingShortUrlWhenRequested(array $body): void
112
    {
113
114
        [$firstStatusCode, ['shortCode' => $firstShortCode]] = $this->createShortUrl($body);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $firstShortCode seems to be never defined.
Loading history...
115
116
        $body['findIfExists'] = true;
117
        [$secondStatusCode, ['shortCode' => $secondShortCode]] = $this->createShortUrl($body);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $secondShortCode seems to be never defined.
Loading history...
118
119
        $this->assertEquals(self::STATUS_OK, $firstStatusCode);
120
        $this->assertEquals(self::STATUS_OK, $secondStatusCode);
121
        $this->assertEquals($firstShortCode, $secondShortCode);
122
    }
123
124
    public function provideMatchingBodies(): array
125
    {
126
        $longUrl = 'https://www.alejandrocelaya.com';
127
128
        return [
129
            'only long URL' => [['longUrl' => $longUrl]],
130
            'long URL and tags' => [['longUrl' => $longUrl, 'tags' => ['boo', 'far']]],
131
            'long URL custom slug' => [['longUrl' => $longUrl, 'customSlug' => 'my cool slug']],
132
            'several params' => [[
133
                'longUrl' => $longUrl,
134
                'tags' => ['boo', 'far'],
135
                'validSince' => Chronos::now()->toAtomString(),
136
                'maxVisits' => 7,
137
            ]],
138
        ];
139
    }
140
141
    /**
142
     * @test
143
     */
144
    public function returnsErrorWhenRequestingReturnExistingButCustomSlugIsInUse(): void
145
    {
146
        $longUrl = 'https://www.alejandrocelaya.com';
147
148
        [$firstStatusCode] = $this->createShortUrl(['longUrl' => $longUrl]);
149
        [$secondStatusCode] = $this->createShortUrl([
150
            'longUrl' => $longUrl,
151
            'customSlug' => 'custom',
152
            'findIfExists' => true,
153
        ]);
154
155
        $this->assertEquals(self::STATUS_OK, $firstStatusCode);
156
        $this->assertEquals(self::STATUS_BAD_REQUEST, $secondStatusCode);
157
    }
158
159
    /**
160
     * @test
161
     */
162
    public function createsNewShortUrlIfRequestedToFindButThereIsNoMatch(): void
163
    {
164
        [$firstStatusCode, ['shortCode' => $firstShortCode]] = $this->createShortUrl([
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $firstShortCode seems to be never defined.
Loading history...
165
            'longUrl' => 'https://www.alejandrocelaya.com',
166
        ]);
167
        [$secondStatusCode, ['shortCode' => $secondShortCode]] = $this->createShortUrl([
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $secondShortCode seems to be never defined.
Loading history...
168
            'longUrl' => 'https://www.alejandrocelaya.com/projects',
169
            'findIfExists' => true,
170
        ]);
171
172
        $this->assertEquals(self::STATUS_OK, $firstStatusCode);
173
        $this->assertEquals(self::STATUS_OK, $secondStatusCode);
174
        $this->assertNotEquals($firstShortCode, $secondShortCode);
175
    }
176
177
    /**
178
     * @return array {
179
     *     @var int $statusCode
180
     *     @var array $payload
181
     * }
182
     */
183
    private function createShortUrl(array $body = []): array
184
    {
185
        if (! isset($body['longUrl'])) {
186
            $body['longUrl'] = 'https://app.shlink.io';
187
        }
188
        $resp = $this->callApiWithKey(self::METHOD_POST, '/short-urls', [RequestOptions::JSON => $body]);
189
        $payload = $this->getJsonResponsePayload($resp);
190
191
        return [$resp->getStatusCode(), $payload];
192
    }
193
}
194