-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Connect] Fix API inconsistent naming + Add Dashboard-only support fo…
…r Account Management component (#4036) ## Summary - **Adds the account management component with DashboardOnly access** - **Fixes inconsistent delegate naming in PayoutsViewController** The account onboarding component had a delegate signature of: ``` accountOnboarding(_ accountOnboarding: AccountOnboardingViewController, didFailLoadWithError error: Error) ``` However, the payouts component was using: ``` payoutsLoadDidFail(_ payouts: PayoutsViewController, withError error: Error) ``` During API review, we had intended to use the account onboarding style signature (see [papertrail](https://docs.google.com/document/d/195BaU6k2J-2CAs9anNE6e4OlZO34N-e2HTYc6pacpTw/edit?pli=1#bookmark=id.dk457iw2wtca)) ## Motivation https://jira.corp.stripe.com/browse/MXMOBILE-2503 ## Testing Unit tests --------- Co-authored-by: Chris Mays <[email protected]>
- Loading branch information
1 parent
14daabf
commit 9e06a39
Showing
9 changed files
with
185 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
StripeConnect/StripeConnect/Source/Components/AccountManagementViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// | ||
// AccountManagementViewController.swift | ||
// StripeConnect | ||
// | ||
// Created by Mel Ludowise on 9/21/24. | ||
// | ||
|
||
import UIKit | ||
|
||
/** | ||
Show details of a given payment and allow users to manage disputes and perform refunds. | ||
*/ | ||
@_spi(DashboardOnly) | ||
@available(iOS 15, *) | ||
public class AccountManagementViewController: UIViewController { | ||
|
||
struct Props: Encodable { | ||
let collectionOptions: AccountCollectionOptions | ||
|
||
enum CodingKeys: String, CodingKey { | ||
case collectionOptions = "setCollectionOptions" | ||
} | ||
} | ||
|
||
let webView: ConnectComponentWebView | ||
|
||
public weak var delegate: AccountManagementViewControllerDelegate? | ||
|
||
init(componentManager: EmbeddedComponentManager, | ||
collectionOptions: AccountCollectionOptions) { | ||
webView = ConnectComponentWebView( | ||
componentManager: componentManager, | ||
componentType: .accountManagement | ||
) { | ||
Props(collectionOptions: collectionOptions) | ||
} | ||
super.init(nibName: nil, bundle: nil) | ||
|
||
webView.addMessageHandler(OnLoadErrorMessageHandler { [weak self] value in | ||
guard let self else { return } | ||
self.delegate?.accountManagement(self, didFailLoadWithError: value.error.connectEmbedError) | ||
}) | ||
|
||
// TODO(MXMOBILE-2796): Send collection options to web view | ||
|
||
webView.presentPopup = { [weak self] vc in | ||
self?.present(vc, animated: true) | ||
} | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
public override func loadView() { | ||
view = webView | ||
} | ||
} | ||
|
||
@_spi(DashboardOnly) | ||
@available(iOS 15, *) | ||
public protocol AccountManagementViewControllerDelegate: AnyObject { | ||
/** | ||
Triggered when an error occurs loading the account management component | ||
- Parameters: | ||
- accountManagement: The account management component that errored when loading | ||
- error: The error that occurred when loading the component | ||
*/ | ||
func accountManagement(_ accountManagement: AccountManagementViewController, | ||
didFailLoadWithError error: Error) | ||
} | ||
|
||
@available(iOS 15, *) | ||
public extension AccountManagementViewControllerDelegate { | ||
// Default implementation to make optional | ||
func accountManagement(_ accountManagement: AccountManagementViewController, | ||
didFailLoadWithError error: Error) { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
StripeConnect/StripeConnectTests/Components/AccountManagementViewControllerTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// | ||
// AccountManagementViewControllerTests.swift | ||
// StripeConnectTests | ||
// | ||
// Created by Mel Ludowise on 9/25/24. | ||
// | ||
|
||
import SafariServices | ||
@_spi(PrivateBetaConnect) @_spi(DashboardOnly) @testable import StripeConnect | ||
@_spi(STP) import StripeCore | ||
import WebKit | ||
import XCTest | ||
|
||
class AccountManagementViewControllerTests: XCTestCase { | ||
let componentManager = EmbeddedComponentManager(fetchClientSecret: { | ||
return nil | ||
}) | ||
|
||
override func setUp() { | ||
super.setUp() | ||
STPAPIClient.shared.publishableKey = "pk_test" | ||
componentManager.shouldLoadContent = false | ||
} | ||
|
||
@MainActor | ||
func testDelegate() async throws { | ||
let vc = componentManager.createAccountManagementViewController() | ||
|
||
let expectationDidFail = XCTestExpectation(description: "didFail called") | ||
let delegate = AccountManagementViewControllerDelegatePassThrough { onboardingVC, error in | ||
XCTAssertEqual(vc, onboardingVC) | ||
XCTAssertEqual((error as? EmbeddedComponentError)?.type, .rateLimitError) | ||
XCTAssertEqual((error as? EmbeddedComponentError)?.description, "Error message") | ||
expectationDidFail.fulfill() | ||
} | ||
|
||
vc.delegate = delegate | ||
try await vc.webView.evaluateOnLoadError(type: "rate_limit_error", message: "Error message") | ||
await fulfillment(of: [expectationDidFail], timeout: TestHelpers.defaultTimeout) | ||
} | ||
|
||
@MainActor | ||
func testFetchInitComponentProps() async throws { | ||
let vc = componentManager.createAccountManagementViewController( | ||
collectionOptions: { | ||
var collectionOptions = AccountCollectionOptions() | ||
collectionOptions.fields = .eventuallyDue | ||
collectionOptions.futureRequirements = .include | ||
return collectionOptions | ||
}() | ||
) | ||
|
||
try await vc.webView.evaluateMessageWithReply(name: "fetchInitComponentProps", | ||
json: "{}", | ||
expectedResponse: """ | ||
{"setCollectionOptions":{"fields":"eventually_due","futureRequirements":"include"}} | ||
""") | ||
} | ||
|
||
} | ||
|
||
private class AccountManagementViewControllerDelegatePassThrough: AccountManagementViewControllerDelegate { | ||
|
||
var didFailLoad: ((_ accountManagement: AccountManagementViewController, _ error: Error) -> Void)? | ||
|
||
init(didFailLoad: ((AccountManagementViewController, Error) -> Void)? = nil) { | ||
self.didFailLoad = didFailLoad | ||
} | ||
|
||
func accountManagement(_ accountManagement: AccountManagementViewController, | ||
didFailLoadWithError error: Error) | ||
{ | ||
didFailLoad?(accountManagement, error) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters