Completed
Pull Request — master (#1478)
by
unknown
10:44
created

WC_Stripe_Level3_Data_Test   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 254
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 254
rs 10
c 0
b 0
f 0
wmc 5
lcom 1
cbo 2

4 Methods

Rating   Name   Duplication   Size   Complexity  
B mock_level_3_order() 0 95 2
B test_data_for_mutli_item_order() 0 79 1
A test_non_us_shipping_zip_codes() 0 40 1
A test_full_level3_data_with_fee() 0 34 1
1
<?php
2
/**
3
 * These tests assert that get_level3_data_from_order() returns the correct
4
 * data.
5
 */
6
7
/**
8
 * Level3 data test suite
9
 */
10
class WC_Stripe_Level3_Data_Test extends WP_UnitTestCase {
11
12
	protected function mock_level_3_order( $shipping_postcode, $with_fee = false ) {
13
		// Setup the item.
14
		$mock_item = $this->getMockBuilder( WC_Order_Item_Product::class )
15
			->disableOriginalConstructor()
16
			->setMethods( [ 'get_name', 'get_quantity', 'get_subtotal', 'get_total_tax', 'get_total', 'get_variation_id', 'get_product_id' ] )
17
			->getMock();
18
19
		$mock_item
20
			->method( 'get_name' )
21
			->will( $this->returnValue( 'Beanie with Logo' ) );
22
23
		$mock_item
24
			->method( 'get_quantity' )
25
			->will( $this->returnValue( 1 ) );
26
27
		$mock_item
28
			->method( 'get_total' )
29
			->will( $this->returnValue( 18 ) );
30
31
		$mock_item
32
			->method( 'get_subtotal' )
33
			->will( $this->returnValue( 18 ) );
34
35
		$mock_item
36
			->method( 'get_total_tax' )
37
			->will( $this->returnValue( 2.7 ) );
38
39
		$mock_item
40
			->method( 'get_variation_id' )
41
			->will( $this->returnValue( false ) );
42
43
		$mock_item
44
			->method( 'get_product_id' )
45
			->will( $this->returnValue( 30 ) );
46
47
		$mock_items[] = $mock_item;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$mock_items was never initialized. Although not strictly required by PHP, it is generally a good practice to add $mock_items = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
48
49
		if ( $with_fee ) {
50
			// Setup the fee.
51
			$mock_fee = $this->getMockBuilder( WC_Order_Item_Fee::class )
52
				->disableOriginalConstructor()
53
				->setMethods( [ 'get_name', 'get_quantity', 'get_total_tax', 'get_total' ] )
54
				->getMock();
55
56
			$mock_fee
57
				->method( 'get_name' )
58
				->will( $this->returnValue( 'fee' ) );
59
60
			$mock_fee
61
				->method( 'get_quantity' )
62
				->will( $this->returnValue( 1 ) );
63
64
			$mock_fee
65
				->method( 'get_total' )
66
				->will( $this->returnValue( 10 ) );
67
68
			$mock_fee
69
				->method( 'get_total_tax' )
70
				->will( $this->returnValue( 1.5 ) );
71
72
			$mock_items[] = $mock_fee;
73
		}
74
75
		// Setup the order.
76
		$mock_order = $this->getMockBuilder( WC_Order::class )
77
			->disableOriginalConstructor()
78
			->setMethods( [ 'get_id', 'get_items', 'get_currency', 'get_shipping_total', 'get_shipping_tax', 'get_shipping_postcode' ] )
79
			->getMock();
80
81
		$mock_order
82
			->method( 'get_id' )
83
			->will( $this->returnValue( 210 ) );
84
85
		$mock_order
86
			->method( 'get_items' )
87
			->will( $this->returnValue( $mock_items ) );
88
89
		$mock_order
90
			->method( 'get_currency' )
91
			->will( $this->returnValue( 'USD' ) );
92
93
		$mock_order
94
			->method( 'get_shipping_total' )
95
			->will( $this->returnValue( 30 ) );
96
97
		$mock_order
98
			->method( 'get_shipping_tax' )
99
			->will( $this->returnValue( 8 ) );
100
101
		$mock_order
102
			->method( 'get_shipping_postcode' )
103
			->will( $this->returnValue( $shipping_postcode ) );
104
105
		return $mock_order;
106
	}
107
108
	public function test_data_for_mutli_item_order() {
109
		$store_postcode = '90210';
110
		update_option( 'woocommerce_store_postcode', $store_postcode );
111
112
		// Arrange: Create a couple of products to use.
113
		$variation_product = WC_Helper_Product::create_variation_product();
114
		$variation_ids     = $variation_product->get_children();
115
116
		$product_1 = wc_get_product ( $variation_ids[0] );
117
		$product_1->set_regular_price( 19.19 );
118
		$product_1->set_sale_price( 11.83 );
119
		$product_1->save();
120
121
		$product_2 = wc_get_product( $variation_ids[1] );
122
		$product_2->set_regular_price( 20.05 );
123
		$product_2->save();
124
125
		// Arrange: Set up an order with:
126
		// 1) A variation product.
127
		// 2) The same product added several times.
128
		// 3) A valid US ZIP code
129
		$order = new WC_Order();
130
		$order->set_shipping_postcode( '90210' );
131
		$order->add_product( $product_1, 1 ); // Add one item of the first product variation
132
		$order->add_product( $product_2, 2 ); // Add two items of the second product variation
133
134
		$order->save();
135
		$order->calculate_totals();
136
137
		// Act: Call get_level3_data_from_order().
138
		$gateway = new WC_Gateway_Stripe();
139
		$result = $gateway->get_level3_data_from_order( $order );
140
141
		// Assert.
142
		$this->assertEquals(
143
			array(
144
				'merchant_reference' => $order->get_id(),
145
				'shipping_address_zip' => $order->get_shipping_postcode(),
146
				'shipping_from_zip' => $store_postcode,
147
				'shipping_amount' => 0,
148
				'line_items' => array(
149
					(object) array(
150
						'product_code'        => (string) $product_1->get_id(),
151
						'product_description' => substr( $product_1->get_name(), 0, 26 ),
152
						'unit_cost'           => 1183,
153
						'quantity'            => 1,
154
						'tax_amount'          => 0,
155
						'discount_amount'     => 0,
156
					),
157
					(object) array(
158
						'product_code'        => (string) $product_2->get_id(),
159
						'product_description' => substr( $product_2->get_name(), 0, 26 ),
160
						'unit_cost'           => 2005,
161
						'quantity'            => 2,
162
						'tax_amount'          => 0,
163
						'discount_amount'     => 0,
164
					),
165
				),
166
			),
167
			$result
168
		);
169
170
		// Assert: Check that Stripe's total charge check passes.
171
		$total_charged = WC_Stripe_Helper::get_stripe_amount( $order->get_total() );
172
		$sum_of_unit_costs = array_reduce( $result['line_items'], function( $sum, $item ) {
173
			return $sum + $item->quantity * $item->unit_cost;
174
		}  );
175
		$sum_of_taxes = array_reduce( $result['line_items'], function( $sum, $item ) {
176
			return $sum + $item->tax_amount;
177
		}  );
178
		$sum_of_discounts = array_reduce( $result['line_items'], function( $sum, $item ) {
179
			return $sum + $item->discount_amount;
180
		}  );
181
		$shipping_amount = $result['shipping_amount'];
182
		$this->assertEquals(
183
			$total_charged,
184
			$sum_of_unit_costs + $sum_of_taxes - $sum_of_discounts + $shipping_amount
185
		);
186
	}
187
188
	public function test_non_us_shipping_zip_codes() {
189
		// Update the store with the right post code.
190
		update_option( 'woocommerce_store_postcode', 1040 );
191
192
		// Arrange: Create a couple of products to use.
193
		$product = WC_Helper_Product::create_simple_product();
194
		$product->set_regular_price( 19.19 );
195
		$product->save();
196
197
		// Arrange: Set up an order with a non-US postcode.
198
		$order = new WC_Order();
199
		$order->set_shipping_postcode( '1050' );
200
		$order->add_product( $product, 1 );
201
		$order->save();
202
		$order->calculate_totals();
203
204
		// Act: Call get_level3_data_from_order().
205
		$store_postcode = '1100';
0 ignored issues
show
Unused Code introduced by
$store_postcode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
206
		$gateway = new WC_Gateway_Stripe();
207
		$result = $gateway->get_level3_data_from_order( $order );
208
209
		// Assert.
210
		$this->assertEquals(
211
			array(
212
				'merchant_reference' => $order->get_id(),
213
				'shipping_amount' => 0,
214
				'line_items' => array(
215
					(object) array(
216
						'product_code'        => (string) $product->get_id(),
217
						'product_description' => substr( $product->get_name(), 0, 26 ),
218
						'unit_cost'           => 1919,
219
						'quantity'            => 1,
220
						'tax_amount'          => 0,
221
						'discount_amount'     => 0,
222
					),
223
				),
224
			),
225
			$result
226
		);
227
	}
228
229
	public function test_full_level3_data_with_fee() {
230
		$expected_data = array(
231
			'merchant_reference'   => '210',
232
			'shipping_amount'      => 3800,
233
			'line_items'           => array(
234
				(object) array(
235
					'product_code'        => 30,
236
					'product_description' => 'Beanie with Logo',
237
					'unit_cost'           => 1800,
238
					'quantity'            => 1,
239
					'tax_amount'          => 270,
240
					'discount_amount'     => 0,
241
				),
242
				(object) array(
243
					'product_code'        => 'fee',
244
					'product_description' => 'fee',
245
					'unit_cost'           => 1000,
246
					'quantity'            => 1,
247
					'tax_amount'          => 150,
248
					'discount_amount'     => 0,
249
				),
250
			),
251
			'shipping_address_zip' => '98012',
252
			'shipping_from_zip'    => '94110',
253
		);
254
255
		update_option( 'woocommerce_store_postcode', '94110' );
256
257
		$mock_order   = $this->mock_level_3_order( '98012', true );
258
		$gateway      = new WC_Gateway_Stripe();
259
		$level_3_data = $gateway->get_level3_data_from_order( $mock_order );
260
261
		$this->assertEquals( $expected_data, $level_3_data );
262
	}
263
}
264