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