Skip to content

Commit

Permalink
Make RideParameters immutable and add builder to mutate, addressing f…
Browse files Browse the repository at this point in the history
…eedback in #177
  • Loading branch information
edjiang committed Sep 14, 2017
1 parent 9368f74 commit fe109c9
Show file tree
Hide file tree
Showing 17 changed files with 315 additions and 189 deletions.
114 changes: 84 additions & 30 deletions source/UberRides/Model/RideParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,62 @@ import MapKit

/// Object to represent the parameters needed to request a ride.
@objc(UBSDKRideParameters) public class RideParameters: NSObject {
@objc(UBSDKRideParametersBuilder) public class Builder: NSObject {
/// ProductID to use for the ride
@objc public var productID: String?

/// The pickup location to use for the ride
@objc public var pickupLocation: CLLocation?

/// The nickname of the pickup location of the ride
@objc public var pickupNickname: String?

/// The address of the pickup location of the ride
@objc public var pickupAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public var pickupPlaceID: String?

/// The dropoff location to use for the ride
@objc public var dropoffLocation: CLLocation?

/// The nickname of the dropoff location for the ride
@objc public var dropoffNickname: String?

/// The adress of the dropoff location of the ride
@objc public var dropoffAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public var dropoffPlaceID: String?

/// The unique identifier of the payment method selected by a user.
@objc public var paymentMethod: String?

/// The unique identifier of the surge session for a user.
@objc public var surgeConfirmationID: String?

/// Upfront fare quote used to request a ride
@objc public var upfrontFare: UpfrontFare?

/// The source to use for attributing the ride. Used internal to the SDK.
@objc var source: String?

public func build() -> RideParameters {
return RideParameters(builder: self)
}
}

/// ProductID to use for the ride
@objc public var productID: String?
@objc public let productID: String?

/// The pickup location to use for the ride
@objc public let pickupLocation: CLLocation?

/// The nickname of the pickup location of the ride
@objc public var pickupNickname: String?
@objc public let pickupNickname: String?

/// The address of the pickup location of the ride
@objc public var pickupAddress: String?
@objc public let pickupAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public let pickupPlaceID: String?
Expand All @@ -46,48 +90,58 @@ import MapKit
@objc public let dropoffLocation: CLLocation?

/// The nickname of the dropoff location for the ride
@objc public var dropoffNickname: String?
@objc public let dropoffNickname: String?

/// The adress of the dropoff location of the ride
@objc public var dropoffAddress: String?
@objc public let dropoffAddress: String?

/// This is the name of an Uber saved place. Only “home” or “work” is acceptable.
@objc public let dropoffPlaceID: String?

/// The unique identifier of the payment method selected by a user.
@objc public var paymentMethod: String?
@objc public let paymentMethod: String?

/// The unique identifier of the surge session for a user.
@objc public var surgeConfirmationID: String?

/// The source to use for attributing the ride
@objc public var source: String?
@objc public let surgeConfirmationID: String?

/// Upfront fare quote used to request a ride
@objc public var upfrontFare: UpfrontFare?
@objc public let upfrontFare: UpfrontFare?

convenience public override init() {
self.init(pickupLocation: nil, dropoffLocation: nil, pickupPlaceID: nil, dropoffPlaceID: nil)
}
/// The source to use for attributing the ride. Used internal to the SDK.
@objc var source: String?

@objc convenience public init(pickupLocation: CLLocation?, dropoffLocation: CLLocation?) {
self.init(pickupLocation: pickupLocation, dropoffLocation: dropoffLocation, pickupPlaceID: nil, dropoffPlaceID: nil)
@objc public func builder() -> Builder {
let builder = Builder()
builder.productID = productID
builder.pickupLocation = pickupLocation
builder.pickupNickname = pickupNickname
builder.pickupAddress = pickupAddress
builder.pickupPlaceID = pickupPlaceID
builder.dropoffLocation = dropoffLocation
builder.dropoffNickname = dropoffNickname
builder.dropoffAddress = dropoffAddress
builder.dropoffPlaceID = dropoffPlaceID
builder.paymentMethod = paymentMethod
builder.surgeConfirmationID = surgeConfirmationID
builder.source = source
builder.upfrontFare = upfrontFare
return builder
}

@objc convenience public init(pickupPlaceID: String?, dropoffPlaceID: String?) {
self.init(pickupLocation: nil, dropoffLocation: nil, pickupPlaceID: pickupPlaceID, dropoffPlaceID: dropoffPlaceID)
}

private init(pickupLocation: CLLocation?,
dropoffLocation: CLLocation?,
pickupPlaceID: String?,
dropoffPlaceID: String?) {
self.pickupLocation = pickupLocation
self.dropoffLocation = dropoffLocation
self.pickupPlaceID = pickupPlaceID
self.dropoffPlaceID = dropoffPlaceID

super.init()
private init(builder: Builder) {
productID = builder.productID
pickupLocation = builder.pickupLocation
pickupNickname = builder.pickupNickname
pickupAddress = builder.pickupAddress
pickupPlaceID = builder.pickupPlaceID
dropoffLocation = builder.dropoffLocation
dropoffNickname = builder.dropoffNickname
dropoffAddress = builder.dropoffAddress
dropoffPlaceID = builder.dropoffPlaceID
paymentMethod = builder.paymentMethod
surgeConfirmationID = builder.surgeConfirmationID
source = builder.source
upfrontFare = builder.upfrontFare
}

var userAgent: String {
Expand Down
13 changes: 2 additions & 11 deletions source/UberRides/RequestDeeplink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,10 @@ import UIKit
* Builds and executes a deeplink to the native Uber app to request a ride.
*/
@objc(UBSDKRequestDeeplink) open class RequestDeeplink: BaseDeeplink {

private let parameters: RideParameters
private let clientID: String

static let sourceString = "deeplink"

@objc public init(rideParameters: RideParameters = RideParameters()) {
parameters = rideParameters
clientID = Configuration.shared.clientID

if rideParameters.source == nil {
rideParameters.source = RequestDeeplink.sourceString
}
@objc public init(rideParameters: RideParameters = RideParameters.Builder().build()) {
rideParameters.source = rideParameters.source ?? RequestDeeplink.sourceString

let queryItems = RequestURLUtil.buildRequestQueryParameters(rideParameters)
let scheme = "uber"
Expand Down
8 changes: 4 additions & 4 deletions source/UberRides/RideRequestButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import CoreLocation
*/
required public init?(coder aDecoder: NSCoder) {
requestBehavior = DeeplinkRequestingBehavior()
rideParameters = RideParameters()
rideParameters = RideParameters.Builder().build()
super.init(coder: aDecoder)
}

Expand Down Expand Up @@ -116,7 +116,7 @@ import CoreLocation
- returns: An initialized RideRequestButton
*/
@objc public convenience init(client: RidesClient) {
self.init(client: client, rideParameters: RideParameters(), requestingBehavior: DeeplinkRequestingBehavior())
self.init(client: client, rideParameters: RideParameters.Builder().build(), requestingBehavior: DeeplinkRequestingBehavior())
}

/**
Expand All @@ -142,7 +142,7 @@ import CoreLocation
- returns: An initialized RideRequestButton
*/
@objc public convenience init(requestingBehavior: RideRequesting) {
self.init(client: RidesClient(), rideParameters: RideParameters(), requestingBehavior: requestingBehavior)
self.init(client: RidesClient(), rideParameters: RideParameters.Builder().build(), requestingBehavior: requestingBehavior)
}

//Mark: UberButton
Expand All @@ -156,7 +156,7 @@ import CoreLocation
- returns: An initialized RideRequestButton
*/
@objc public convenience init() {
self.init(client: RidesClient(), rideParameters: RideParameters(), requestingBehavior: DeeplinkRequestingBehavior())
self.init(client: RidesClient(), rideParameters: RideParameters.Builder().build(), requestingBehavior: DeeplinkRequestingBehavior())
}

/**
Expand Down
10 changes: 4 additions & 6 deletions source/UberRides/RideRequestView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ import CoreLocation
- returns: An initialized RideRequestView
*/
@objc public convenience override init(frame: CGRect) {
self.init(rideParameters: RideParameters(), accessToken: TokenManager.fetchToken(), frame: frame)
self.init(rideParameters: RideParameters.Builder().build(), accessToken: TokenManager.fetchToken(), frame: frame)
}

/**
Expand All @@ -121,11 +121,11 @@ import CoreLocation
- returns: An initialized RideRequestView
*/
@objc public convenience init() {
self.init(rideParameters: RideParameters(), accessToken: TokenManager.fetchToken(), frame: CGRect.zero)
self.init(rideParameters: RideParameters.Builder().build(), accessToken: TokenManager.fetchToken(), frame: CGRect.zero)
}

required public init?(coder aDecoder: NSCoder) {
rideParameters = RideParameters()
rideParameters = RideParameters.Builder().build()
let configuration = WKWebViewConfiguration()
configuration.processPool = Configuration.shared.processPool
webView = WKWebView(frame: CGRect.zero, configuration: configuration)
Expand All @@ -152,9 +152,7 @@ import CoreLocation

let tokenString = accessToken.tokenString

if rideParameters.source == nil {
rideParameters.source = RideRequestView.sourceString
}
rideParameters.source = rideParameters.source ?? RideRequestView.sourceString

let endpoint = Components.rideRequestWidget(rideParameters: rideParameters)
guard let request = Request(session: nil, endpoint: endpoint, bearerToken: tokenString) else {
Expand Down
8 changes: 3 additions & 5 deletions source/UberRides/RideRequestViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ import MapKit

super.init(coder: aDecoder)

let defaultRideParameters = RideParameters()
let defaultRideParameters = RideParameters.Builder()
defaultRideParameters.source = RideRequestViewController.sourceString

rideRequestView.rideParameters = defaultRideParameters
rideRequestView.rideParameters = defaultRideParameters.build()
}

/**
Expand All @@ -100,9 +100,7 @@ import MapKit

super.init(nibName: nil, bundle: nil)

if rideParameters.source == nil {
rideParameters.source = RideRequestViewController.sourceString
}
rideParameters.source = rideParameters.source ?? RideRequestViewController.sourceString

rideRequestView.rideParameters = rideParameters
rideRequestView.accessToken = TokenManager.fetchToken(identifier: accessTokenIdentifier, accessGroup: keychainAccessGroup)
Expand Down
2 changes: 1 addition & 1 deletion source/UberRides/RideRequestViewRequestingBehavior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
*/
@objc public init(presentingViewController: UIViewController, loginManager: LoginManager) {
self.presentingViewController = presentingViewController
let rideRequestViewController = RideRequestViewController(rideParameters: RideParameters(), loginManager: loginManager)
let rideRequestViewController = RideRequestViewController(rideParameters: RideParameters.Builder().build(), loginManager: loginManager)
modalRideRequestViewController = ModalRideRequestViewController(rideRequestViewController: rideRequestViewController)
}

Expand Down
38 changes: 24 additions & 14 deletions source/UberRidesTests/APIManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,17 @@ class APIManagerTests: XCTestCase {
func testRequestBuilderAllParameters() {
let pickupLocation = CLLocation(latitude: pickupLat, longitude: pickupLong)
let dropoffLocation = CLLocation(latitude: dropoffLat, longitude: dropoffLong)
let rideParameters = RideParameters(pickupLocation: pickupLocation, dropoffLocation: dropoffLocation)
rideParameters.pickupNickname = pickupNickname
rideParameters.pickupAddress = pickupAddress
rideParameters.dropoffNickname = dropoffNickname
rideParameters.dropoffAddress = dropoffAddress
rideParameters.productID = productID
rideParameters.surgeConfirmationID = surgeConfirm
rideParameters.paymentMethod = paymentMethod
let builder = RideParameters.Builder()
builder.pickupLocation = pickupLocation
builder.pickupNickname = pickupNickname
builder.pickupAddress = pickupAddress
builder.dropoffLocation = dropoffLocation
builder.dropoffNickname = dropoffNickname
builder.dropoffAddress = dropoffAddress
builder.productID = productID
builder.surgeConfirmationID = surgeConfirm
builder.paymentMethod = paymentMethod
let rideParameters = builder.build()

guard let data = RideRequestDataBuilder(rideParameters: rideParameters).build() else {
XCTAssert(false)
Expand Down Expand Up @@ -261,8 +264,10 @@ class APIManagerTests: XCTestCase {
Test the POST /v1/requests endpoint.
*/
func testPostRequest() {
let rideParameters = RideParameters(pickupPlaceID: "home", dropoffPlaceID: nil)
rideParameters.productID = productID
let builder = RideParameters.Builder()
builder.pickupPlaceID = Place.home
builder.productID = productID
let rideParameters = builder.build()
let request = buildRequestForEndpoint(Requests.make(rideParameters: rideParameters))
XCTAssertEqual(request.httpMethod, Method.post.rawValue)
if let url = request.url {
Expand Down Expand Up @@ -304,8 +309,9 @@ class APIManagerTests: XCTestCase {
Tests the POST /v1/requests/estimate endpoint.
*/
func testPostRequestEstimate() {
let rideParameters = RideParameters(pickupPlaceID: "home", dropoffPlaceID: nil)
let request = buildRequestForEndpoint(Requests.estimate(rideParameters: rideParameters))
let builder = RideParameters.Builder()
builder.pickupPlaceID = Place.home
let request = buildRequestForEndpoint(Requests.estimate(rideParameters: builder.build()))
XCTAssertEqual(request.httpMethod, "POST")
if let url = request.url {
XCTAssertEqual(url.absoluteString, ExpectedEndpoint.PostRequestEstimate)
Expand Down Expand Up @@ -381,7 +387,9 @@ class APIManagerTests: XCTestCase {
Tests the PATCH /v1/requests/curent endpoint.
*/
func testPatchCurrentRequest() {
let rideParams = RideParameters(pickupPlaceID: Place.home, dropoffPlaceID: nil)
let builder = RideParameters.Builder()
builder.pickupPlaceID = Place.home
let rideParams = builder.build()
let request = buildRequestForEndpoint(Requests.patchCurrent(rideParameters: rideParams))
XCTAssertEqual(request.httpMethod, "PATCH")
if let url = request.url {
Expand Down Expand Up @@ -420,7 +428,9 @@ class APIManagerTests: XCTestCase {
Tests the PATCH /v1/requests/{request_id} endpoint.
*/
func testPatchRequestByID() {
let rideParams = RideParameters(pickupPlaceID: Place.home, dropoffPlaceID: nil)
let builder = RideParameters.Builder()
builder.pickupPlaceID = Place.home
let rideParams = builder.build()
let request = buildRequestForEndpoint(Requests.patchRequest(requestID: requestID, rideParameters: rideParams))
XCTAssertEqual(request.httpMethod, "PATCH")
if let url = request.url {
Expand Down
6 changes: 3 additions & 3 deletions source/UberRidesTests/DeeplinkRequestingBehaviorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class DeeplinkRequestingBehaviorTests : XCTestCase {
func testCreateAppStoreDeeplinkWithButtonSource() {
let expectedUrlString = "https://m.uber.com/sign-up?client_id=\(clientID)&user-agent=\(expectedButtonUserAgent!)"

let rideParameters = RideParameters()
let rideParameters = RideParameters.Builder().build()
rideParameters.source = RideRequestButton.sourceString
let requestingBehavior = DeeplinkRequestingBehavior()

Expand All @@ -73,7 +73,7 @@ class DeeplinkRequestingBehaviorTests : XCTestCase {
func testCreateURLWithDeeplinkSource() {
let expectedUrlString = "https://m.uber.com/sign-up?client_id=\(clientID)&user-agent=\(expectedDeeplinkUserAgent!)"

let rideParameters = RideParameters()
let rideParameters = RideParameters.Builder().build()
rideParameters.source = RequestDeeplink.sourceString
let requestingBehavior = DeeplinkRequestingBehavior()

Expand All @@ -88,7 +88,7 @@ class DeeplinkRequestingBehaviorTests : XCTestCase {
}

func testRequestRideExecutesDeeplink() {
let rideParameters = RideParameters()
let rideParameters = RideParameters.Builder().build()
rideParameters.source = RideRequestButton.sourceString
let expectation = self.expectation(description: "Deeplink executed")
let testClosure:((URL?) -> (Bool)) = { _ in
Expand Down
Loading

0 comments on commit fe109c9

Please sign in to comment.