1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Tests for PaymentRequest::complete().
6 
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
9 #include "third_party/blink/renderer/modules/payments/payment_request.h"
10 #include "third_party/blink/renderer/modules/payments/payment_test_helper.h"
11 #include "third_party/blink/renderer/platform/bindings/exception_code.h"
12 
13 namespace blink {
14 namespace {
15 
TEST(CompleteTest,CannotCallCompleteTwice)16 TEST(CompleteTest, CannotCallCompleteTwice) {
17   PaymentRequestV8TestingScope scope;
18   PaymentRequest* request = PaymentRequest::Create(
19       scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
20       BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
21   request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
22   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
23       ->OnPaymentResponse(BuildPaymentResponseForTest());
24   request->Complete(scope.GetScriptState(),
25                     PaymentStateResolver::PaymentComplete::kFail,
26                     ASSERT_NO_EXCEPTION);
27 
28   request->Complete(scope.GetScriptState(),
29                     PaymentStateResolver::PaymentComplete::kSuccess,
30                     scope.GetExceptionState());
31   EXPECT_EQ(scope.GetExceptionState().Code(),
32             ToExceptionCode(DOMExceptionCode::kInvalidStateError));
33 }
34 
TEST(CompleteTest,ResolveCompletePromiseOnUnknownError)35 TEST(CompleteTest, ResolveCompletePromiseOnUnknownError) {
36   PaymentRequestV8TestingScope scope;
37   PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
38   PaymentRequest* request = PaymentRequest::Create(
39       scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
40       BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
41   request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
42   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
43       ->OnPaymentResponse(BuildPaymentResponseForTest());
44 
45   request
46       ->Complete(scope.GetScriptState(),
47                  PaymentStateResolver::PaymentComplete::kSuccess,
48                  ASSERT_NO_EXCEPTION)
49       .Then(funcs.ExpectCall(), funcs.ExpectNoCall());
50 
51   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
52       payments::mojom::blink::PaymentErrorReason::UNKNOWN, "Unknown error.");
53 }
54 
TEST(CompleteTest,ResolveCompletePromiseOnUserClosingUI)55 TEST(CompleteTest, ResolveCompletePromiseOnUserClosingUI) {
56   PaymentRequestV8TestingScope scope;
57   PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
58   PaymentRequest* request = PaymentRequest::Create(
59       scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
60       BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
61   request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
62   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
63       ->OnPaymentResponse(BuildPaymentResponseForTest());
64 
65   request
66       ->Complete(scope.GetScriptState(),
67                  PaymentStateResolver::PaymentComplete::kSuccess,
68                  ASSERT_NO_EXCEPTION)
69       .Then(funcs.ExpectCall(), funcs.ExpectNoCall());
70 
71   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
72       payments::mojom::blink::PaymentErrorReason::USER_CANCEL,
73       "User closed the UI.");
74 }
75 
76 // If user cancels the transaction during processing, the complete() promise
77 // should be rejected.
TEST(CompleteTest,RejectCompletePromiseAfterError)78 TEST(CompleteTest, RejectCompletePromiseAfterError) {
79   PaymentRequestV8TestingScope scope;
80   PaymentRequest* request = PaymentRequest::Create(
81       scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
82       BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
83   request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
84   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
85       ->OnPaymentResponse(BuildPaymentResponseForTest());
86   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)->OnError(
87       payments::mojom::blink::PaymentErrorReason::USER_CANCEL,
88       "User closed the UI.");
89 
90   request->Complete(scope.GetScriptState(),
91                     PaymentStateResolver::PaymentComplete::kSuccess,
92                     scope.GetExceptionState());
93   EXPECT_EQ(scope.GetExceptionState().Code(),
94             ToExceptionCode(DOMExceptionCode::kInvalidStateError));
95 }
96 
TEST(CompleteTest,ResolvePromiseOnComplete)97 TEST(CompleteTest, ResolvePromiseOnComplete) {
98   PaymentRequestV8TestingScope scope;
99   PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
100   PaymentRequest* request = PaymentRequest::Create(
101       scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
102       BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
103   request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION);
104   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
105       ->OnPaymentResponse(BuildPaymentResponseForTest());
106 
107   request
108       ->Complete(scope.GetScriptState(),
109                  PaymentStateResolver::PaymentComplete::kSuccess,
110                  ASSERT_NO_EXCEPTION)
111       .Then(funcs.ExpectCall(), funcs.ExpectNoCall());
112 
113   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
114       ->OnComplete();
115 }
116 
TEST(CompleteTest,RejectCompletePromiseOnUpdateDetailsFailure)117 TEST(CompleteTest, RejectCompletePromiseOnUpdateDetailsFailure) {
118   PaymentRequestV8TestingScope scope;
119   PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
120   PaymentRequest* request = PaymentRequest::Create(
121       scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
122       BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
123   request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
124       .Then(funcs.ExpectCall(), funcs.ExpectNoCall());
125   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
126       ->OnPaymentResponse(BuildPaymentResponseForTest());
127 
128   String error_message;
129   request
130       ->Complete(scope.GetScriptState(),
131                  PaymentStateResolver::PaymentComplete::kSuccess,
132                  ASSERT_NO_EXCEPTION)
133       .Then(funcs.ExpectNoCall(), funcs.ExpectCall(&error_message));
134 
135   request->OnUpdatePaymentDetailsFailure("oops");
136 
137   v8::MicrotasksScope::PerformCheckpoint(scope.GetScriptState()->GetIsolate());
138   EXPECT_EQ("AbortError: oops", error_message);
139 }
140 
TEST(CompleteTest,RejectCompletePromiseAfterTimeout)141 TEST(CompleteTest, RejectCompletePromiseAfterTimeout) {
142   PaymentRequestV8TestingScope scope;
143   PaymentRequestMockFunctionScope funcs(scope.GetScriptState());
144   PaymentRequest* request = PaymentRequest::Create(
145       scope.GetExecutionContext(), BuildPaymentMethodDataForTest(),
146       BuildPaymentDetailsInitForTest(), ASSERT_NO_EXCEPTION);
147   request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION)
148       .Then(funcs.ExpectCall(), funcs.ExpectNoCall());
149   static_cast<payments::mojom::blink::PaymentRequestClient*>(request)
150       ->OnPaymentResponse(BuildPaymentResponseForTest());
151   request->OnCompleteTimeoutForTesting();
152 
153   String error_message;
154   request->Complete(scope.GetScriptState(),
155                     PaymentStateResolver::PaymentComplete::kSuccess,
156                     scope.GetExceptionState());
157   EXPECT_EQ(scope.GetExceptionState().Code(),
158             ToExceptionCode(DOMExceptionCode::kInvalidStateError));
159 
160   v8::MicrotasksScope::PerformCheckpoint(scope.GetScriptState()->GetIsolate());
161   EXPECT_EQ("Timed out after 60 seconds, complete() called too late",
162             scope.GetExceptionState().Message());
163 }
164 
165 }  // namespace
166 }  // namespace blink
167