| Index: third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
|
| diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
|
| index 1f0d20c65d93438c17c281f8d13176dc4457eed3..06d7e7b473e93b4bd999da966dd7062a432824fd 100644
|
| --- a/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
|
| +++ b/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
|
| @@ -4,47 +4,23 @@
|
|
|
| #include "modules/payments/PaymentRequest.h"
|
|
|
| -#include "bindings/core/v8/ExceptionState.h"
|
| #include "bindings/core/v8/JSONValuesForV8.h"
|
| +#include "bindings/core/v8/ScriptFunction.h"
|
| #include "bindings/core/v8/ScriptState.h"
|
| #include "bindings/modules/v8/V8PaymentResponse.h"
|
| #include "core/dom/ExceptionCode.h"
|
| -#include "core/testing/DummyPageHolder.h"
|
| -#include "modules/payments/CurrencyAmount.h"
|
| #include "modules/payments/PaymentAddress.h"
|
| -#include "modules/payments/PaymentItem.h"
|
| +#include "modules/payments/PaymentRequestTestBase.h"
|
| +#include "modules/payments/PaymentResponse.h"
|
| #include "modules/payments/PaymentTestHelper.h"
|
| -#include "modules/payments/ShippingOption.h"
|
| #include "platform/heap/HeapAllocator.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| -#include "wtf/OwnPtr.h"
|
| #include <utility>
|
|
|
| namespace blink {
|
| namespace {
|
|
|
| -class PaymentRequestTest : public testing::Test {
|
| -public:
|
| - PaymentRequestTest()
|
| - : m_page(DummyPageHolder::create())
|
| - {
|
| - setSecurityOrigin("https://www.example.com/");
|
| - }
|
| -
|
| - ~PaymentRequestTest() override {}
|
| -
|
| - ScriptState* getScriptState() { return ScriptState::forMainWorld(m_page->document().frame()); }
|
| - ExceptionState& getExceptionState() { return m_exceptionState; }
|
| -
|
| - void setSecurityOrigin(const String& securityOrigin)
|
| - {
|
| - m_page->document().setSecurityOrigin(SecurityOrigin::create(KURL(KURL(), securityOrigin)));
|
| - }
|
| -
|
| -private:
|
| - OwnPtr<DummyPageHolder> m_page;
|
| - TrackExceptionState m_exceptionState;
|
| +class PaymentRequestTest : public PaymentRequestTestBase {
|
| };
|
|
|
| TEST_F(PaymentRequestTest, NoExceptionWithValidData)
|
| @@ -192,92 +168,13 @@ TEST_F(PaymentRequestTest, SelectLastSelectedShippingOptionWhenShippingRequested
|
| EXPECT_EQ("express", request->shippingOption());
|
| }
|
|
|
| -TEST_F(PaymentRequestTest, AbortWithoutShowShouldThrow)
|
| -{
|
| - PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| - EXPECT_FALSE(getExceptionState().hadException());
|
| -
|
| - request->abort(getExceptionState());
|
| - EXPECT_TRUE(getExceptionState().hadException());
|
| -}
|
| -
|
| -class MockFunction : public ScriptFunction {
|
| -public:
|
| - static v8::Local<v8::Function> noExpectations(ScriptState* scriptState)
|
| - {
|
| - MockFunction* self = new MockFunction(scriptState);
|
| - return self->bindToV8Function();
|
| - }
|
| -
|
| - static v8::Local<v8::Function> expectCall(ScriptState* scriptState)
|
| - {
|
| - MockFunction* self = new MockFunction(scriptState);
|
| - EXPECT_CALL(*self, call(testing::_));
|
| - return self->bindToV8Function();
|
| - }
|
| -
|
| - static v8::Local<v8::Function> expectNoCall(ScriptState* scriptState)
|
| - {
|
| - MockFunction* self = new MockFunction(scriptState);
|
| - EXPECT_CALL(*self, call(testing::_)).Times(0);
|
| - return self->bindToV8Function();
|
| - }
|
| -
|
| -private:
|
| - explicit MockFunction(ScriptState* scriptState)
|
| - : ScriptFunction(scriptState)
|
| - {
|
| - ON_CALL(*this, call(testing::_)).WillByDefault(testing::ReturnArg<0>());
|
| - }
|
| -
|
| - MOCK_METHOD1(call, ScriptValue(ScriptValue));
|
| -};
|
| -
|
| -class PaymentResponseFunction : public ScriptFunction {
|
| -public:
|
| - static v8::Local<v8::Function> create(ScriptState* scriptState, ScriptValue* outValue)
|
| - {
|
| - PaymentResponseFunction* self = new PaymentResponseFunction(scriptState, outValue);
|
| - return self->bindToV8Function();
|
| - }
|
| -
|
| - ScriptValue call(ScriptValue value) override
|
| - {
|
| - DCHECK(!value.isEmpty());
|
| - *m_value = value;
|
| - return value;
|
| - }
|
| -
|
| -private:
|
| - PaymentResponseFunction(ScriptState* scriptState, ScriptValue* outValue)
|
| - : ScriptFunction(scriptState)
|
| - , m_value(outValue)
|
| - {
|
| - DCHECK(m_value);
|
| - }
|
| -
|
| - ScriptValue* m_value;
|
| -};
|
| -
|
| -TEST_F(PaymentRequestTest, CanAbortAfterShow)
|
| -{
|
| - ScriptState::Scope scope(getScriptState());
|
| - PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| - EXPECT_FALSE(getExceptionState().hadException());
|
| -
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::noExpectations(getScriptState()));
|
| - request->abort(getExceptionState());
|
| -
|
| - EXPECT_FALSE(getExceptionState().hadException());
|
| -}
|
| -
|
| TEST_F(PaymentRequestTest, RejectShowPromiseOnInvalidShippingAddress)
|
| {
|
| ScriptState::Scope scope(getScriptState());
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnShippingAddressChange(mojom::blink::PaymentAddress::New());
|
| }
|
| @@ -291,7 +188,7 @@ TEST_F(PaymentRequestTest, RejectShowPromiseWithRequestShippingTrueAndEmptyShipp
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| mojom::blink::PaymentResponsePtr response = mojom::blink::PaymentResponse::New();
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(std::move(response));
|
| }
|
| @@ -306,7 +203,7 @@ TEST_F(PaymentRequestTest, RejectShowPromiseWithRequestShippingTrueAndInvalidShi
|
| mojom::blink::PaymentResponsePtr response = mojom::blink::PaymentResponse::New();
|
| response->shipping_address = mojom::blink::PaymentAddress::New();
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(std::move(response));
|
| }
|
| @@ -318,16 +215,43 @@ TEST_F(PaymentRequestTest, RejectShowPromiseWithRequestShippingFalseAndShippingA
|
| options.setRequestShipping(false);
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), options, getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| - mojom::blink::PaymentAddressPtr shippingAddress = mojom::blink::PaymentAddress::New();
|
| - shippingAddress->country = "US";
|
| - shippingAddress->language_code = "en";
|
| - shippingAddress->script_code = "Latn";
|
| + mojom::blink::PaymentResponsePtr response = mojom::blink::PaymentResponse::New();
|
| + response->shipping_address = mojom::blink::PaymentAddress::New();
|
| + response->shipping_address->country = "US";
|
| + response->shipping_address->language_code = "en";
|
| + response->shipping_address->script_code = "Latn";
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| - static_cast<mojom::blink::PaymentRequestClient*>(request)->OnShippingAddressChange(std::move(shippingAddress));
|
| + static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(std::move(response));
|
| }
|
|
|
| +class PaymentResponseFunction : public ScriptFunction {
|
| +public:
|
| + static v8::Local<v8::Function> create(ScriptState* scriptState, ScriptValue* outValue)
|
| + {
|
| + PaymentResponseFunction* self = new PaymentResponseFunction(scriptState, outValue);
|
| + return self->bindToV8Function();
|
| + }
|
| +
|
| + ScriptValue call(ScriptValue value) override
|
| + {
|
| + DCHECK(!value.isEmpty());
|
| + *m_value = value;
|
| + return value;
|
| + }
|
| +
|
| +private:
|
| + PaymentResponseFunction(ScriptState* scriptState, ScriptValue* outValue)
|
| + : ScriptFunction(scriptState)
|
| + , m_value(outValue)
|
| + {
|
| + DCHECK(m_value);
|
| + }
|
| +
|
| + ScriptValue* m_value;
|
| +};
|
| +
|
| TEST_F(PaymentRequestTest, ResolveShowPromiseWithRequestShippingTrueAndValidShippingAddressInResponse)
|
| {
|
| ScriptState::Scope scope(getScriptState());
|
| @@ -342,10 +266,10 @@ TEST_F(PaymentRequestTest, ResolveShowPromiseWithRequestShippingTrueAndValidShip
|
| response->shipping_address->script_code = "Latn";
|
|
|
| ScriptValue outValue;
|
| - request->show(getScriptState()).then(PaymentResponseFunction::create(getScriptState(), &outValue), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(PaymentResponseFunction::create(getScriptState(), &outValue), expectNoCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(std::move(response));
|
| - v8::MicrotasksScope::PerformCheckpoint(getScriptState()->isolate());
|
| + firePromiseCallbacks();
|
| PaymentResponse* pr = V8PaymentResponse::toImplWithTypeCheck(getScriptState()->isolate(), outValue.v8Value());
|
|
|
| EXPECT_EQ("US", pr->shippingAddress()->country());
|
| @@ -361,10 +285,10 @@ TEST_F(PaymentRequestTest, ResolveShowPromiseWithRequestShippingFalseAndEmptyShi
|
| EXPECT_FALSE(getExceptionState().hadException());
|
|
|
| ScriptValue outValue;
|
| - request->show(getScriptState()).then(PaymentResponseFunction::create(getScriptState(), &outValue), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(PaymentResponseFunction::create(getScriptState(), &outValue), expectNoCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(mojom::blink::PaymentResponse::New());
|
| - v8::MicrotasksScope::PerformCheckpoint(getScriptState()->isolate());
|
| + firePromiseCallbacks();
|
| PaymentResponse* pr = V8PaymentResponse::toImplWithTypeCheck(getScriptState()->isolate(), outValue.v8Value());
|
|
|
| EXPECT_EQ(nullptr, pr->shippingAddress());
|
| @@ -376,7 +300,7 @@ TEST_F(PaymentRequestTest, OnShippingOptionChange)
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectNoCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnShippingOptionChange("standardShipping");
|
| }
|
| @@ -388,7 +312,7 @@ TEST_F(PaymentRequestTest, CannotCallShowTwice)
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| request->show(getScriptState());
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
| }
|
|
|
| TEST_F(PaymentRequestTest, CannotCallCompleteTwice)
|
| @@ -400,7 +324,7 @@ TEST_F(PaymentRequestTest, CannotCallCompleteTwice)
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(mojom::blink::PaymentResponse::New());
|
| request->complete(getScriptState(), false);
|
|
|
| - request->complete(getScriptState(), true).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->complete(getScriptState(), true).then(expectNoCall(), expectCall());
|
| }
|
|
|
| TEST_F(PaymentRequestTest, RejectShowPromiseOnError)
|
| @@ -409,7 +333,7 @@ TEST_F(PaymentRequestTest, RejectShowPromiseOnError)
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnError();
|
| }
|
| @@ -422,7 +346,7 @@ TEST_F(PaymentRequestTest, RejectCompletePromiseOnError)
|
| request->show(getScriptState());
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(mojom::blink::PaymentResponse::New());
|
|
|
| - request->complete(getScriptState(), true).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->complete(getScriptState(), true).then(expectNoCall(), expectCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnError();
|
| }
|
| @@ -435,7 +359,7 @@ TEST_F(PaymentRequestTest, ResolvePromiseOnComplete)
|
| request->show(getScriptState());
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(mojom::blink::PaymentResponse::New());
|
|
|
| - request->complete(getScriptState(), true).then(MockFunction::expectCall(getScriptState()), MockFunction::expectNoCall(getScriptState()));
|
| + request->complete(getScriptState(), true).then(expectCall(), expectNoCall());
|
|
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnComplete();
|
| }
|
| @@ -446,7 +370,7 @@ TEST_F(PaymentRequestTest, RejectShowPromiseOnUpdateDetailsFailure)
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| request->onUpdatePaymentDetailsFailure(ScriptValue::from(getScriptState(), "oops"));
|
| }
|
| @@ -456,10 +380,10 @@ TEST_F(PaymentRequestTest, RejectCompletePromiseOnUpdateDetailsFailure)
|
| ScriptState::Scope scope(getScriptState());
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| - request->show(getScriptState()).then(MockFunction::expectCall(getScriptState()), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectCall(), expectNoCall());
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(mojom::blink::PaymentResponse::New());
|
|
|
| - request->complete(getScriptState(), true).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->complete(getScriptState(), true).then(expectNoCall(), expectCall());
|
|
|
| request->onUpdatePaymentDetailsFailure(ScriptValue::from(getScriptState(), "oops"));
|
| }
|
| @@ -469,7 +393,7 @@ TEST_F(PaymentRequestTest, IgnoreUpdatePaymentDetailsAfterShowPromiseResolved)
|
| ScriptState::Scope scope(getScriptState());
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| - request->show(getScriptState()).then(MockFunction::expectCall(getScriptState()), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectCall(), expectNoCall());
|
| static_cast<mojom::blink::PaymentRequestClient*>(request)->OnPaymentResponse(mojom::blink::PaymentResponse::New());
|
|
|
| request->onUpdatePaymentDetails(ScriptValue::from(getScriptState(), "foo"));
|
| @@ -481,7 +405,7 @@ TEST_F(PaymentRequestTest, RejectShowPromiseOnNonPaymentDetailsUpdate)
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| request->onUpdatePaymentDetails(ScriptValue::from(getScriptState(), "NotPaymentDetails"));
|
| }
|
| @@ -492,7 +416,7 @@ TEST_F(PaymentRequestTest, RejectShowPromiseOnInvalidPaymentDetailsUpdate)
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
|
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectCall());
|
|
|
| request->onUpdatePaymentDetails(ScriptValue::from(getScriptState(), fromJSONString(getScriptState(), "{}", getExceptionState())));
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| @@ -508,7 +432,7 @@ TEST_F(PaymentRequestTest, ClearShippingOptionOnPaymentDetailsUpdateWithoutShipp
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), details, options, getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| EXPECT_TRUE(request->shippingOption().isNull());
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectNoCall());
|
| String detailWithShippingOptions = "{\"total\": {\"label\": \"Total\", \"amount\": {\"currency\": \"USD\", \"value\": \"5.00\"}},"
|
| "\"shippingOptions\": [{\"id\": \"standardShippingOption\", \"label\": \"Standard shipping\", \"amount\": {\"currency\": \"USD\", \"value\": \"5.00\"}, \"selected\": true}]}";
|
| request->onUpdatePaymentDetails(ScriptValue::from(getScriptState(), fromJSONString(getScriptState(), detailWithShippingOptions, getExceptionState())));
|
| @@ -529,7 +453,7 @@ TEST_F(PaymentRequestTest, ClearShippingOptionOnPaymentDetailsUpdateWithMultiple
|
| options.setRequestShipping(true);
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), options, getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectNoCall());
|
| String detail = "{\"total\": {\"label\": \"Total\", \"amount\": {\"currency\": \"USD\", \"value\": \"5.00\"}},"
|
| "\"shippingOptions\": [{\"id\": \"slow\", \"label\": \"Slow\", \"amount\": {\"currency\": \"USD\", \"value\": \"5.00\"}},"
|
| "{\"id\": \"fast\", \"label\": \"Fast\", \"amount\": {\"currency\": \"USD\", \"value\": \"50.00\"}}]}";
|
| @@ -547,7 +471,7 @@ TEST_F(PaymentRequestTest, UseTheSelectedShippingOptionFromPaymentDetailsUpdate)
|
| options.setRequestShipping(true);
|
| PaymentRequest* request = PaymentRequest::create(getScriptState(), buildPaymentMethodDataForTest(), buildPaymentDetailsForTest(), options, getExceptionState());
|
| EXPECT_FALSE(getExceptionState().hadException());
|
| - request->show(getScriptState()).then(MockFunction::expectNoCall(getScriptState()), MockFunction::expectNoCall(getScriptState()));
|
| + request->show(getScriptState()).then(expectNoCall(), expectNoCall());
|
| String detail = "{\"total\": {\"label\": \"Total\", \"amount\": {\"currency\": \"USD\", \"value\": \"5.00\"}},"
|
| "\"shippingOptions\": [{\"id\": \"slow\", \"label\": \"Slow\", \"amount\": {\"currency\": \"USD\", \"value\": \"5.00\"}},"
|
| "{\"id\": \"fast\", \"label\": \"Fast\", \"amount\": {\"currency\": \"USD\", \"value\": \"50.00\"}, \"selected\": true}]}";
|
|
|