Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions swift-sdk/Core/Utilities/AuthFailureReason.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,32 @@ import Foundation
case authTokenGenerationError
case authTokenMissing
}

extension AuthFailureReason: CustomDebugStringConvertible {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already solve this exact problem for IterableInAppContentType and IterableInAppTriggerType in InAppPersistence.swift using CustomStringConvertible and description, with a comment explaining why it's needed for @objc enums.

Should we stay consistent and use CustomStringConvertible + description here too?

Both protocols technically work for String(describing:) thanks to the fallback chain, but description is the right semantic for output customers will see in their AuthDelegate logs, and it matches the existing convention in this SDK.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, and the InAppPersistence precedent is useful context. Keeping CustomDebugStringConvertible here since SDK-470 asks for it specifically. It still covers the customer path: print(reason) and "\(reason)" go through String(describing:), which falls back to debugDescription, so AuthDelegate logs show the case name. Updated the test (your other comment) to assert String(describing: reason) so it guards that path.

public var debugDescription: String {
switch self {
case .authTokenExpired:
return "authTokenExpired"
case .authTokenGenericError:
return "authTokenGenericError"
case .authTokenExpirationInvalid:
return "authTokenExpirationInvalid"
case .authTokenSignatureInvalid:
return "authTokenSignatureInvalid"
case .authTokenFormatInvalid:
return "authTokenFormatInvalid"
case .authTokenInvalidated:
return "authTokenInvalidated"
case .authTokenPayloadInvalid:
return "authTokenPayloadInvalid"
case .authTokenUserKeyInvalid:
return "authTokenUserKeyInvalid"
case .authTokenNull:
return "authTokenNull"
case .authTokenGenerationError:
return "authTokenGenerationError"
case .authTokenMissing:
return "authTokenMissing"
}
}
}
20 changes: 20 additions & 0 deletions tests/unit-tests/AuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ class AuthTests: XCTestCase {
override func setUp() {
super.setUp()
}

func testAuthFailureReasonDebugDescriptions() {
let expectedDescriptions: [(AuthFailureReason, String)] = [
(.authTokenExpired, "authTokenExpired"),
(.authTokenGenericError, "authTokenGenericError"),
(.authTokenExpirationInvalid, "authTokenExpirationInvalid"),
(.authTokenSignatureInvalid, "authTokenSignatureInvalid"),
(.authTokenFormatInvalid, "authTokenFormatInvalid"),
(.authTokenInvalidated, "authTokenInvalidated"),
(.authTokenPayloadInvalid, "authTokenPayloadInvalid"),
(.authTokenUserKeyInvalid, "authTokenUserKeyInvalid"),
(.authTokenNull, "authTokenNull"),
(.authTokenGenerationError, "authTokenGenerationError"),
(.authTokenMissing, "authTokenMissing")
]

expectedDescriptions.forEach { reason, description in
XCTAssertEqual(String(describing: reason), description)
}
}

func testEmailPersistence() {
let internalAPI = InternalIterableAPI.initializeForTesting()
Expand Down
Loading