Completed
Push — 1.0-community-org ( 019488 )
by Kamil
24:49
created

ThemeLoaderSpec::let()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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