Completed
Push — develop ( 397f7d...ae636a )
by Alejandro
24s queued 13s
created

module/Core/test/Service/Tag/TagServiceTest.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Core\Service\Tag;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use PHPUnit\Framework\TestCase;
9
use Prophecy\Argument;
10
use Prophecy\Prophecy\ObjectProphecy;
11
use Shlinkio\Shlink\Core\Entity\Tag;
12
use Shlinkio\Shlink\Core\Exception\TagConflictException;
13
use Shlinkio\Shlink\Core\Exception\TagNotFoundException;
14
use Shlinkio\Shlink\Core\Repository\TagRepository;
15
use Shlinkio\Shlink\Core\Tag\Model\TagInfo;
16
use Shlinkio\Shlink\Core\Tag\TagService;
17
18
class TagServiceTest extends TestCase
19
{
20
    private TagService $service;
21
    private ObjectProphecy $em;
22
    private ObjectProphecy $repo;
23
24
    public function setUp(): void
25
    {
26
        $this->em = $this->prophesize(EntityManagerInterface::class);
27
        $this->repo = $this->prophesize(TagRepository::class);
28
        $this->em->getRepository(Tag::class)->willReturn($this->repo->reveal())->shouldBeCalled();
29
30
        $this->service = new TagService($this->em->reveal());
31
    }
32
33
    /** @test */
34
    public function listTagsDelegatesOnRepository(): void
35
    {
36
        $expected = [new Tag('foo'), new Tag('bar')];
37
38
        $find = $this->repo->findBy(Argument::cetera())->willReturn($expected);
39
40
        $result = $this->service->listTags();
41
42
        self::assertEquals($expected, $result);
43
        $find->shouldHaveBeenCalled();
44
    }
45
46
    /** @test */
47
    public function tagsInfoDelegatesOnRepository(): void
48
    {
49
        $expected = [new TagInfo(new Tag('foo'), 1, 1), new TagInfo(new Tag('bar'), 3, 10)];
50
51
        $find = $this->repo->findTagsWithInfo()->willReturn($expected);
52
53
        $result = $this->service->tagsInfo();
54
55
        self::assertEquals($expected, $result);
56
        $find->shouldHaveBeenCalled();
57
    }
58
59
    /** @test */
60
    public function deleteTagsDelegatesOnRepository(): void
61
    {
62
        $delete = $this->repo->deleteByName(['foo', 'bar'])->willReturn(4);
63
64
        $this->service->deleteTags(['foo', 'bar']);
65
66
        $delete->shouldHaveBeenCalled();
67
    }
68
69
    /** @test */
70
    public function createTagsPersistsEntities(): void
71
    {
72
        $find = $this->repo->findOneBy(Argument::cetera())->willReturn(new Tag('foo'));
73
        $persist = $this->em->persist(Argument::type(Tag::class))->willReturn(null);
74
        $flush = $this->em->flush()->willReturn(null);
75
76
        $result = $this->service->createTags(['foo', 'bar']);
0 ignored issues
show
Deprecated Code introduced by
The function Shlinkio\Shlink\Core\Tag\TagService::createTags() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

76
        $result = /** @scrutinizer ignore-deprecated */ $this->service->createTags(['foo', 'bar']);
Loading history...
77
78
        self::assertCount(2, $result);
79
        $find->shouldHaveBeenCalled();
80
        $persist->shouldHaveBeenCalledTimes(2);
81
        $flush->shouldHaveBeenCalled();
82
    }
83
84
    /** @test */
85
    public function renameInvalidTagThrowsException(): void
86
    {
87
        $find = $this->repo->findOneBy(Argument::cetera())->willReturn(null);
88
89
        $find->shouldBeCalled();
90
        $this->expectException(TagNotFoundException::class);
91
92
        $this->service->renameTag('foo', 'bar');
93
    }
94
95
    /**
96
     * @test
97
     * @dataProvider provideValidRenames
98
     */
99
    public function renameValidTagChangesItsName(string $oldName, string $newName, int $count): void
100
    {
101
        $expected = new Tag('foo');
102
103
        $find = $this->repo->findOneBy(Argument::cetera())->willReturn($expected);
104
        $countTags = $this->repo->count(Argument::cetera())->willReturn($count);
105
        $flush = $this->em->flush()->willReturn(null);
106
107
        $tag = $this->service->renameTag($oldName, $newName);
108
109
        self::assertSame($expected, $tag);
110
        self::assertEquals($newName, (string) $tag);
111
        $find->shouldHaveBeenCalled();
112
        $flush->shouldHaveBeenCalled();
113
        $countTags->shouldHaveBeenCalledTimes($count > 0 ? 0 : 1);
114
    }
115
116
    public function provideValidRenames(): iterable
117
    {
118
        yield 'same names' => ['foo', 'foo', 1];
119
        yield 'different names names' => ['foo', 'bar', 0];
120
    }
121
122
    /** @test */
123
    public function renameTagToAnExistingNameThrowsException(): void
124
    {
125
        $find = $this->repo->findOneBy(Argument::cetera())->willReturn(new Tag('foo'));
126
        $countTags = $this->repo->count(Argument::cetera())->willReturn(1);
127
        $flush = $this->em->flush(Argument::any())->willReturn(null);
128
129
        $find->shouldBeCalled();
130
        $countTags->shouldBeCalled();
131
        $flush->shouldNotBeCalled();
132
        $this->expectException(TagConflictException::class);
133
134
        $this->service->renameTag('foo', 'bar');
135
    }
136
}
137