StandardTest::testPatchException()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2025
6
 */
7
8
9
namespace Aimeos\Admin\JsonAdm;
10
11
12
class StandardTest extends \PHPUnit\Framework\TestCase
13
{
14
	private $context;
15
	private $object;
16
	private $view;
17
18
19
	protected function setUp() : void
20
	{
21
		\Aimeos\MShop::cache( true );
22
23
		$this->context = \TestHelper::context();
24
		$this->view = $this->context->view();
25
26
		$this->object = new \Aimeos\Admin\JsonAdm\Standard( $this->context, 'product' );
27
		$this->object->setAimeos( \TestHelper::getAimeos() );
28
		$this->object->setView( $this->view );
29
	}
30
31
32
	protected function tearDown() : void
33
	{
34
		\Aimeos\MShop::cache( false );
35
		unset( $this->object, $this->view, $this->context );
36
	}
37
38
39
	public function testDelete()
40
	{
41
		$this->getProductMock( array( 'delete' ) )->expects( $this->once() )->method( 'delete' );
42
43
		$params = array( 'id' => $this->getProductItem()->getId() );
44
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
45
		$this->view->addHelper( 'param', $helper );
46
47
		$response = $this->object->delete( $this->view->request(), $this->view->response() );
48
		$result = json_decode( (string) $response->getBody(), true );
49
50
51
		$this->assertEquals( 200, $response->getStatusCode() );
52
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
53
54
		$this->assertEquals( 1, $result['meta']['total'] );
55
56
		$this->assertArrayNotHasKey( 'included', $result );
57
		$this->assertArrayNotHasKey( 'data', $result );
58
		$this->assertArrayNotHasKey( 'errors', $result );
59
	}
60
61
62
	public function testDeleteBulk()
63
	{
64
		$this->getProductMock( array( 'delete' ) )->expects( $this->once() )->method( 'delete' );
65
66
		$body = '{"data":[{"type": "product", "id": "-1"},{"type": "product", "id": "-2"}]}';
67
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
68
69
		$response = $this->object->delete( $request, $this->view->response() );
70
		$result = json_decode( (string) $response->getBody(), true );
71
72
73
		$this->assertEquals( 200, $response->getStatusCode() );
74
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
75
76
		$this->assertEquals( 2, $result['meta']['total'] );
77
		$this->assertArrayNotHasKey( 'included', $result );
78
		$this->assertArrayNotHasKey( 'data', $result );
79
		$this->assertArrayNotHasKey( 'errors', $result );
80
	}
81
82
83
	public function testDeleteInvalid()
84
	{
85
		$body = '{"data":null}';
86
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
87
88
		$response = $this->object->delete( $request, $this->view->response() );
89
		$result = json_decode( (string) $response->getBody(), true );
90
91
92
		$this->assertEquals( 400, $response->getStatusCode() );
93
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
94
95
		$this->assertEquals( 0, $result['meta']['total'] );
96
		$this->assertArrayHasKey( 'errors', $result );
97
		$this->assertArrayNotHasKey( 'included', $result );
98
		$this->assertArrayNotHasKey( 'data', $result );
99
	}
100
101
102
	public function testDeleteException()
103
	{
104
		$this->getProductMock( array( 'delete' ) )->expects( $this->once() )->method( 'delete' )
105
			->will( $this->throwException( new \RuntimeException( 'test exception' ) ) );
106
107
		$params = array( 'id' => $this->getProductItem()->getId() );
108
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
109
		$this->view->addHelper( 'param', $helper );
110
111
		$response = $this->object->delete( $this->view->request(), $this->view->response() );
112
		$result = json_decode( (string) $response->getBody(), true );
113
114
		$this->assertEquals( 500, $response->getStatusCode() );
115
		$this->assertArrayHasKey( 'errors', $result );
116
	}
117
118
119
	public function testDeleteMShopException()
120
	{
121
		$this->getProductMock( array( 'delete' ) )->expects( $this->once() )->method( 'delete' )
122
			->will( $this->throwException( new \Aimeos\MShop\Exception( 'test exception' ) ) );
123
124
		$params = array( 'id' => $this->getProductItem()->getId() );
125
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
126
		$this->view->addHelper( 'param', $helper );
127
128
		$response = $this->object->delete( $this->view->request(), $this->view->response() );
129
		$result = json_decode( (string) $response->getBody(), true );
130
131
		$this->assertEquals( 404, $response->getStatusCode() );
132
		$this->assertArrayHasKey( 'errors', $result );
133
	}
134
135
136
	public function testGet()
137
	{
138
		$response = $this->object->get( $this->view->request(), $this->view->response() );
139
		$result = json_decode( (string) $response->getBody(), true );
140
141
		$this->assertEquals( 200, $response->getStatusCode() );
142
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
143
144
		$this->assertEquals( 28, $result['meta']['total'] );
145
		$this->assertEquals( 25, count( $result['data'] ) );
146
		$this->assertEquals( 'product', $result['data'][0]['type'] );
147
		$this->assertEquals( 0, count( $result['included'] ) );
148
		$this->assertArrayHasKey( 'next', $result['links'] );
149
		$this->assertArrayHasKey( 'last', $result['links'] );
150
		$this->assertArrayHasKey( 'self', $result['links'] );
151
		$this->assertArrayNotHasKey( 'errors', $result );
152
	}
153
154
155
	public function testGetType()
156
	{
157
		$object = new \Aimeos\Admin\JsonAdm\Standard( $this->context, 'product/property/type' );
158
		$object->setView( $this->view );
159
160
		$response = $object->get( $this->view->request(), $this->view->response() );
161
		$result = json_decode( (string) $response->getBody(), true );
162
163
164
		$this->assertEquals( 200, $response->getStatusCode() );
165
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
166
167
		$this->assertEquals( 4, $result['meta']['total'] );
168
		$this->assertEquals( 4, count( $result['data'] ) );
169
		$this->assertEquals( 'product/property/type', $result['data'][0]['type'] );
170
		$this->assertEquals( 0, count( $result['included'] ) );
171
172
		$this->assertArrayNotHasKey( 'errors', $result );
173
	}
174
175
176
	public function testGetInvalid()
177
	{
178
		$object = new \Aimeos\Admin\JsonAdm\Standard( $this->context, 'invalid' );
179
		$object->setView( $this->view );
180
181
		$response = $object->get( $this->view->request(), $this->view->response() );
182
		$result = json_decode( (string) $response->getBody(), true );
183
184
185
		$this->assertEquals( 500, $response->getStatusCode() );
186
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
187
188
		$this->assertEquals( 1, count( $result['errors'] ) );
189
		$this->assertArrayHasKey( 'title', $result['errors'][0] );
190
		$this->assertArrayHasKey( 'detail', $result['errors'][0] );
191
		$this->assertArrayNotHasKey( 'data', $result );
192
		$this->assertArrayNotHasKey( 'indluded', $result );
193
	}
194
195
196
	public function testGetException()
197
	{
198
		$this->getProductMock( ['get'] )->expects( $this->once() )->method( 'get' )
199
			->will( $this->throwException( new \RuntimeException( 'test exception' ) ) );
200
201
		$params = array( 'id' => -1 );
202
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
203
		$this->view->addHelper( 'param', $helper );
204
205
		$response = $this->object->get( $this->view->request(), $this->view->response() );
206
		$result = json_decode( (string) $response->getBody(), true );
207
208
		$this->assertEquals( 500, $response->getStatusCode() );
209
		$this->assertArrayHasKey( 'errors', $result );
210
	}
211
212
213
	public function testGetMShopException()
214
	{
215
		$this->getProductMock( ['get'] )->expects( $this->once() )->method( 'get' )
216
			->will( $this->throwException( new \Aimeos\MShop\Exception( 'test exception' ) ) );
217
218
		$params = array( 'id' => -1 );
219
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
220
		$this->view->addHelper( 'param', $helper );
221
222
		$response = $this->object->get( $this->view->request(), $this->view->response() );
223
		$result = json_decode( (string) $response->getBody(), true );
224
225
		$this->assertEquals( 404, $response->getStatusCode() );
226
		$this->assertArrayHasKey( 'errors', $result );
227
	}
228
229
230
	public function testGetFilter()
231
	{
232
		$params = array(
233
			'filter' => array(
234
				'==' => array( 'product.type' => 'select' )
235
			)
236
		);
237
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
238
		$this->view->addHelper( 'param', $helper );
239
240
		$response = $this->object->get( $this->view->request(), $this->view->response() );
241
		$result = json_decode( (string) $response->getBody(), true );
242
243
244
		$this->assertEquals( 200, $response->getStatusCode() );
245
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
246
247
		$this->assertEquals( 3, $result['meta']['total'] );
248
		$this->assertEquals( 3, count( $result['data'] ) );
249
		$this->assertEquals( 'product', $result['data'][0]['type'] );
250
		$this->assertEquals( 0, count( $result['included'] ) );
251
252
		$this->assertArrayNotHasKey( 'errors', $result );
253
	}
254
255
256
	public function testGetFilterCombine()
257
	{
258
		$params = array(
259
			'filter' => array(
260
				'&&' => array(
261
					array( '=~' => array( 'product.label' => 'Unittest: Test' ) ),
262
					array( '==' => array( 'product.type' => 'select' ) ),
263
				)
264
			)
265
		);
266
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
267
		$this->view->addHelper( 'param', $helper );
268
269
		$response = $this->object->get( $this->view->request(), $this->view->response() );
270
		$result = json_decode( (string) $response->getBody(), true );
271
272
273
		$this->assertEquals( 200, $response->getStatusCode() );
274
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
275
276
		$this->assertEquals( 2, $result['meta']['total'] );
277
		$this->assertEquals( 2, count( $result['data'] ) );
278
		$this->assertEquals( 'product', $result['data'][0]['type'] );
279
		$this->assertEquals( 0, count( $result['included'] ) );
280
281
		$this->assertArrayNotHasKey( 'errors', $result );
282
	}
283
284
285
	public function testGetPage()
286
	{
287
		$params = array(
288
			'page' => array(
289
				'offset' => 25,
290
				'limit' => 25
291
			)
292
		);
293
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
294
		$this->view->addHelper( 'param', $helper );
295
296
		$response = $this->object->get( $this->view->request(), $this->view->response() );
297
		$result = json_decode( (string) $response->getBody(), true );
298
299
		$this->assertEquals( 200, $response->getStatusCode() );
300
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
301
302
		$this->assertEquals( 28, $result['meta']['total'] );
303
		$this->assertEquals( 3, count( $result['data'] ) );
304
		$this->assertEquals( 'product', $result['data'][0]['type'] );
305
		$this->assertEquals( 0, count( $result['included'] ) );
306
		$this->assertArrayHasKey( 'first', $result['links'] );
307
		$this->assertArrayHasKey( 'prev', $result['links'] );
308
		$this->assertArrayHasKey( 'self', $result['links'] );
309
310
		$this->assertArrayNotHasKey( 'errors', $result );
311
	}
312
313
314
	public function testGetSort()
315
	{
316
		$params = array(
317
			'sort' => 'product.label'
318
		);
319
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
320
		$this->view->addHelper( 'param', $helper );
321
322
		$response = $this->object->get( $this->view->request(), $this->view->response() );
323
		$result = json_decode( (string) $response->getBody(), true );
324
325
326
		$this->assertEquals( 200, $response->getStatusCode() );
327
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
328
329
		$this->assertEquals( 28, $result['meta']['total'] );
330
		$this->assertEquals( 25, count( $result['data'] ) );
331
		$this->assertEquals( 'product', $result['data'][0]['type'] );
332
		$this->assertEquals( 'ABCD', $result['data'][0]['attributes']['product.code'] );
333
		$this->assertEquals( 'ABCD/16 discs', $result['data'][0]['attributes']['product.label'] );
334
		$this->assertEquals( 0, count( $result['included'] ) );
335
336
		$this->assertArrayNotHasKey( 'errors', $result );
337
	}
338
339
340
	public function testGetFields()
341
	{
342
		$params = array(
343
			'fields' => array(
344
				'product' => 'product.id,product.label'
345
			),
346
			'sort' => 'product.id',
347
			'include' => 'product'
348
		);
349
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
350
		$this->view->addHelper( 'param', $helper );
351
352
		$response = $this->object->get( $this->view->request(), $this->view->response() );
353
		$result = json_decode( (string) $response->getBody(), true );
354
355
356
		$this->assertEquals( 200, $response->getStatusCode() );
357
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
358
359
		$this->assertEquals( 28, $result['meta']['total'] );
360
		$this->assertEquals( 25, count( $result['data'] ) );
361
		$this->assertEquals( 'product', $result['data'][0]['type'] );
362
		$this->assertEquals( 2, count( $result['data'][0]['attributes'] ) );
363
364
		$this->assertArrayNotHasKey( 'errors', $result );
365
	}
366
367
368
	public function testPatch()
369
	{
370
		$productManagerStub = $this->getProductMock( array( 'get', 'save' ) );
371
372
		$item = $productManagerStub->create();
373
		$item->setLabel( 'test' );
374
		$item->setId( '-1' );
375
376
		$productManagerStub->expects( $this->once() )->method( 'save' )
377
			->willReturn( $item );
378
		$productManagerStub->expects( $this->atLeastOnce() )->method( 'get' )
379
			->willReturn( $item );
380
381
382
		$params = array( 'id' => '-1' );
383
		$helper = new \Aimeos\Base\View\Helper\Param\Standard( $this->view, $params );
384
		$this->view->addHelper( 'param', $helper );
385
386
		$body = '{"data": {"type": "product", "attributes": {"product.label": "test"}}}';
387
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
388
389
		$response = $this->object->patch( $request, $this->view->response() );
390
		$result = json_decode( (string) $response->getBody(), true );
391
392
393
		$this->assertEquals( 200, $response->getStatusCode() );
394
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
395
396
		$this->assertEquals( 1, $result['meta']['total'] );
397
		$this->assertArrayHasKey( 'data', $result );
398
		$this->assertEquals( '-1', $result['data']['id'] );
399
		$this->assertEquals( 'product', $result['data']['type'] );
400
		$this->assertEquals( 'test', $result['data']['attributes']['product.label'] );
401
402
		$this->assertArrayNotHasKey( 'included', $result );
403
		$this->assertArrayNotHasKey( 'errors', $result );
404
	}
405
406
407
	public function testPatchBulk()
408
	{
409
		$productManagerStub = $this->getProductMock( array( 'get', 'save' ) );
410
411
		$item = $productManagerStub->create();
412
		$item->setLabel( 'test' );
413
		$item->setId( '-1' );
414
415
		$productManagerStub->expects( $this->exactly( 2 ) )->method( 'save' )
416
			->willReturn( $item );
417
		$productManagerStub->expects( $this->atLeastOnce() )->method( 'get' )
418
			->willReturn( $item );
419
420
421
		$body = '{"data": [{"id": "-1", "type": "product", "attributes": {"product.label": "test"}}, {"id": "-1", "type": "product", "attributes": {"product.label": "test"}}]}';
422
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
423
424
		$response = $this->object->patch( $request, $this->view->response() );
425
		$result = json_decode( (string) $response->getBody(), true );
426
427
428
		$this->assertEquals( 200, $response->getStatusCode() );
429
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
430
431
		$this->assertEquals( 2, $result['meta']['total'] );
432
		$this->assertArrayHasKey( 'data', $result );
433
		$this->assertEquals( 2, count( $result['data'] ) );
434
		$this->assertEquals( '-1', $result['data'][0]['id'] );
435
		$this->assertEquals( 'product', $result['data'][0]['type'] );
436
		$this->assertEquals( 'test', $result['data'][0]['attributes']['product.label'] );
437
438
		$this->assertArrayNotHasKey( 'included', $result );
439
		$this->assertArrayNotHasKey( 'errors', $result );
440
	}
441
442
443
	public function testPatchInvalid()
444
	{
445
		$body = '{"data":null}';
446
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
447
448
		$response = $this->object->patch( $request, $this->view->response() );
449
		$result = json_decode( (string) $response->getBody(), true );
450
451
452
		$this->assertEquals( 400, $response->getStatusCode() );
453
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
454
455
		$this->assertEquals( 0, $result['meta']['total'] );
456
		$this->assertArrayHasKey( 'errors', $result );
457
		$this->assertArrayNotHasKey( 'included', $result );
458
		$this->assertArrayNotHasKey( 'data', $result );
459
	}
460
461
462
	public function testPatchInvalidId()
463
	{
464
		$body = '{"data":{"id":-1}}';
465
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
466
467
		$response = $this->object->patch( $request, $this->view->response() );
468
		$result = json_decode( (string) $response->getBody(), true );
469
470
471
		$this->assertEquals( 400, $response->getStatusCode() );
472
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
473
474
		$this->assertEquals( 0, $result['meta']['total'] );
475
		$this->assertArrayHasKey( 'errors', $result );
476
	}
477
478
479
	public function testPatchException()
480
	{
481
		$this->getProductMock( ['get'] )->expects( $this->once() )->method( 'get' )
482
			->will( $this->throwException( new \RuntimeException( 'test exception' ) ) );
483
484
		$body = '{"data":[{"id":-1}]}';
485
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
486
487
		$response = $this->object->patch( $request, $this->view->response() );
488
		$result = json_decode( (string) $response->getBody(), true );
489
490
491
		$this->assertEquals( 500, $response->getStatusCode() );
492
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
493
		$this->assertArrayHasKey( 'errors', $result );
494
	}
495
496
497
	public function testPatchMShopException()
498
	{
499
		$this->getProductMock( ['get'] )->expects( $this->once() )->method( 'get' )
500
			->will( $this->throwException( new \Aimeos\MShop\Exception( 'test exception' ) ) );
501
502
		$body = '{"data":[{"id":-1}]}';
503
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
504
505
		$response = $this->object->patch( $request, $this->view->response() );
506
		$result = json_decode( (string) $response->getBody(), true );
507
508
509
		$this->assertEquals( 404, $response->getStatusCode() );
510
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
511
		$this->assertArrayHasKey( 'errors', $result );
512
	}
513
514
515
	public function testPost()
516
	{
517
		$productManagerStub = $this->getProductMock( array( 'create', 'get', 'save' ) );
518
519
		$item = new \Aimeos\MShop\Product\Item\Standard( 'product.' );
520
		$item->setId( '-1' );
521
522
		$productManagerStub->expects( $this->once() )->method( 'create' )
523
			->willReturn( $item );
524
		$productManagerStub->expects( $this->any() )->method( 'get' )
525
			->willReturn( $item );
526
		$productManagerStub->expects( $this->once() )->method( 'save' )
527
			->willReturn( $item );
528
529
530
		$body = '{"data": {"type": "product", "attributes": {"product.type": "default", "product.label": "test"}}}';
531
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
532
533
		$response = $this->object->post( $request, $this->view->response() );
534
		$result = json_decode( (string) $response->getBody(), true );
535
536
		$this->assertEquals( 201, $response->getStatusCode() );
537
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
538
539
		$this->assertEquals( 1, $result['meta']['total'] );
540
		$this->assertArrayHasKey( 'data', $result );
541
		$this->assertEquals( '-1', $result['data']['id'] );
542
		$this->assertEquals( 'product', $result['data']['type'] );
543
		$this->assertEquals( 'default', $result['data']['attributes']['product.type'] );
544
		$this->assertEquals( 'test', $result['data']['attributes']['product.label'] );
545
546
		$this->assertArrayNotHasKey( 'included', $result );
547
		$this->assertArrayNotHasKey( 'errors', $result );
548
	}
549
550
551
	public function testPostBulk()
552
	{
553
		$productManagerStub = $this->getProductMock( array( 'get', 'save' ) );
554
555
		$item = $productManagerStub->create();
556
		$item->setLabel( 'test' );
557
		$item->setId( '-1' );
558
559
		$productManagerStub->expects( $this->exactly( 2 ) )->method( 'save' )
560
			->willReturn( $item );
561
		$productManagerStub->expects( $this->exactly( 2 ) )->method( 'get' )
562
			->willReturn( $item );
563
564
565
		$body = '{"data": [{"type": "product", "attributes": {"product.label": "test"}}, {"type": "product", "attributes": {"product.label": "test"}}]}';
566
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
567
568
		$response = $this->object->post( $request, $this->view->response() );
569
		$result = json_decode( (string) $response->getBody(), true );
570
571
572
		$this->assertEquals( 201, $response->getStatusCode() );
573
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
574
575
		$this->assertEquals( 2, $result['meta']['total'] );
576
		$this->assertArrayHasKey( 'data', $result );
577
		$this->assertEquals( 2, count( $result['data'] ) );
578
		$this->assertEquals( '-1', $result['data'][0]['id'] );
579
		$this->assertEquals( 'product', $result['data'][0]['type'] );
580
		$this->assertEquals( 'test', $result['data'][0]['attributes']['product.label'] );
581
582
		$this->assertArrayNotHasKey( 'included', $result );
583
		$this->assertArrayNotHasKey( 'errors', $result );
584
	}
585
586
587
	public function testPostRelationships()
588
	{
589
		$productManagerStub = $this->getProductMock( array( 'getSubManager', 'create', 'get', 'save' ) );
590
		$productManagerListsStub = $this->getProductListsMock( array( 'save' ) );
591
592
		$product = $productManagerStub->find( 'CNE' );
593
		$item = new \Aimeos\MShop\Product\Item\Standard( 'product.' );
594
		$item->setId( '-1' );
595
596
		$productManagerStub->expects( $this->once() )->method( 'create' )
597
			->willReturn( $item );
598
		$productManagerStub->expects( $this->any() )->method( 'get' )
599
			->willReturn( $item );
600
		$productManagerStub->expects( $this->once() )->method( 'getSubManager' )
601
			->willReturn( $productManagerListsStub );
602
		$productManagerStub->expects( $this->once() )->method( 'save' )
603
			->willReturn( $item );
604
605
		$productManagerListsStub->expects( $this->exactly( 2 ) )->method( 'save' );
606
607
		$body = '{"data": {"type": "product",
608
			"attributes": {"product.label": "test"},
609
			"relationships": {"text": {"data": [
610
				{"type": "text", "id": "-2", "attributes": {"product.lists.type": "default"}},
611
				{"type": "product", "id": "' . $product->getId() . '", "attributes": {"product.lists.type": "default"}}
612
			]}}
613
		}}';
614
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
615
616
		$response = $this->object->post( $request, $this->view->response() );
617
		$result = json_decode( (string) $response->getBody(), true );
618
619
		$this->assertEquals( 201, $response->getStatusCode() );
620
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
621
622
		$this->assertEquals( 1, $result['meta']['total'] );
623
		$this->assertArrayHasKey( 'data', $result );
624
		$this->assertEquals( '-1', $result['data']['id'] );
625
		$this->assertEquals( 'product', $result['data']['type'] );
626
		$this->assertEquals( 'test', $result['data']['attributes']['product.label'] );
627
628
		$this->assertArrayNotHasKey( 'included', $result );
629
		$this->assertArrayNotHasKey( 'errors', $result );
630
	}
631
632
633
	public function testPostInvalid()
634
	{
635
		$body = '{"data":null}';
636
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
637
638
		$response = $this->object->post( $request, $this->view->response() );
639
		$result = json_decode( (string) $response->getBody(), true );
640
641
642
		$this->assertEquals( 400, $response->getStatusCode() );
643
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
644
645
		$this->assertEquals( 0, $result['meta']['total'] );
646
		$this->assertArrayHasKey( 'errors', $result );
647
		$this->assertArrayNotHasKey( 'included', $result );
648
		$this->assertArrayNotHasKey( 'data', $result );
649
	}
650
651
652
	public function testPostInvalidId()
653
	{
654
		$body = '{"data":{"id":-1}}';
655
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
656
657
		$response = $this->object->post( $request, $this->view->response() );
658
		$result = json_decode( (string) $response->getBody(), true );
659
660
661
		$this->assertEquals( 403, $response->getStatusCode() );
662
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
663
664
		$this->assertEquals( 0, $result['meta']['total'] );
665
		$this->assertArrayHasKey( 'errors', $result );
666
	}
667
668
669
	public function testPostException()
670
	{
671
		$this->getProductMock( array( 'save' ) )->expects( $this->once() )->method( 'save' )
672
			->will( $this->throwException( new \RuntimeException( 'test exception' ) ) );
673
674
		$body = '{"data":{}}';
675
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
676
677
		$response = $this->object->post( $request, $this->view->response() );
678
		$result = json_decode( (string) $response->getBody(), true );
679
680
681
		$this->assertEquals( 500, $response->getStatusCode() );
682
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
683
		$this->assertArrayHasKey( 'errors', $result );
684
	}
685
686
687
	public function testPostMShopException()
688
	{
689
		$this->getProductMock( array( 'save' ) )->expects( $this->once() )->method( 'save' )
690
			->will( $this->throwException( new \Aimeos\MShop\Exception( 'test exception' ) ) );
691
692
		$body = '{"data":{}}';
693
		$request = $this->view->request()->withBody( $this->view->response()->createStreamFromString( $body ) );
694
695
		$response = $this->object->post( $request, $this->view->response() );
696
		$result = json_decode( (string) $response->getBody(), true );
697
698
699
		$this->assertEquals( 404, $response->getStatusCode() );
700
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
701
		$this->assertArrayHasKey( 'errors', $result );
702
	}
703
704
705
	public function testPut()
706
	{
707
		$response = $this->object->put( $this->view->request(), $this->view->response() );
708
		$result = json_decode( (string) $response->getBody(), true );
709
710
		$this->assertEquals( 501, $response->getStatusCode() );
711
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
712
		$this->assertArrayHasKey( 'errors', $result );
713
	}
714
715
716
	public function testOptions()
717
	{
718
		$response = $this->object->options( $this->view->request(), $this->view->response() );
719
		$result = json_decode( (string) $response->getBody(), true );
720
721
722
		$this->assertEquals( 200, $response->getStatusCode() );
723
		$this->assertEquals( 1, count( $response->getHeader( 'Allow' ) ) );
724
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
725
726
		$this->assertNull( $result['meta']['prefix'] );
727
		$this->assertGreaterThan( 42, count( $result['meta']['resources'] ) );
728
		$this->assertGreaterThan( 0, count( $result['meta']['attributes'] ) );
729
730
		$this->assertArrayNotHasKey( 'errors', $result );
731
	}
732
733
734
	public function testOptionsWithPrefix()
735
	{
736
		$this->view->prefix = 'prefix';
737
		$response = $this->object->options( $this->view->request(), $this->view->response() );
738
		$result = json_decode( (string) $response->getBody(), true );
739
740
741
		$this->assertEquals( 200, $response->getStatusCode() );
742
		$this->assertEquals( 1, count( $response->getHeader( 'Allow' ) ) );
743
		$this->assertEquals( 1, count( $response->getHeader( 'Content-Type' ) ) );
744
745
		$this->assertEquals( 'prefix', $result['meta']['prefix'] );
746
		$this->assertGreaterThan( 42, count( $result['meta']['resources'] ) );
747
		$this->assertGreaterThan( 0, count( $result['meta']['attributes'] ) );
748
749
		$this->assertArrayNotHasKey( 'errors', $result );
750
	}
751
752
753
	public function testOptionsException()
754
	{
755
		$this->getProductMock( array( 'getSearchAttributes' ) )->expects( $this->once() )->method( 'getSearchAttributes' )
756
			->will( $this->throwException( new \RuntimeException( 'test exception' ) ) );
757
758
		$response = $this->object->options( $this->view->request(), $this->view->response() );
759
		$result = json_decode( (string) $response->getBody(), true );
760
761
		$this->assertEquals( 500, $response->getStatusCode() );
762
		$this->assertArrayHasKey( 'errors', $result );
763
	}
764
765
766
	public function testOptionsMShopException()
767
	{
768
		$this->getProductMock( array( 'getSearchAttributes' ) )->expects( $this->once() )->method( 'getSearchAttributes' )
769
			->will( $this->throwException( new \Aimeos\MShop\Exception( 'test exception' ) ) );
770
771
		$response = $this->object->options( $this->view->request(), $this->view->response() );
772
		$result = json_decode( (string) $response->getBody(), true );
773
774
		$this->assertEquals( 404, $response->getStatusCode() );
775
		$this->assertArrayHasKey( 'errors', $result );
776
	}
777
778
779
	protected function getProductMock( array $methods )
780
	{
781
		$stub = $this->getMockBuilder( '\\Aimeos\\MShop\\Product\\Manager\\Standard' )
782
			->setConstructorArgs( array( $this->context ) )
783
			->onlyMethods( array_merge( $methods, ['type'] ) )
784
			->getMock();
785
786
		$stub->method( 'type' )->willReturn( ['product'] );
787
788
		\Aimeos\MShop::inject( '\\Aimeos\\MShop\\Product\\Manager\\Standard', $stub );
789
790
		return $stub;
791
	}
792
793
794
	protected function getProductListsMock( array $methods )
795
	{
796
		$stub = $this->getMockBuilder( '\\Aimeos\\MShop\\Product\\Manager\\Lists\\Standard' )
797
			->setConstructorArgs( array( $this->context ) )
798
			->onlyMethods( $methods )
799
			->getMock();
800
801
		\Aimeos\MShop::inject( '\\Aimeos\\MShop\\Product\\Manager\\Lists\\Standard', $stub );
802
803
		return $stub;
804
	}
805
806
807
	protected function getProductItem( $code = 'CNC' )
808
	{
809
		$manager = \Aimeos\MShop::create( $this->context, 'product' );
810
		$search = $manager->filter();
811
		$search->setConditions( $search->compare( '==', 'product.code', $code ) );
812
813
		if( ( $item = $manager->search( $search )->first() ) === null ) {
814
			throw new \RuntimeException( sprintf( 'No product item with code "%1$s" found', $code ) );
815
		}
816
817
		return $item;
818
	}
819
}
820