|
6 | 6 | */
|
7 | 7 |
|
8 | 8 | use WCPay\Exceptions\API_Exception;
|
| 9 | +use WCPay\Exceptions\Connection_Exception; |
9 | 10 | use WCPay\Fraud_Prevention\Fraud_Prevention_Service;
|
10 | 11 | use WCPay\Fraud_Prevention\Buyer_Fingerprinting_Service;
|
11 | 12 |
|
@@ -2146,6 +2147,190 @@ public function test_authorizations_summary_success() {
|
2146 | 2147 | $this->assertSame( 1200, $summary['total'] );
|
2147 | 2148 | }
|
2148 | 2149 |
|
| 2150 | + /** |
| 2151 | + * Test that API client will retry request in case of network error |
| 2152 | + * |
| 2153 | + * POST calls have `Idempotency-Key` set in the `request`, thus are |
| 2154 | + * possible to retry. |
| 2155 | + * |
| 2156 | + * @throws Exception in case of the test failure. |
| 2157 | + */ |
| 2158 | + public function test_request_retries_post_on_network_failure() { |
| 2159 | + $this->mock_http_client |
| 2160 | + ->expects( $this->exactly( 4 ) ) |
| 2161 | + ->method( 'remote_request' ) |
| 2162 | + ->willReturn( |
| 2163 | + [ |
| 2164 | + 'body' => wp_json_encode( [ 'result' => 'error' ] ), |
| 2165 | + 'response' => [ |
| 2166 | + 'code' => 0, |
| 2167 | + 'message' => 'Unknown network error', |
| 2168 | + ], |
| 2169 | + ] |
| 2170 | + ); |
| 2171 | + |
| 2172 | + PHPUnit_Utils::call_method( |
| 2173 | + $this->payments_api_client, |
| 2174 | + 'request', |
| 2175 | + [ [], 'intentions', 'POST' ] |
| 2176 | + ); |
| 2177 | + } |
| 2178 | + |
| 2179 | + /** |
| 2180 | + * Test that API client will retry request in case of network error |
| 2181 | + * indiciated by Connection_Exception. |
| 2182 | + * |
| 2183 | + * POST calls have `Idempotency-Key` set in the `request`, thus are |
| 2184 | + * possible to retry. |
| 2185 | + * |
| 2186 | + * @throws Exception in case of the test failure. |
| 2187 | + */ |
| 2188 | + public function test_request_retries_post_on_network_failure_exception() { |
| 2189 | + $this->mock_http_client |
| 2190 | + ->expects( $this->exactly( 4 ) ) |
| 2191 | + ->method( 'remote_request' ) |
| 2192 | + ->willThrowException( |
| 2193 | + new Connection_Exception( 'HTTP request failed', 'wcpay_http_request_failed', 500 ) |
| 2194 | + ); |
| 2195 | + |
| 2196 | + $this->expectException( Connection_Exception::class ); |
| 2197 | + |
| 2198 | + PHPUnit_Utils::call_method( |
| 2199 | + $this->payments_api_client, |
| 2200 | + 'request', |
| 2201 | + [ [], 'intentions', 'POST' ] |
| 2202 | + ); |
| 2203 | + } |
| 2204 | + |
| 2205 | + /** |
| 2206 | + * Test that API client will retry request in case of network error |
| 2207 | + * and stop on success. |
| 2208 | + * |
| 2209 | + * POST calls have `Idempotency-Key` set in the `request`, thus are |
| 2210 | + * possible to retry. |
| 2211 | + * |
| 2212 | + * @throws Exception in case of the test failure. |
| 2213 | + */ |
| 2214 | + public function test_request_retries_post_on_network_failure_exception_and_stops_on_success() { |
| 2215 | + $this->mock_http_client |
| 2216 | + ->expects( $this->exactly( 3 ) ) |
| 2217 | + ->method( 'remote_request' ) |
| 2218 | + ->willReturnOnConsecutiveCalls( |
| 2219 | + $this->throwException( |
| 2220 | + new Connection_Exception( 'HTTP request failed', 'wcpay_http_request_failed', 500 ) |
| 2221 | + ), |
| 2222 | + $this->throwException( |
| 2223 | + new Connection_Exception( 'HTTP request failed', 'wcpay_http_request_failed', 500 ) |
| 2224 | + ), |
| 2225 | + [ |
| 2226 | + 'body' => wp_json_encode( [ 'result' => 'success' ] ), |
| 2227 | + 'response' => [ |
| 2228 | + 'code' => 200, |
| 2229 | + 'message' => 'OK', |
| 2230 | + ], |
| 2231 | + ] |
| 2232 | + ); |
| 2233 | + |
| 2234 | + PHPUnit_Utils::call_method( |
| 2235 | + $this->payments_api_client, |
| 2236 | + 'request', |
| 2237 | + [ [], 'intentions', 'POST' ] |
| 2238 | + ); |
| 2239 | + } |
| 2240 | + |
| 2241 | + /** |
| 2242 | + * Test that API client will not retry if connection exception indicates there |
| 2243 | + * was a response. |
| 2244 | + * |
| 2245 | + * @throws Exception in case of the test failure. |
| 2246 | + */ |
| 2247 | + public function test_request_doesnt_retry_on_other_exceptions() { |
| 2248 | + $this->mock_http_client |
| 2249 | + ->expects( $this->exactly( 1 ) ) |
| 2250 | + ->method( 'remote_request' ) |
| 2251 | + ->willThrowException( |
| 2252 | + new Exception( 'Random exception' ) |
| 2253 | + ); |
| 2254 | + |
| 2255 | + $this->expectException( Exception::class ); |
| 2256 | + |
| 2257 | + PHPUnit_Utils::call_method( |
| 2258 | + $this->payments_api_client, |
| 2259 | + 'request', |
| 2260 | + [ [], 'intentions', 'POST' ] |
| 2261 | + ); |
| 2262 | + } |
| 2263 | + |
| 2264 | + /** |
| 2265 | + * Test that API client will retry request in case of network error with |
| 2266 | + * Idempotency-Key header |
| 2267 | + * |
| 2268 | + * @throws Exception in case of the test failure. |
| 2269 | + */ |
| 2270 | + public function test_request_retries_get_with_idempotency_header_on_network_failure() { |
| 2271 | + $this->mock_http_client |
| 2272 | + ->expects( $this->exactly( 4 ) ) |
| 2273 | + ->method( 'remote_request' ) |
| 2274 | + ->willReturn( |
| 2275 | + [ |
| 2276 | + 'body' => wp_json_encode( [ 'result' => 'error' ] ), |
| 2277 | + 'response' => [ |
| 2278 | + 'code' => 0, |
| 2279 | + 'message' => 'Unknown network error', |
| 2280 | + ], |
| 2281 | + ] |
| 2282 | + ); |
| 2283 | + |
| 2284 | + $callable = function ( $headers ) { |
| 2285 | + $headers['Idempotency-Key'] = 'ik_42'; |
| 2286 | + return $headers; |
| 2287 | + }; |
| 2288 | + |
| 2289 | + add_filter( |
| 2290 | + 'wcpay_api_request_headers', |
| 2291 | + $callable, |
| 2292 | + 10, |
| 2293 | + 2 |
| 2294 | + ); |
| 2295 | + |
| 2296 | + PHPUnit_Utils::call_method( |
| 2297 | + $this->payments_api_client, |
| 2298 | + 'request', |
| 2299 | + [ [], 'intentions', 'GET' ] |
| 2300 | + ); |
| 2301 | + |
| 2302 | + remove_filter( |
| 2303 | + 'wcpay_api_request_headers', |
| 2304 | + $callable, |
| 2305 | + 10 |
| 2306 | + ); |
| 2307 | + } |
| 2308 | + |
| 2309 | + /** |
| 2310 | + * Test that API client won't retry GET request without Idemptency-Key header. |
| 2311 | + * |
| 2312 | + * @throws Exception in case of the test failure. |
| 2313 | + */ |
| 2314 | + public function test_request_doesnt_retry_get_without_idempotency_header_on_network_failure() { |
| 2315 | + $this->mock_http_client |
| 2316 | + ->expects( $this->exactly( 1 ) ) |
| 2317 | + ->method( 'remote_request' ) |
| 2318 | + ->willReturn( |
| 2319 | + [ |
| 2320 | + 'body' => wp_json_encode( [ 'result' => 'error' ] ), |
| 2321 | + 'response' => [ |
| 2322 | + 'code' => 0, |
| 2323 | + 'message' => 'Unknown network error', |
| 2324 | + ], |
| 2325 | + ] |
| 2326 | + ); |
| 2327 | + |
| 2328 | + PHPUnit_Utils::call_method( |
| 2329 | + $this->payments_api_client, |
| 2330 | + 'request', |
| 2331 | + [ [], 'intentions', 'GET' ] |
| 2332 | + ); |
| 2333 | + } |
2149 | 2334 | /**
|
2150 | 2335 | * Set up http mock response.
|
2151 | 2336 | *
|
|
0 commit comments