REGRESSION (r260717): installmentConfiguration member is no longer available on Apple...
authoraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 May 2020 19:13:58 +0000 (19:13 +0000)
committeraestes@apple.com <aestes@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 16 May 2020 19:13:58 +0000 (19:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=211911
<rdar://problem/63236367>

Reviewed by Tim Horton.

Source/WebCore:

Prior to r260717, installmentConfiguration was a member of ApplePayRequestBase, making it
available on ApplePayRequest and ApplePayPaymentRequest. In r260717, it was mistakenly
moved to ApplePayRequest.

This change moves it back to ApplePayRequestBase, adds infrastructure for regression testing
ApplePayInstallmentConfiguration, and adds a regression test.

Test: http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html

* Modules/applepay/ApplePayInstallmentConfiguration.idl:
* Modules/applepay/ApplePayRequestBase.cpp:
(WebCore::convertAndValidate):
(WebCore::finishConverting): Deleted.
* Modules/applepay/ApplePayRequestBase.idl:
* Modules/applepay/PaymentInstallmentConfiguration.mm:
(WebCore::fromDecimalNumber):
(WebCore::applePaySetupFeatureType):
(WebCore::PaymentInstallmentConfiguration::applePayInstallmentConfiguration const):
* Modules/applepay/PaymentInstallmentConfigurationWebCore.h:
* Modules/applepay/paymentrequest/ApplePayRequest.idl:
* testing/MockPaymentCoordinator.cpp:
(WebCore::MockPaymentCoordinator::showPaymentUI):
* testing/MockPaymentCoordinator.h:
* testing/MockPaymentCoordinator.idl:

Source/WebKit:

* Shared/Cocoa/WebCoreArgumentCodersCocoa.mm:
(IPC::ArgumentCoder<ApplePaySessionPaymentRequest>::encode):
(IPC::ArgumentCoder<ApplePaySessionPaymentRequest>::decode):
(IPC::finishDecoding): Deleted.
(IPC::finishEncoding): Deleted.

LayoutTests:

* http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https-expected.txt: Added.
* http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261785 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html [new file with mode: 0644]
LayoutTests/platform/mac-wk2/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/Modules/applepay/ApplePayInstallmentConfiguration.idl
Source/WebCore/Modules/applepay/ApplePayRequestBase.cpp
Source/WebCore/Modules/applepay/ApplePayRequestBase.idl
Source/WebCore/Modules/applepay/PaymentInstallmentConfiguration.mm
Source/WebCore/Modules/applepay/PaymentInstallmentConfigurationWebCore.h
Source/WebCore/Modules/applepay/paymentrequest/ApplePayRequest.idl
Source/WebCore/testing/MockPaymentCoordinator.cpp
Source/WebCore/testing/MockPaymentCoordinator.h
Source/WebCore/testing/MockPaymentCoordinator.idl
Source/WebKit/ChangeLog
Source/WebKit/Shared/Cocoa/WebCoreArgumentCodersCocoa.mm

index dae5be7..407371c 100644 (file)
@@ -1,3 +1,14 @@
+2020-05-16  Andy Estes  <aestes@apple.com>
+
+        REGRESSION (r260717): installmentConfiguration member is no longer available on ApplePayPaymentRequest
+        https://bugs.webkit.org/show_bug.cgi?id=211911
+        <rdar://problem/63236367>
+
+        Reviewed by Tim Horton.
+
+        * http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https-expected.txt: Added.
+        * http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html: Added.
+
 2020-05-16  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][TFC] Ignore table padding when borders are collapsed
diff --git a/LayoutTests/http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https-expected.txt b/LayoutTests/http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https-expected.txt
new file mode 100644 (file)
index 0000000..f97253d
--- /dev/null
@@ -0,0 +1,17 @@
+Test ApplePayInstallmentConfiguration.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS internals.mockPaymentCoordinator.installmentConfiguration.bindingTotalAmount is expectedBindingTotalAmount
+PASS internals.mockPaymentCoordinator.installmentConfiguration.currencyCode is expectedCurrencyCode
+PASS internals.mockPaymentCoordinator.installmentConfiguration.featureType is expectedFeatureType
+PASS internals.mockPaymentCoordinator.installmentConfiguration.isInStorePurchase is expectedIsInStorePurchase
+PASS internals.mockPaymentCoordinator.installmentConfiguration.merchandisingImageData is expectedMerchandisingImageData
+PASS internals.mockPaymentCoordinator.installmentConfiguration.merchantIdentifier is expectedMerchantIdentifier
+PASS internals.mockPaymentCoordinator.installmentConfiguration.openToBuyThresholdAmount is expectedOpenToBuyThresholdAmount
+PASS internals.mockPaymentCoordinator.installmentConfiguration.referrerIdentifier is expectedReferrerIdentifier
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html b/LayoutTests/http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html
new file mode 100644 (file)
index 0000000..a873b35
--- /dev/null
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="/js-test-resources/ui-helper.js"></script>
+<script src="/resources/js-test-pre.js"></script>
+<script src="/resources/payment-request.js"></script>
+</head>
+<body>
+<script>
+
+description("Test ApplePayInstallmentConfiguration.");
+
+window.jsTestIsAsync = true;
+
+expectedBindingTotalAmount = '1.00';
+expectedCurrencyCode = 'USD';
+expectedFeatureType = 'appleCard';
+expectedIsInStorePurchase = false;
+expectedMerchandisingImageData = 'dGVzdA==';
+expectedMerchantIdentifier = 'merchant';
+expectedOpenToBuyThresholdAmount = '2.50';
+expectedReferrerIdentifier = 'referrer';
+
+function validRequest()
+{
+    return {
+        countryCode: 'US',
+        currencyCode: 'USD',
+        supportedNetworks: ['visa', 'masterCard'],
+        merchantCapabilities: ['supports3DS'],
+        total: { label: 'Your Label', amount: '10.00' },
+        installmentConfiguration: {
+            bindingTotalAmount: expectedBindingTotalAmount,
+            currencyCode: expectedCurrencyCode,
+            merchandisingImageData: expectedMerchandisingImageData,
+            merchantIdentifier: expectedMerchantIdentifier,
+            openToBuyThresholdAmount: expectedOpenToBuyThresholdAmount,
+            referrerIdentifier: expectedReferrerIdentifier,
+        },
+    }
+}
+
+activateThen(() => {
+    var session = new ApplePaySession(8, validRequest());
+    session.begin();
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.bindingTotalAmount', 'expectedBindingTotalAmount');
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.currencyCode', 'expectedCurrencyCode');
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.featureType', 'expectedFeatureType');
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.isInStorePurchase', 'expectedIsInStorePurchase');
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.merchandisingImageData', 'expectedMerchandisingImageData');
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.merchantIdentifier', 'expectedMerchantIdentifier');
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.openToBuyThresholdAmount', 'expectedOpenToBuyThresholdAmount');
+    shouldBe('internals.mockPaymentCoordinator.installmentConfiguration.referrerIdentifier', 'expectedReferrerIdentifier');
+    internals.mockPaymentCoordinator.cancelPayment();
+    finishJSTest();
+});
+</script>
+<script src="/resources/js-test-post.js"></script>
+</body>
+</html>
index 37c5737..a6704af 100644 (file)
@@ -36,6 +36,9 @@ fast/media/mq-prefers-reduced-motion-live-update.html [ Pass ]
 
 http/tests/ssl/applepay/ [ Pass ]
 
+# ApplePayInstallmentConfiguration was first available in Catalina.
+[ Mojave ] http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html [ Skip ]
+
 fast/visual-viewport/rubberbanding-viewport-rects.html [ Pass ]
 fast/visual-viewport/rubberbanding-viewport-rects-header-footer.html  [ Pass ]
 
index 224eb4f..e2b8eb1 100644 (file)
@@ -1,3 +1,36 @@
+2020-05-16  Andy Estes  <aestes@apple.com>
+
+        REGRESSION (r260717): installmentConfiguration member is no longer available on ApplePayPaymentRequest
+        https://bugs.webkit.org/show_bug.cgi?id=211911
+        <rdar://problem/63236367>
+
+        Reviewed by Tim Horton.
+
+        Prior to r260717, installmentConfiguration was a member of ApplePayRequestBase, making it
+        available on ApplePayRequest and ApplePayPaymentRequest. In r260717, it was mistakenly
+        moved to ApplePayRequest.
+
+        This change moves it back to ApplePayRequestBase, adds infrastructure for regression testing
+        ApplePayInstallmentConfiguration, and adds a regression test.
+
+        Test: http/tests/ssl/applepay/ApplePayInstallmentConfiguration.https.html
+
+        * Modules/applepay/ApplePayInstallmentConfiguration.idl:
+        * Modules/applepay/ApplePayRequestBase.cpp:
+        (WebCore::convertAndValidate):
+        (WebCore::finishConverting): Deleted.
+        * Modules/applepay/ApplePayRequestBase.idl:
+        * Modules/applepay/PaymentInstallmentConfiguration.mm:
+        (WebCore::fromDecimalNumber):
+        (WebCore::applePaySetupFeatureType):
+        (WebCore::PaymentInstallmentConfiguration::applePayInstallmentConfiguration const):
+        * Modules/applepay/PaymentInstallmentConfigurationWebCore.h:
+        * Modules/applepay/paymentrequest/ApplePayRequest.idl:
+        * testing/MockPaymentCoordinator.cpp:
+        (WebCore::MockPaymentCoordinator::showPaymentUI):
+        * testing/MockPaymentCoordinator.h:
+        * testing/MockPaymentCoordinator.idl:
+
 2020-05-16  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][TFC] Ignore table padding when borders are collapsed
index ae9f19b..068c28a 100644 (file)
@@ -25,6 +25,8 @@
 
 [
     Conditional=APPLE_PAY_INSTALLMENTS,
+    ExportMacro=WEBCORE_EXPORT,
+    JSGenerateToJSObject,
 ] dictionary ApplePayInstallmentConfiguration {
     ApplePaySetupFeatureType featureType = "appleCard";
     DOMString merchandisingImageData;
index 913c797..1ea567e 100644 (file)
 
 namespace WebCore {
 
-static void finishConverting(ApplePaySessionPaymentRequest& result, ApplePayRequestBase& request)
-{
-#if ENABLE(APPLE_PAY_INSTALLMENTS)
-    if (request.installmentConfiguration)
-        result.setInstallmentConfiguration(WTFMove(*request.installmentConfiguration));
-#else
-    UNUSED_PARAM(result);
-    UNUSED_PARAM(request);
-#endif
-}
-
 static bool requiresSupportedNetworks(unsigned version, const ApplePayRequestBase& request)
 {
 #if ENABLE(APPLE_PAY_INSTALLMENTS)
@@ -116,7 +105,10 @@ ExceptionOr<ApplePaySessionPaymentRequest> convertAndValidate(Document& document
     if (version >= 3)
         result.setSupportedCountries(WTFMove(request.supportedCountries));
 
-    finishConverting(result, request);
+#if ENABLE(APPLE_PAY_INSTALLMENTS)
+    if (request.installmentConfiguration)
+        result.setInstallmentConfiguration(WTFMove(*request.installmentConfiguration));
+#endif
 
     return WTFMove(result);
 }
index 342b408..e57d00d 100644 (file)
@@ -38,4 +38,6 @@
 
     DOMString applicationData;
     [Conditional=APPLE_PAY_SESSION_V3] sequence<DOMString> supportedCountries;
+
+    [Conditional=APPLE_PAY_INSTALLMENTS] ApplePayInstallmentConfiguration installmentConfiguration;
 };
index 27615e2..8fa83ed 100644 (file)
@@ -41,6 +41,15 @@ static NSDecimalNumber *toDecimalNumber(const String& amount)
     return [NSDecimalNumber decimalNumberWithString:amount locale:@{ NSLocaleDecimalSeparator : @"." }];
 }
 
+static String fromDecimalNumber(NSDecimalNumber *number)
+{
+    auto numberFormatter = adoptNS([[NSNumberFormatter alloc] init]);
+    numberFormatter.numberStyle = NSNumberFormatterNoStyle;
+    numberFormatter.minimumIntegerDigits = 1;
+    numberFormatter.minimumFractionDigits = 2;
+    return [numberFormatter stringFromNumber:number];
+}
+
 static PKPaymentSetupFeatureType platformFeatureType(const ApplePaySetupFeatureType& featureType)
 {
     switch (featureType) {
@@ -53,6 +62,18 @@ static PKPaymentSetupFeatureType platformFeatureType(const ApplePaySetupFeatureT
     }
 }
 
+static ApplePaySetupFeatureType applePaySetupFeatureType(PKPaymentSetupFeatureType featureType)
+{
+    switch (featureType) {
+    case PKPaymentSetupFeatureTypeApplePay:
+        return ApplePaySetupFeatureType::ApplePay;
+    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
+    case PKPaymentSetupFeatureTypeApplePay_X:
+    ALLOW_DEPRECATED_DECLARATIONS_END
+        return ApplePaySetupFeatureType::AppleCard;
+    }
+}
+
 static RetainPtr<PKPaymentInstallmentConfiguration> createPlatformConfiguration(const ApplePayInstallmentConfiguration& coreConfiguration)
 {
     auto configuration = adoptNS([PAL::allocPKPaymentInstallmentConfigurationInstance() init]);
@@ -94,6 +115,31 @@ PKPaymentInstallmentConfiguration *PaymentInstallmentConfiguration::platformConf
     return m_configuration.get();
 }
 
+ApplePayInstallmentConfiguration PaymentInstallmentConfiguration::applePayInstallmentConfiguration() const
+{
+    ApplePayInstallmentConfiguration installmentConfiguration;
+
+    installmentConfiguration.featureType = applePaySetupFeatureType([m_configuration feature]);
+
+    installmentConfiguration.bindingTotalAmount = fromDecimalNumber([m_configuration bindingTotalAmount]);
+    installmentConfiguration.currencyCode = [m_configuration currencyCode];
+    installmentConfiguration.isInStorePurchase = [m_configuration isInStorePurchase];
+    installmentConfiguration.openToBuyThresholdAmount = fromDecimalNumber([m_configuration openToBuyThresholdAmount]);
+
+    installmentConfiguration.merchandisingImageData = [[m_configuration merchandisingImageData] base64EncodedStringWithOptions:0];
+
+#if HAVE(PASSKIT_INSTALLMENT_IDENTIFIERS)
+#if PLATFORM(MAC)
+    if (![m_configuration respondsToSelector:@selector(installmentMerchantIdentifier)] || ![m_configuration respondsToSelector:@selector(referrerIdentifier)])
+        return installmentConfiguration;
+#endif
+    installmentConfiguration.merchantIdentifier = [m_configuration installmentMerchantIdentifier];
+    installmentConfiguration.referrerIdentifier = [m_configuration referrerIdentifier];
+#endif
+    
+    return installmentConfiguration;
+}
+
 } // namespace WebCore
 
 #endif // HAVE(PASSKIT_INSTALLMENTS)
index 5634a6f..3bf176a 100644 (file)
@@ -42,6 +42,7 @@ public:
     PaymentInstallmentConfiguration(RetainPtr<PKPaymentInstallmentConfiguration>&&);
 
     PKPaymentInstallmentConfiguration *platformConfiguration() const;
+    ApplePayInstallmentConfiguration applePayInstallmentConfiguration() const;
 
 private:
     RetainPtr<PKPaymentInstallmentConfiguration> m_configuration;
index 6c1dc53..fb590af 100644 (file)
@@ -28,5 +28,4 @@
 ] dictionary ApplePayRequest : ApplePayRequestBase {
     required unsigned long version;
     required DOMString merchantIdentifier;
-    [Conditional=APPLE_PAY_INSTALLMENTS] ApplePayInstallmentConfiguration installmentConfiguration;
 };
index fd7fddd..782dd7e 100644 (file)
@@ -109,6 +109,9 @@ bool MockPaymentCoordinator::showPaymentUI(const URL&, const Vector<URL>&, const
     m_shippingMethods = convert(request.shippingMethods());
     m_requiredBillingContactFields = request.requiredBillingContactFields();
     m_requiredShippingContactFields = request.requiredShippingContactFields();
+#if ENABLE(APPLE_PAY_INSTALLMENTS)
+    m_installmentConfiguration = request.installmentConfiguration().applePayInstallmentConfiguration();
+#endif
 
     ASSERT(showCount == hideCount);
     ++showCount;
index b1f7309..a444162 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(APPLE_PAY)
 
+#include "ApplePayInstallmentConfigurationWebCore.h"
 #include "ApplePayLineItem.h"
 #include "ApplePayShippingMethod.h"
 #include "MockPaymentAddress.h"
@@ -62,6 +63,10 @@ public:
 
     bool supportsUnrestrictedApplePay() const final { return m_supportsUnrestrictedApplePay; }
     void setSupportsUnrestrictedApplePay(bool supports) { m_supportsUnrestrictedApplePay = supports; }
+    
+#if ENABLE(APPLE_PAY_INSTALLMENTS)
+    ApplePayInstallmentConfiguration installmentConfiguration() const { return m_installmentConfiguration; }
+#endif
 
     void ref() const { }
     void deref() const { }
@@ -99,6 +104,9 @@ private:
     MockPaymentContactFields m_requiredBillingContactFields;
     MockPaymentContactFields m_requiredShippingContactFields;
     bool m_supportsUnrestrictedApplePay { true };
+#if ENABLE(APPLE_PAY_INSTALLMENTS)
+    ApplePayInstallmentConfiguration m_installmentConfiguration;
+#endif
 };
 
 } // namespace WebCore
index aa0f94b..7934b50 100644 (file)
@@ -43,4 +43,6 @@
     readonly attribute MockPaymentContactFields requiredShippingContactFields;
 
     attribute boolean supportsUnrestrictedApplePay;
+
+    [Conditional=APPLE_PAY_INSTALLMENTS] readonly attribute ApplePayInstallmentConfiguration installmentConfiguration;
 };
index ed74fd8..8232003 100644 (file)
@@ -1,3 +1,17 @@
+2020-05-16  Andy Estes  <aestes@apple.com>
+
+        REGRESSION (r260717): installmentConfiguration member is no longer available on ApplePayPaymentRequest
+        https://bugs.webkit.org/show_bug.cgi?id=211911
+        <rdar://problem/63236367>
+
+        Reviewed by Tim Horton.
+
+        * Shared/Cocoa/WebCoreArgumentCodersCocoa.mm:
+        (IPC::ArgumentCoder<ApplePaySessionPaymentRequest>::encode):
+        (IPC::ArgumentCoder<ApplePaySessionPaymentRequest>::decode):
+        (IPC::finishDecoding): Deleted.
+        (IPC::finishEncoding): Deleted.
+
 2020-05-16  Yury Semikhatsky  <yurys@chromium.org>
 
         [GTK] Do not leak pages created by window.open
index 083e66d..1ae81a1 100644 (file)
@@ -64,33 +64,6 @@ Optional<WebCore::AttributedString> ArgumentCoder<WebCore::AttributedString>::de
 
 #if ENABLE(APPLE_PAY)
 
-static bool finishDecoding(Decoder& decoder, WebCore::ApplePaySessionPaymentRequest& request)
-{
-#if ENABLE(APPLE_PAY_INSTALLMENTS)
-    Optional<WebCore::PaymentInstallmentConfiguration> installmentConfiguration;
-    decoder >> installmentConfiguration;
-    if (!installmentConfiguration)
-        return false;
-
-    request.setInstallmentConfiguration(WTFMove(*installmentConfiguration));
-    return true;
-#else
-    UNUSED_PARAM(decoder);
-    UNUSED_PARAM(request);
-    return true;
-#endif
-}
-
-static void finishEncoding(Encoder& encoder, const WebCore::ApplePaySessionPaymentRequest& request)
-{
-#if ENABLE(APPLE_PAY_INSTALLMENTS)
-    encoder << request.installmentConfiguration();
-#else
-    UNUSED_PARAM(encoder);
-    UNUSED_PARAM(request);
-#endif
-}
-
 #if HAVE(PASSKIT_INSTALLMENTS)
 
 void ArgumentCoder<WebCore::PaymentInstallmentConfiguration>::encode(Encoder& encoder, const WebCore::PaymentInstallmentConfiguration& configuration)
@@ -244,7 +217,9 @@ void ArgumentCoder<ApplePaySessionPaymentRequest>::encode(Encoder& encoder, cons
     encoder << request.applicationData();
     encoder << request.supportedCountries();
     encoder.encodeEnum(request.requester());
-    finishEncoding(encoder, request);
+#if ENABLE(APPLE_PAY_INSTALLMENTS)
+    encoder << request.installmentConfiguration();
+#endif
 }
 
 bool ArgumentCoder<ApplePaySessionPaymentRequest>::decode(Decoder& decoder, ApplePaySessionPaymentRequest& request)
@@ -326,10 +301,16 @@ bool ArgumentCoder<ApplePaySessionPaymentRequest>::decode(Decoder& decoder, Appl
     if (!decoder.decodeEnum(requester))
         return false;
     request.setRequester(requester);
-
-    if (!finishDecoding(decoder, request))
+    
+#if ENABLE(APPLE_PAY_INSTALLMENTS)
+    Optional<WebCore::PaymentInstallmentConfiguration> installmentConfiguration;
+    decoder >> installmentConfiguration;
+    if (!installmentConfiguration)
         return false;
 
+    request.setInstallmentConfiguration(WTFMove(*installmentConfiguration));
+#endif
+
     return true;
 }