Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SonarCloud "Cognitive Complexity" warning in OmiseError's BadRequestReason (2) #299

Merged
merged 2 commits into from
Jun 17, 2024
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
167 changes: 102 additions & 65 deletions OmiseSDK/Sources/Models/OmiseError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,6 @@ extension OmiseError.APIErrorCode.BadRequestReason: Decodable {
return preferredRecoverySuggestionMessage.isEmpty ? nil : preferredRecoverySuggestionMessage
}

// swiftlint:disable:next function_body_length
static func parseBadRequestReasonsFromMessage(_ message: String, currency: Currency?) throws -> [OmiseError.APIErrorCode.BadRequestReason] {
let reasonMessages = message.components(separatedBy: ", and ")
.flatMap { $0.components(separatedBy: ", ") }
Expand All @@ -840,86 +839,124 @@ extension OmiseError.APIErrorCode.BadRequestReason: Decodable {
try OmiseError.APIErrorCode.BadRequestReason(message: $0, currency: currency)
})

// swiftlint:disable:next closure_body_length
return parsedReasons.sorted {
switch $0 {
case .amountIsLessThanValidAmount:
return true
case .other:
return false

case .amountIsGreaterThanValidAmount:
switch $1 {
case .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName, .nameIsTooLong, .invalidName,
.invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .other:
return false
}
return Self.sortByAmountIsGreaterThanValidAmount(reason: $1)
case .invalidCurrency:
switch $1 {
case .invalidCurrency, .emptyName, .nameIsTooLong, .invalidName, .invalidEmail,
.invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .other:
return false
}
return Self.sortByInvalidCurrency(reason: $1)
case .emptyName:
switch $1 {
case .emptyName, .nameIsTooLong, .invalidName, .invalidEmail, .invalidPhoneNumber,
.typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .other:
return false
}
return Self.sortByEmptyName(reason: $1)
case .nameIsTooLong:
switch $1 {
case .nameIsTooLong, .invalidName, .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName, .other:
return false
}
return Self.sortByNameIsTooLong(reason: $1)
case .invalidName:
switch $1 {
case .invalidName, .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName, .nameIsTooLong, .other:
return false
}
return Self.sortByInvalidName(reason: $1)
case .invalidEmail:
switch $1 {
case .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount,
.invalidCurrency, .emptyName, .nameIsTooLong, .invalidName, .other:
return false
}
return Self.sortByInvalidEmail(reason: $1)
case .invalidPhoneNumber:
switch $1 {
case .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency,
.emptyName, .nameIsTooLong, .invalidEmail, .invalidName, .other:
return false
}
return Self.sortByInvalidPhoneNumber(reason: $1)
case .typeNotSupported:
switch $1 {
case .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency,
.emptyName, .nameIsTooLong, .invalidEmail, .invalidName, .invalidPhoneNumber, .other:
return false
}
return Self.sortByTypeNotSupported(reason: $1)
case .currencyNotSupported:
switch $1 {
case .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName,
.nameIsTooLong, .invalidName, .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .other:
return false
}
return Self.sortByCurrencyNotSupported(reason: $1)
}
}
}
// swiftlint:enable line_length
}

extension OmiseError.APIErrorCode.BadRequestReason {
static func sortByAmountIsGreaterThanValidAmount(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName, .nameIsTooLong, .invalidName,
.invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .other:
return false
}
}

static func sortByInvalidCurrency(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .invalidCurrency, .emptyName, .nameIsTooLong, .invalidName, .invalidEmail,
.invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .other:
return false
}

}
static func sortByEmptyName(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .emptyName, .nameIsTooLong, .invalidName, .invalidEmail, .invalidPhoneNumber,
.typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .other:
return false
}

}

static func sortByNameIsTooLong(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .nameIsTooLong, .invalidName, .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName, .other:
return false
}
}

static func sortByInvalidName(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .invalidName, .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName, .nameIsTooLong, .other:
return false
}
}

static func sortByInvalidEmail(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount,
.invalidCurrency, .emptyName, .nameIsTooLong, .invalidName, .other:
return false
}
}

static func sortByInvalidPhoneNumber(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .invalidPhoneNumber, .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency,
.emptyName, .nameIsTooLong, .invalidEmail, .invalidName, .other:
return false
}
}

static func sortByTypeNotSupported(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .typeNotSupported, .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency,
.emptyName, .nameIsTooLong, .invalidEmail, .invalidName, .invalidPhoneNumber, .other:
return false
}
}

static func sortByCurrencyNotSupported(reason: OmiseError.APIErrorCode.BadRequestReason) -> Bool {
switch reason {
case .currencyNotSupported:
return true
case .amountIsLessThanValidAmount, .amountIsGreaterThanValidAmount, .invalidCurrency, .emptyName,
.nameIsTooLong, .invalidName, .invalidEmail, .invalidPhoneNumber, .typeNotSupported, .other:
return false
}
}
}

// swiftlint:enable line_length
50 changes: 50 additions & 0 deletions OmiseSDKTests/OmiseErrorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,54 @@ class OmiseErrorTests: XCTestCase {
}
}
}

typealias BadRequestReason = OmiseError.APIErrorCode.BadRequestReason
func testParseBadRequestReasonsFromMessage() {
// Array of tuples for test cases
let currency: Currency = .thb
let testCases: [(message: String, expected: Set<BadRequestReason>)] = [
(
"amount must be at least 100 THB",
[.amountIsLessThanValidAmount(validAmount: 100, currency: currency)]
),
(
"amount must be less than 5000 USD",
[.amountIsGreaterThanValidAmount(validAmount: 5000, currency: currency)]
),
(
"currency must be.., empty name",
[.invalidCurrency, .nameIsTooLong(maximum: nil)]
),
(
"other currency error, empty name",
[.currencyNotSupported, .nameIsTooLong(maximum: nil)]
),
(
"name is too long (maximum is 25 characters), invalid email",
[.nameIsTooLong(maximum: 25), .invalidEmail]
),
(
"invalid phone number",
[.invalidPhoneNumber]
),
(
"type not supported, currency not supported",
[.typeNotSupported, .currencyNotSupported]
),
(
"unknown issue",
[.other("unknown issue")]
)
]

for (message, expected) in testCases {
do {
let results = try BadRequestReason.parseBadRequestReasonsFromMessage(message, currency: currency)
XCTAssertEqual(Set(results), expected, "Failed to parse or incorrect order for message: \(message)")
} catch {
XCTFail("Unexpected error for message: \(message): \(error)")
}
}
}

}
Loading