Completed
Push — develop ( f71bd8...4fb2c6 )
by Alejandro
17s queued 14s
created

findShortUrlMetaByShortCode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioApiTest\Shlink\Rest\Action;
6
7
use Cake\Chronos\Chronos;
8
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
9
use GuzzleHttp\RequestOptions;
10
use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
11
12
use function Functional\first;
13
use function sprintf;
14
15
class EditShortUrlActionTest extends ApiTestCase
16
{
17
    use ArraySubsetAsserts;
18
19
    /**
20
     * @test
21
     * @dataProvider provideMeta
22
     */
23
    public function metadataCanBeReset(array $meta): void
24
    {
25
        $shortCode = 'abc123';
26
        $url = sprintf('/short-urls/%s', $shortCode);
27
        $resetMeta = [
28
            'validSince' => null,
29
            'validUntil' => null,
30
            'maxVisits' => null,
31
        ];
32
33
        $editWithProvidedMeta = $this->callApiWithKey(self::METHOD_PATCH, $url, [RequestOptions::JSON => $meta]);
34
        $metaAfterEditing = $this->findShortUrlMetaByShortCode($shortCode);
35
36
        $editWithResetMeta = $this->callApiWithKey(self::METHOD_PATCH, $url, [
37
            RequestOptions::JSON => $resetMeta,
38
        ]);
39
        $metaAfterResetting = $this->findShortUrlMetaByShortCode($shortCode);
40
41
        $this->assertEquals(self::STATUS_NO_CONTENT, $editWithProvidedMeta->getStatusCode());
42
        $this->assertEquals(self::STATUS_NO_CONTENT, $editWithResetMeta->getStatusCode());
43
        $this->assertEquals($resetMeta, $metaAfterResetting);
44
        self::assertArraySubset($meta, $metaAfterEditing);
45
    }
46
47
    public function provideMeta(): iterable
48
    {
49
        $now = Chronos::now();
50
51
        yield [['validSince' => $now->addMonth()->toAtomString()]];
52
        yield [['validUntil' => $now->subMonth()->toAtomString()]];
53
        yield [['maxVisits' => 20]];
54
        yield [['validUntil' => $now->addYear()->toAtomString(), 'maxVisits' => 100]];
55
        yield [[
56
            'validSince' => $now->subYear()->toAtomString(),
57
            'validUntil' => $now->addYear()->toAtomString(),
58
            'maxVisits' => 100,
59
        ]];
60
    }
61
62
    private function findShortUrlMetaByShortCode(string $shortCode): ?array
63
    {
64
        // FIXME Call GET /short-urls/{shortCode} once issue https://github.com/shlinkio/shlink/issues/628 is fixed
65
        $allShortUrls = $this->getJsonResponsePayload($this->callApiWithKey(self::METHOD_GET, '/short-urls'));
66
        $list = $allShortUrls['shortUrls']['data'] ?? [];
67
        $matchingShortUrl = first($list, fn (array $shortUrl) => $shortUrl['shortCode'] ?? '' === $shortCode);
68
69
        return $matchingShortUrl['meta'] ?? null;
70
    }
71
72
    /** @test */
73
    public function tryingToEditInvalidUrlReturnsNotFoundError(): void
74
    {
75
        $expectedDetail = 'No URL found with short code "invalid"';
76
77
        $resp = $this->callApiWithKey(self::METHOD_PATCH, '/short-urls/invalid', [RequestOptions::JSON => []]);
78
        $payload = $this->getJsonResponsePayload($resp);
79
80
        $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode());
81
        $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']);
82
        $this->assertEquals('INVALID_SHORTCODE', $payload['type']);
83
        $this->assertEquals($expectedDetail, $payload['detail']);
84
        $this->assertEquals('Short URL not found', $payload['title']);
85
        $this->assertEquals('invalid', $payload['shortCode']);
86
    }
87
88
    /** @test */
89
    public function providingInvalidDataReturnsBadRequest(): void
90
    {
91
        $expectedDetail = 'Provided data is not valid';
92
93
        $resp = $this->callApiWithKey(self::METHOD_PATCH, '/short-urls/invalid', [RequestOptions::JSON => [
94
            'maxVisits' => 'not_a_number',
95
        ]]);
96
        $payload = $this->getJsonResponsePayload($resp);
97
98
        $this->assertEquals(self::STATUS_BAD_REQUEST, $resp->getStatusCode());
99
        $this->assertEquals(self::STATUS_BAD_REQUEST, $payload['status']);
100
        $this->assertEquals('INVALID_ARGUMENT', $payload['type']);
101
        $this->assertEquals($expectedDetail, $payload['detail']);
102
        $this->assertEquals('Invalid data', $payload['title']);
103
    }
104
}
105