Completed
Push — develop ( 8ca45e...f71bd8 )
by Alejandro
21s queued 11s
created

EditShortUrlActionTest::provideDisablingMeta()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 12
rs 9.9666
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 provideDisablingMeta
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
        // Setting meta that disables the URL should not let it be visited
34
        $editWithProvidedMeta = $this->callApiWithKey(self::METHOD_PATCH, $url, [RequestOptions::JSON => $meta]);
35
        $metaAfterEditing = $this->findShortUrlMetaByShortCode($shortCode);
36
37
        // Resetting all meta should allow the URL to be visitable again
38
        $editWithResetMeta = $this->callApiWithKey(self::METHOD_PATCH, $url, [
39
            RequestOptions::JSON => $resetMeta,
40
        ]);
41
        $metaAfterResetting = $this->findShortUrlMetaByShortCode($shortCode);
42
43
        $this->assertEquals(self::STATUS_NO_CONTENT, $editWithProvidedMeta->getStatusCode());
44
        $this->assertEquals(self::STATUS_NO_CONTENT, $editWithResetMeta->getStatusCode());
45
        $this->assertEquals($resetMeta, $metaAfterResetting);
46
        self::assertArraySubset($meta, $metaAfterEditing);
47
    }
48
49
    public function provideDisablingMeta(): iterable
50
    {
51
        $now = Chronos::now();
52
53
        yield [['validSince' => $now->addMonth()->toAtomString()]];
54
        yield [['validUntil' => $now->subMonth()->toAtomString()]];
55
        yield [['maxVisits' => 20]];
56
        yield [['validUntil' => $now->addYear()->toAtomString(), 'maxVisits' => 100]];
57
        yield [[
58
            'validSince' => $now->subYear()->toAtomString(),
59
            'validUntil' => $now->addYear()->toAtomString(),
60
            'maxVisits' => 100,
61
        ]];
62
    }
63
64
    private function findShortUrlMetaByShortCode(string $shortCode): ?array
65
    {
66
        // FIXME Call GET /short-urls/{shortCode} once issue https://github.com/shlinkio/shlink/issues/628 is fixed
67
        $allShortUrls = $this->getJsonResponsePayload($this->callApiWithKey(self::METHOD_GET, '/short-urls'));
68
        $list = $allShortUrls['shortUrls']['data'] ?? [];
69
        $matchingShortUrl = first($list, fn (array $shortUrl) => $shortUrl['shortCode'] ?? '' === $shortCode);
70
71
        return $matchingShortUrl['meta'] ?? null;
72
    }
73
74
    /** @test */
75
    public function tryingToEditInvalidUrlReturnsNotFoundError(): void
76
    {
77
        $expectedDetail = 'No URL found with short code "invalid"';
78
79
        $resp = $this->callApiWithKey(self::METHOD_PATCH, '/short-urls/invalid', [RequestOptions::JSON => []]);
80
        $payload = $this->getJsonResponsePayload($resp);
81
82
        $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode());
83
        $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']);
84
        $this->assertEquals('INVALID_SHORTCODE', $payload['type']);
85
        $this->assertEquals($expectedDetail, $payload['detail']);
86
        $this->assertEquals('Short URL not found', $payload['title']);
87
        $this->assertEquals('invalid', $payload['shortCode']);
88
    }
89
90
    /** @test */
91
    public function providingInvalidDataReturnsBadRequest(): void
92
    {
93
        $expectedDetail = 'Provided data is not valid';
94
95
        $resp = $this->callApiWithKey(self::METHOD_PATCH, '/short-urls/invalid', [RequestOptions::JSON => [
96
            'maxVisits' => 'not_a_number',
97
        ]]);
98
        $payload = $this->getJsonResponsePayload($resp);
99
100
        $this->assertEquals(self::STATUS_BAD_REQUEST, $resp->getStatusCode());
101
        $this->assertEquals(self::STATUS_BAD_REQUEST, $payload['status']);
102
        $this->assertEquals('INVALID_ARGUMENT', $payload['type']);
103
        $this->assertEquals($expectedDetail, $payload['detail']);
104
        $this->assertEquals('Invalid data', $payload['title']);
105
    }
106
}
107