Skip to content

Commit

Permalink
Merge pull request #299 from omise/fix/MIT-2552-SonarCloud-OmiseError-2
Browse files Browse the repository at this point in the history
Fix SonarCloud "Cognitive Complexity" warning in OmiseError's BadRequestReason (2)
  • Loading branch information
Andrei Solovev authored Jun 17, 2024
2 parents 7b2d39f + d34c238 commit 8369b21
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 65 deletions.
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)")
}
}
}

}

0 comments on commit 8369b21

Please sign in to comment.