Passed
Push — master ( a70374...09ef1e )
by Mike
05:06
created

WC_Tests_API_Product::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Tests for Products API.
4
 *
5
 * @package WooCommerce\Tests\API
6
 * @since 3.5.0
7
 */
8
9
 /**
10
  * WC_Tests_API_Product class.
11
  */
12
class WC_Tests_API_Product extends WC_REST_Unit_Test_Case {
0 ignored issues
show
Bug introduced by
The type WC_REST_Unit_Test_Case was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
14
	/**
15
	 * Setup our test server, endpoints, and user info.
16
	 */
17
	public function setUp() {
18
		parent::setUp();
19
		$this->endpoint = new WC_REST_Products_Controller();
0 ignored issues
show
Bug Best Practice introduced by
The property endpoint does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
20
		$this->user     = $this->factory->user->create(
0 ignored issues
show
Bug Best Practice introduced by
The property user does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
21
			array(
22
				'role' => 'administrator',
23
			)
24
		);
25
	}
26
27
	/**
28
	 * Test route registration.
29
	 *
30
	 * @since 3.5.0
31
	 */
32
	public function test_register_routes() {
33
		$routes = $this->server->get_routes();
34
		$this->assertArrayHasKey( '/wc/v3/products', $routes );
35
		$this->assertArrayHasKey( '/wc/v3/products/(?P<id>[\d]+)', $routes );
36
		$this->assertArrayHasKey( '/wc/v3/products/batch', $routes );
37
	}
38
39
	/**
40
	 * Test getting products.
41
	 *
42
	 * @since 3.5.0
43
	 */
44
	public function test_get_products() {
45
		wp_set_current_user( $this->user );
46
		\Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product();
47
		sleep( 1 ); // So both products have different timestamps.
48
		\Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
49
		$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) );
50
		$products = $response->get_data();
51
52
		$this->assertEquals( 200, $response->get_status() );
53
54
		$this->assertEquals( 2, count( $products ) );
55
		$this->assertEquals( 'Dummy Product', $products[0]['name'] );
56
		$this->assertEquals( 'DUMMY SKU', $products[0]['sku'] );
57
		$this->assertEquals( 'Dummy External Product', $products[1]['name'] );
58
		$this->assertEquals( 'DUMMY EXTERNAL SKU', $products[1]['sku'] );
59
	}
60
61
	/**
62
	 * Test getting products without permission.
63
	 *
64
	 * @since 3.5.0
65
	 */
66
	public function test_get_products_without_permission() {
67
		wp_set_current_user( 0 );
68
		\Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
69
		$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) );
70
		$this->assertEquals( 401, $response->get_status() );
71
	}
72
73
	/**
74
	 * Test getting a single product.
75
	 *
76
	 * @since 3.5.0
77
	 */
78
	public function test_get_product() {
79
		wp_set_current_user( $this->user );
80
		$simple   = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product();
81
		$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $simple->get_id() ) );
82
		$product  = $response->get_data();
83
84
		$this->assertEquals( 200, $response->get_status() );
85
		$this->assertContains(
86
			array(
87
				'id'            => $simple->get_id(),
88
				'name'          => 'Dummy External Product',
89
				'type'          => 'simple',
90
				'status'        => 'publish',
91
				'sku'           => 'DUMMY EXTERNAL SKU',
92
				'regular_price' => 10,
93
			),
94
			$product
95
		);
96
	}
97
98
	/**
99
	 * Test getting single product without permission.
100
	 *
101
	 * @since 3.5.0
102
	 */
103
	public function test_get_product_without_permission() {
104
		wp_set_current_user( 0 );
105
		$product  = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
106
		$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) );
107
		$this->assertEquals( 401, $response->get_status() );
108
	}
109
110
	/**
111
	 * Test deleting a single product.
112
	 *
113
	 * @since 3.5.0
114
	 */
115
	public function test_delete_product() {
116
		wp_set_current_user( $this->user );
117
		$product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
118
119
		$request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() );
120
		$request->set_param( 'force', true );
121
		$response = $this->server->dispatch( $request );
122
		$this->assertEquals( 200, $response->get_status() );
123
124
		$response   = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) );
125
		$variations = $response->get_data();
126
		$this->assertEquals( 0, count( $variations ) );
127
	}
128
129
	/**
130
	 * Test deleting a single product without permission.
131
	 *
132
	 * @since 3.5.0
133
	 */
134
	public function test_delete_product_without_permission() {
135
		wp_set_current_user( 0 );
136
		$product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
137
		$request = new WP_REST_Request( 'DELETE', '/wc/v3/products/' . $product->get_id() );
138
		$request->set_param( 'force', true );
139
		$response = $this->server->dispatch( $request );
140
		$this->assertEquals( 401, $response->get_status() );
141
	}
142
143
	/**
144
	 * Test deleting a single product with an invalid ID.
145
	 *
146
	 * @since 3.5.0
147
	 */
148
	public function test_delete_product_with_invalid_id() {
149
		wp_set_current_user( 0 );
150
		$request = new WP_REST_Request( 'DELETE', '/wc/v3/products/0' );
151
		$request->set_param( 'force', true );
152
		$response = $this->server->dispatch( $request );
153
		$this->assertEquals( 404, $response->get_status() );
154
	}
155
156
	/**
157
	 * Test editing a single product. Tests multiple product types.
158
	 *
159
	 * @since 3.5.0
160
	 */
161
	public function test_update_product() {
162
		wp_set_current_user( $this->user );
163
164
		// test simple products.
165
		$product      = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
166
		$response     = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) );
167
		$data         = $response->get_data();
168
		$date_created = date( 'Y-m-d\TH:i:s', current_time( 'timestamp' ) );
169
170
		$this->assertEquals( 'DUMMY SKU', $data['sku'] );
171
		$this->assertEquals( 10, $data['regular_price'] );
172
		$this->assertEmpty( $data['sale_price'] );
173
174
		$request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() );
175
		$request->set_body_params(
176
			array(
177
				'sku'          => 'FIXED-SKU',
178
				'sale_price'   => '8',
179
				'description'  => 'Testing',
180
				'date_created' => $date_created,
181
				'images'       => array(
182
					array(
183
						'position' => 0,
184
						'src'      => 'http://cldup.com/Dr1Bczxq4q.png',
185
						'alt'      => 'test upload image',
186
					),
187
				),
188
			)
189
		);
190
		$response = $this->server->dispatch( $request );
191
		$data     = $response->get_data();
192
193
		$this->assertContains( 'Testing', $data['description'] );
194
		$this->assertEquals( '8', $data['price'] );
195
		$this->assertEquals( '8', $data['sale_price'] );
196
		$this->assertEquals( '10', $data['regular_price'] );
197
		$this->assertEquals( 'FIXED-SKU', $data['sku'] );
198
		$this->assertEquals( $date_created, $data['date_created'] );
199
		$this->assertContains( 'Dr1Bczxq4q', $data['images'][0]['src'] );
200
		$this->assertContains( 'test upload image', $data['images'][0]['alt'] );
201
		$product->delete( true );
202
203
		// test variable product (variations are tested in product-variations.php).
204
		$product  = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product();
205
		$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) );
206
		$data     = $response->get_data();
207
208
		foreach ( array( 'small', 'large' ) as $term_name ) {
209
			$this->assertContains( $term_name, $data['attributes'][0]['options'] );
210
		}
211
212
		$request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() );
213
		$request->set_body_params(
214
			array(
215
				'attributes' => array(
216
					array(
217
						'id'        => 0,
218
						'name'      => 'pa_color',
219
						'options'   => array(
220
							'red',
221
							'yellow',
222
						),
223
						'visible'   => false,
224
						'variation' => 1,
225
					),
226
					array(
227
						'id'        => 0,
228
						'name'      => 'pa_size',
229
						'options'   => array(
230
							'small',
231
						),
232
						'visible'   => false,
233
						'variation' => 1,
234
					),
235
				),
236
			)
237
		);
238
		$response = $this->server->dispatch( $request );
239
		$data     = $response->get_data();
240
241
		$this->assertEquals( array( 'small' ), $data['attributes'][0]['options'] );
242
243
		foreach ( array( 'red', 'yellow' ) as $term_name ) {
244
			$this->assertContains( $term_name, $data['attributes'][1]['options'] );
245
		}
246
247
		$product->delete( true );
248
249
		// test external product.
250
		$product  = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product();
251
		$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products/' . $product->get_id() ) );
252
		$data     = $response->get_data();
253
254
		$this->assertEquals( 'Buy external product', $data['button_text'] );
255
		$this->assertEquals( 'http://woocommerce.com', $data['external_url'] );
256
257
		$request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() );
258
		$request->set_body_params(
259
			array(
260
				'button_text'  => 'Test API Update',
261
				'external_url' => 'http://automattic.com',
262
			)
263
		);
264
		$response = $this->server->dispatch( $request );
265
		$data     = $response->get_data();
266
267
		$this->assertEquals( 'Test API Update', $data['button_text'] );
268
		$this->assertEquals( 'http://automattic.com', $data['external_url'] );
269
	}
270
271
	/**
272
	 * Test updating a single product without permission.
273
	 *
274
	 * @since 3.5.0
275
	 */
276
	public function test_update_product_without_permission() {
277
		wp_set_current_user( 0 );
278
		$product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
279
		$request = new WP_REST_Request( 'PUT', '/wc/v3/products/' . $product->get_id() );
280
		$request->set_body_params(
281
			array(
282
				'sku' => 'FIXED-SKU-NO-PERMISSION',
283
			)
284
		);
285
		$response = $this->server->dispatch( $request );
286
		$this->assertEquals( 401, $response->get_status() );
287
	}
288
289
	/**
290
	 * Test updating a single product with an invalid ID.
291
	 *
292
	 * @since 3.5.0
293
	 */
294
	public function test_update_product_with_invalid_id() {
295
		wp_set_current_user( $this->user );
296
		$request = new WP_REST_Request( 'PUT', '/wc/v2/products/0' );
297
		$request->set_body_params(
298
			array(
299
				'sku' => 'FIXED-SKU-INVALID-ID',
300
			)
301
		);
302
		$response = $this->server->dispatch( $request );
303
		$this->assertEquals( 400, $response->get_status() );
304
	}
305
306
	/**
307
	 * Test creating a single product.
308
	 *
309
	 * @since 3.5.0
310
	 */
311
	public function test_create_product() {
312
		wp_set_current_user( $this->user );
313
314
		$request = new WP_REST_Request( 'POST', '/wc/v3/products/shipping_classes' );
315
		$request->set_body_params(
316
			array(
317
				'name' => 'Test',
318
			)
319
		);
320
		$response          = $this->server->dispatch( $request );
321
		$data              = $response->get_data();
322
		$shipping_class_id = $data['id'];
323
324
		// Create simple.
325
		$request = new WP_REST_Request( 'POST', '/wc/v3/products' );
326
		$request->set_body_params(
327
			array(
328
				'type'           => 'simple',
329
				'name'           => 'Test Simple Product',
330
				'sku'            => 'DUMMY SKU SIMPLE API',
331
				'regular_price'  => '10',
332
				'shipping_class' => 'test',
333
			)
334
		);
335
		$response = $this->server->dispatch( $request );
336
		$data     = $response->get_data();
337
338
		$this->assertEquals( '10', $data['price'] );
339
		$this->assertEquals( '10', $data['regular_price'] );
340
		$this->assertTrue( $data['purchasable'] );
341
		$this->assertEquals( 'DUMMY SKU SIMPLE API', $data['sku'] );
342
		$this->assertEquals( 'Test Simple Product', $data['name'] );
343
		$this->assertEquals( 'simple', $data['type'] );
344
		$this->assertEquals( $shipping_class_id, $data['shipping_class_id'] );
345
346
		// Create external.
347
		$request = new WP_REST_Request( 'POST', '/wc/v3/products' );
348
		$request->set_body_params(
349
			array(
350
				'type'          => 'external',
351
				'name'          => 'Test External Product',
352
				'sku'           => 'DUMMY SKU EXTERNAL API',
353
				'regular_price' => '10',
354
				'button_text'   => 'Test Button',
355
				'external_url'  => 'https://wordpress.org',
356
			)
357
		);
358
		$response = $this->server->dispatch( $request );
359
		$data     = $response->get_data();
360
361
		$this->assertEquals( '10', $data['price'] );
362
		$this->assertEquals( '10', $data['regular_price'] );
363
		$this->assertFalse( $data['purchasable'] );
364
		$this->assertEquals( 'DUMMY SKU EXTERNAL API', $data['sku'] );
365
		$this->assertEquals( 'Test External Product', $data['name'] );
366
		$this->assertEquals( 'external', $data['type'] );
367
		$this->assertEquals( 'Test Button', $data['button_text'] );
368
		$this->assertEquals( 'https://wordpress.org', $data['external_url'] );
369
370
		// Create variable.
371
		$request = new WP_REST_Request( 'POST', '/wc/v3/products' );
372
		$request->set_body_params(
373
			array(
374
				'type'       => 'variable',
375
				'name'       => 'Test Variable Product',
376
				'sku'        => 'DUMMY SKU VARIABLE API',
377
				'attributes' => array(
378
					array(
379
						'id'        => 0,
380
						'name'      => 'pa_size',
381
						'options'   => array(
382
							'small',
383
							'medium',
384
						),
385
						'visible'   => false,
386
						'variation' => 1,
387
					),
388
				),
389
			)
390
		);
391
		$response = $this->server->dispatch( $request );
392
		$data     = $response->get_data();
393
394
		$this->assertEquals( 'DUMMY SKU VARIABLE API', $data['sku'] );
395
		$this->assertEquals( 'Test Variable Product', $data['name'] );
396
		$this->assertEquals( 'variable', $data['type'] );
397
		$this->assertEquals( array( 'small', 'medium' ), $data['attributes'][0]['options'] );
398
399
		$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/products' ) );
400
		$products = $response->get_data();
401
		$this->assertEquals( 3, count( $products ) );
402
	}
403
404
	/**
405
	 * Test creating a single product without permission.
406
	 *
407
	 * @since 3.5.0
408
	 */
409
	public function test_create_product_without_permission() {
410
		wp_set_current_user( 0 );
411
412
		$request = new WP_REST_Request( 'POST', '/wc/v3/products' );
413
		$request->set_body_params(
414
			array(
415
				'name'          => 'Test Product',
416
				'regular_price' => '12',
417
			)
418
		);
419
		$response = $this->server->dispatch( $request );
420
		$this->assertEquals( 401, $response->get_status() );
421
	}
422
423
	/**
424
	 * Test batch managing products.
425
	 *
426
	 * @since 3.5.0
427
	 */
428
	public function test_products_batch() {
429
		wp_set_current_user( $this->user );
430
		$product   = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
431
		$product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
432
		$request   = new WP_REST_Request( 'POST', '/wc/v3/products/batch' );
433
		$request->set_body_params(
434
			array(
435
				'update' => array(
436
					array(
437
						'id'          => $product->get_id(),
438
						'description' => 'Updated description.',
439
					),
440
				),
441
				'delete' => array(
442
					$product_2->get_id(),
443
				),
444
				'create' => array(
445
					array(
446
						'sku'           => 'DUMMY SKU BATCH TEST 1',
447
						'regular_price' => '10',
448
						'name'          => 'Test Batch Create 1',
449
						'type'          => 'external',
450
						'button_text'   => 'Test Button',
451
					),
452
					array(
453
						'sku'           => 'DUMMY SKU BATCH TEST 2',
454
						'regular_price' => '20',
455
						'name'          => 'Test Batch Create 2',
456
						'type'          => 'simple',
457
					),
458
				),
459
			)
460
		);
461
		$response = $this->server->dispatch( $request );
462
		$data     = $response->get_data();
463
464
		$this->assertContains( 'Updated description.', $data['update'][0]['description'] );
465
		$this->assertEquals( 'DUMMY SKU BATCH TEST 1', $data['create'][0]['sku'] );
466
		$this->assertEquals( 'DUMMY SKU BATCH TEST 2', $data['create'][1]['sku'] );
467
		$this->assertEquals( 'Test Button', $data['create'][0]['button_text'] );
468
		$this->assertEquals( 'external', $data['create'][0]['type'] );
469
		$this->assertEquals( 'simple', $data['create'][1]['type'] );
470
		$this->assertEquals( $product_2->get_id(), $data['delete'][0]['id'] );
471
472
		$request  = new WP_REST_Request( 'GET', '/wc/v3/products' );
473
		$response = $this->server->dispatch( $request );
474
		$data     = $response->get_data();
475
476
		$this->assertEquals( 3, count( $data ) );
477
	}
478
479
	/**
480
	 * Tests to make sure you can filter products post statuses by both
481
	 * the status query arg and WP_Query.
482
	 *
483
	 * @since 3.5.0
484
	 */
485
	public function test_products_filter_post_status() {
486
		wp_set_current_user( $this->user );
487
		for ( $i = 0; $i < 8; $i++ ) {
488
			$product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
489
			if ( 0 === $i % 2 ) {
490
				wp_update_post(
491
					array(
492
						'ID'          => $product->get_id(),
493
						'post_status' => 'draft',
494
					)
495
				);
496
			}
497
		}
498
499
		// Test filtering with status=publish.
500
		$request = new WP_REST_Request( 'GET', '/wc/v3/products' );
501
		$request->set_param( 'status', 'publish' );
502
		$response = $this->server->dispatch( $request );
503
		$products = $response->get_data();
504
505
		$this->assertEquals( 4, count( $products ) );
506
		foreach ( $products as $product ) {
507
			$this->assertEquals( 'publish', $product['status'] );
508
		}
509
510
		// Test filtering with status=draft.
511
		$request = new WP_REST_Request( 'GET', '/wc/v3/products' );
512
		$request->set_param( 'status', 'draft' );
513
		$response = $this->server->dispatch( $request );
514
		$products = $response->get_data();
515
516
		$this->assertEquals( 4, count( $products ) );
517
		foreach ( $products as $product ) {
518
			$this->assertEquals( 'draft', $product['status'] );
519
		}
520
521
		// Test filtering with no filters - which should return 'any' (all 8).
522
		$request  = new WP_REST_Request( 'GET', '/wc/v3/products' );
523
		$response = $this->server->dispatch( $request );
524
		$products = $response->get_data();
525
526
		$this->assertEquals( 8, count( $products ) );
527
	}
528
529
	/**
530
	 * Test product schema.
531
	 *
532
	 * @since 3.5.0
533
	 */
534
	public function test_product_schema() {
535
		wp_set_current_user( $this->user );
536
		$product    = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
537
		$request    = new WP_REST_Request( 'OPTIONS', '/wc/v3/products/' . $product->get_id() );
538
		$response   = $this->server->dispatch( $request );
539
		$data       = $response->get_data();
540
		$properties = $data['schema']['properties'];
541
		$this->assertEquals( 65, count( $properties ) );
542
	}
543
544
	/**
545
	 * Test product category.
546
	 *
547
	 * @since 3.5.0
548
	 */
549
	public function test_get_products_by_category() {
550
		wp_set_current_user( $this->user );
551
552
		// Create one product with a category.
553
		$category = wp_insert_term( 'Some Category', 'product_cat' );
554
555
		$product = new WC_Product_Simple();
556
		$product->set_category_ids( array( $category['term_id'] ) );
557
		$product->save();
558
559
		// Create one product without category, i.e. Uncategorized.
560
		$product_2 = new WC_Product_Simple();
561
		$product_2->save();
562
563
		// Test product assigned to a single category.
564
		$query_params = array(
565
			'category' => (string) $category['term_id'],
566
		);
567
		$request      = new WP_REST_Request( 'GET', '/wc/v2/products' );
568
		$request->set_query_params( $query_params );
569
		$response          = $this->server->dispatch( $request );
570
		$response_products = $response->get_data();
571
572
		$this->assertEquals( 200, $response->get_status() );
573
		foreach ( $response_products as $response_product ) {
574
			$this->assertEquals( $product->get_id(), $response_product['id'] );
575
			$this->assertEquals( $product->get_category_ids(), wp_list_pluck( $response_product['categories'], 'id' ) );
576
		}
577
578
		// Test product without categories.
579
		$request          = new WP_REST_Request( 'GET', '/wc/v2/products/' . $product_2->get_id() );
580
		$response         = $this->server->dispatch( $request );
581
		$response_product = $response->get_data();
582
583
		$this->assertEquals( 200, $response->get_status() );
584
		$this->assertCount( 1, $response_product['categories'], print_r( $response_product, true ) );
585
		$this->assertEquals( 'uncategorized', $response_product['categories'][0]['slug'] );
586
587
	}
588
589
	/**
590
	 * Test getting products by product type.
591
	 *
592
	 * @since 3.5.0
593
	 */
594
	public function test_get_products_by_type() {
595
		wp_set_current_user( $this->user );
596
597
		$simple   = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
598
		$external = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_external_product();
599
		$grouped  = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_grouped_product();
600
		$variable = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product();
601
602
		$product_ids_for_type = array(
603
			'simple'   => array( $simple->get_id() ),
604
			'external' => array( $external->get_id() ),
605
			'grouped'  => array( $grouped->get_id() ),
606
			'variable' => array( $variable->get_id() ),
607
		);
608
609
		foreach ( $grouped->get_children() as $additional_product ) {
610
			$product_ids_for_type['simple'][] = $additional_product;
611
		}
612
613
		foreach ( $product_ids_for_type as $product_type => $product_ids ) {
614
			$query_params = array(
615
				'type' => $product_type,
616
			);
617
			$request      = new WP_REST_Request( 'GET', '/wc/v2/products' );
618
			$request->set_query_params( $query_params );
619
			$response          = $this->server->dispatch( $request );
620
			$response_products = $response->get_data();
621
622
			$this->assertEquals( 200, $response->get_status() );
623
			$this->assertEquals( count( $product_ids ), count( $response_products ) );
624
			foreach ( $response_products as $response_product ) {
625
				$this->assertContains( $response_product['id'], $product_ids_for_type[ $product_type ], 'REST API: ' . $product_type . ' not found correctly' );
626
			}
627
		}
628
	}
629
630
	/**
631
	 * Test getting products by featured property.
632
	 *
633
	 * @since 3.5.0
634
	 */
635
	public function test_get_featured_products() {
636
		wp_set_current_user( $this->user );
637
638
		// Create a featured product.
639
		$feat_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
640
		$feat_product->set_featured( true );
641
		$feat_product->save();
642
643
		// Create a non-featured product.
644
		$nonfeat_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
645
		$nonfeat_product->save();
646
647
		$query_params = array(
648
			'featured' => 'true',
649
		);
650
		$request      = new WP_REST_Request( 'GET', '/wc/v2/products' );
651
		$request->set_query_params( $query_params );
652
		$response          = $this->server->dispatch( $request );
653
		$response_products = $response->get_data();
654
655
		$this->assertEquals( 200, $response->get_status() );
656
		foreach ( $response_products as $response_product ) {
657
			$this->assertEquals( $feat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' );
658
		}
659
660
		$query_params = array(
661
			'featured' => 'false',
662
		);
663
		$request      = new WP_REST_Request( 'GET', '/wc/v2/products' );
664
		$request->set_query_params( $query_params );
665
		$response          = $this->server->dispatch( $request );
666
		$response_products = $response->get_data();
667
668
		$this->assertEquals( 200, $response->get_status() );
669
		foreach ( $response_products as $response_product ) {
670
			$this->assertEquals( $nonfeat_product->get_id(), $response_product['id'], 'REST API: Featured product not found correctly' );
671
		}
672
	}
673
674
	/**
675
	 * Test getting products by shipping class property.
676
	 *
677
	 * @since 3.5.0
678
	 */
679
	public function test_get_products_by_shipping_class() {
680
		wp_set_current_user( $this->user );
681
682
		$shipping_class_1 = wp_insert_term( 'Bulky', 'product_shipping_class' );
683
684
		$product_1 = new WC_Product_Simple();
685
		$product_1->set_shipping_class_id( $shipping_class_1['term_id'] );
686
		$product_1->save();
687
688
		$query_params = array(
689
			'shipping_class' => (string) $shipping_class_1['term_id'],
690
		);
691
		$request      = new WP_REST_Request( 'GET', '/wc/v2/products' );
692
		$request->set_query_params( $query_params );
693
		$response          = $this->server->dispatch( $request );
694
		$response_products = $response->get_data();
695
696
		$this->assertEquals( 200, $response->get_status() );
697
		foreach ( $response_products as $response_product ) {
698
			$this->assertEquals( $product_1->get_id(), $response_product['id'] );
699
		}
700
	}
701
702
	/**
703
	 * Test getting products by tag.
704
	 *
705
	 * @since 3.5.0
706
	 */
707
	public function test_get_products_by_tag() {
708
		wp_set_current_user( $this->user );
709
710
		$test_tag_1 = wp_insert_term( 'Tag 1', 'product_tag' );
711
712
		// Product with a tag.
713
		$product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
714
		$product->set_tag_ids( array( $test_tag_1['term_id'] ) );
715
		$product->save();
716
717
		// Product without a tag.
718
		$product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
719
720
		$query_params = array(
721
			'tag' => (string) $test_tag_1['term_id'],
722
		);
723
		$request      = new WP_REST_Request( 'GET', '/wc/v2/products' );
724
		$request->set_query_params( $query_params );
725
		$response          = $this->server->dispatch( $request );
726
		$response_products = $response->get_data();
727
728
		$this->assertEquals( 200, $response->get_status() );
729
		foreach ( $response_products as $response_product ) {
730
			$this->assertEquals( $product->get_id(), $response_product['id'] );
731
		}
732
	}
733
734
	/**
735
	 * Test getting products by global attribute.
736
	 *
737
	 * @since 3.5.0
738
	 */
739
	public function test_get_products_by_attribute() {
740
		global $wpdb;
741
		wp_set_current_user( $this->user );
742
743
		// Variable product with 2 different variations.
744
		$variable_product = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_variation_product();
745
746
		// Terms created by variable product.
747
		$term_large = get_term_by( 'slug', 'large', 'pa_size' );
748
		$term_small = get_term_by( 'slug', 'small', 'pa_size' );
749
750
		// Simple product without attribute.
751
		$product_1 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
752
753
		// Simple product with attribute size = large.
754
		$product_2 = \Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper::create_simple_product();
755
		$product_2->set_attributes( array( 'pa_size' => 'large' ) );
756
		$product_2->save();
757
758
		// Link the product to the term.
759
		$wpdb->insert(
760
			$wpdb->prefix . 'term_relationships',
761
			array(
762
				'object_id'        => $product_2->get_id(),
763
				'term_taxonomy_id' => $term_large->term_id,
764
				'term_order'       => 0,
765
			)
766
		);
767
768
		// Products with attribute size == large.
769
		$expected_product_ids = array(
770
			$variable_product->get_id(),
771
			$product_2->get_id(),
772
		);
773
		$query_params         = array(
774
			'attribute'      => 'pa_size',
775
			'attribute_term' => (string) $term_large->term_id,
776
		);
777
		$request              = new WP_REST_Request( 'GET', '/wc/v2/products' );
778
		$request->set_query_params( $query_params );
779
		$response          = $this->server->dispatch( $request );
780
		$response_products = $response->get_data();
781
782
		$this->assertEquals( 200, $response->get_status() );
783
		$this->assertEquals( count( $expected_product_ids ), count( $response_products ) );
784
		foreach ( $response_products as $response_product ) {
785
			$this->assertContains( $response_product['id'], $expected_product_ids );
786
		}
787
788
		// Products with attribute size == small.
789
		$expected_product_ids = array(
790
			$variable_product->get_id(),
791
		);
792
		$query_params         = array(
793
			'attribute'      => 'pa_size',
794
			'attribute_term' => (string) $term_small->term_id,
795
		);
796
		$request              = new WP_REST_Request( 'GET', '/wc/v2/products' );
797
		$request->set_query_params( $query_params );
798
		$response          = $this->server->dispatch( $request );
799
		$response_products = $response->get_data();
800
801
		$this->assertEquals( 200, $response->get_status() );
802
		$this->assertEquals( count( $expected_product_ids ), count( $response_products ) );
803
		foreach ( $response_products as $response_product ) {
804
			$this->assertContains( $response_product['id'], $expected_product_ids );
805
		}
806
	}
807
}
808