-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #70 from devlucky/feature/JSONAPIErrors
Feature/jsonapi errors
- Loading branch information
Showing
3 changed files
with
184 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// | ||
// JSONAPIError.swift | ||
// Kakapo | ||
// | ||
// Created by Alex Manzella on 26/06/16. | ||
// Copyright © 2016 devlucky. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
// A convenince error object that conform to JSON API | ||
public struct JSONAPIError: ResponseFieldsProvider { | ||
|
||
/// An object containing references to the source of the error, optionally including any of the following members | ||
public struct Source: Serializable { | ||
/// A JSON `Pointer` ([RFC6901](https://tools.ietf.org/html/rfc6901)) to the associated entity in the request document [e.g. `/data` for a primary data object, or `/data/attributes/title` for a specific attribute]. | ||
public let pointer: String? | ||
|
||
/// A string indicating which URI query parameter caused the error. | ||
public let parameter: String? | ||
} | ||
|
||
/// A builder for JSONAPIError | ||
public struct Builder: Serializable { | ||
|
||
/// A unique identifier for this particular occurrence of the problem. | ||
public var id: String? | ||
|
||
/// A link object that leads to further details about this particular occurrence of the problem. | ||
public var about: JSONAPILink? | ||
|
||
/// The HTTP status code applicable to this problem, expressed as a string value. | ||
public var status: Int | ||
|
||
/// An application-specific error code, expressed as a string value | ||
public var code: String? | ||
|
||
/// A short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization | ||
public var title: String? | ||
|
||
/// A human-readable explanation specific to this occurrence of the problem. Like title, this field’s value can be localized. | ||
public var detail: String? | ||
|
||
/** | ||
An object containing references to the source of the error, optionally including any of the following members: | ||
|
||
- pointer: a JSON `Pointer` ([RFC6901](https://tools.ietf.org/html/rfc6901)) to the associated entity in the request document [e.g. `/data` for a primary data object, or `/data/attributes/title` for a specific attribute]. | ||
- parameter: a string indicating which URI query parameter caused the error. | ||
*/ | ||
public var source: Source? | ||
|
||
/// A meta object containing non-standard meta-information about the error. | ||
public var meta: Serializable? | ||
|
||
private init(statusCode: Int) { | ||
status = statusCode | ||
} | ||
} | ||
|
||
private let builder: Builder | ||
|
||
// MARK: ResponseFieldsProvider | ||
|
||
public var statusCode: Int { | ||
return builder.status | ||
} | ||
|
||
public var body: Serializable { | ||
return builder | ||
} | ||
|
||
public var headerFields: [String : String]? { | ||
return nil | ||
} | ||
|
||
/** | ||
Initialize a `JSONAPIError` and build it with `JSONAPIError.Builder` | ||
|
||
- parameter statusCode: The status code of the response, will be used also to provide a statusCode for your request | ||
- parameter errorBuilder: A builder that can be used to fill the error objects, it contains all you need to provide an error object confiorming to JSON API (**see `JSONAPIError.Builder`**) | ||
|
||
- returns: An error that conforms to JSON API specifications and it's ready to be serialized | ||
*/ | ||
public init(statusCode: Int, errorBuilder: (error: inout Builder) -> ()) { | ||
var builder = Builder(statusCode: statusCode) | ||
errorBuilder(error: &builder) | ||
self.builder = builder | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// | ||
// JSONAPIErrorTests.swift | ||
// Kakapo | ||
// | ||
// Created by Alex Manzella on 26/06/16. | ||
// Copyright © 2016 devlucky. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
import Quick | ||
import Nimble | ||
import SwiftyJSON | ||
@testable import Kakapo | ||
|
||
class JSONAPIErrorsSpec: QuickSpec { | ||
|
||
private struct ErrorDescription: Serializable { | ||
let description: String | ||
} | ||
|
||
override func spec() { | ||
|
||
func json(object: Serializable) -> JSON { | ||
return JSON(object.serialize()!) | ||
} | ||
|
||
describe("JSON API errors") { | ||
|
||
it("should serialize errors") { | ||
let error = JSONAPIError(statusCode: 404) { (error) in | ||
error.title = "test" | ||
} | ||
let object = json(error) | ||
expect(object.count).to(equal(2)) | ||
expect(object["status"]).to(equal(404)) | ||
expect(object["title"]).to(equal("test")) | ||
} | ||
|
||
it("should serialize members of the error") { | ||
let error = JSONAPIError(statusCode: 404) { (error) in | ||
error.source = JSONAPIError.Source(pointer: "ptr", parameter: "param") | ||
error.meta = ErrorDescription(description: "test") | ||
} | ||
|
||
let object = json(error) | ||
expect(object.count).to(equal(3)) | ||
|
||
let source = object["source"].dictionaryValue | ||
expect(source["pointer"]).to(equal("ptr")) | ||
expect(source["parameter"]).to(equal("param")) | ||
|
||
let meta = object["meta"].dictionaryValue | ||
expect(meta["description"]).to(equal("test")) | ||
} | ||
|
||
it("should affect the status code of the request") { | ||
let router = Router.register("http://www.test.com") | ||
|
||
router.get("/users"){ request in | ||
return JSONAPIError(statusCode: 501) { (error) in | ||
error.title = "test" | ||
} | ||
} | ||
|
||
var statusCode: Int? = nil | ||
NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: "http://www.test.com/users")!) { (data, response, _) in | ||
let response = response as! NSHTTPURLResponse | ||
statusCode = response.statusCode | ||
}.resume() | ||
|
||
expect(statusCode).toEventually(equal(501)) | ||
} | ||
} | ||
} | ||
} |