Passed
Pull Request — develop (#1)
by Andreas
03:30
created

getCatalog_IntegrationTest_LocalSampleCatalogFile()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 27
rs 8.8571
cc 2
eloc 16
nc 2
nop 0
1
<?php
2
3
use League\Flysystem\Adapter\Local;
4
use League\Flysystem\Filesystem;
5
use League\Flysystem\Memory\MemoryAdapter;
6
use Wambo\Catalog\JSONCatalogProvider;
7
use Wambo\Catalog\Mapper\CatalogMapper;
8
use Wambo\Catalog\Mapper\ContentMapper;
9
use Wambo\Catalog\Mapper\ProductMapper;
10
use Wambo\Catalog\Model\Catalog;
11
use Wambo\Catalog\Model\Product;
12
13
/**
14
 * Class JSONCatalogTest tests the JSONCatalog class.
15
 *
16
 * @package Wambo\Catalog\Tests
17
 */
18
class JSONCatalogTest extends \PHPUnit_Framework_TestCase
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
19
{
20
    /**
21
     * If the JSONCatalog is empty no products should be returned.
22
     *
23
     * @test
24
     */
25
    public function getCatalog_JSONIsEmpty_NoProductsAreReturned()
26
    {
27
        // arrange
28
        $filesystem = new Filesystem(new MemoryAdapter());
29
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
30
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
31
        $jsonCatalog = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
32
33
        // act
34
        $catalog = $jsonCatalog->getCatalog();
35
36
        // assert
37
        $this->assertEmpty($catalog, "getCatalog should not have returned a catalog if the catalog JSON is empty");
38
    }
39
40
    /**
41
     * If the CatalogMapper returns a catalog, the provider should return that catalog.
42
     *
43
     * @test
44
     * @expectedException \Wambo\Catalog\Error\CatalogException
45
     */
46 View Code Duplication
    public function getCatalog_JSONIsInvalid_CatalogExceptionIsThrown()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
47
    {
48
        // arrange
49
        $filesystem = new Filesystem(new MemoryAdapter());
50
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
51
        $catalogMapperMock->method("getCatalog")->willReturn(new Catalog(array()));
52
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
53
54
        $catalogJSON = <<<JSON
55
[
56
    {},,],,
57
]
58
JSON;
59
        $filesystem->write("catalog.json", $catalogJSON);
60
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
61
62
        // act
63
        $jsonCatalogProvider->getCatalog();
64
    }
65
66
    /**
67
     * If the CatalogMapper throws an exception, the provider should throw a CatalogException.
68
     *
69
     * @test
70
     * @expectedException Wambo\Catalog\Error\CatalogException
71
     */
72 View Code Duplication
    public function getCatalog_JSONIsValid_MapperThrowsException_CatalogExceptionIsThrown()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
73
    {
74
        // arrange
75
        $filesystem = new Filesystem(new MemoryAdapter());
76
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
77
        $catalogMapperMock->method("getCatalog")->willThrowException(new Exception("Some mapping error"));
78
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
79
80
        $catalogJSON = <<<JSON
81
[]
82
JSON;
83
        $filesystem->write("catalog.json", $catalogJSON);
84
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
85
86
        // act
87
        $jsonCatalogProvider->getCatalog();
88
    }
89
90
    /**
91
     * If the CatalogMapper returns a catalog, the provider should return that catalog.
92
     *
93
     * @test
94
     */
95 View Code Duplication
    public function getCatalog_JSONIsValid_MapperReturnsCatalog_CatalogIsReturned()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
    {
97
        // arrange
98
        $filesystem = new Filesystem(new MemoryAdapter());
99
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
100
        $catalogMapperMock->method("getCatalog")->willReturn(new Catalog(array()));
101
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
102
103
        $catalogJSON = <<<JSON
104
[
105
    {}
106
]
107
JSON;
108
        $filesystem->write("catalog.json", $catalogJSON);
109
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
110
111
        // act
112
        $catalog = $jsonCatalogProvider->getCatalog();
113
114
        // assert
115
        $this->assertNotNull($catalog, "getCatalog should return a catalog if the mapper returned one");
116
    }
117
118
    /**
119
     * Integration test with local filesystem
120
     *
121
     * @test
122
     */
123
    public function getCatalog_IntegrationTest_LocalSampleCatalogFile()
124
    {
125
        // arrange
126
        $sampleCatalogFilename = "sample-catalog.json";
127
        $testResourceFolderPath = realpath(__DIR__ . '/resources');
128
        $adapter = new Local($testResourceFolderPath);
129
        $filesystem = new Filesystem($adapter);
130
131
        $contentMapper = new ContentMapper();
132
        $productMapper = new ProductMapper($contentMapper);
133
        $catalogMapper = new CatalogMapper($productMapper);
134
135
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, $sampleCatalogFilename, $catalogMapper);
136
137
        // act
138
        $catalog = $jsonCatalogProvider->getCatalog();
139
140
        // assert
141
        foreach ($catalog->getProducts() as $product) {
142
            /** @var Product $product */
143
            $this->assertNotEmpty($product->getSku(), "The SKU should not be empty");
144
            $this->assertNotEmpty($product->getSlug(), "The slug should not be empty");
145
            $this->assertNotEmpty($product->getTitle(), "The title should not be empty");
146
            $this->assertNotEmpty($product->getSummaryText(), "The summary should not be empty");
147
            $this->assertNotEmpty($product->getProductDescription(), "The product description should not be empty");
148
        }
149
    }
150
151
    /**
152
     * Integration test
153
     *
154
     * @test
155
     */
156
    public function getCatalog_IntegrationTest_CatalogWithProductsIsReturned()
157
    {
158
        // arrange
159
        $filesystem = new Filesystem(new MemoryAdapter());
160
        $contentMapper = new ContentMapper();
161
        $productMapper = new ProductMapper($contentMapper);
162
        $catalogMapper = new CatalogMapper($productMapper);
163
164
        $catalogJSON = <<<JSON
165
[
166
    {
167
        "sku": "t-shirt-no-1",
168
        "slug": "t-shirt-no-1",
169
        "title": "T-Shirt No. 1",
170
        "summary": "Our T-Shirt No. 1",
171
        "description": "Our fancy T-Shirt No. 1 is ..."
172
    },
173
    {
174
        "sku": "t-shirt-no-2",
175
        "slug": "t-shirt-no-2",
176
        "title": "T-Shirt No. 2",
177
        "summary": "Our T-Shirt No. 2",
178
        "description": "Our fancy T-Shirt No. 2 is ..."
179
    },
180
    {
181
        "sku": "t-shirt-no-3",
182
        "slug": "t-shirt-no-3",
183
        "title": "T-Shirt No. 3",
184
        "summary": "Our T-Shirt No. 3",
185
        "description": "Our fancy T-Shirt No. 3 is ..."
186
    }
187
]
188
JSON;
189
        $filesystem->write("catalog.json", $catalogJSON);
190
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapper);
191
192
        // act
193
        $catalog = $jsonCatalogProvider->getCatalog();
194
195
        // assert
196
        $this->assertCount(3, $catalog, "getCatalog should return a catalog with 3 products");
197
    }
198
199
    /**
200
     * Integration test: invalid JSON
201
     *
202
     * @test
203
     * @dataProvider                   getInvalidCatalogJSON
204
     *
205
     * @param string $json
206
     *
207
     * @expectedException Wambo\Catalog\Error\CatalogException
208
     * @expectedExceptionMessageRegExp /Unable to read catalog/
209
     */
210
    public function getCatalog_IntegrationTest_ValidCatalog_CatalogExceptionIsThrown($json)
211
    {
212
        // arrange
213
        $filesystem = new Filesystem(new MemoryAdapter());
214
        $contentMapper = new ContentMapper();
215
        $productMapper = new ProductMapper($contentMapper);
216
        $catalogMapper = new CatalogMapper($productMapper);
217
218
        $filesystem->write("catalog.json", $json);
219
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapper);
220
221
        // act
222
        $jsonCatalogProvider->getCatalog();
223
    }
224
225
    /**
226
     * Integration test: valid catalog
227
     *
228
     * @test
229
     */
230
    public function getCatalog_IntegrationTest_ValidCatalog_AllProductAttributesAreSet()
231
    {
232
        // arrange
233
        $filesystem = new Filesystem(new MemoryAdapter());
234
        $contentMapper = new ContentMapper();
235
        $productMapper = new ProductMapper($contentMapper);
236
        $catalogMapper = new CatalogMapper($productMapper);
237
238
        $catalogJSON = <<<JSON
239
[
240
    {
241
        "sku": "t-shirt-no-1",
242
        "slug": "t-shirt-no-1-slug",
243
        "title": "T-Shirt No. 1",
244
        "summary": "Our T-Shirt No. 1",
245
        "description": "Our fancy T-Shirt No. 1 is ..."
246
    }
247
]
248
JSON;
249
        $filesystem->write("catalog.json", $catalogJSON);
250
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapper);
251
252
        // act
253
        $catalog = $jsonCatalogProvider->getCatalog();
254
255
        // assert
256
        $products = $catalog->getProducts();
257
        $this->assertCount(1, $products, "getCatalog should return a catalog with one product");
258
259
        /** @var Product $firstProduct */
260
        $firstProduct = $products[0];
261
        $this->assertEquals("t-shirt-no-1", $firstProduct->getSku(), "Wrong SKU");
262
        $this->assertEquals("t-shirt-no-1-slug", $firstProduct->getSlug(), "Wrong slug");
263
        $this->assertEquals("T-Shirt No. 1", $firstProduct->getTitle(), "Wrong title");
264
        $this->assertEquals("Our T-Shirt No. 1", $firstProduct->getSummaryText(), "Wrong summary");
265
        $this->assertEquals("Our fancy T-Shirt No. 1 is ...", $firstProduct->getProductDescription(),
266
            "Wrong description");
267
    }
268
269
    /**
270
     * Get invalid catalog JSON for testing
271
     *
272
     * @return array
273
     */
274
    public static function getInvalidCatalogJSON()
275
    {
276
        return array(
277
278
            // JavaScript instead of JSON
279
            [
280
                <<<JSON
281
                var test = {
282
    "sku": "t-shirt-no-1",
283
    "slug": "t-shirt-no-1-slug",
284
    "title": "T-Shirt No. 1",
285
    "summary": "Our T-Shirt No. 1",
286
    "description": "Our fancy T-Shirt No. 1 is ..."
287
};
288
JSON
289
            ],
290
291
            // Missing attribute quotes
292
            [
293
                <<<JSON
294
                [
295
    {
296
        sku: "t-shirt-no-1",
297
        slug: "t-shirt-no-1-slug",
298
        title: "T-Shirt No. 1",
299
        summary: "Our T-Shirt No. 1",
300
        description: "Our fancy T-Shirt No. 1 is ..."
301
    }
302
]
303
JSON
304
            ],
305
306
            // Missing comma
307
            [
308
                <<<JSON
309
                [
310
    {
311
        "sku": "t-shirt-no-1"
312
        "slug": "t-shirt-no-1-slug"
313
        "title": "T-Shirt No. 1"
314
        "summary": "Our T-Shirt No. 1"
315
        "description": "Our fancy T-Shirt No. 1 is ..."
316
    }
317
]
318
JSON
319
            ],
320
321
            // Control Character
322
            [
323
                <<<JSON
324
                [
325
    {
326
        "sku": "t-shirt-no-1"
327
        "slug": "t-shirt-no-1-slug"
328
        "title": "T-Shirt No. 1"
329
        "summary": "Our T-Shirt No. 1"
330
        "���": "Our fancy T-Shirt No. 1 is ..."
331
    }
332
]
333
JSON
334
            ]
335
        );
336
    }
337
}
338