Completed
Push — master ( 79d213...eeff33 )
by Kamil
23:15
created

ThemeLoaderSpec::it_loads_a_theme_with_author()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 27
rs 8.8571
cc 1
eloc 17
nc 1
nop 6
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace spec\Sylius\Bundle\ThemeBundle\Loader;
13
14
use PhpSpec\ObjectBehavior;
15
use Prophecy\Argument;
16
use Sylius\Bundle\ThemeBundle\Configuration\Provider\ConfigurationProviderInterface;
17
use Sylius\Bundle\ThemeBundle\Factory\ThemeAuthorFactoryInterface;
18
use Sylius\Bundle\ThemeBundle\Factory\ThemeFactoryInterface;
19
use Sylius\Bundle\ThemeBundle\Loader\CircularDependencyCheckerInterface;
20
use Sylius\Bundle\ThemeBundle\Loader\CircularDependencyFoundException;
21
use Sylius\Bundle\ThemeBundle\Loader\ThemeLoader;
22
use Sylius\Bundle\ThemeBundle\Loader\ThemeLoaderInterface;
23
use Sylius\Bundle\ThemeBundle\Loader\ThemeLoadingFailedException;
24
use Sylius\Bundle\ThemeBundle\Model\ThemeAuthor;
25
use Sylius\Bundle\ThemeBundle\Model\ThemeInterface;
26
use Zend\Hydrator\HydrationInterface;
27
28
/**
29
 * @mixin ThemeLoader
30
 *
31
 * @author Kamil Kokot <[email protected]>
32
 */
33
class ThemeLoaderSpec extends ObjectBehavior
34
{
35
    function let(
36
        ConfigurationProviderInterface $configurationProvider,
37
        ThemeFactoryInterface $themeFactory,
38
        ThemeAuthorFactoryInterface $themeAuthorFactory,
39
        HydrationInterface $themeHydrator,
40
        CircularDependencyCheckerInterface $circularDependencyChecker
41
    ) {
42
        $this->beConstructedWith(
43
            $configurationProvider,
44
            $themeFactory,
45
            $themeAuthorFactory,
46
            $themeHydrator,
47
            $circularDependencyChecker
48
        );
49
    }
50
51
    function it_is_initializable()
52
    {
53
        $this->shouldHaveType('Sylius\Bundle\ThemeBundle\Loader\ThemeLoader');
54
    }
55
56
    function it_implements_theme_loader_interface()
57
    {
58
        $this->shouldImplement(ThemeLoaderInterface::class);
59
    }
60
61
    function it_loads_a_single_theme(
62
        ConfigurationProviderInterface $configurationProvider,
63
        ThemeFactoryInterface $themeFactory,
64
        HydrationInterface $themeHydrator,
65
        CircularDependencyCheckerInterface $circularDependencyChecker,
66
        ThemeInterface $theme
67
    ) {
68
        $configurationProvider->getConfigurations()->willReturn([
69
            ['name' => 'first/theme', 'parents' => [], 'authors' => []]
70
        ]);
71
72
        $themeFactory->createNamed('first/theme')->willReturn($theme);
73
74
        $themeHydrator->hydrate(['name' => 'first/theme', 'parents' => [], 'authors' => []], $theme)->willReturn($theme);
75
76
        $circularDependencyChecker->check($theme)->shouldBeCalled();
77
78
        $this->load()->shouldReturn([$theme]);
79
    }
80
81
    function it_loads_a_theme_with_author(
82
        ConfigurationProviderInterface $configurationProvider,
83
        ThemeFactoryInterface $themeFactory,
84
        ThemeAuthorFactoryInterface $themeAuthorFactory,
85
        HydrationInterface $themeHydrator,
86
        CircularDependencyCheckerInterface $circularDependencyChecker,
87
        ThemeInterface $theme
88
    ) {
89
        $themeAuthor = new ThemeAuthor();
90
91
        $configurationProvider->getConfigurations()->willReturn([
92
            [
93
                'name' => 'first/theme',
94
                'parents' => [],
95
                'authors' => [['name' => 'Richard Rynkowsky']]
96
            ]
97
        ]);
98
99
        $themeFactory->createNamed('first/theme')->willReturn($theme);
100
        $themeAuthorFactory->createFromArray(['name' => 'Richard Rynkowsky'])->willReturn($themeAuthor);
101
102
        $themeHydrator->hydrate(['name' => 'first/theme', 'parents' => [], 'authors' => [$themeAuthor]], $theme)->willReturn($theme);
103
104
        $circularDependencyChecker->check($theme)->shouldBeCalled();
105
106
        $this->load()->shouldReturn([$theme]);
107
    }
108
109
    function it_loads_a_theme_with_its_dependency(
110
        ConfigurationProviderInterface $configurationProvider,
111
        ThemeFactoryInterface $themeFactory,
112
        HydrationInterface $themeHydrator,
113
        CircularDependencyCheckerInterface $circularDependencyChecker,
114
        ThemeInterface $firstTheme,
115
        ThemeInterface $secondTheme
116
    ) {
117
        $configurationProvider->getConfigurations()->willReturn([
118
            ['name' => 'first/theme', 'parents' => ['second/theme'], 'authors' => []],
119
            ['name' => 'second/theme', 'parents' => [], 'authors' => []],
120
        ]);
121
122
        $themeFactory->createNamed('first/theme')->willReturn($firstTheme);
123
        $themeFactory->createNamed('second/theme')->willReturn($secondTheme);
124
125
        $themeHydrator->hydrate(['name' => 'first/theme', 'parents' => [$secondTheme], 'authors' => []], $firstTheme)->willReturn($firstTheme);
126
        $themeHydrator->hydrate(['name' => 'second/theme', 'parents' => [], 'authors' => []], $secondTheme)->willReturn($secondTheme);
127
128
        $circularDependencyChecker->check($firstTheme)->shouldBeCalled();
129
        $circularDependencyChecker->check($secondTheme)->shouldBeCalled();
130
131
        $this->load()->shouldReturn([$firstTheme, $secondTheme]);
132
    }
133
134
    function it_throws_an_exception_if_requires_not_existing_dependency(
135
        ConfigurationProviderInterface $configurationProvider,
136
        ThemeFactoryInterface $themeFactory,
137
        ThemeInterface $firstTheme
138
    ) {
139
        $configurationProvider->getConfigurations()->willReturn([
140
            ['name' => 'first/theme', 'parents' => ['second/theme'], 'authors' => []],
141
        ]);
142
143
        $themeFactory->createNamed('first/theme')->willReturn($firstTheme);
144
145
        $this
146
            ->shouldThrow(new ThemeLoadingFailedException('Unexisting theme "second/theme" is required by "first/theme".'))
147
            ->during('load')
148
        ;
149
    }
150
151
    function it_throws_an_exception_if_there_is_a_circular_dependency_found(
152
        ConfigurationProviderInterface $configurationProvider,
153
        ThemeFactoryInterface $themeFactory,
154
        HydrationInterface $themeHydrator,
155
        CircularDependencyCheckerInterface $circularDependencyChecker,
156
        ThemeInterface $firstTheme,
157
        ThemeInterface $secondTheme
158
    ) {
159
        $configurationProvider->getConfigurations()->willReturn([
160
            ['name' => 'first/theme', 'parents' => ['second/theme'], 'authors' => []],
161
            ['name' => 'second/theme', 'parents' => ['first/theme'], 'authors' => []],
162
        ]);
163
164
        $themeFactory->createNamed('first/theme')->willReturn($firstTheme);
165
        $themeFactory->createNamed('second/theme')->willReturn($secondTheme);
166
167
        $themeHydrator->hydrate(['name' => 'first/theme', 'parents' => [$secondTheme], 'authors' => []], $firstTheme)->willReturn($firstTheme);
168
        $themeHydrator->hydrate(['name' => 'second/theme', 'parents' => [$firstTheme], 'authors' => []], $secondTheme)->willReturn($secondTheme);
169
170
        $circularDependencyChecker->check(Argument::cetera())->willThrow(CircularDependencyFoundException::class);
171
172
        $this
173
            ->shouldThrow(new ThemeLoadingFailedException('Circular dependency found.'))
174
            ->during('load')
175
        ;
176
    }
177
}
178