Passed
Pull Request — develop (#1)
by Andreas
02:52
created

getCatalog_IntegrationTest_ValidCatalog_CatalogExceptionIsThrown()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 14
rs 9.4285
cc 1
eloc 8
nc 1
nop 1
1
<?php
2
3
use League\Flysystem\Filesystem;
4
use League\Flysystem\Memory\MemoryAdapter;
5
use Wambo\Catalog\Error\CatalogException;
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
use Wambo\Catalog\Validation\SKUValidator;
13
use Wambo\Catalog\Validation\SlugValidator;
14
15
/**
16
 * Class JSONCatalogTest tests the JSONCatalog class.
17
 *
18
 * @package Wambo\Catalog\Tests
19
 */
20
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...
21
{
22
    /**
23
     * If the JSONCatalog is empty no products should be returned.
24
     *
25
     * @test
26
     */
27
    public function getCatalog_JSONIsEmpty_NoProductsAreReturned()
28
    {
29
        // arrange
30
        $filesystem = new Filesystem(new MemoryAdapter());
31
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
32
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
33
        $jsonCatalog = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
34
35
        // act
36
        $catalog = $jsonCatalog->getCatalog();
37
38
        // assert
39
        $this->assertEmpty($catalog, "getCatalog should not have returned a catalog if the catalog JSON is empty");
40
    }
41
42
    /**
43
     * If the CatalogMapper returns a catalog, the provider should return that catalog.
44
     *
45
     * @test
46
     * @expectedException \Wambo\Catalog\Error\CatalogException
47
     */
48 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...
49
    {
50
        // arrange
51
        $filesystem = new Filesystem(new MemoryAdapter());
52
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
53
        $catalogMapperMock->method("getCatalog")->willReturn(new Catalog(array()));
54
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
55
56
        $catalogJSON = <<<JSON
57
[
58
    {},,],,
59
]
60
JSON;
61
        $filesystem->write("catalog.json", $catalogJSON);
62
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
63
64
        // act
65
        $jsonCatalogProvider->getCatalog();
66
    }
67
68
    /**
69
     * If the CatalogMapper throws an exception, the provider should throw a CatalogException.
70
     *
71
     * @test
72
     * @expectedException Wambo\Catalog\Error\CatalogException
73
     */
74 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...
75
    {
76
        // arrange
77
        $filesystem = new Filesystem(new MemoryAdapter());
78
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
79
        $catalogMapperMock->method("getCatalog")->willThrowException(new Exception("Some mapping error"));
80
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
81
82
        $catalogJSON = <<<JSON
83
[]
84
JSON;
85
        $filesystem->write("catalog.json", $catalogJSON);
86
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
87
88
        // act
89
        $jsonCatalogProvider->getCatalog();
90
    }
91
92
    /**
93
     * If the CatalogMapper returns a catalog, the provider should return that catalog.
94
     *
95
     * @test
96
     */
97 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...
98
    {
99
        // arrange
100
        $filesystem = new Filesystem(new MemoryAdapter());
101
        $catalogMapperMock = $this->getMockBuilder(CatalogMapper::class)->disableOriginalConstructor()->getMock();
102
        $catalogMapperMock->method("getCatalog")->willReturn(new Catalog(array()));
103
        /** @var $catalogMapperMock CatalogMapper A mock for the CatalogMapper class */
104
105
        $catalogJSON = <<<JSON
106
[
107
    {}
108
]
109
JSON;
110
        $filesystem->write("catalog.json", $catalogJSON);
111
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapperMock);
112
113
        // act
114
        $catalog = $jsonCatalogProvider->getCatalog();
115
116
        // assert
117
        $this->assertNotNull($catalog, "getCatalog should return a catalog if the mapper returned one");
118
    }
119
120
    /**
121
     * Integration test
122
     *
123
     * @test
124
     */
125
    public function getCatalog_IntegrationTest_CatalogWithProductsIsReturned()
126
    {
127
        // arrange
128
        $filesystem = new Filesystem(new MemoryAdapter());
129
        $contentMapper = new ContentMapper();
130
        $productMapper = new ProductMapper($contentMapper);
131
        $catalogMapper = new CatalogMapper($productMapper);
132
133
        $catalogJSON = <<<JSON
134
[
135
    {
136
        "sku": "t-shirt-no-1",
137
        "slug": "t-shirt-no-1",
138
        "title": "T-Shirt No. 1",
139
        "summary": "Our T-Shirt No. 1",
140
        "description": "Our fancy T-Shirt No. 1 is ..."
141
    },
142
    {
143
        "sku": "t-shirt-no-2",
144
        "slug": "t-shirt-no-2",
145
        "title": "T-Shirt No. 2",
146
        "summary": "Our T-Shirt No. 2",
147
        "description": "Our fancy T-Shirt No. 2 is ..."
148
    },
149
    {
150
        "sku": "t-shirt-no-3",
151
        "slug": "t-shirt-no-3",
152
        "title": "T-Shirt No. 3",
153
        "summary": "Our T-Shirt No. 3",
154
        "description": "Our fancy T-Shirt No. 3 is ..."
155
    }
156
]
157
JSON;
158
        $filesystem->write("catalog.json", $catalogJSON);
159
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapper);
160
161
        // act
162
        $catalog = $jsonCatalogProvider->getCatalog();
163
164
        // assert
165
        $this->assertCount(3, $catalog, "getCatalog should return a catalog with 3 products");
166
    }
167
168
    /**
169
     * Integration test: invalid JSON
170
     *
171
     * @test
172
     * @dataProvider                   getInvalidCatalogJSON
173
     *
174
     * @param string $json
175
     *
176
     * @expectedException Wambo\Catalog\Error\CatalogException
177
     * @expectedExceptionMessageRegExp /Unable to read catalog/
178
     */
179
    public function getCatalog_IntegrationTest_ValidCatalog_CatalogExceptionIsThrown($json)
180
    {
181
        // arrange
182
        $filesystem = new Filesystem(new MemoryAdapter());
183
        $contentMapper = new ContentMapper();
184
        $productMapper = new ProductMapper($contentMapper);
185
        $catalogMapper = new CatalogMapper($productMapper);
186
187
        $filesystem->write("catalog.json", $json);
188
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapper);
189
190
        // act
191
        $jsonCatalogProvider->getCatalog();
192
    }
193
194
    /**
195
     * Integration test: valid catalog
196
     *
197
     * @test
198
     */
199
    public function getCatalog_IntegrationTest_ValidCatalog_AllProductAttributesAreSet()
200
    {
201
        // arrange
202
        $filesystem = new Filesystem(new MemoryAdapter());
203
        $contentMapper = new ContentMapper();
204
        $productMapper = new ProductMapper($contentMapper);
205
        $catalogMapper = new CatalogMapper($productMapper);
206
207
        $catalogJSON = <<<JSON
208
[
209
    {
210
        "sku": "t-shirt-no-1",
211
        "slug": "t-shirt-no-1-slug",
212
        "title": "T-Shirt No. 1",
213
        "summary": "Our T-Shirt No. 1",
214
        "description": "Our fancy T-Shirt No. 1 is ..."
215
    }
216
]
217
JSON;
218
        $filesystem->write("catalog.json", $catalogJSON);
219
        $jsonCatalogProvider = new JSONCatalogProvider($filesystem, "catalog.json", $catalogMapper);
220
221
        // act
222
        $catalog = $jsonCatalogProvider->getCatalog();
223
224
        // assert
225
        $products = $catalog->getProducts();
226
        $this->assertCount(1, $products, "getCatalog should return a catalog with one product");
227
228
        /** @var Product $firstProduct */
229
        $firstProduct = $products[0];
230
        $this->assertEquals("t-shirt-no-1", $firstProduct->getSku(), "Wrong SKU");
231
        $this->assertEquals("t-shirt-no-1-slug", $firstProduct->getSlug(), "Wrong slug");
232
        $this->assertEquals("T-Shirt No. 1", $firstProduct->getTitle(), "Wrong title");
233
        $this->assertEquals("Our T-Shirt No. 1", $firstProduct->getSummaryText(), "Wrong summary");
234
        $this->assertEquals("Our fancy T-Shirt No. 1 is ...", $firstProduct->getProductDescription(),
235
            "Wrong description");
236
    }
237
238
    /**
239
     * Get invalid catalog JSON for testing
240
     *
241
     * @return array
242
     */
243
    public static function getInvalidCatalogJSON()
244
    {
245
        return array(
246
247
                // JavaScript instead of JSON
248
            [
249
                <<<JSON
250
                var test = {
251
    "sku": "t-shirt-no-1",
252
    "slug": "t-shirt-no-1-slug",
253
    "title": "T-Shirt No. 1",
254
    "summary": "Our T-Shirt No. 1",
255
    "description": "Our fancy T-Shirt No. 1 is ..."
256
};
257
JSON
258
            ],
259
260
                // Missing attribute quotes
261
            [<<<JSON
262
[
263
    {
264
        sku: "t-shirt-no-1",
265
        slug: "t-shirt-no-1-slug",
266
        title: "T-Shirt No. 1",
267
        summary: "Our T-Shirt No. 1",
268
        description: "Our fancy T-Shirt No. 1 is ..."
269
    }
270
]
271
JSON
272
            ],
273
274
                // Missing comma
275
            [<<<JSON
276
[
277
    {
278
        "sku": "t-shirt-no-1"
279
        "slug": "t-shirt-no-1-slug"
280
        "title": "T-Shirt No. 1"
281
        "summary": "Our T-Shirt No. 1"
282
        "description": "Our fancy T-Shirt No. 1 is ..."
283
    }
284
]
285
JSON
286
            ],
287
288
                // Control Character
289
            [<<<JSON
290
[
291
    {
292
        "sku": "t-shirt-no-1"
293
        "slug": "t-shirt-no-1-slug"
294
        "title": "T-Shirt No. 1"
295
        "summary": "Our T-Shirt No. 1"
296
        "���": "Our fancy T-Shirt No. 1 is ..."
297
    }
298
]
299
JSON
300
            ]
301
        );
302
    }
303
}
304