| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "build/build_config.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/blink/public/mojom/payments/payment_request.mojom-blink.h" |
| #include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" |
| #include "third_party/blink/renderer/modules/payments/payment_request.h" |
| #include "third_party/blink/renderer/modules/payments/payment_test_helper.h" |
| #include "third_party/blink/renderer/platform/bindings/exception_code.h" |
| #include "third_party/blink/renderer/platform/heap/heap_allocator.h" |
| #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" |
| #include "third_party/googletest/src/googletest/include/gtest/gtest.h" |
| |
| namespace blink { |
| namespace { |
| |
| class MockPaymentProvider : public payments::mojom::blink::PaymentRequest { |
| public: |
| void Init( |
| mojo::PendingRemote<payments::mojom::blink::PaymentRequestClient> client, |
| WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr> method_data, |
| payments::mojom::blink::PaymentDetailsPtr details, |
| payments::mojom::blink::PaymentOptionsPtr options |
| #if defined(OS_ANDROID) |
| , |
| bool google_pay_bridge_eligible |
| #endif |
| ) override { |
| client_.Bind(std::move(client)); |
| client_->OnError(payments::mojom::PaymentErrorReason:: |
| NOT_SUPPORTED_FOR_INVALID_ORIGIN_OR_SSL, |
| "mock error message"); |
| has_closed_ = true; |
| } |
| |
| void Show(bool is_user_gesture, bool wait_for_updated_details) override {} |
| void Retry( |
| payments::mojom::blink::PaymentValidationErrorsPtr errors) override { |
| NOTREACHED(); |
| } |
| void UpdateWith( |
| payments::mojom::blink::PaymentDetailsPtr update_with_details) override { |
| NOTREACHED(); |
| } |
| void OnPaymentDetailsNotUpdated() override { NOTREACHED(); } |
| void Abort() override { NOTREACHED(); } |
| void Complete(payments::mojom::PaymentComplete result) override { |
| NOTREACHED(); |
| } |
| void CanMakePayment() override {} |
| void HasEnrolledInstrument() override {} |
| |
| mojo::PendingRemote<payments::mojom::blink::PaymentRequest> |
| CreatePendingRemoteAndBind() { |
| mojo::PendingRemote<payments::mojom::blink::PaymentRequest> remote; |
| receiver_.Bind(remote.InitWithNewPipeAndPassReceiver()); |
| return remote; |
| } |
| |
| private: |
| mojo::Receiver<payments::mojom::blink::PaymentRequest> receiver_{this}; |
| mojo::Remote<payments::mojom::blink::PaymentRequestClient> client_; |
| bool has_closed_ = false; |
| }; |
| |
| // This tests PaymentRequest API on invalid origin or invalid ssl. |
| class PaymentRequestForInvalidOriginOrSslTest : public testing::Test { |
| public: |
| PaymentRequestForInvalidOriginOrSslTest() |
| : payment_provider_(std::make_unique<MockPaymentProvider>()) {} |
| |
| ScriptValue GetRejectValue(ScriptState* script_state, |
| ScriptPromise& promise) { |
| ScriptPromiseTester tester(script_state, promise); |
| tester.WaitUntilSettled(); |
| EXPECT_TRUE(tester.IsRejected()); |
| return tester.Value(); |
| } |
| |
| bool ResolvePromise(ScriptState* script_state, ScriptPromise& promise) { |
| ScriptPromiseTester tester(script_state, promise); |
| tester.WaitUntilSettled(); |
| return tester.Value().V8Value()->IsTrue(); |
| } |
| |
| std::string GetRejectString(ScriptState* script_state, |
| ScriptPromise& promise) { |
| ScriptValue on_reject = GetRejectValue(script_state, promise); |
| return ToCoreString(on_reject.V8Value() |
| ->ToString(script_state->GetContext()) |
| .ToLocalChecked()) |
| .Ascii() |
| .data(); |
| } |
| |
| PaymentRequest* CreatePaymentRequest(PaymentRequestV8TestingScope& scope) { |
| return MakeGarbageCollected<PaymentRequest>( |
| scope.GetExecutionContext(), BuildPaymentMethodDataForTest(), |
| BuildPaymentDetailsInitForTest(), PaymentOptions::Create(), |
| payment_provider_->CreatePendingRemoteAndBind(), ASSERT_NO_EXCEPTION); |
| } |
| |
| std::unique_ptr<MockPaymentProvider> payment_provider_; |
| ScopedTestingPlatformSupport<TestingPlatformSupport> platform_; |
| }; |
| |
| TEST_F(PaymentRequestForInvalidOriginOrSslTest, |
| ShowIsRejected_WhenShowBeforeIdle) { |
| PaymentRequestV8TestingScope scope; |
| PaymentRequest* request = CreatePaymentRequest(scope); |
| ScriptPromise promise = |
| request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION); |
| // PaymentRequest.OnError() runs in this idle. |
| platform_->RunUntilIdle(); |
| |
| EXPECT_EQ("NotSupportedError: mock error message", |
| GetRejectString(scope.GetScriptState(), promise)); |
| } |
| |
| TEST_F(PaymentRequestForInvalidOriginOrSslTest, |
| ShowIsRejected_WhenShowAfterIdle) { |
| PaymentRequestV8TestingScope scope; |
| PaymentRequest* request = CreatePaymentRequest(scope); |
| // PaymentRequest.OnError() runs in this idle. |
| platform_->RunUntilIdle(); |
| |
| ScriptPromise promise = |
| request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION); |
| EXPECT_EQ("NotSupportedError: mock error message", |
| GetRejectString(scope.GetScriptState(), promise)); |
| } |
| |
| TEST_F(PaymentRequestForInvalidOriginOrSslTest, |
| SelfRejectingPromiseCanBeRepeated) { |
| PaymentRequestV8TestingScope scope; |
| PaymentRequest* request = CreatePaymentRequest(scope); |
| // PaymentRequest.OnError() runs in this idle. |
| platform_->RunUntilIdle(); |
| |
| ScriptPromise promise1 = |
| request->show(scope.GetScriptState(), ASSERT_NO_EXCEPTION); |
| EXPECT_EQ("NotSupportedError: mock error message", |
| GetRejectString(scope.GetScriptState(), promise1)); |
| |
| ScriptPromise promise2 = |
| request->show(scope.GetScriptState(), scope.GetExceptionState()); |
| EXPECT_EQ("NotSupportedError: mock error message", |
| GetRejectString(scope.GetScriptState(), promise2)); |
| } |
| |
| TEST_F(PaymentRequestForInvalidOriginOrSslTest, |
| CanMakePaymentIsRejected_CheckAfterIdle) { |
| PaymentRequestV8TestingScope scope; |
| PaymentRequest* request = CreatePaymentRequest(scope); |
| // PaymentRequest.OnError() runs in this idle. |
| platform_->RunUntilIdle(); |
| |
| ScriptPromise promise = |
| request->canMakePayment(scope.GetScriptState(), ASSERT_NO_EXCEPTION); |
| EXPECT_FALSE(ResolvePromise(scope.GetScriptState(), promise)); |
| } |
| |
| TEST_F(PaymentRequestForInvalidOriginOrSslTest, |
| CanMakePaymentIsRejected_CheckBeforeIdle) { |
| PaymentRequestV8TestingScope scope; |
| PaymentRequest* request = CreatePaymentRequest(scope); |
| ScriptPromise promise = |
| request->canMakePayment(scope.GetScriptState(), ASSERT_NO_EXCEPTION); |
| // PaymentRequest.OnError() runs in this idle. |
| platform_->RunUntilIdle(); |
| |
| EXPECT_FALSE(ResolvePromise(scope.GetScriptState(), promise)); |
| } |
| |
| TEST_F(PaymentRequestForInvalidOriginOrSslTest, |
| HasEnrolledInstrument_CheckAfterIdle) { |
| PaymentRequestV8TestingScope scope; |
| PaymentRequest* request = CreatePaymentRequest(scope); |
| // PaymentRequest.OnError() runs in this idle. |
| platform_->RunUntilIdle(); |
| |
| ScriptPromise promise = request->hasEnrolledInstrument(scope.GetScriptState(), |
| ASSERT_NO_EXCEPTION); |
| EXPECT_FALSE(ResolvePromise(scope.GetScriptState(), promise)); |
| } |
| |
| TEST_F(PaymentRequestForInvalidOriginOrSslTest, |
| HasEnrolledInstrument_CheckBeforeIdle) { |
| PaymentRequestV8TestingScope scope; |
| PaymentRequest* request = CreatePaymentRequest(scope); |
| ScriptPromise promise = request->hasEnrolledInstrument(scope.GetScriptState(), |
| ASSERT_NO_EXCEPTION); |
| // PaymentRequest.OnError() runs in this idle. |
| platform_->RunUntilIdle(); |
| |
| EXPECT_FALSE(ResolvePromise(scope.GetScriptState(), promise)); |
| } |
| |
| } // namespace |
| } // namespace blink |