Skip to content

Commit

Permalink
Remove Authorization argument in ConfigurationLoader.getConfig me…
Browse files Browse the repository at this point in the history
…thod (#1361)

* Remove unneeded authorization param on ConfigurationLoader.get() method; use authorization on associated BTHTTP instead

Co-authored-by: Jax DesMarais-Leder <[email protected]>
  • Loading branch information
scannillo and jaxdesmarais authored Jul 16, 2024
1 parent 006ec11 commit aa394b1
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 26 deletions.
4 changes: 2 additions & 2 deletions Sources/BraintreeCore/BTAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ import Foundation
/// cached on subsequent calls for better performance.
@_documentation(visibility: private)
public func fetchOrReturnRemoteConfiguration(_ completion: @escaping (BTConfiguration?, Error?) -> Void) {
configurationLoader.getConfig(authorization) { [weak self] configuration, error in
configurationLoader.getConfig { [weak self] configuration, error in
guard let self else {
completion(nil, BTAPIClientError.deallocated)
return
Expand All @@ -117,7 +117,7 @@ import Foundation
}

func fetchConfiguration() async throws -> BTConfiguration {
try await configurationLoader.getConfig(authorization)
try await configurationLoader.getConfig()
}

/// Fetches a customer's vaulted payment method nonces.
Expand Down
11 changes: 5 additions & 6 deletions Sources/BraintreeCore/ConfigurationLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@ class ConfigurationLoader {
/// 3. If fetching the configuration fails, it returns an error.
///
/// - Parameters:
/// - authorization: An `ClientAuthorization` object required to access the configuration.
/// - completion: A completion handler that is called with the fetched or cached `BTConfiguration` object or an `Error`.
///
/// - Completion:
/// - `BTConfiguration?`: The configuration object if it is successfully fetched or retrieved from the cache.
/// - `Error?`: An error object if fetching the configuration fails or if the instance is deallocated.
@_documentation(visibility: private)
func getConfig(_ authorization: ClientAuthorization, completion: @escaping (BTConfiguration?, Error?) -> Void) {
if let cachedConfig = try? configurationCache.getFromCache(authorization: authorization.bearer) {
func getConfig(completion: @escaping (BTConfiguration?, Error?) -> Void) {
if let cachedConfig = try? configurationCache.getFromCache(authorization: http.authorization.bearer) {
completion(cachedConfig, nil)
return
}
Expand All @@ -56,17 +55,17 @@ class ConfigurationLoader {
} else {
let configuration = BTConfiguration(json: body)

try? configurationCache.putInCache(authorization: authorization.bearer, configuration: configuration)
try? configurationCache.putInCache(authorization: http.authorization.bearer, configuration: configuration)

completion(configuration, nil)
return
}
}
}

func getConfig(_ authorization: ClientAuthorization) async throws -> BTConfiguration {
func getConfig() async throws -> BTConfiguration {
try await withCheckedThrowingContinuation { continuation in
getConfig(authorization) { configuration, error in
getConfig { configuration, error in
if let error {
continuation.resume(throwing: error)
} else if let configuration {
Expand Down
25 changes: 9 additions & 16 deletions UnitTests/BraintreeCoreTests/ConfigurationLoader_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ class ConfigurationLoader_Tests: XCTestCase {
func testGetConfig_whenCached_returnsConfigFromCache() {
let sampleJSON = ["test": "value", "environment": "fake-env1"]
try? ConfigurationCache.shared.putInCache(authorization: "development_tokenization_key", configuration: BTConfiguration(json: BTJSON(value: sampleJSON)))
let mockClientAuthorization = MockClientAuthorization(bearer: "development_tokenization_key")

let expectation = expectation(description: "Callback invoked")
sut.getConfig(mockClientAuthorization) { configuration, error in
sut.getConfig { configuration, error in
XCTAssertEqual(configuration?.environment, "fake-env1")
XCTAssertEqual(configuration?.json?["test"].asString(), "value")
XCTAssertNil(self.mockHTTP.lastRequestEndpoint)
Expand All @@ -37,10 +36,9 @@ class ConfigurationLoader_Tests: XCTestCase {

func testGetConfig_performsGETWithCorrectPayload() {
mockHTTP.stubRequest(withMethod: "GET", toEndpoint: "/v1/configuration", respondWith: [] as [Any?], statusCode: 200)
let mockClientAuthorization = MockClientAuthorization()


let expectation = expectation(description: "Callback invoked")
sut.getConfig(mockClientAuthorization) { _,_ in
sut.getConfig { _, _ in
XCTAssertEqual(self.mockHTTP.lastRequestEndpoint, "v1/configuration")
XCTAssertEqual(self.mockHTTP.lastRequestParameters?["configVersion"] as? String, "3")
expectation.fulfill()
Expand All @@ -52,10 +50,9 @@ class ConfigurationLoader_Tests: XCTestCase {
func testGetConfig_canGetRemoteConfiguration() {
mockHTTP.cannedConfiguration = BTJSON(value: ["test": true])
mockHTTP.cannedStatusCode = 200
let mockClientAuthorization = MockClientAuthorization()

let expectation = expectation(description: "Fetch configuration")
sut.getConfig(mockClientAuthorization) { configuration, error in
sut.getConfig { configuration, error in
XCTAssertNotNil(configuration)
XCTAssertNil(error)
XCTAssertGreaterThanOrEqual(self.mockHTTP.GETRequestCount, 1)
Expand All @@ -75,10 +72,9 @@ class ConfigurationLoader_Tests: XCTestCase {
respondWith: ["error_message": "Something bad happened"],
statusCode: 503
)
let mockClientAuthorization = MockClientAuthorization()


let expectation = expectation(description: "Callback invoked")
sut.getConfig(mockClientAuthorization) { configuration, error in
sut.getConfig { configuration, error in
guard let error = error as NSError? else { return }
XCTAssertNil(configuration)
XCTAssertEqual(error.domain, BTAPIClientError.errorDomain)
Expand All @@ -93,11 +89,10 @@ class ConfigurationLoader_Tests: XCTestCase {
func testGetConfig_whenNetworkHasError_returnsNetworkErrorInCallback() {
ConfigurationCache.shared.cacheInstance.removeAllObjects()
let mockError: NSError = NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotConnectToHost)
let mockClientAuthorization = MockClientAuthorization()
mockHTTP.stubRequest(withMethod: "GET", toEndpoint: "/client_api/v1/configuration", respondWithError: mockError)

let expectation = expectation(description: "Fetch configuration")
sut.getConfig(mockClientAuthorization) { configuration, error in
sut.getConfig { configuration, error in
// BTAPIClient fetches the config when initialized so there can potentially be 2 requests here
XCTAssertLessThanOrEqual(self.mockHTTP.GETRequestCount, 2)
XCTAssertNil(configuration)
Expand All @@ -111,10 +106,9 @@ class ConfigurationLoader_Tests: XCTestCase {
func testGetConfig_returnsConfiguration() async throws {
mockHTTP.cannedConfiguration = BTJSON(value: ["test": true])
mockHTTP.cannedStatusCode = 200
let mockClientAuthorization = MockClientAuthorization()

let asyncTask = Task {
return try await sut.getConfig(mockClientAuthorization)
return try await sut.getConfig()
}

let returnedConfig = try await asyncTask.value
Expand All @@ -124,11 +118,10 @@ class ConfigurationLoader_Tests: XCTestCase {

func testGetConfig_returnsNetworkErrorInCallback() async throws {
let mockError: NSError = NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotConnectToHost)
let mockClientAuthorization = MockClientAuthorization()
mockHTTP.stubRequest(withMethod: "GET", toEndpoint: "/client_api/v1/configuration", respondWithError: mockError)

let asyncTask = Task {
return try await sut.getConfig(mockClientAuthorization)
return try await sut.getConfig()
}

do {
Expand Down
4 changes: 2 additions & 2 deletions UnitTests/BraintreeCoreTests/MockConfigurationLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ class MockConfigurationLoader: ConfigurationLoader {
super.init(http: http)
}

override func getConfig(_ authorization: ClientAuthorization, completion: @escaping (BTConfiguration?, Error?) -> Void) {
override func getConfig(completion: @escaping (BTConfiguration?, Error?) -> Void) {
if let error = mockError {
completion(nil, error)
} else {
completion(mockConfig, nil)
}
}

override func getConfig(_ authorization: ClientAuthorization) async throws -> BTConfiguration {
override func getConfig() async throws -> BTConfiguration {
if let error = mockError {
throw error
} else if let config = mockConfig {
Expand Down

0 comments on commit aa394b1

Please sign in to comment.