Completed
Push — scalar-types/theme ( 71f30c )
by Kamil
21:15
created

ThemeLoaderSpec::it_is_initializable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
nc 1
cc 1
eloc 2
nop 0
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
declare(strict_types=1);
13
14
namespace spec\Sylius\Bundle\ThemeBundle\Loader;
15
16
use PhpSpec\ObjectBehavior;
17
use Prophecy\Argument;
18
use Sylius\Bundle\ThemeBundle\Configuration\ConfigurationProviderInterface;
19
use Sylius\Bundle\ThemeBundle\Factory\ThemeAuthorFactoryInterface;
20
use Sylius\Bundle\ThemeBundle\Factory\ThemeFactoryInterface;
21
use Sylius\Bundle\ThemeBundle\Factory\ThemeScreenshotFactoryInterface;
22
use Sylius\Bundle\ThemeBundle\Loader\CircularDependencyCheckerInterface;
23
use Sylius\Bundle\ThemeBundle\Loader\CircularDependencyFoundException;
24
use Sylius\Bundle\ThemeBundle\Loader\ThemeLoader;
25
use Sylius\Bundle\ThemeBundle\Loader\ThemeLoaderInterface;
26
use Sylius\Bundle\ThemeBundle\Loader\ThemeLoadingFailedException;
27
use Sylius\Bundle\ThemeBundle\Model\ThemeAuthor;
28
use Sylius\Bundle\ThemeBundle\Model\ThemeInterface;
29
use Sylius\Bundle\ThemeBundle\Model\ThemeScreenshot;
30
use Zend\Hydrator\HydrationInterface;
31
32
/**
33
 * @author Kamil Kokot <[email protected]>
34
 */
35
final class ThemeLoaderSpec extends ObjectBehavior
36
{
37
    function let(
38
        ConfigurationProviderInterface $configurationProvider,
39
        ThemeFactoryInterface $themeFactory,
40
        ThemeAuthorFactoryInterface $themeAuthorFactory,
41
        ThemeScreenshotFactoryInterface $themeScreenshotFactory,
42
        HydrationInterface $themeHydrator,
43
        CircularDependencyCheckerInterface $circularDependencyChecker
44
    ): void {
45
        $this->beConstructedWith(
46
            $configurationProvider,
47
            $themeFactory,
48
            $themeAuthorFactory,
49
            $themeScreenshotFactory,
50
            $themeHydrator,
51
            $circularDependencyChecker
52
        );
53
    }
54
55
    function it_implements_theme_loader_interface(): void
56
    {
57
        $this->shouldImplement(ThemeLoaderInterface::class);
58
    }
59
60
    function it_loads_a_single_theme(
61
        ConfigurationProviderInterface $configurationProvider,
62
        ThemeFactoryInterface $themeFactory,
63
        HydrationInterface $themeHydrator,
64
        CircularDependencyCheckerInterface $circularDependencyChecker,
65
        ThemeInterface $theme
66
    ): void {
67
        $configurationProvider->getConfigurations()->willReturn([
68
            [
69
                'name' => 'first/theme',
70
                'path' => '/theme/path',
71
                'parents' => [],
72
                'authors' => [],
73
                'screenshots' => [],
74
            ],
75
        ]);
76
77
        $themeFactory->create('first/theme', '/theme/path')->willReturn($theme);
78
79
        $themeHydrator->hydrate([
80
            'name' => 'first/theme',
81
            'path' => '/theme/path',
82
            'parents' => [],
83
            'authors' => [],
84
            'screenshots' => [],
85
        ], $theme)->willReturn($theme);
86
87
        $circularDependencyChecker->check($theme)->shouldBeCalled();
88
89
        $this->load()->shouldReturn([$theme]);
90
    }
91
92
    function it_loads_a_theme_with_author(
93
        ConfigurationProviderInterface $configurationProvider,
94
        ThemeFactoryInterface $themeFactory,
95
        ThemeAuthorFactoryInterface $themeAuthorFactory,
96
        HydrationInterface $themeHydrator,
97
        CircularDependencyCheckerInterface $circularDependencyChecker,
98
        ThemeInterface $theme
99
    ): void {
100
        $themeAuthor = new ThemeAuthor();
101
102
        $configurationProvider->getConfigurations()->willReturn([
103
            [
104
                'name' => 'first/theme',
105
                'path' => '/theme/path',
106
                'parents' => [],
107
                'authors' => [['name' => 'Richard Rynkowsky']],
108
                'screenshots' => [],
109
            ]
110
        ]);
111
112
        $themeFactory->create('first/theme', '/theme/path')->willReturn($theme);
113
        $themeAuthorFactory->createFromArray(['name' => 'Richard Rynkowsky'])->willReturn($themeAuthor);
114
115
        $themeHydrator->hydrate([
116
            'name' => 'first/theme',
117
            'path' => '/theme/path',
118
            'parents' => [],
119
            'authors' => [$themeAuthor],
120
            'screenshots' => [],
121
        ], $theme)->willReturn($theme);
122
123
        $circularDependencyChecker->check($theme)->shouldBeCalled();
124
125
        $this->load()->shouldReturn([$theme]);
126
    }
127
128
    function it_loads_a_theme_with_screenshot(
129
        ConfigurationProviderInterface $configurationProvider,
130
        ThemeFactoryInterface $themeFactory,
131
        ThemeScreenshotFactoryInterface $themeScreenshotFactory,
132
        HydrationInterface $themeHydrator,
133
        CircularDependencyCheckerInterface $circularDependencyChecker,
134
        ThemeInterface $theme
135
    ): void {
136
        $themeScreenshot = new ThemeScreenshot('screenshot/omg.jpg');
137
138
        $configurationProvider->getConfigurations()->willReturn([
139
            [
140
                'name' => 'first/theme',
141
                'path' => '/theme/path',
142
                'parents' => [],
143
                'authors' => [],
144
                'screenshots' => [
145
                    ['path' => 'screenshot/omg.jpg', 'title' => 'Title'],
146
                ],
147
            ],
148
        ]);
149
150
        $themeFactory->create('first/theme', '/theme/path')->willReturn($theme);
151
        $themeScreenshotFactory->createFromArray(['path' => 'screenshot/omg.jpg', 'title' => 'Title'])->willReturn($themeScreenshot);
152
153
        $themeHydrator->hydrate([
154
            'name' => 'first/theme',
155
            'path' => '/theme/path',
156
            'parents' => [],
157
            'authors' => [],
158
            'screenshots' => [$themeScreenshot],
159
        ], $theme)->willReturn($theme);
160
161
        $circularDependencyChecker->check($theme)->shouldBeCalled();
162
163
        $this->load()->shouldReturn([$theme]);
164
    }
165
166
    function it_loads_a_theme_with_its_dependency(
167
        ConfigurationProviderInterface $configurationProvider,
168
        ThemeFactoryInterface $themeFactory,
169
        HydrationInterface $themeHydrator,
170
        CircularDependencyCheckerInterface $circularDependencyChecker,
171
        ThemeInterface $firstTheme,
172
        ThemeInterface $secondTheme
173
    ): void {
174
        $configurationProvider->getConfigurations()->willReturn([
175
            [
176
                'name' => 'first/theme',
177
                'path' => '/first/theme/path',
178
                'parents' => ['second/theme'],
179
                'authors' => [],
180
                'screenshots' => [],
181
            ],
182
            [
183
                'name' => 'second/theme',
184
                'path' => '/second/theme/path',
185
                'parents' => [],
186
                'authors' => [],
187
                'screenshots' => [],
188
            ],
189
        ]);
190
191
        $themeFactory->create('first/theme', '/first/theme/path')->willReturn($firstTheme);
192
        $themeFactory->create('second/theme', '/second/theme/path')->willReturn($secondTheme);
193
194
        $themeHydrator->hydrate([
195
            'name' => 'first/theme',
196
            'path' => '/first/theme/path',
197
            'parents' => [$secondTheme],
198
            'authors' => [],
199
            'screenshots' => [],
200
        ], $firstTheme)->willReturn($firstTheme);
201
        $themeHydrator->hydrate([
202
            'name' => 'second/theme',
203
            'path' => '/second/theme/path',
204
            'parents' => [],
205
            'authors' => [],
206
            'screenshots' => [],
207
        ], $secondTheme)->willReturn($secondTheme);
208
209
        $circularDependencyChecker->check($firstTheme)->shouldBeCalled();
210
        $circularDependencyChecker->check($secondTheme)->shouldBeCalled();
211
212
        $this->load()->shouldReturn([$firstTheme, $secondTheme]);
213
    }
214
215
    function it_throws_an_exception_if_requires_not_existing_dependency(
216
        ConfigurationProviderInterface $configurationProvider,
217
        ThemeFactoryInterface $themeFactory,
218
        ThemeInterface $firstTheme
219
    ): void {
220
        $configurationProvider->getConfigurations()->willReturn([
221
            [
222
                'name' => 'first/theme',
223
                'path' => '/theme/path',
224
                'parents' => ['second/theme'],
225
                'authors' => [],
226
                'screenshots' => [],
227
            ],
228
        ]);
229
230
        $themeFactory->create('first/theme', '/theme/path')->willReturn($firstTheme);
231
232
        $this
233
            ->shouldThrow(new ThemeLoadingFailedException('Unexisting theme "second/theme" is required by "first/theme".'))
234
            ->during('load')
235
        ;
236
    }
237
238
    function it_throws_an_exception_if_there_is_a_circular_dependency_found(
239
        ConfigurationProviderInterface $configurationProvider,
240
        ThemeFactoryInterface $themeFactory,
241
        HydrationInterface $themeHydrator,
242
        CircularDependencyCheckerInterface $circularDependencyChecker,
243
        ThemeInterface $firstTheme,
244
        ThemeInterface $secondTheme
245
    ): void {
246
        $configurationProvider->getConfigurations()->willReturn([
247
            [
248
                'name' => 'first/theme',
249
                'path' => '/first/theme/path',
250
                'parents' => ['second/theme'],
251
                'authors' => [],
252
                'screenshots' => [],
253
            ],
254
            [
255
                'name' => 'second/theme',
256
                'path' => '/second/theme/path',
257
                'parents' => ['first/theme'],
258
                'authors' => [],
259
                'screenshots' => [],
260
            ],
261
        ]);
262
263
        $themeFactory->create('first/theme', '/first/theme/path')->willReturn($firstTheme);
264
        $themeFactory->create('second/theme', '/second/theme/path')->willReturn($secondTheme);
265
266
        $themeHydrator->hydrate([
267
            'name' => 'first/theme',
268
            'path' => '/first/theme/path',
269
            'parents' => [$secondTheme],
270
            'authors' => [],
271
            'screenshots' => [],
272
        ], $firstTheme)->willReturn($firstTheme);
273
        $themeHydrator->hydrate([
274
            'name' => 'second/theme',
275
            'path' => '/second/theme/path',
276
            'parents' => [$firstTheme],
277
            'authors' => [],
278
            'screenshots' => [],
279
        ], $secondTheme)->willReturn($secondTheme);
280
281
        $circularDependencyChecker->check(Argument::cetera())->willThrow(CircularDependencyFoundException::class);
282
283
        $this
284
            ->shouldThrow(new ThemeLoadingFailedException('Circular dependency found.'))
285
            ->during('load')
286
        ;
287
    }
288
}
289