source/UberRidesTests/RequestLayerTests.swift (287 lines of code) (raw):
//
// RequestLayerTests.swift
// UberRidesTests
//
// Copyright © 2016 Uber Technologies, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import XCTest
import OHHTTPStubs
import OHHTTPStubsSwift
import UberCore
@testable import UberRides
class RequestLayerTests: XCTestCase {
var client: RidesClient!
var headers: [AnyHashable: Any]!
let timeout: Double = 10
override func setUp() {
super.setUp()
Configuration.plistName = "testInfo"
Configuration.restoreDefaults()
Configuration.shared.isSandbox = true
headers = ["Content-Type": "application/json"]
client = RidesClient()
}
override func tearDown() {
HTTPStubs.removeAllStubs()
Configuration.restoreDefaults()
super.tearDown()
}
/**
Test 200 success response
*/
func test200Response() {
stub(condition: isHost("sandbox-api.uber.com")) { _ in
return HTTPStubsResponse(fileAtPath:OHPathForFile("getProductID.json", type(of: self))!, statusCode:200, headers:self.headers)
}
let expectation = self.expectation(description: "200 success response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 200)
XCTAssertNil(response.error)
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
Test 401 authorization error response.
*/
func test401Error() {
let message = "Invalid OAuth 2.0 credentials provided."
let code = "unauthorized"
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let json = ["message": message, "code": code]
return HTTPStubsResponse(jsonObject: json, statusCode: 401, headers: self.headers)
}
let expectation = self.expectation(description: "401 error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 401)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberClientError)
XCTAssertEqual(response.error!.title, message)
XCTAssertEqual(response.error!.code, code)
XCTAssertNil(response.error!.meta)
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
Test 409 surge error response.
*/
func test409Error() {
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let json = ["meta": ["surge_confirmation": ["href": "api.uber.com/v1/surge-confirmations/abc", "surge_confirmation_id": "abc"]]]
return HTTPStubsResponse(jsonObject: json, statusCode: 409, headers: self.headers)
}
let expectation = self.expectation(description: "409 error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 409)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberClientError)
XCTAssertNotNil(response.error!.meta)
let meta = response.error!.meta! as! [String: [String: String]]
XCTAssertEqual(meta["surge_confirmation"]!["href"], "api.uber.com/v1/surge-confirmations/abc")
XCTAssertEqual(meta["surge_confirmation"]!["surge_confirmation_id"], "abc")
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
Test 422 lat/long validation error response.
*/
func test422ValidationError() {
let message = "Invalid request."
let code = "validation_failed"
let fields = ["latitude": ["Must be between -90.0 and 90.0"], "longitude": ["Must be between -90.0 and 90.0"]]
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let json = ["message": message, "code": code, "fields": fields] as [String : Any]
return HTTPStubsResponse(jsonObject: json, statusCode: 422, headers: self.headers)
}
let expectation = self.expectation(description: "422 error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 422)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberClientError)
XCTAssertEqual(response.error!.title, message)
XCTAssertEqual(response.error!.code, code)
let fields = response.error!.meta! as! [String: [String]]
XCTAssertEqual(fields.count, 2)
XCTAssertEqual(fields["latitude"]![0], "Must be between -90.0 and 90.0")
XCTAssertEqual(fields["longitude"]![0], "Must be between -90.0 and 90.0")
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
Test 422 distance exceeded error response.
*/
func test422DistanceExceededError() {
let message = "Distance between two points exceeds 100 miles."
let code = "distance_exceeded"
let fields = ["start_latitude": [message], "end_latitude": [message], "start_longitude": [message], "end_longitude": [message]]
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let json = ["message": message, "code": code, "fields": fields] as [String : Any]
return HTTPStubsResponse(jsonObject: json, statusCode: 422, headers: self.headers)
}
let expectation = self.expectation(description: "422 error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 422)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberClientError)
XCTAssertEqual(response.error!.title, message)
XCTAssertEqual(response.error!.code, code)
let fields = response.error!.meta! as! [String: [String]]
XCTAssertEqual(fields.count, 4)
XCTAssertEqual(fields["start_latitude"]![0], message)
XCTAssertEqual(fields["start_longitude"]![0], message)
XCTAssertEqual(fields["end_latitude"]![0], message)
XCTAssertEqual(fields["end_longitude"]![0], message)
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
Test 422 same pickup and dropoff error response.
*/
func test422SamePickupDropoffError() {
let code = "same_pickup_dropoff"
let message = "Pickup and Dropoff can't be the same."
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let json = ["meta": [], "errors": [["status": 422, "code": code, "title": message]]]
return HTTPStubsResponse(jsonObject: json, statusCode: 409, headers: self.headers)
}
let expectation = self.expectation(description: "422 error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 409)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberClientError)
XCTAssertNil(response.error!.meta)
XCTAssertEqual(response.error!.errors!.count, 1)
let error = response.error!.errors![0]
XCTAssertEqual(error.status, 422)
XCTAssertEqual(error.code, code)
XCTAssertEqual(error.title, message)
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
Test 500 internal server error response.
*/
func test500Error() {
let message = "Unexpected internal server error occurred."
let code = "internal_server_error"
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let json = ["message": message, "code": code]
return HTTPStubsResponse(jsonObject: json, statusCode: 500, headers: self.headers)
}
let expectation = self.expectation(description: "500 error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 500)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberServerError)
XCTAssertEqual(response.error!.title, message)
XCTAssertEqual(response.error!.code, code)
XCTAssertNil(response.error!.meta)
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
Test 503 service unavailable error response.
*/
func test503Error() {
let message = "Service temporarily unavailable."
let code = "service_unavailable"
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let json = ["message": message, "code": code]
return HTTPStubsResponse(jsonObject: json, statusCode: 503, headers: self.headers)
}
let expectation = self.expectation(description: "503 error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 503)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberServerError)
XCTAssertEqual(response.error!.title, message)
XCTAssertEqual(response.error!.code, code)
XCTAssertNil(response.error!.meta)
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
/**
* Test no network error response - unknown error.
*/
func testNoNetworkError() {
stub(condition: isHost("sandbox-api.uber.com")) { _ in
let notConnectedError = NSError(domain: NSURLErrorDomain, code: Int(CFNetworkErrors.cfurlErrorNotConnectedToInternet.rawValue), userInfo: nil)
return HTTPStubsResponse(error:notConnectedError)
}
let expectation = self.expectation(description: "No network error response")
let endpoint = Products.getProduct(productID: productID)
guard let request = Request(session: client.session, endpoint: endpoint) else {
XCTFail("Unable to create request")
return
}
request.execute({ response in
XCTAssertEqual(response.statusCode, 0)
XCTAssertNotNil(response.error)
XCTAssertTrue(response.error is UberUnknownError)
XCTAssertEqual(response.error!.title, NSURLErrorDomain)
XCTAssertEqual(response.error!.status, Int(CFNetworkErrors.cfurlErrorNotConnectedToInternet.rawValue))
XCTAssertNil(response.error!.meta)
expectation.fulfill()
})
waitForExpectations(timeout: timeout, handler: { error in
if let error = error {
print("Error: \(error.localizedDescription)")
}
request.cancelTasks()
})
}
}