Commit 5dd5cb93 authored by Mauro E. Bender's avatar Mauro E. Bender

Close #4 - Add request methods to Resource

parent 5698cafc
......@@ -28,38 +28,19 @@ public class Resource {
self.path = path
}
public func item<T: JSONSerializable>( id: AnyObject, parameters: [ String: String ]? = nil,
headers: [ String: String]? = nil, completion: ( ( T?, error: ApiError? ) -> Void ) )
{
api.get( resourceMemberPath( id ), parameters: parameters, headers: headers ) { response in
self.handleItemResult( response, handler: completion )
}
}
public func create<T: JSONSerializable>( item: T, parameters: [ String: String ]? = nil,
headers: [ String: String]? = nil, encoding: ParameterEncoding = .JSON,
completion: ( ( T?, error: ApiError? ) -> Void ) )
{
var requestParameters = item.toJSON()
if parameters != nil { requestParameters += parameters! }
api.post( path, parameters: requestParameters, encoding: encoding, headers: headers ) { response in
self.handleItemResult( response, handler: completion )
}
}
func handleItemResult<T: JSONSerializable>( response: Response<AnyObject, NSError>,
handler: ( T?, error: ApiError? ) -> Void )
// MARK: UTILS
private func handleItemResult<T: JSONSerializable>( response: Response<AnyObject, NSError>,
handler: ( T?, error: ApiError? ) -> Void )
{
switch(response.result) {
case .Success(let JSON):
handler( T( fromJSON: JSON as! [String : AnyObject] ), error: nil )
case .Failure(let error):
handler( nil, error: handleError( response ) )
case .Success(let JSON):
handler( T( fromJSON: JSON as! [String : AnyObject] ), error: nil )
case .Failure(let error):
handler( nil, error: handleError( response ) )
}
}
func handleError( response: Response<AnyObject, NSError> ) -> ApiError {
private func handleError( response: Response<AnyObject, NSError> ) -> ApiError {
let error = response.result.error!
if let statusCode = response.response?.statusCode where !(200...299).contains( statusCode ) {
......@@ -70,7 +51,73 @@ public class Resource {
return .Unknown( error: error )
}
}
// MARK: REQUESTS
extension Resource {
public func request( method: ApiMethod, path: String? = nil,
parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil, completion: Response<AnyObject, NSError> -> Void )
{
let requestPath = path != nil ? "\(self.path)/\(path!)" : self.path
api.request( method, path: requestPath, parameters: parameters, encoding: encoding,
headers: headers, completion: completion )
}
public func get( path: String? = nil, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil, completion: Response<AnyObject, NSError> -> Void )
{
return request( .GET, path: path, parameters: parameters, encoding: encoding,
headers: headers, completion: completion)
}
public func post( path: String? = nil, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil, completion: Response<AnyObject, NSError> -> Void )
{
return request( .POST, path: path, parameters: parameters, encoding: encoding,
headers: headers, completion: completion)
}
public func put( path: String? = nil, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil, completion: Response<AnyObject, NSError> -> Void )
{
return request( .PUT, path: path, parameters: parameters, encoding: encoding,
headers: headers, completion: completion)
}
public func delete( path: String? = nil, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL,
headers: [String: String]? = nil, completion: Response<AnyObject, NSError> -> Void )
{
return request( .DELETE, path: path, parameters: parameters, encoding: encoding,
headers: headers, completion: completion)
}
}
// MARK: CRUD
extension Resource {
public func item<T: JSONSerializable>( id: AnyObject, parameters: [ String: String ]? = nil,
headers: [ String: String]? = nil, completion: ( ( T?, error: ApiError? ) -> Void ) )
{
get( "\(id)", parameters: parameters, headers: headers ) { response in
self.handleItemResult( response, handler: completion )
}
}
public func create<T: JSONSerializable>( item: T, parameters: [ String: String ]? = nil,
headers: [ String: String]? = nil, encoding: ParameterEncoding = .JSON,
completion: ( ( T?, error: ApiError? ) -> Void ) )
{
var requestParameters = item.toJSON()
if parameters != nil { requestParameters += parameters! }
post( parameters: requestParameters, encoding: encoding, headers: headers ) { response in
self.handleItemResult( response, handler: completion )
}
}
}
// MARK: NESTED RESOURCES
extension Resource {
public func member( memberID: AnyObject ) -> Resource {
let memberPath = resourceMemberPath( memberID )
return Resource( api: api, path: memberPath )
......
......@@ -19,6 +19,8 @@ class ResourceTests: QuickSpec {
stub( matchApiPath( "items/1" ), builder: json( [ "id": 1, "name": "Item 1" ] ) )
stub( matchApiPath( "items/1/components/1" ), builder: json( [ "id": 1, "name": "Component 1" ] ) )
stub( matchApiPath( "items", method: .POST ), builder: buildItemFromRequest( 2 ) )
stub( matchApiPath( "items/1", method: .DELETE ), builder: http( 200 ) )
stub( matchApiPath( "items/1", method: .PUT ), builder: http( 200 ) )
stub( matchApiPath( "failedItems", method: .POST ), builder: http( 422 ) )
}
......@@ -28,78 +30,108 @@ class ResourceTests: QuickSpec {
describe( "Resource" ) {
let resource: Resource = api.resource( "items" )
describe( "item" ) {
context( "when the request is successful" ) {
it( "should call the correct endpoint and return the item" ) {
waitUntil { done in
resource.item( 1 ) { ( item: Item?, error: ApiError? ) in
expect( item?.id ) == 1
expect( item?.name ) == "Item 1"
done()
}
}
describe( "Requests methods" ) {
describe( "get" ) {
it( "should call the correct endpoint" ) {
waitUntil { done in resource.get( "1" ) { result in done() } }
}
}
describe( "post" ) {
it( "should call the correct endpoint" ) {
waitUntil { done in resource.post() { result in done() } }
}
}
describe( "put" ) {
it( "should call the correct endpoint" ) {
waitUntil { done in resource.put( "1" ) { result in done() } }
}
}
describe( "delete" ) {
it( "should call the correct endpoint" ) {
waitUntil { done in resource.delete( "1" ) { result in done() } }
}
}
}
describe( "create" ) {
context( "when the request is successful" ) {
let itemToCreate = Item( id: 0, name: "Item 2" )
it( "should call the correct endpoint and return the created item" ) {
waitUntil { done in
resource.create( itemToCreate ) { ( item: Item?, error: ApiError? ) in
expect( item?.id ) == 2
expect( item?.name ) == "Item 2"
done()
describe( "CRUD methods" ) {
describe( "item" ) {
context( "when the request is successful" ) {
it( "should call the correct endpoint and return the item" ) {
waitUntil { done in
resource.item( 1 ) { ( item: Item?, error: ApiError? ) in
expect( item?.id ) == 1
expect( item?.name ) == "Item 1"
done()
}
}
}
}
}
context( "when there's an error" ) {
let failResource : Resource = api.resource( "failedItems" )
let itemToCreate = Item( id: 0, name: "Item 2" )
it( "should call the correct endpoint and return the correct error" ) {
waitUntil { done in
failResource.create( itemToCreate ) { ( item: Item?, error: ApiError? ) in
expect( item ).to( beNil() )
expect( error ).toNot( beNil() )
done()
describe( "create" ) {
context( "when the request is successful" ) {
let itemToCreate = Item( id: 0, name: "Item 2" )
it( "should call the correct endpoint and return the created item" ) {
waitUntil { done in
resource.create( itemToCreate ) { ( item: Item?, error: ApiError? ) in
expect( item?.id ) == 2
expect( item?.name ) == "Item 2"
done()
}
}
}
}
context( "when there's an error" ) {
let failResource : Resource = api.resource( "failedItems" )
let itemToCreate = Item( id: 0, name: "Item 2" )
it( "should call the correct endpoint and return the correct error" ) {
waitUntil { done in
failResource.create( itemToCreate ) { ( item: Item?, error: ApiError? ) in
expect( item ).to( beNil() )
expect( error ).toNot( beNil() )
done()
}
}
}
}
}
}
describe( "member" ) {
let member = resource.member( 1 )
it( "should add the correct path" ) {
expect( member.api ).to( equal( resource.api ) )
expect( member.path ).to( equal( "\(resource.path)/1" ) )
describe( "nested resources methods" ) {
describe( "member" ) {
let member = resource.member( 1 )
it( "should add the correct path" ) {
expect( member.api ).to( equal( resource.api ) )
expect( member.path ).to( equal( "\(resource.path)/1" ) )
}
}
}
describe( "resource" ) {
let nestedResource = resource.resource( "components" )
it( "should add the correct path" ) {
expect( nestedResource.api ).to( equal( resource.api ) )
expect( nestedResource.path ).to( equal( "\(resource.path)/components" ) )
describe( "resource" ) {
let nestedResource = resource.resource( "components" )
it( "should add the correct path" ) {
expect( nestedResource.api ).to( equal( resource.api ) )
expect( nestedResource.path ).to( equal( "\(resource.path)/components" ) )
}
}
}
context( "when getting a nested resource item" ) {
let nestedResource = resource.member( 1 ).resource( "components" )
it( "should call the correct endpoint and return correct the item" ) {
waitUntil { done in
nestedResource.item( 1 ) { ( component: Component?, error: ApiError? ) in
expect( component?.id ) == 1
expect( component?.name ) == "Component 1"
done()
context( "when getting a nested resource item" ) {
let nestedResource = resource.member( 1 ).resource( "components" )
it( "should call the correct endpoint and return correct the item" ) {
waitUntil { done in
nestedResource.item( 1 ) { ( component: Component?, error: ApiError? ) in
expect( component?.id ) == 1
expect( component?.name ) == "Component 1"
done()
}
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment