Add a "supportedConfiguration" dictionary to MediaCapabilitiesDecodingInfo and MediaC...
[WebKit-https.git] / Source / WebCore / testing / MockPaymentCoordinator.cpp
1 /*
2  * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "MockPaymentCoordinator.h"
28
29 #if ENABLE(APPLE_PAY)
30
31 #include "ApplePaySessionPaymentRequest.h"
32 #include "MockPayment.h"
33 #include "MockPaymentContact.h"
34 #include "MockPaymentMethod.h"
35 #include "Page.h"
36 #include "PaymentCoordinator.h"
37 #include <wtf/CompletionHandler.h>
38 #include <wtf/RunLoop.h>
39 #include <wtf/URL.h>
40
41 namespace WebCore {
42
43 MockPaymentCoordinator::MockPaymentCoordinator(Page& page)
44     : m_page { page }
45 {
46     m_availablePaymentNetworks.add("amex");
47     m_availablePaymentNetworks.add("carteBancaire");
48     m_availablePaymentNetworks.add("chinaUnionPay");
49     m_availablePaymentNetworks.add("discover");
50     m_availablePaymentNetworks.add("interac");
51     m_availablePaymentNetworks.add("jcb");
52     m_availablePaymentNetworks.add("masterCard");
53     m_availablePaymentNetworks.add("privateLabel");
54     m_availablePaymentNetworks.add("visa");
55 }
56
57 Optional<String> MockPaymentCoordinator::validatedPaymentNetwork(const String& paymentNetwork)
58 {
59     auto result = m_availablePaymentNetworks.find(paymentNetwork);
60     if (result == m_availablePaymentNetworks.end())
61         return WTF::nullopt;
62     return *result;
63 }
64
65 bool MockPaymentCoordinator::canMakePayments()
66 {
67     return m_canMakePayments;
68 }
69
70 void MockPaymentCoordinator::canMakePaymentsWithActiveCard(const String&, const String&, CompletionHandler<void(bool)>&& completionHandler)
71 {
72     RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler), canMakePaymentsWithActiveCard = m_canMakePaymentsWithActiveCard]() mutable {
73         completionHandler(canMakePaymentsWithActiveCard);
74     });
75 }
76
77 void MockPaymentCoordinator::openPaymentSetup(const String&, const String&, CompletionHandler<void(bool)>&& completionHandler)
78 {
79     RunLoop::main().dispatch([completionHandler = WTFMove(completionHandler)]() mutable {
80         completionHandler(true);
81     });
82 }
83
84 static uint64_t showCount;
85 static uint64_t hideCount;
86
87 static void dispatchIfShowing(Function<void()>&& function)
88 {
89     ASSERT(showCount > hideCount);
90     RunLoop::main().dispatch([currentShowCount = showCount, function = WTFMove(function)]() {
91         if (showCount > hideCount && showCount == currentShowCount)
92             function();
93     });
94 }
95
96 static Vector<ApplePayShippingMethod> convert(const Vector<ApplePaySessionPaymentRequest::ShippingMethod>& shippingMethods)
97 {
98     return WTF::map(shippingMethods, [] (auto& shippingMethod) {
99         return ApplePayShippingMethod { shippingMethod.label, shippingMethod.detail, shippingMethod.amount, shippingMethod.identifier };
100     });
101 }
102
103 bool MockPaymentCoordinator::showPaymentUI(const URL&, const Vector<URL>&, const ApplePaySessionPaymentRequest& request)
104 {
105     if (request.shippingContact().pkContact())
106         m_shippingAddress = request.shippingContact().toApplePayPaymentContact(request.version());
107     m_shippingMethods = convert(request.shippingMethods());
108     m_requiredBillingContactFields = request.requiredBillingContactFields();
109     m_requiredShippingContactFields = request.requiredShippingContactFields();
110
111     ASSERT(showCount == hideCount);
112     ++showCount;
113     dispatchIfShowing([page = &m_page]() {
114         page->paymentCoordinator().validateMerchant({ URL(), "https://webkit.org/"_s });
115     });
116     return true;
117 }
118
119 void MockPaymentCoordinator::completeMerchantValidation(const PaymentMerchantSession&)
120 {
121     dispatchIfShowing([page = &m_page, shippingAddress = m_shippingAddress]() mutable {
122         page->paymentCoordinator().didSelectShippingContact(MockPaymentContact { WTFMove(shippingAddress) });
123     });
124 }
125
126 static ApplePayLineItem convert(const ApplePaySessionPaymentRequest::LineItem& lineItem)
127 {
128     ApplePayLineItem result;
129     result.type = lineItem.type;
130     result.label = lineItem.label;
131     result.amount = lineItem.amount;
132     return result;
133 }
134
135 void MockPaymentCoordinator::updateTotalAndLineItems(const ApplePaySessionPaymentRequest::TotalAndLineItems& totalAndLineItems)
136 {
137     m_total = convert(totalAndLineItems.total);
138     m_lineItems.clear();
139     for (auto& lineItem : totalAndLineItems.lineItems)
140         m_lineItems.append(convert(lineItem));
141 }
142
143 void MockPaymentCoordinator::completeShippingMethodSelection(Optional<ShippingMethodUpdate>&& shippingMethodUpdate)
144 {
145     if (shippingMethodUpdate)
146         updateTotalAndLineItems(shippingMethodUpdate->newTotalAndLineItems);
147 }
148
149 void MockPaymentCoordinator::completeShippingContactSelection(Optional<ShippingContactUpdate>&& shippingContactUpdate)
150 {
151     if (!shippingContactUpdate)
152         return;
153
154     m_shippingMethods = convert(shippingContactUpdate->newShippingMethods);
155     updateTotalAndLineItems(shippingContactUpdate->newTotalAndLineItems);
156     m_errors = WTFMove(shippingContactUpdate->errors);
157 }
158
159 void MockPaymentCoordinator::completePaymentMethodSelection(Optional<PaymentMethodUpdate>&& paymentMethodUpdate)
160 {
161     if (paymentMethodUpdate)
162         updateTotalAndLineItems(paymentMethodUpdate->newTotalAndLineItems);
163 }
164
165 void MockPaymentCoordinator::changeShippingOption(String&& shippingOption)
166 {
167     dispatchIfShowing([page = &m_page, shippingOption = WTFMove(shippingOption)]() mutable {
168         ApplePaySessionPaymentRequest::ShippingMethod shippingMethod;
169         shippingMethod.identifier = WTFMove(shippingOption);
170         page->paymentCoordinator().didSelectShippingMethod(shippingMethod);
171     });
172 }
173
174 void MockPaymentCoordinator::changePaymentMethod(ApplePayPaymentMethod&& paymentMethod)
175 {
176     dispatchIfShowing([page = &m_page, paymentMethod = WTFMove(paymentMethod)]() mutable {
177         page->paymentCoordinator().didSelectPaymentMethod(MockPaymentMethod { WTFMove(paymentMethod) });
178     });
179 }
180
181 void MockPaymentCoordinator::acceptPayment()
182 {
183     dispatchIfShowing([page = &m_page, shippingAddress = m_shippingAddress]() mutable {
184         ApplePayPayment payment;
185         payment.shippingContact = WTFMove(shippingAddress);
186         page->paymentCoordinator().didAuthorizePayment(MockPayment { WTFMove(payment) });
187     });
188 }
189
190 void MockPaymentCoordinator::cancelPayment()
191 {
192     dispatchIfShowing([page = &m_page] {
193         page->paymentCoordinator().didCancelPaymentSession();
194         ++hideCount;
195         ASSERT(showCount == hideCount);
196     });
197 }
198
199 void MockPaymentCoordinator::completePaymentSession(Optional<PaymentAuthorizationResult>&& result)
200 {
201     auto isFinalState = isFinalStateResult(result);
202     m_errors = WTFMove(result->errors);
203
204     if (!isFinalState)
205         return;
206
207     ++hideCount;
208     ASSERT(showCount == hideCount);
209 }
210
211 void MockPaymentCoordinator::abortPaymentSession()
212 {
213     ++hideCount;
214     ASSERT(showCount == hideCount);
215 }
216
217 void MockPaymentCoordinator::cancelPaymentSession()
218 {
219     ++hideCount;
220     ASSERT(showCount == hideCount);
221 }
222
223 void MockPaymentCoordinator::paymentCoordinatorDestroyed()
224 {
225     ASSERT(showCount == hideCount);
226     delete this;
227 }
228
229 } // namespace WebCore
230
231 #endif // ENABLE(APPLE_PAY)