diff --git a/Data/AuthenticationClient/Sources/AuthenticationData.swift b/Data/AuthenticationClient/Sources/AuthenticationData.swift index 1831f79c..a7cda366 100644 --- a/Data/AuthenticationClient/Sources/AuthenticationData.swift +++ b/Data/AuthenticationClient/Sources/AuthenticationData.swift @@ -22,36 +22,26 @@ enum AuthenticationStateError: Error { /// /// The abstraction is mainly for testing purposes. The API has been designed to be in conjunction /// with the `AppAuth's OIDAuthState` class. -class AuthenticationData: NSObject, Codable { +protocol AuthenticationData: Codable { /// Invokes subscribers when the state changes. Usually happens during refreshing tokens. - var stateChangedPublisher: AnyPublisher { fatalError() } + var stateChangedPublisher: AnyPublisher { get } - var isAuthorized: Bool { - fatalError() - } + var isAuthorized: Bool { get } /// Returns fresh access token to be used for API requests. /// /// - throws: `AuthenticationStateError.failedToRefreshTokens` if the /// refresh operation fails for any reason. - func getFreshTokens() async throws -> String { - fatalError() - } - - override init() { } - - required init(from decoder: any Decoder) throws { - fatalError() - } + func getFreshTokens() async throws -> String } -class AppAuthAuthenticationData: AuthenticationData { +final class AppAuthAuthenticationData: NSObject, AuthenticationData { private enum CodingKeys: String, CodingKey { case state } private let stateChangedSubject: PassthroughSubject = .init() - override var stateChangedPublisher: AnyPublisher { + var stateChangedPublisher: AnyPublisher { stateChangedSubject.eraseToAnyPublisher() } @@ -61,7 +51,7 @@ class AppAuthAuthenticationData: AuthenticationData { } } - override var isAuthorized: Bool { + var isAuthorized: Bool { state.isAuthorized } @@ -88,13 +78,13 @@ class AppAuthAuthenticationData: AuthenticationData { state.stateChangeDelegate = self } - override func encode(to encoder: any Encoder) throws { + func encode(to encoder: any Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: CodingKeys.self) let data = try NSKeyedArchiver.archivedData(withRootObject: state, requiringSecureCoding: true) try container.encode(data, forKey: .state) } - override func getFreshTokens() async throws -> String { + func getFreshTokens() async throws -> String { return try await withCheckedThrowingContinuation { continuation in state.performAction { accessToken, clientID, error in guard error == nil else { diff --git a/Data/AuthenticationClient/Tests/AuthenticationClientTests.swift b/Data/AuthenticationClient/Tests/AuthenticationClientTests.swift index 1385a3bc..43c3b19c 100644 --- a/Data/AuthenticationClient/Tests/AuthenticationClientTests.swift +++ b/Data/AuthenticationClient/Tests/AuthenticationClientTests.swift @@ -40,7 +40,7 @@ final class AuthenticationClientTests: XCTestCase { func testLoginSuccessful() async throws { sut.set(appConfiguration: configuration) - persistance.currentState = AuthenticationData() + persistance.currentState = AutehenticationDataMock() let state = AutehenticationDataMock() state.accessToken = "abcd" @@ -142,7 +142,7 @@ private final class OAuthCallerMock: OAuthCaller { } } -private final class AutehenticationDataMock: AuthenticationData { +private final class AutehenticationDataMock: Equatable, AuthenticationData { var accessToken: String? { didSet { guard oldValue != nil else { return } @@ -150,25 +150,27 @@ private final class AutehenticationDataMock: AuthenticationData { } } - override var stateChangedPublisher: AnyPublisher { + var stateChangedPublisher: AnyPublisher { subject.eraseToAnyPublisher() } let subject = PassthroughSubject() - override init() { - super.init() - } + init() { } required init(from decoder: any Decoder) throws { fatalError() } - override var isAuthorized: Bool { + func encode(to encoder: any Encoder) throws { + fatalError() + } + + var isAuthorized: Bool { accessToken != nil } - override func getFreshTokens() async throws -> String { + func getFreshTokens() async throws -> String { guard let token = accessToken else { throw AuthenticationStateError.failedToRefreshTokens(nil) }