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

ShortUrlResolverTest::provideDisabledShortUrls()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 19
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 30
rs 9.6333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Core\Service\ShortUrl;
6
7
use Cake\Chronos\Chronos;
8
use Doctrine\Common\Collections\ArrayCollection;
9
use Doctrine\ORM\EntityManagerInterface;
10
use PHPUnit\Framework\TestCase;
11
use Prophecy\Prophecy\ObjectProphecy;
12
use Shlinkio\Shlink\Core\Entity\ShortUrl;
13
use Shlinkio\Shlink\Core\Entity\Visit;
14
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
15
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
16
use Shlinkio\Shlink\Core\Model\Visitor;
17
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
18
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolver;
19
20
use function Functional\map;
21
use function range;
22
23
class ShortUrlResolverTest extends TestCase
24
{
25
    private ShortUrlResolver $urlResolver;
26
    private ObjectProphecy $em;
27
28
    public function setUp(): void
29
    {
30
        $this->em = $this->prophesize(EntityManagerInterface::class);
31
        $this->urlResolver = new ShortUrlResolver($this->em->reveal());
32
    }
33
34
    /** @test */
35
    public function shortCodeIsProperlyParsed(): void
36
    {
37
        $shortUrl = new ShortUrl('expected_url');
38
        $shortCode = $shortUrl->getShortCode();
39
40
        $repo = $this->prophesize(ShortUrlRepositoryInterface::class);
41
        $findOneByShortCode = $repo->findOneByShortCode($shortCode, null)->willReturn($shortUrl);
42
        $getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
43
44
        $result = $this->urlResolver->shortCodeToShortUrl($shortCode);
45
46
        $this->assertSame($shortUrl, $result);
47
        $findOneByShortCode->shouldHaveBeenCalledOnce();
48
        $getRepo->shouldHaveBeenCalledOnce();
49
    }
50
51
    /** @test */
52
    public function exceptionIsThrownIfShortcodeIsNotFound(): void
53
    {
54
        $shortCode = 'abc123';
55
56
        $repo = $this->prophesize(ShortUrlRepositoryInterface::class);
57
        $findOneByShortCode = $repo->findOneByShortCode($shortCode, null)->willReturn(null);
58
        $getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
59
60
        $this->expectException(ShortUrlNotFoundException::class);
61
        $findOneByShortCode->shouldBeCalledOnce();
62
        $getRepo->shouldBeCalledOnce();
63
64
        $this->urlResolver->shortCodeToShortUrl($shortCode);
65
    }
66
67
    /** @test */
68
    public function shortCodeToEnabledShortUrlProperlyParsesShortCode(): void
69
    {
70
        $shortUrl = new ShortUrl('expected_url');
71
        $shortCode = $shortUrl->getShortCode();
72
73
        $repo = $this->prophesize(ShortUrlRepositoryInterface::class);
74
        $findOneByShortCode = $repo->findOneByShortCode($shortCode, null)->willReturn($shortUrl);
75
        $getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
76
77
        $result = $this->urlResolver->shortCodeToEnabledShortUrl($shortCode);
78
79
        $this->assertSame($shortUrl, $result);
80
        $findOneByShortCode->shouldHaveBeenCalledOnce();
81
        $getRepo->shouldHaveBeenCalledOnce();
82
    }
83
84
    /**
85
     * @test
86
     * @dataProvider provideDisabledShortUrls
87
     */
88
    public function shortCodeToEnabledShortUrlThrowsExceptionIfUrlIsNotEnabled(ShortUrl $shortUrl): void
89
    {
90
        $shortCode = $shortUrl->getShortCode();
91
92
        $repo = $this->prophesize(ShortUrlRepositoryInterface::class);
93
        $findOneByShortCode = $repo->findOneByShortCode($shortCode, null)->willReturn($shortUrl);
94
        $getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
95
96
        $this->expectException(ShortUrlNotFoundException::class);
97
        $findOneByShortCode->shouldBeCalledOnce();
98
        $getRepo->shouldBeCalledOnce();
99
100
        $this->urlResolver->shortCodeToEnabledShortUrl($shortCode);
101
    }
102
103
    public function provideDisabledShortUrls(): iterable
104
    {
105
        $now = Chronos::now();
106
107
        yield 'maxVisits reached' => [(function () {
108
            $shortUrl = new ShortUrl('', ShortUrlMeta::fromRawData(['maxVisits' => 3]));
109
            $shortUrl->setVisits(new ArrayCollection(map(
110
                range(0, 4),
111
                fn () => new Visit($shortUrl, Visitor::emptyInstance()),
112
            )));
113
114
            return $shortUrl;
115
        })()];
116
        yield 'future validSince' => [new ShortUrl('', ShortUrlMeta::fromRawData([
117
            'validSince' => $now->addMonth()->toAtomString(),
118
        ]))];
119
        yield 'past validUntil' => [new ShortUrl('', ShortUrlMeta::fromRawData([
120
            'validUntil' => $now->subMonth()->toAtomString(),
121
        ]))];
122
        yield 'mixed' => [(function () use ($now) {
123
            $shortUrl = new ShortUrl('', ShortUrlMeta::fromRawData([
124
                'maxVisits' => 3,
125
                'validUntil' => $now->subMonth()->toAtomString(),
126
            ]));
127
            $shortUrl->setVisits(new ArrayCollection(map(
128
                range(0, 4),
129
                fn () => new Visit($shortUrl, Visitor::emptyInstance()),
130
            )));
131
132
            return $shortUrl;
133
        })()];
134
    }
135
}
136