Browse Source

Added status code and content type values into NSError userInfo dictionaries.

Cédric Luthi 9 years ago
parent
commit
2b91b8fc05
3 changed files with 86 additions and 46 deletions
  1. 9 0
      Source/Error.swift
  2. 25 2
      Source/Validation.swift
  3. 52 44
      Tests/ValidationTests.swift

+ 9 - 0
Source/Error.swift

@@ -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.
 

+ 25 - 2
Source/Validation.swift

@@ -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)
             }
         }
     }
@@ -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)
         }
     }
 

+ 52 - 44
Tests/ValidationTests.swift

@@ -43,7 +43,7 @@ class StatusCodeValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithUnacceptableStatusCodeResponseFails() {
@@ -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")
         }
     }
 
@@ -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")
         }
     }
 }
@@ -126,7 +128,7 @@ class ContentTypeValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithAcceptableWildcardContentTypeResponseSucceeds() {
@@ -149,7 +151,7 @@ class ContentTypeValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithUnacceptableContentTypeResponseFails() {
@@ -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")
         }
     }
 
@@ -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")
         }
     }
 
@@ -226,7 +230,7 @@ class ContentTypeValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithAcceptableWildcardContentTypeResponseSucceedsWhenResponseIsNil() {
@@ -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)
         }
     }
 }
@@ -330,7 +334,7 @@ class MultipleValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithUnacceptableStatusCodeAndContentTypeResponseFailsWithStatusCodeError() {
@@ -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")
         }
     }
 
@@ -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")
         }
     }
 }
@@ -416,7 +422,7 @@ class AutomaticValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithUnacceptableStatusCodeResponseFails() {
@@ -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")
         }
     }
 
@@ -468,7 +475,7 @@ class AutomaticValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithAcceptableComplexContentTypeResponseSucceeds() {
@@ -494,7 +501,7 @@ class AutomaticValidationTestCase: BaseTestCase {
         waitForExpectationsWithTimeout(timeout, handler: nil)
 
         // Then
-        XCTAssertNil(error, "error should be nil")
+        XCTAssertNil(error)
     }
 
     func testThatValidationForRequestWithUnacceptableContentTypeResponseFails() {
@@ -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")
         }
     }
 }