Completed
Pull Request — develop (#688)
by Alejandro
05:47
created

ShortUrlServiceTest::provideShortUrlEdits()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 14
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Core\Service;
6
7
use Cake\Chronos\Chronos;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Doctrine\ORM\EntityRepository;
10
use PHPUnit\Framework\TestCase;
11
use Prophecy\Argument;
12
use Prophecy\Prophecy\ObjectProphecy;
13
use Shlinkio\Shlink\Core\Entity\ShortUrl;
14
use Shlinkio\Shlink\Core\Entity\Tag;
15
use Shlinkio\Shlink\Core\Model\ShortUrlEdit;
16
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
17
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
18
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
19
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
20
use Shlinkio\Shlink\Core\Service\ShortUrlService;
21
use Shlinkio\Shlink\Core\Util\UrlValidatorInterface;
22
23
use function count;
24
25
class ShortUrlServiceTest extends TestCase
26
{
27
    private ShortUrlService $service;
28
    private ObjectProphecy $em;
29
    private ObjectProphecy $urlResolver;
30
    private ObjectProphecy $urlValidator;
31
32
    public function setUp(): void
33
    {
34
        $this->em = $this->prophesize(EntityManagerInterface::class);
35
        $this->em->persist(Argument::any())->willReturn(null);
36
        $this->em->flush()->willReturn(null);
37
38
        $this->urlResolver = $this->prophesize(ShortUrlResolverInterface::class);
39
        $this->urlValidator = $this->prophesize(UrlValidatorInterface::class);
40
41
        $this->service = new ShortUrlService(
42
            $this->em->reveal(),
43
            $this->urlResolver->reveal(),
44
            $this->urlValidator->reveal(),
45
        );
46
    }
47
48
    /** @test */
49
    public function listedUrlsAreReturnedFromEntityManager(): void
50
    {
51
        $list = [
52
            new ShortUrl(''),
53
            new ShortUrl(''),
54
            new ShortUrl(''),
55
            new ShortUrl(''),
56
        ];
57
58
        $repo = $this->prophesize(ShortUrlRepository::class);
59
        $repo->findList(Argument::cetera())->willReturn($list)->shouldBeCalledOnce();
60
        $repo->countList(Argument::cetera())->willReturn(count($list))->shouldBeCalledOnce();
61
        $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
62
63
        $list = $this->service->listShortUrls(ShortUrlsParams::emptyInstance());
64
        $this->assertEquals(4, $list->getCurrentItemCount());
65
    }
66
67
    /** @test */
68
    public function providedTagsAreGetFromRepoAndSetToTheShortUrl(): void
69
    {
70
        $shortUrl = $this->prophesize(ShortUrl::class);
71
        $shortUrl->setTags(Argument::any())->shouldBeCalledOnce();
72
        $shortCode = 'abc123';
73
        $this->urlResolver->resolveShortUrl(new ShortUrlIdentifier($shortCode))->willReturn($shortUrl->reveal())
74
                                                                               ->shouldBeCalledOnce();
75
76
        $tagRepo = $this->prophesize(EntityRepository::class);
77
        $tagRepo->findOneBy(['name' => 'foo'])->willReturn(new Tag('foo'))->shouldBeCalledOnce();
78
        $tagRepo->findOneBy(['name' => 'bar'])->willReturn(null)->shouldBeCalledOnce();
79
        $this->em->getRepository(Tag::class)->willReturn($tagRepo->reveal());
80
81
        $this->service->setTagsByShortCode(new ShortUrlIdentifier($shortCode), ['foo', 'bar']);
82
    }
83
84
    /**
85
     * @test
86
     * @dataProvider provideShortUrlEdits
87
     */
88
    public function updateMetadataByShortCodeUpdatesProvidedData(
89
        int $expectedValidateCalls,
90
        ShortUrlEdit $shortUrlEdit
91
    ): void {
92
        $originalLongUrl = 'originalLongUrl';
93
        $shortUrl = new ShortUrl($originalLongUrl);
94
95
        $findShortUrl = $this->urlResolver->resolveShortUrl(new ShortUrlIdentifier('abc123'))->willReturn($shortUrl);
96
        $flush = $this->em->flush()->willReturn(null);
97
98
        $result = $this->service->updateMetadataByShortCode(new ShortUrlIdentifier('abc123'), $shortUrlEdit);
99
100
        $this->assertSame($shortUrl, $result);
101
        $this->assertEquals($shortUrlEdit->validSince(), $shortUrl->getValidSince());
102
        $this->assertEquals($shortUrlEdit->validUntil(), $shortUrl->getValidUntil());
103
        $this->assertEquals($shortUrlEdit->maxVisits(), $shortUrl->getMaxVisits());
104
        $this->assertEquals($shortUrlEdit->longUrl() ?? $originalLongUrl, $shortUrl->getLongUrl());
105
        $findShortUrl->shouldHaveBeenCalled();
106
        $flush->shouldHaveBeenCalled();
107
        $this->urlValidator->validateUrl($shortUrlEdit->longUrl())->shouldHaveBeenCalledTimes($expectedValidateCalls);
108
    }
109
110
    public function provideShortUrlEdits(): iterable
111
    {
112
        yield 'no long URL' => [0, ShortUrlEdit::fromRawData(
113
            [
114
                'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
115
                'validUntil' => Chronos::parse('2017-01-05 00:00:00')->toAtomString(),
116
                'maxVisits' => 5,
117
            ],
118
        )];
119
        yield 'long URL' => [1, ShortUrlEdit::fromRawData(
120
            [
121
                'validSince' => Chronos::parse('2017-01-01 00:00:00')->toAtomString(),
122
                'maxVisits' => 10,
123
                'longUrl' => 'modifiedLongUrl',
124
            ],
125
        )];
126
    }
127
}
128