Skip to content

Commit

Permalink
Add VerticalSavedPaymentOptionsViewController (#3569)
Browse files Browse the repository at this point in the history
## Summary
- Adds VerticalSavedPaymentOptionsViewController
- Adds scaffolding in place snapshot tests
- Handles navigation between vertical PaymentSheet and
VerticalSavedPaymentOptionsViewController


https://github.com/stripe/stripe-ios/assets/88012362/b340e598-3300-4b40-9320-d36504958c5c


## Motivation
https://jira.corp.stripe.com/browse/MOBILESDK-2023

## Testing
- Manual

## Changelog
N/A
  • Loading branch information
porter-stripe authored May 8, 2024
1 parent e5e1685 commit 8d7dc51
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@
6103F2BC2BE45990002D67F8 /* SavedPaymentMethodManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6103F2BB2BE45990002D67F8 /* SavedPaymentMethodManager.swift */; };
614A8AE72BE53C6900E8688B /* SavedPaymentMethodManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6103F2BD2BE53737002D67F8 /* SavedPaymentMethodManagerTest.swift */; };
6151DDC02B14FDCF00ED4F7E /* UpdateCardViewControllerSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6151DDBF2B14FDCF00ED4F7E /* UpdateCardViewControllerSnapshotTests.swift */; };
619E5B972BEA84630040647A /* VerticalSavedPaymentOptionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619E5B962BEA84630040647A /* VerticalSavedPaymentOptionsViewController.swift */; };
619E5B9A2BEA89D90040647A /* VerticalSavedPaymentOptionsViewControllerSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619E5B982BEA891E0040647A /* VerticalSavedPaymentOptionsViewControllerSnapshotTests.swift */; };
61C0D3B8C63EB4558AB74A7E /* StripePayments.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A1C7CFA5C9C1A8A73CFA1C0 /* StripePayments.framework */; };
623C2D9F87929D6DA9C09E23 /* STPCameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D39B31D0B890A4F8E4819B15 /* STPCameraView.swift */; };
630A3B22BC5C176928538511 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B7188D37BDE69B56D8223046 /* Main.storyboard */; };
Expand Down Expand Up @@ -429,6 +431,8 @@
6151DDBF2B14FDCF00ED4F7E /* UpdateCardViewControllerSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateCardViewControllerSnapshotTests.swift; sourceTree = "<group>"; };
617C44F9338DE2E93E318291 /* PayWithLinkWebController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayWithLinkWebController.swift; sourceTree = "<group>"; };
6193FC5E14E1EC459E31B5F4 /* SheetNavigationButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetNavigationButton.swift; sourceTree = "<group>"; };
619E5B962BEA84630040647A /* VerticalSavedPaymentOptionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalSavedPaymentOptionsViewController.swift; sourceTree = "<group>"; };
619E5B982BEA891E0040647A /* VerticalSavedPaymentOptionsViewControllerSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalSavedPaymentOptionsViewControllerSnapshotTests.swift; sourceTree = "<group>"; };
62CE362B80042827F47ABC3F /* AffirmCopyLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AffirmCopyLabel.swift; sourceTree = "<group>"; };
64C8F350CDB5A29F62E86592 /* FlowControllerStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowControllerStateTests.swift; sourceTree = "<group>"; };
64D658AC15478BF1E0A76B9D /* TestModeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestModeView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -934,6 +938,7 @@
children = (
5AA26FF00FD57F6AA1A7CB83 /* SavedPaymentMethodCollectionView.swift */,
2B3ECDF6CF9AABD573F86CA2 /* SavedPaymentOptionsViewController.swift */,
619E5B962BEA84630040647A /* VerticalSavedPaymentOptionsViewController.swift */,
);
path = "Saved Payment Method Screen";
sourceTree = "<group>";
Expand Down Expand Up @@ -1318,6 +1323,7 @@
C1AED4473AD4C07D461E9E48 /* SavedPaymentOptionsViewControllerSnapshotTests.swift */,
BA3902DA8D647E934686CB5C /* SepaMandateViewControllerSnapshotTest.swift */,
6151DDBF2B14FDCF00ED4F7E /* UpdateCardViewControllerSnapshotTests.swift */,
619E5B982BEA891E0040647A /* VerticalSavedPaymentOptionsViewControllerSnapshotTests.swift */,
B68CB9622B0D2169006ACDB1 /* STPAPIClient+PaymentSheetTest.swift */,
D16926577504D37992F8917E /* STPApplePayContext+PaymentSheetTest.swift */,
E09C073021CE89593466548C /* STPCardBrandChoiceTest.swift */,
Expand Down Expand Up @@ -1590,6 +1596,7 @@
EEC6283DB21D04AD5B77F9D2 /* STPApplePayContext+PaymentSheetTest.swift in Sources */,
714FBCA75296C291FDB3B345 /* STPCardBrandChoiceTest.swift in Sources */,
E0E47773D3C0B432E26AA457 /* STPElementsSessionTest.swift in Sources */,
619E5B9A2BEA89D90040647A /* VerticalSavedPaymentOptionsViewControllerSnapshotTests.swift in Sources */,
29C98FB712F3FB987CBE18B0 /* STPFixtures+PaymentSheet.swift in Sources */,
45D9849E9B36C56E15EAAE0A /* SavedPaymentOptionsViewControllerSnapshotTests.swift in Sources */,
9787A622B527C1AD96A73827 /* SepaMandateViewControllerSnapshotTest.swift in Sources */,
Expand Down Expand Up @@ -1627,6 +1634,7 @@
40806EF506CB719299FC90CC /* STPLocalizedString.swift in Sources */,
71132CE036C3EE0655ECD2DB /* STPStringUtils.swift in Sources */,
1AF3BBA86D643AAF26CD0E2B /* StripePaymentSheet+Exports.swift in Sources */,
619E5B972BEA84630040647A /* VerticalSavedPaymentOptionsViewController.swift in Sources */,
B6859A882BE54CD30018E06C /* PaymentSheetVerticalViewController.swift in Sources */,
73F3E8DCF2314972A162B2A3 /* StripePaymentSheetBundleLocator.swift in Sources */,
73EE441CF71707651109CE19 /* ConsumerSession+LookupResponse.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ e.g, 'Pay faster at Example, Inc. and thousands of businesses.' */
to be saved and used in future checkout sessions. */
"Save your info for secure 1-click checkout with Link" = "Save your info for secure 1-click checkout with Link";

/* Title shown above a view containing the customer's card payment methods */
"Select card" = "Select card";

/* Title shown above a view containing the customer's payment methods */
"Select payment method" = "Select payment method";

/* Title shown above a carousel containing the customer's payment methods */
"Select your payment method" = "Select your payment method";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,24 @@ extension String.Localized {
"Amazon Pay mandate text"
)
}

static var select_payment_method: String {
STPLocalizedString(
"Select payment method",
"Title shown above a view containing the customer's payment methods"
)
}

static var select_card: String {
STPLocalizedString(
"Select card",
"Title shown above a view containing the customer's card payment methods"
)
}

static var select_your_payment_method: String {
STPLocalizedString(
"Select your payment method",
"Title shown above a carousel containing the customer's payment methods")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//
// VerticalSavedPaymentOptionsViewController.swift
// StripePaymentSheet
//
// Created by Nick Porter on 5/7/24.
//

import Foundation
@_spi(STP) import StripeCore
@_spi(STP) import StripeUICore
import UIKit

/// A view controller that shows a list of saved payment methods in a vertical orientation
class VerticalSavedPaymentOptionsViewController: UIViewController {

private let configuration: PaymentSheet.Configuration

// MARK: - UI properties

lazy var navigationBar: SheetNavigationBar = {
let navBar = SheetNavigationBar(isTestMode: configuration.apiClient.isTestmode,
appearance: configuration.appearance)
navBar.setStyle(.back)
navBar.delegate = self
return navBar
}()

private lazy var headerLabel: UILabel = {
let label = PaymentSheetUI.makeHeaderLabel(appearance: configuration.appearance)
label.text = .Localized.select_payment_method
return label
}()

private lazy var stackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [headerLabel])
stackView.directionalLayoutMargins = PaymentSheetUI.defaultMargins
stackView.isLayoutMarginsRelativeArrangement = true
stackView.axis = .vertical
stackView.spacing = PaymentSheetUI.defaultPadding
return stackView
}()

init(configuration: PaymentSheet.Configuration) {
self.configuration = configuration
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = configuration.appearance.colors.background
configuration.style.configure(self)

view.addAndPinSubviewToSafeArea(stackView, insets: PaymentSheetUI.defaultSheetMargins)
}
}

// MARK: - BottomSheetContentViewController
extension VerticalSavedPaymentOptionsViewController: BottomSheetContentViewController {
var allowsDragToDismiss: Bool {
// TODO
return true
}

func didTapOrSwipeToDismiss() {
dismiss(animated: true)
}

var requiresFullScreen: Bool {
// TODO
return false
}

func didFinishAnimatingHeight() {
// no-op
}
}

// MARK: - SheetNavigationBarDelegate
extension VerticalSavedPaymentOptionsViewController: SheetNavigationBarDelegate {
func sheetNavigationBarDidClose(_ sheetNavigationBar: SheetNavigationBar) {
// no-op we are in 'back' style mode
}

func sheetNavigationBarDidBack(_ sheetNavigationBar: SheetNavigationBar) {
_ = bottomSheetController?.popContentViewController()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,7 @@ class PaymentSheetFlowControllerViewController: UIViewController, FlowController

switch mode {
case .selectingSaved:
headerLabel.text = STPLocalizedString(
"Select your payment method",
"Title shown above a carousel containing the customer's payment methods")
headerLabel.text = .Localized.select_your_payment_method
case .addingNew:
if addPaymentMethodViewController.paymentMethodTypes == [.stripe(.card)] {
headerLabel.text = STPLocalizedString("Add a card", "Title shown above a card entry form")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,22 @@ class PaymentSheetVerticalViewController: UIViewController, FlowControllerViewCo
view.backgroundColor = configuration.appearance.colors.background
configuration.style.configure(self)

let dummyView = UILabel()
dummyView.text = "Welcome to vertical mode"
let dummyButton = UIButton(type: .system)
dummyButton.setTitle("Welcome to vertical mode", for: .normal)
dummyButton.addTarget(self, action: #selector(presentManageScreen), for: .touchUpInside)

// One stack view contains all our subviews
let stackView = UIStackView(arrangedSubviews: [
dummyView,
dummyButton,
])
view.addAndPinSubview(stackView, insets: .init(top: 0, leading: 0, bottom: 0, trailing: PaymentSheetUI.defaultSheetMargins.bottom))
}

// TOOD(porter) Remove/rename
@objc func presentManageScreen() {
bottomSheetController?.pushContentViewController(VerticalSavedPaymentOptionsViewController(configuration: configuration))
// TODO(porter) Set delegate
}
}

// MARK: - BottomSheetContentViewController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,7 @@ class PaymentSheetViewController: UIViewController {
)
case .selectingSaved:
headerLabel.isHidden = shouldShowWalletHeader
headerLabel.text = STPLocalizedString(
"Select your payment method",
"Title shown above a carousel containing the customer's payment methods"
)
headerLabel.text = .Localized.select_your_payment_method
}

// Content
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ final class UpdateCardViewControllerSnapshotTests: STPSnapshotTestCase {
}
}

private extension UIView {
extension UIView {
/// Constrains the view to the given width and autosizes its height.
/// - Parameter width: Resizes the view to this width
/// - Parameter height: Resizes the view to this height
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// VerticalSavedPaymentOptionsViewControllerSnapshotTests.swift
// StripePaymentSheet
//
// Created by Nick Porter on 5/7/24.
//

import StripeCoreTestUtils
@_spi(STP) @testable import StripePaymentSheet
@testable import StripePaymentsTestUtils
import XCTest

final class VerticalSavedPaymentOptionsViewControllerSnapshotTests: STPSnapshotTestCase {

func test_VerticalSavedPaymentOptionsViewControllerSnapshotTestsDarkMode() {
_test_VerticalSavedPaymentOptionsViewControllerSnapshotTests(darkMode: true)
}

func test_VerticalSavedPaymentOptionsViewControllerSnapshotTestsLightMode() {
_test_VerticalSavedPaymentOptionsViewControllerSnapshotTests(darkMode: false)
}

func test_VerticalSavedPaymentOptionsViewControllerSnapshotTestsAppearance() {
_test_VerticalSavedPaymentOptionsViewControllerSnapshotTests(darkMode: false, appearance: ._testMSPaintTheme)
}

func _test_VerticalSavedPaymentOptionsViewControllerSnapshotTests(darkMode: Bool, appearance: PaymentSheet.Appearance = .default) {
var configuration = PaymentSheet.Configuration()
configuration.appearance = appearance
let sut = VerticalSavedPaymentOptionsViewController(configuration: configuration)
let testWindow = UIWindow(frame: CGRect(x: 0, y: 0, width: 428, height: 500))
testWindow.isHidden = false
if darkMode {
testWindow.overrideUserInterfaceStyle = .dark
}
testWindow.rootViewController = sut
sut.view.autosizeHeight(width: 375)
STPSnapshotVerifyView(sut.view)
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8d7dc51

Please sign in to comment.