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 Sylius\Tests\Controller; |
13
|
|
|
|
14
|
|
|
use Lakion\ApiTestCase\JsonApiTestCase; |
15
|
|
|
use Symfony\Component\HttpFoundation\Response; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* @author Anna Walasek <[email protected]> |
19
|
|
|
*/ |
20
|
|
|
final class ProductVariantApiTest extends JsonApiTestCase |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* @var array |
24
|
|
|
*/ |
25
|
|
|
private static $authorizedHeaderWithContentType = [ |
26
|
|
|
'HTTP_Authorization' => 'Bearer SampleTokenNjZkNjY2MDEwMTAzMDkxMGE0OTlhYzU3NzYyMTE0ZGQ3ODcyMDAwM2EwMDZjNDI5NDlhMDdlMQ', |
27
|
|
|
'CONTENT_TYPE' => 'application/json', |
28
|
|
|
]; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var array |
32
|
|
|
*/ |
33
|
|
|
private static $authorizedHeaderWithAccept = [ |
34
|
|
|
'HTTP_Authorization' => 'Bearer SampleTokenNjZkNjY2MDEwMTAzMDkxMGE0OTlhYzU3NzYyMTE0ZGQ3ODcyMDAwM2EwMDZjNDI5NDlhMDdlMQ', |
35
|
|
|
'ACCEPT' => 'application/json', |
36
|
|
|
]; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @test |
40
|
|
|
*/ |
41
|
|
|
public function it_does_not_allow_to_show_product_variant_list_when_access_is_denied() |
42
|
|
|
{ |
43
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
44
|
|
|
|
45
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants', $product_variants_data['product1']->getId())); |
|
|
|
|
46
|
|
|
$response = $this->client->getResponse(); |
47
|
|
|
|
48
|
|
|
$this->assertResponse($response, 'authentication/access_denied_response', Response::HTTP_UNAUTHORIZED); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @test |
53
|
|
|
*/ |
54
|
|
|
public function it_does_not_allow_to_show_product_variant_when_it_does_not_exist() |
55
|
|
|
{ |
56
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
57
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
58
|
|
|
|
59
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants/-1', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
60
|
|
|
$response = $this->client->getResponse(); |
61
|
|
|
|
62
|
|
|
$this->assertResponse($response, 'error/not_found_response', Response::HTTP_NOT_FOUND); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @test |
67
|
|
|
*/ |
68
|
|
|
public function it_allows_showing_product_variant() |
69
|
|
|
{ |
70
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
71
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
72
|
|
|
|
73
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants/%s', $product_variants_data['product1']->getId(), $product_variants_data['productVariant2']->getId()), [], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
74
|
|
|
$response = $this->client->getResponse(); |
75
|
|
|
|
76
|
|
|
$this->assertResponse($response, 'product_variant/show_response', Response::HTTP_OK); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @test |
81
|
|
|
*/ |
82
|
|
|
public function it_allows_indexing_product_variants() |
83
|
|
|
{ |
84
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
85
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
86
|
|
|
|
87
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
88
|
|
|
$response = $this->client->getResponse(); |
89
|
|
|
|
90
|
|
|
$this->assertResponse($response, 'product_variant/index_response', Response::HTTP_OK); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* @test |
95
|
|
|
*/ |
96
|
|
|
public function it_allows_paginating_the_index_of_product_variant() |
97
|
|
|
{ |
98
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
99
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
100
|
|
|
|
101
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), ['page' => 2], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
102
|
|
|
$response = $this->client->getResponse(); |
103
|
|
|
|
104
|
|
|
$this->assertResponse($response, 'product_variant/paginated_index_response', Response::HTTP_OK); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* @test |
109
|
|
|
*/ |
110
|
|
|
public function it_allows_sorting_the_index_of_product_variants() |
111
|
|
|
{ |
112
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
113
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
114
|
|
|
|
115
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), ['sorting' => ['position' => 'desc']], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
116
|
|
|
$response = $this->client->getResponse(); |
117
|
|
|
|
118
|
|
|
$this->assertResponse($response, 'product_variant/sorted_index_response'); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @test |
123
|
|
|
*/ |
124
|
|
|
public function it_allows_create_product_variant() |
125
|
|
|
{ |
126
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
127
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
128
|
|
|
|
129
|
|
|
$data = |
130
|
|
|
<<<EOT |
131
|
|
|
{ |
132
|
|
|
"code": "MONSTER_MUG" |
133
|
|
|
} |
134
|
|
|
EOT; |
135
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
136
|
|
|
$response = $this->client->getResponse(); |
137
|
|
|
|
138
|
|
|
$this->assertResponse($response, 'product_variant/create_response', Response::HTTP_CREATED); |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @test |
143
|
|
|
*/ |
144
|
|
|
public function it_does_not_allow_to_create_product_variant_without_required_fields() |
145
|
|
|
{ |
146
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
147
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
148
|
|
|
|
149
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, []); |
|
|
|
|
150
|
|
|
$response = $this->client->getResponse(); |
151
|
|
|
|
152
|
|
|
$this->assertResponse($response, 'product_variant/create_validation_fail_response', Response::HTTP_BAD_REQUEST); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* @test |
157
|
|
|
*/ |
158
|
|
|
public function it_allows_create_product_variant_with_multiple_translations() |
159
|
|
|
{ |
160
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
161
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
162
|
|
|
$this->loadFixturesFromFile('resources/locales.yml'); |
163
|
|
|
|
164
|
|
|
$data = |
165
|
|
|
<<<EOT |
166
|
|
|
{ |
167
|
|
|
"code": "MONSTER_MUG", |
168
|
|
|
"translations": { |
169
|
|
|
"de_CH": { |
170
|
|
|
"name": "Monsterbecher" |
171
|
|
|
}, |
172
|
|
|
"en_US": { |
173
|
|
|
"name": "Monster Mug" |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
} |
177
|
|
|
EOT; |
178
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
179
|
|
|
$response = $this->client->getResponse(); |
180
|
|
|
|
181
|
|
|
$this->assertResponse($response, 'product_variant/create_with_translations_response', Response::HTTP_CREATED); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* @test |
186
|
|
|
*/ |
187
|
|
|
public function it_allows_create_product_variant_with_channel_pricings() |
188
|
|
|
{ |
189
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
190
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
191
|
|
|
$this->loadFixturesFromFile('resources/channels.yml'); |
192
|
|
|
|
193
|
|
|
$data = |
194
|
|
|
<<<EOT |
195
|
|
|
{ |
196
|
|
|
"code": "MONSTER_MUG", |
197
|
|
|
"channelPricings": [ |
198
|
|
|
{ |
199
|
|
|
"price": "1243" |
200
|
|
|
}, |
201
|
|
|
{ |
202
|
|
|
"price": "342" |
203
|
|
|
} |
204
|
|
|
] |
205
|
|
|
} |
206
|
|
|
EOT; |
207
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
208
|
|
|
$response = $this->client->getResponse(); |
209
|
|
|
|
210
|
|
|
$this->assertResponse($response, 'product_variant/create_with_channel_pricings_response', Response::HTTP_CREATED); |
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
/** |
214
|
|
|
* @test |
215
|
|
|
*/ |
216
|
|
|
public function it_allows_create_tracked_product_variant() |
217
|
|
|
{ |
218
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
219
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
220
|
|
|
|
221
|
|
|
$data = |
222
|
|
|
<<<EOT |
223
|
|
|
{ |
224
|
|
|
"code": "MONSTER_MUG", |
225
|
|
|
"tracked": true, |
226
|
|
|
"onHand": 5 |
227
|
|
|
} |
228
|
|
|
EOT; |
229
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
230
|
|
|
$response = $this->client->getResponse(); |
231
|
|
|
|
232
|
|
|
$this->assertResponse($response, 'product_variant/create_tracked_response', Response::HTTP_CREATED); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* @test |
237
|
|
|
*/ |
238
|
|
|
public function it_allows_create_product_variant_with_tax_category() |
239
|
|
|
{ |
240
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
241
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
242
|
|
|
$this->loadFixturesFromFile('resources/tax_categories.yml'); |
243
|
|
|
|
244
|
|
|
$data = |
245
|
|
|
<<<EOT |
246
|
|
|
{ |
247
|
|
|
"code": "MONSTER_MUG", |
248
|
|
|
"tax_category": "TC1" |
249
|
|
|
} |
250
|
|
|
EOT; |
251
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
252
|
|
|
$response = $this->client->getResponse(); |
253
|
|
|
|
254
|
|
|
$this->assertResponse($response, 'product_variant/create_with_tax_category_response', Response::HTTP_CREATED); |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* @test |
259
|
|
|
*/ |
260
|
|
|
public function it_allows_create_product_variant_with_shipping_category() |
261
|
|
|
{ |
262
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
263
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
264
|
|
|
$this->loadFixturesFromFile('resources/shipping_categories.yml'); |
265
|
|
|
|
266
|
|
|
$data = |
267
|
|
|
<<<EOT |
268
|
|
|
{ |
269
|
|
|
"code": "MONSTER_MUG", |
270
|
|
|
"shipping_category": "SC1" |
271
|
|
|
} |
272
|
|
|
EOT; |
273
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
274
|
|
|
$response = $this->client->getResponse(); |
275
|
|
|
|
276
|
|
|
$this->assertResponse($response, 'product_variant/create_with_shipping_category_response', Response::HTTP_CREATED); |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
/** |
280
|
|
|
* @test |
281
|
|
|
*/ |
282
|
|
|
public function it_allows_create_product_variant_with_product_option() |
283
|
|
|
{ |
284
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
285
|
|
|
$this->loadFixturesFromFile('resources/locales.yml'); |
286
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
287
|
|
|
|
288
|
|
|
$data = |
289
|
|
|
<<<EOT |
290
|
|
|
{ |
291
|
|
|
"code": "MONSTER_MUG", |
292
|
|
|
"option_values": { |
293
|
|
|
"MUG__TYPE": "MUG_TYPE_MEDIUM" |
294
|
|
|
} |
295
|
|
|
} |
296
|
|
|
EOT; |
297
|
|
|
$this->client->request('POST', sprintf('/api/v1/products/%s/variants/', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
298
|
|
|
$response = $this->client->getResponse(); |
299
|
|
|
|
300
|
|
|
$this->assertResponse($response, 'product_variant/create_with_product_option_response', Response::HTTP_CREATED); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
/** |
304
|
|
|
* @test |
305
|
|
|
*/ |
306
|
|
|
public function it_does_not_allow_delete_product_variant_if_it_does_not_exist() |
307
|
|
|
{ |
308
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
309
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
310
|
|
|
|
311
|
|
|
$this->client->request('DELETE', sprintf('/api/v1/products/%s/variants/-1', $product_variants_data['product1']->getId()), [], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
312
|
|
|
$response = $this->client->getResponse(); |
313
|
|
|
|
314
|
|
|
$this->assertResponse($response, 'error/not_found_response', Response::HTTP_NOT_FOUND); |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
/** |
318
|
|
|
* @test |
319
|
|
|
*/ |
320
|
|
|
public function it_allows_delete_product_variant() |
321
|
|
|
{ |
322
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
323
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
324
|
|
|
|
325
|
|
|
$this->client->request('DELETE', sprintf('/api/v1/products/%s/variants/%s', $product_variants_data['product1']->getId(), $product_variants_data['productVariant1']->getId()), [], [], static::$authorizedHeaderWithContentType, []); |
|
|
|
|
326
|
|
|
|
327
|
|
|
$response = $this->client->getResponse(); |
328
|
|
|
$this->assertResponseCode($response, Response::HTTP_NO_CONTENT); |
329
|
|
|
|
330
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants/%s', $product_variants_data['product1']->getId(), $product_variants_data['productVariant1']->getId()), [], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
331
|
|
|
$response = $this->client->getResponse(); |
332
|
|
|
|
333
|
|
|
$this->assertResponse($response, 'error/not_found_response', Response::HTTP_NOT_FOUND); |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* @test |
338
|
|
|
*/ |
339
|
|
|
public function it_allows_updating_information_about_product_variant() |
340
|
|
|
{ |
341
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
342
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
343
|
|
|
|
344
|
|
|
$data = |
345
|
|
|
<<<EOT |
346
|
|
|
{ |
347
|
|
|
"code": "NEW_MUG_CODE" |
348
|
|
|
} |
349
|
|
|
EOT; |
350
|
|
|
$this->client->request('PUT', sprintf('/api/v1/products/%s/variants/%s', $product_variants_data['product1']->getId(), $product_variants_data['productVariant1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
351
|
|
|
$response = $this->client->getResponse(); |
352
|
|
|
|
353
|
|
|
$this->assertResponseCode($response, Response::HTTP_NO_CONTENT); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* @test |
359
|
|
|
*/ |
360
|
|
|
public function it_allows_updating_partial_information_about_product_variant() |
361
|
|
|
{ |
362
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
363
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
364
|
|
|
$this->loadFixturesFromFile('resources/locales.yml'); |
365
|
|
|
|
366
|
|
|
$data = |
367
|
|
|
<<<EOT |
368
|
|
|
{ |
369
|
|
|
"translations": { |
370
|
|
|
"de_CH": { |
371
|
|
|
"name": "Monsterbecher" |
372
|
|
|
|
373
|
|
|
} |
374
|
|
|
} |
375
|
|
|
} |
376
|
|
|
EOT; |
377
|
|
|
$this->client->request('PATCH', sprintf('/api/v1/products/%s/variants/%s', $product_variants_data['product1']->getId(), $product_variants_data['productVariant1']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
378
|
|
|
$response = $this->client->getResponse(); |
379
|
|
|
|
380
|
|
|
$this->assertResponseCode($response, Response::HTTP_NO_CONTENT); |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
/** |
384
|
|
|
* @test |
385
|
|
|
*/ |
386
|
|
|
public function it_not_change_on_hand_after_updating_product_variant() |
387
|
|
|
{ |
388
|
|
|
$this->loadFixturesFromFile('authentication/api_administrator.yml'); |
389
|
|
|
$product_variants_data = $this->loadFixturesFromFile('resources/product_variants.yml'); |
|
|
|
|
390
|
|
|
$this->loadFixturesFromFile('resources/locales.yml'); |
391
|
|
|
|
392
|
|
|
$data = |
393
|
|
|
<<<EOT |
394
|
|
|
{ |
395
|
|
|
"tracked": false |
396
|
|
|
} |
397
|
|
|
EOT; |
398
|
|
|
$this->client->request('PATCH', sprintf('/api/v1/products/%s/variants/%s', $product_variants_data['product2']->getId(), $product_variants_data['productVariant21']->getId()), [], [], static::$authorizedHeaderWithContentType, $data); |
|
|
|
|
399
|
|
|
$response = $this->client->getResponse(); |
400
|
|
|
|
401
|
|
|
$this->assertResponseCode($response, Response::HTTP_NO_CONTENT); |
402
|
|
|
|
403
|
|
|
$this->client->request('GET', sprintf('/api/v1/products/%s/variants/%s', $product_variants_data['product2']->getId(), $product_variants_data['productVariant21']->getId()), [], [], static::$authorizedHeaderWithAccept); |
|
|
|
|
404
|
|
|
$response = $this->client->getResponse(); |
405
|
|
|
|
406
|
|
|
$this->assertResponse($response, 'product_variant/not_changed_on_hand_response', Response::HTTP_OK); |
407
|
|
|
} |
408
|
|
|
} |
409
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.