Skip to content

Commit

Permalink
Added status code and content type values into NSError userInfo dicti…
Browse files Browse the repository at this point in the history
…onaries.
  • Loading branch information
0xced authored and cnoon committed Apr 10, 2016
1 parent 8d9f79a commit 2b91b8f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 46 deletions.
9 changes: 9 additions & 0 deletions Source/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public struct Error {
case PropertyListSerializationFailed = -6007
}

/// Custom keys contained within certain NSError `userInfo` dictionaries generated by Alamofire.
public struct UserInfoKeys {
/// The content type user info key for a `.ContentTypeValidationFailed` error stored as a `String` value.
public static let ContentType = "ContentType"

/// The status code user info key for a `.StatusCodeValidationFailed` error stored as an `Int` value.
public static let StatusCode = "StatusCode"
}

/**
Creates an `NSError` with the given error code and failure reason.

Expand Down
27 changes: 25 additions & 2 deletions Source/Validation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,17 @@ extension Request {
return .Success
} else {
let failureReason = "Response status code was unacceptable: \(response.statusCode)"
return .Failure(Error.error(code: .StatusCodeValidationFailed, failureReason: failureReason))

let error = NSError(
domain: Error.Domain,
code: Error.Code.StatusCodeValidationFailed.rawValue,
userInfo: [
NSLocalizedFailureReasonErrorKey: failureReason,
Error.UserInfoKeys.StatusCode: response.statusCode
]
)

return .Failure(error)
}
}
}
Expand Down Expand Up @@ -149,18 +159,31 @@ extension Request {
}
}

let contentType: String
let failureReason: String

if let responseContentType = response.MIMEType {
contentType = responseContentType

failureReason = (
"Response content type \"\(responseContentType)\" does not match any acceptable " +
"content types: \(acceptableContentTypes)"
)
} else {
contentType = ""
failureReason = "Response content type was missing and acceptable content type does not match \"*/*\""
}

return .Failure(Error.error(code: .ContentTypeValidationFailed, failureReason: failureReason))
let error = NSError(
domain: Error.Domain,
code: Error.Code.ContentTypeValidationFailed.rawValue,
userInfo: [
NSLocalizedFailureReasonErrorKey: failureReason,
Error.UserInfoKeys.ContentType: contentType
]
)

return .Failure(error)
}
}

Expand Down
96 changes: 52 additions & 44 deletions Tests/ValidationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class StatusCodeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithUnacceptableStatusCodeResponseFails() {
Expand All @@ -64,13 +64,14 @@ class StatusCodeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(error, "error should not be nil")
XCTAssertNotNil(error)

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue, "code should be status code validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.StatusCode] as? Int, 404)
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}

Expand All @@ -92,13 +93,14 @@ class StatusCodeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(error, "error should not be nil")
XCTAssertNotNil(error)

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue, "code should be status code validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.StatusCode] as? Int, 201)
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}
}
Expand Down Expand Up @@ -126,7 +128,7 @@ class ContentTypeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithAcceptableWildcardContentTypeResponseSucceeds() {
Expand All @@ -149,7 +151,7 @@ class ContentTypeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithUnacceptableContentTypeResponseFails() {
Expand All @@ -170,13 +172,14 @@ class ContentTypeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(error, "error should not be nil")
XCTAssertNotNil(error)

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue, "code should be content type validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.ContentType] as? String, "application/xml")
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}

Expand All @@ -201,10 +204,11 @@ class ContentTypeValidationTestCase: BaseTestCase {
XCTAssertNotNil(error, "error should not be nil")

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue, "code should be content type validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.ContentType] as? String, "application/xml")
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}

Expand All @@ -226,7 +230,7 @@ class ContentTypeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithAcceptableWildcardContentTypeResponseSucceedsWhenResponseIsNil() {
Expand Down Expand Up @@ -297,13 +301,13 @@ class ContentTypeValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(response, "response should not be nil")
XCTAssertNotNil(data, "data should not be nil")
XCTAssertNil(error, "error should be nil")
XCTAssertNotNil(response)
XCTAssertNotNil(data)
XCTAssertNil(error)

if let response = response {
XCTAssertEqual(response.statusCode, 204, "response status code should be 204")
XCTAssertNil(response.MIMEType, "response mime type should be nil")
XCTAssertEqual(response.statusCode, 204)
XCTAssertNil(response.MIMEType)
}
}
}
Expand All @@ -330,7 +334,7 @@ class MultipleValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithUnacceptableStatusCodeAndContentTypeResponseFailsWithStatusCodeError() {
Expand All @@ -352,13 +356,14 @@ class MultipleValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(error, "error should not be nil")
XCTAssertNotNil(error)

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue, "code should be status code validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.StatusCode] as? Int, 200)
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}

Expand All @@ -381,13 +386,14 @@ class MultipleValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(error, "error should not be nil")
XCTAssertNotNil(error)

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue, "code should be content type validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.ContentType] as? String, "application/xml")
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}
}
Expand Down Expand Up @@ -416,7 +422,7 @@ class AutomaticValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithUnacceptableStatusCodeResponseFails() {
Expand All @@ -437,13 +443,14 @@ class AutomaticValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(error, "error should not be nil")
XCTAssertNotNil(error)

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue, "code should be status code validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.StatusCodeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.StatusCode] as? Int, 404)
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}

Expand All @@ -468,7 +475,7 @@ class AutomaticValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithAcceptableComplexContentTypeResponseSucceeds() {
Expand All @@ -494,7 +501,7 @@ class AutomaticValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNil(error, "error should be nil")
XCTAssertNil(error)
}

func testThatValidationForRequestWithUnacceptableContentTypeResponseFails() {
Expand All @@ -518,13 +525,14 @@ class AutomaticValidationTestCase: BaseTestCase {
waitForExpectationsWithTimeout(timeout, handler: nil)

// Then
XCTAssertNotNil(error, "error should not be nil")
XCTAssertNotNil(error)

if let error = error {
XCTAssertEqual(error.domain, Error.Domain, "domain should be Alamofire error domain")
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue, "code should be content type validation failure")
XCTAssertEqual(error.domain, Error.Domain)
XCTAssertEqual(error.code, Error.Code.ContentTypeValidationFailed.rawValue)
XCTAssertEqual(error.userInfo[Error.UserInfoKeys.ContentType] as? String, "application/xml")
} else {
XCTFail("error should be an NSError")
XCTFail("error should not be nil")
}
}
}

0 comments on commit 2b91b8f

Please sign in to comment.