diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d79bd88..8f11068c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Require Xcode 14.1+ and Swift 5.7.1+ (per [App Store requirements](https://developer.apple.com/news/?id=jd9wcyov#:~:text=Starting%20April%2025%2C%202023%2C%20iOS,on%20the%20Mac%20App%20Store)) * Add California Privacy Laws notice of collection to credit card form * Fix bug where presenting the Drop-in from a modal screen without a `modalPresentationStyle` does not display the status bar when both device and Drop-in are in light mode (fixes #419) +* Add `BTDropInRequest.cardLogosDisabled` to hide card logos on the credit card form if desired ## 9.8.2 (2023-04-10) * Silence UnionPay related deprecation warnings introduced in `braintree_ios` 5.21.0 and higher. diff --git a/Demo/Application/DemoDropInViewController.swift b/Demo/Application/DemoDropInViewController.swift index e660f8a9..8ffcccee 100644 --- a/Demo/Application/DemoDropInViewController.swift +++ b/Demo/Application/DemoDropInViewController.swift @@ -44,6 +44,7 @@ class DemoDropInViewController: DemoBaseViewController, DemoDropInViewDelegate { dropInRequest.paypalDisabled = DemoSettings.paypalDisabled dropInRequest.cardDisabled = ProcessInfo.processInfo.arguments.contains("-CardDisabled") + dropInRequest.cardLogosDisabled = ProcessInfo.processInfo.arguments.contains("-CardLogosDisabled") dropInRequest.shouldMaskSecurityCode = DemoSettings.maskSecurityCode dropInRequest.cardholderNameSetting = DemoSettings.cardholderNameSetting dropInRequest.vaultCard = DemoSettings.vaultCardSetting diff --git a/Demo/UITests/BraintreeDropIn_UITests.swift b/Demo/UITests/BraintreeDropIn_UITests.swift index a285eff6..e4342dea 100644 --- a/Demo/UITests/BraintreeDropIn_UITests.swift +++ b/Demo/UITests/BraintreeDropIn_UITests.swift @@ -180,6 +180,61 @@ class BraintreeDropIn_CardDisabled_UITests: XCTestCase { } } +class BraintreeDropIn_CardLogosDisabled_UITests: XCTestCase { + + var app: XCUIApplication! + + override func setUp() { + super.setUp() + continueAfterFailure = false + app = XCUIApplication() + app.launchArguments.append("-EnvironmentSandbox") + app.launchArguments.append("-TokenizationKey") + app.launchArguments.append("-CardLogosDisabled") + app.launch() + sleep(1) + waitForElementToBeHittable(app.buttons["Add Payment Method"]) + app.buttons["Add Payment Method"].tap() + } + + func testDropIn_cardLogosDisabledOption_hidesCardLogos() { + waitForElementToBeHittable(app.staticTexts["Credit or Debit Card"]) + app.staticTexts["Credit or Debit Card"].tap() + + let elementsQuery = app.scrollViews.otherElements + let cardLogoImages = elementsQuery.images.element.exists + + XCTAssertFalse(cardLogoImages) + } +} + +class BraintreeDropIn_CardLogosEnabled_UITests: XCTestCase { + + var app: XCUIApplication! + + override func setUp() { + super.setUp() + continueAfterFailure = false + app = XCUIApplication() + app.launchArguments.append("-EnvironmentSandbox") + app.launchArguments.append("-TokenizationKey") + app.launch() + sleep(1) + waitForElementToBeHittable(app.buttons["Add Payment Method"]) + app.buttons["Add Payment Method"].tap() + } + + func testDropIn_cardLogosEnabledOption_showsCardLogos() { + waitForElementToBeHittable(app.staticTexts["Credit or Debit Card"]) + app.staticTexts["Credit or Debit Card"].tap() + + let elementsQuery = app.scrollViews.otherElements + let cardLogoImages = elementsQuery.images.element.exists + + XCTAssertTrue(cardLogoImages) + } +} + class BraintreeDropIn_CardForm_RequestOptions_UITests: XCTestCase { var app: XCUIApplication! diff --git a/Sources/BraintreeDropIn/BTCardFormViewController.m b/Sources/BraintreeDropIn/BTCardFormViewController.m index a739972c..2ef0702a 100644 --- a/Sources/BraintreeDropIn/BTCardFormViewController.m +++ b/Sources/BraintreeDropIn/BTCardFormViewController.m @@ -234,12 +234,15 @@ - (void)setupForm { self.cardNumberFooter.layoutMargins = UIEdgeInsetsMake(0, [BTUIKAppearance verticalFormSpace], 0, [BTUIKAppearance verticalFormSpace]); self.cardNumberFooter.layoutMarginsRelativeArrangement = true; [self.stackView addArrangedSubview:self.cardNumberFooter]; - self.cardList = [BTUIKCardListLabel new]; - self.cardList.translatesAutoresizingMaskIntoConstraints = NO; - self.cardList.availablePaymentOptions = self.supportedCardTypes; - [self.cardNumberFooter addArrangedSubview:self.cardList]; - [BTDropInUIUtilities addSpacerToStackView:self.cardNumberFooter beforeView:self.cardList size: [BTUIKAppearance horizontalFormContentPadding]]; - + + if (!self.dropInRequest.cardLogosDisabled) { + self.cardList = [BTUIKCardListLabel new]; + self.cardList.translatesAutoresizingMaskIntoConstraints = NO; + self.cardList.availablePaymentOptions = self.supportedCardTypes; + [self.cardNumberFooter addArrangedSubview:self.cardList]; + [BTDropInUIUtilities addSpacerToStackView:self.cardNumberFooter beforeView:self.cardList size: [BTUIKAppearance horizontalFormContentPadding]]; + } + NSUInteger indexOfCardNumberField = [self.stackView.arrangedSubviews indexOfObject:self.cardNumberField]; [self.stackView insertArrangedSubview:self.cardNumberFooter atIndex:(indexOfCardNumberField + 1)]; diff --git a/Sources/BraintreeDropIn/Models/BTDropInRequest.m b/Sources/BraintreeDropIn/Models/BTDropInRequest.m index 513f03ba..7957fe2b 100644 --- a/Sources/BraintreeDropIn/Models/BTDropInRequest.m +++ b/Sources/BraintreeDropIn/Models/BTDropInRequest.m @@ -25,6 +25,7 @@ - (id)copyWithZone:(__unused NSZone *)zone { request.paypalDisabled = self.paypalDisabled; request.venmoDisabled = self.venmoDisabled; request.cardDisabled = self.cardDisabled; + request.cardLogosDisabled = self.cardLogosDisabled; request.threeDSecureRequest = self.threeDSecureRequest; request.cardholderNameSetting = self.cardholderNameSetting; request.shouldMaskSecurityCode = self.shouldMaskSecurityCode; diff --git a/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h b/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h index 4d3210c2..2aa928d5 100644 --- a/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h +++ b/Sources/BraintreeDropIn/Public/BraintreeDropIn/BTDropInRequest.h @@ -40,6 +40,9 @@ typedef NS_ENUM(NSInteger, BTFormFieldSetting) { /// Defaults to false. Set to true to hide the Card option even if enabled for your account. @property (nonatomic, assign) BOOL cardDisabled; +/// Defaults to false. Set to true to hide all card logos for your account. +@property (nonatomic, assign) BOOL cardLogosDisabled; + /// Optional: Enable 3DS verification and specify options and additional information. /// /// Note: To encourage 3DS 2.0 flows, set `billingAddress`, `amount`, `email`, `mobilePhone` for best results. diff --git a/UnitTests/BTDropInRequestTests.m b/UnitTests/BTDropInRequestTests.m index be436f32..58518d46 100644 --- a/UnitTests/BTDropInRequestTests.m +++ b/UnitTests/BTDropInRequestTests.m @@ -45,6 +45,7 @@ - (void)test_copyProperties { originalRequest.paypalDisabled = YES; originalRequest.venmoDisabled = YES; originalRequest.cardDisabled = YES; + originalRequest.cardLogosDisabled = YES; originalRequest.threeDSecureRequest = threeDSecureRequest; originalRequest.cardholderNameSetting = BTFormFieldOptional; originalRequest.shouldMaskSecurityCode = YES; @@ -60,6 +61,7 @@ - (void)test_copyProperties { XCTAssertEqual(originalRequest.paypalDisabled, copiedRequest.paypalDisabled); XCTAssertEqual(originalRequest.venmoDisabled, copiedRequest.venmoDisabled); XCTAssertEqual(originalRequest.cardDisabled, copiedRequest.cardDisabled); + XCTAssertEqual(originalRequest.cardLogosDisabled, copiedRequest.cardLogosDisabled); XCTAssertEqual(originalRequest.cardholderNameSetting, copiedRequest.cardholderNameSetting); XCTAssertEqual(originalRequest.shouldMaskSecurityCode, copiedRequest.shouldMaskSecurityCode); XCTAssertEqual(originalRequest.vaultManager, copiedRequest.vaultManager);