Skip to content

Commit

Permalink
Merge pull request #22 from uphold/feature/update-transaction
Browse files Browse the repository at this point in the history
Update transaction model
  • Loading branch information
SandroMachado committed Dec 11, 2015
2 parents 70b2062 + be69a4e commit ed25d31
Show file tree
Hide file tree
Showing 15 changed files with 474 additions and 86 deletions.
14 changes: 13 additions & 1 deletion Source/Model/Card.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,23 @@ public class Card: BaseModel, Mappable {
- returns: A promise with the transaction.
*/
public func createTransaction(transactionRequest: TransactionRequest) -> Promise<Transaction> {
return createTransaction(false, transactionRequest: transactionRequest)
}

/**
Creates a transaction.

- parameter commit: A boolean to indicate if it is to commit the transaction on the creation process.
- parameter transactionRequest: The transaction request information.

- returns: A promise with the transaction.
*/
public func createTransaction(commit: Bool, transactionRequest: TransactionRequest) -> Promise<Transaction> {
guard let id = self.id else {
return Promise<Transaction>(error: UnexpectedResponseError(message: "Card id should not be nil."))
}

let request = self.adapter.buildRequest(UserCardService.createTransaction(id, transactionRequest: Mapper().toJSONString(transactionRequest, prettyPrint: false)!))
let request = self.adapter.buildRequest(UserCardService.createTransaction(id, commit: commit, transactionRequest: Mapper().toJSONString(transactionRequest, prettyPrint: false)!))

return self.adapter.buildResponse(request)
}
Expand Down
66 changes: 64 additions & 2 deletions Source/Model/Transaction.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import Foundation
import PromiseKit
import ObjectMapper

/// Transaction model.
public class Transaction: Mappable {
public class Transaction: BaseModel, Mappable {

/// The id of the transaction.
public private(set) var id: String?
Expand Down Expand Up @@ -78,7 +79,7 @@ public class Transaction: Mappable {
Maps the JSON to the Object.

- parameter map: The object to map.
*/
*/
public func mapping(map: Map) {
id <- map["id"]
createdAt <- map["createdAt"]
Expand All @@ -93,4 +94,65 @@ public class Transaction: Mappable {
type <- map["type"]
}

/**
Cancel a transaction.

- returns: A promise with the transaction.
*/
public func cancel() -> Promise<Transaction> {
guard let id = self.id else {
return Promise<Transaction>(error: UnexpectedResponseError(message: "Transaction id should not be nil."))
}

guard let cardId = self.origin?.cardId else {
return Promise<Transaction>(error: UnexpectedResponseError(message: "Origin cardId is missing from this transaction."))
}

guard let status = self.status else {
return Promise<Transaction>(error: UnexpectedResponseError(message: "Transaction status should not be nil."))
}

switch (status) {
case "pending":
return Promise<Transaction>(error: LogicError(code: nil, message: "Unable to cancel uncommited transaction."))

case "waiting":
let request = self.adapter.buildRequest(UserCardService.cancelTransaction(cardId, transactionId: id))

return self.adapter.buildResponse(request)

default:
return Promise<Transaction>(error: LogicError(code: nil, message: String(format: "This transaction cannot be cancelled, because the current status is %@.", status)))
}
}

/**
Confirm a transaction.

- parameter transactionCommit: A transactionCommitRequest with an optional transaction message.

- returns: A promise with the transaction.
*/
public func commit(transactionCommit: TransactionCommitRequest) -> Promise<Transaction> {
guard let id = self.id else {
return Promise<Transaction>(error: UnexpectedResponseError(message: "Transaction id should not be nil."))
}

guard let cardId = self.origin?.cardId else {
return Promise<Transaction>(error: UnexpectedResponseError(message: "Origin cardId is missing from this transaction."))
}

guard let status = self.status else {
return Promise<Transaction>(error: UnexpectedResponseError(message: "Transaction status should not be nil."))
}

if (status != "pending") {
return Promise<Transaction>(error: LogicError(code: nil, message: String(format: "This transaction cannot be committed, because the current status is %@.", status)))
}

let request = self.adapter.buildRequest(UserCardService.confirmTransaction(cardId, transactionId: id, transactionCommitRequest: Mapper().toJSONString(transactionCommit, prettyPrint: false)!))

return self.adapter.buildResponse(request)
}

}
6 changes: 5 additions & 1 deletion Source/Model/Transaction/Denomination.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ public class Denomination: Mappable {
required public init?(_ map: Map) {
}

/// Maps the JSON to the Object.
/**
Maps the JSON to the Object.

- parameter map: The object to map.
*/
public func mapping(map: Map) {
amount <- map["amount"]
currency <- map["currency"]
Expand Down
2 changes: 1 addition & 1 deletion Source/Model/Transaction/Destination.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class Destination: Mappable {
- parameter rate: The rate from the destination of the transaction.
- parameter type: The type from the destination of the transaction.
- parameter username: The username from the destination of the transaction.
*/
*/
public init(accountId: String, cardId: String, accountType: String, amount: String, base: String, commission: String, currency: String, description: String, fee: String, rate: String, type: String, username: String) {
self.accountId = accountId
self.cardId = cardId
Expand Down
4 changes: 2 additions & 2 deletions Source/Model/Transaction/NormalizedTransaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class NormalizedTransaction: Mappable {
- parameter currency: The currency of the transaction normalized.
- parameter fee: The fee of the transaction normalized.
- parameter rate: The rate of the transaction normalized.
*/
*/
public init(amount: String, commission: String, currency: String, fee: String, rate: String) {
self.amount = amount
self.commission = commission
Expand All @@ -48,7 +48,7 @@ public class NormalizedTransaction: Mappable {
Maps the JSON to the Object.

- parameter map: The object to map.
*/
*/
public func mapping(map: Map) {
self.amount <- map["amount"]
self.commission <- map["commission"]
Expand Down
6 changes: 5 additions & 1 deletion Source/Model/Transaction/Source.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ public class Source: Mappable {
required public init?(_ map: Map) {
}

/// Maps the JSON to the Object.
/**
Maps the JSON to the Object.

- parameter map: The object to map.
*/
public func mapping(map: Map) {
id <- map["id"]
amount <- map["amount"]
Expand Down
36 changes: 36 additions & 0 deletions Source/Model/Transaction/TransactionCommitRequest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Foundation
import ObjectMapper

/// Transaction commit request model.
public class TransactionCommitRequest: Mappable {

/// The transaction message.
public private(set) final var message: String?

/**
Constructor.

- parameter message: The transaction message.
*/
public init(message: String) {
self.message = message
}

// MARK: Required by the ObjectMapper.

/**
Constructor.
*/
required public init?(_ map: Map) {
}

/**
Maps the JSON to the Object.

- parameter map: The object to map.
*/
public func mapping(map: Map) {
self.message <- map["message"]
}

}
9 changes: 5 additions & 4 deletions Source/Service/UserCardService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,21 @@ public class UserCardService {

- returns: A request to confirm the transaction.
*/
static func confirmTransaction(cardId: String, transactionId: String, message: String) -> Request {
return UpholdClient().post(String(format: "/v0/me/cards/%@/transactions/%@/commit", cardId, transactionId)).send(message)
static func confirmTransaction(cardId: String, transactionId: String, transactionCommitRequest: String) -> Request {
return UpholdClient().post(String(format: "/v0/me/cards/%@/transactions/%@/commit", cardId, transactionId)).send(transactionCommitRequest)
}

/**
Creates a request to create a transaction.

- parameter cardId: The id of the card.
- parameter commit: A boolean to indicate if it is to commit the transaction on the creation process.
- parameter transactionRequest: The transaction request.

- returns: A request to create a transaction.
*/
static func createTransaction(cardId: String, transactionRequest: String) -> Request {
return UpholdClient().post(String(format: "/v0/me/cards/%@/transactions", cardId)).send(transactionRequest)
static func createTransaction(cardId: String, commit: Bool, transactionRequest: String) -> Request {
return UpholdClient().post(String(format: "/v0/me/cards/%@/transactions", cardId)).query(["commit": commit ? "true" : "false"]).send(transactionRequest)
}

/**
Expand Down
82 changes: 49 additions & 33 deletions Tests/Integration/Model/CardTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,20 @@ class CardTest: UpholdTestCase {

card.createTransaction(transactionRequest).then { (transaction: Transaction) -> () in
XCTAssertEqual(transaction.createdAt, "2014-08-27T00:01:11.616Z", "Failed: Wrong transaction createdAt.")
XCTAssertEqual(transaction.denomination?.amount, "0.1", "Failed: Wrong transaction denomination amount.")
XCTAssertEqual(transaction.denomination?.currency, "BTC", "Failed: Wrong transaction denomination currency.")
XCTAssertEqual(transaction.denomination?.pair, "BTCBTC", "Failed: Wrong transaction denomination pair.")
XCTAssertEqual(transaction.denomination?.rate, "1.00", "Failed: Wrong transaction denomination rate.")
XCTAssertEqual(transaction.destination?.accountId, "fuz", "Failed: Wrong transaction destination accountId.")
XCTAssertEqual(transaction.destination?.accountType, "buz", "Failed: Wrong transaction destination accountType.")
XCTAssertEqual(transaction.destination?.amount, "0.1", "Failed: Wrong transaction destination amount.")
XCTAssertEqual(transaction.destination?.base, "0.1", "Failed: Wrong transaction destination base.")
XCTAssertEqual(transaction.destination?.commission, "0.00", "Failed: Wrong transaction destination commission.")
XCTAssertEqual(transaction.destination?.currency, "BTC", "Failed: Wrong transaction destination currency.")
XCTAssertEqual(transaction.destination?.description, "[email protected]", "Failed: Wrong transaction destination description.")
XCTAssertEqual(transaction.destination?.fee, "0.00", "Failed: Wrong transaction destination fee.")
XCTAssertEqual(transaction.destination?.rate, "1.00", "Failed: Wrong transaction destination rate.")
XCTAssertEqual(transaction.destination?.type, "email", "Failed: Wrong transaction destination type.")
XCTAssertEqual(transaction.denomination!.amount, "0.1", "Failed: Wrong transaction denomination amount.")
XCTAssertEqual(transaction.denomination!.currency, "BTC", "Failed: Wrong transaction denomination currency.")
XCTAssertEqual(transaction.denomination!.pair, "BTCBTC", "Failed: Wrong transaction denomination pair.")
XCTAssertEqual(transaction.denomination!.rate, "1.00", "Failed: Wrong transaction denomination rate.")
XCTAssertEqual(transaction.destination!.accountId, "fuz", "Failed: Wrong transaction destination accountId.")
XCTAssertEqual(transaction.destination!.accountType, "buz", "Failed: Wrong transaction destination accountType.")
XCTAssertEqual(transaction.destination!.amount, "0.1", "Failed: Wrong transaction destination amount.")
XCTAssertEqual(transaction.destination!.base, "0.1", "Failed: Wrong transaction destination base.")
XCTAssertEqual(transaction.destination!.commission, "0.00", "Failed: Wrong transaction destination commission.")
XCTAssertEqual(transaction.destination!.currency, "BTC", "Failed: Wrong transaction destination currency.")
XCTAssertEqual(transaction.destination!.description, "[email protected]", "Failed: Wrong transaction destination description.")
XCTAssertEqual(transaction.destination!.fee, "0.00", "Failed: Wrong transaction destination fee.")
XCTAssertEqual(transaction.destination!.rate, "1.00", "Failed: Wrong transaction destination rate.")
XCTAssertEqual(transaction.destination!.type, "email", "Failed: Wrong transaction destination type.")
XCTAssertEqual(transaction.id, "foobar", "Failed: Wrong transaction id.")
XCTAssertEqual(transaction.message, "foobar", "Failed: Wrong transaction message.")
XCTAssertEqual(transaction.normalized!.count, 1, "Failed: Wrong transaction normalized count.")
Expand All @@ -137,25 +137,25 @@ class CardTest: UpholdTestCase {
XCTAssertEqual(transaction.normalized![0].currency, "BTC", "Failed: Wrong transaction normalized currency.")
XCTAssertEqual(transaction.normalized![0].fee, "1.00", "Failed: Wrong transaction normalized fee.")
XCTAssertEqual(transaction.normalized![0].rate, "2.00", "Failed: Wrong transaction normalized rate.")
XCTAssertEqual(transaction.origin?.accountId, "fiz", "Failed: Wrong transaction origin accountId.")
XCTAssertEqual(transaction.origin?.cardId, "bar", "Failed: Wrong transaction origin cardId.")
XCTAssertEqual(transaction.origin?.accountType, "biz", "Failed: Wrong transaction origin accountType.")
XCTAssertEqual(transaction.origin?.amount, "0.1", "Failed: Wrong transaction origin amount.")
XCTAssertEqual(transaction.origin?.base, "0.1", "Failed: Wrong transaction origin base.")
XCTAssertEqual(transaction.origin?.commission, "0.00", "Failed: Wrong transaction origin comission.")
XCTAssertEqual(transaction.origin?.currency, "BTC", "Failed: Wrong transaction origin currency.")
XCTAssertEqual(transaction.origin?.description, "Foo Bar", "Failed: Wrong transaction origin description.")
XCTAssertEqual(transaction.origin?.fee, "0.00", "Failed: Wrong transaction origin fee.")
XCTAssertEqual(transaction.origin?.rate, "1.00", "Failed: Wrong transaction origin rate.")
XCTAssertEqual(transaction.origin?.type, "card", "Failed: Wrong transaction origin type.")
XCTAssertEqual(transaction.origin?.username, "foobar", "Failed: Wrong transaction origin username.")
XCTAssertEqual(transaction.params?.currency, "BTC", "Failed: Wrong transaction parameter currency.")
XCTAssertEqual(transaction.params?.margin, "0.00", "Failed: Wrong transaction parameter margin.")
XCTAssertEqual(transaction.params?.pair, "BTCBTC", "Failed: Wrong transaction parameter pair.")
XCTAssertEqual(transaction.params?.rate, "1.00", "Failed: Wrong transaction parameter rate.")
XCTAssertEqual(transaction.params?.refunds, "fizbiz", "Failed: Wrong transaction parameter refunds.")
XCTAssertEqual(transaction.params?.ttl, 30000, "Failed: Wrong transaction parameter ttl.")
XCTAssertEqual(transaction.params?.type, "invite", "Failed: Wrong transaction parameter type.")
XCTAssertEqual(transaction.origin!.accountId, "fiz", "Failed: Wrong transaction origin accountId.")
XCTAssertEqual(transaction.origin!.cardId, "bar", "Failed: Wrong transaction origin cardId.")
XCTAssertEqual(transaction.origin!.accountType, "biz", "Failed: Wrong transaction origin accountType.")
XCTAssertEqual(transaction.origin!.amount, "0.1", "Failed: Wrong transaction origin amount.")
XCTAssertEqual(transaction.origin!.base, "0.1", "Failed: Wrong transaction origin base.")
XCTAssertEqual(transaction.origin!.commission, "0.00", "Failed: Wrong transaction origin comission.")
XCTAssertEqual(transaction.origin!.currency, "BTC", "Failed: Wrong transaction origin currency.")
XCTAssertEqual(transaction.origin!.description, "Foo Bar", "Failed: Wrong transaction origin description.")
XCTAssertEqual(transaction.origin!.fee, "0.00", "Failed: Wrong transaction origin fee.")
XCTAssertEqual(transaction.origin!.rate, "1.00", "Failed: Wrong transaction origin rate.")
XCTAssertEqual(transaction.origin!.type, "card", "Failed: Wrong transaction origin type.")
XCTAssertEqual(transaction.origin!.username, "foobar", "Failed: Wrong transaction origin username.")
XCTAssertEqual(transaction.params!.currency, "BTC", "Failed: Wrong transaction parameter currency.")
XCTAssertEqual(transaction.params!.margin, "0.00", "Failed: Wrong transaction parameter margin.")
XCTAssertEqual(transaction.params!.pair, "BTCBTC", "Failed: Wrong transaction parameter pair.")
XCTAssertEqual(transaction.params!.rate, "1.00", "Failed: Wrong transaction parameter rate.")
XCTAssertEqual(transaction.params!.refunds, "fizbiz", "Failed: Wrong transaction parameter refunds.")
XCTAssertEqual(transaction.params!.ttl, 30000, "Failed: Wrong transaction parameter ttl.")
XCTAssertEqual(transaction.params!.type, "invite", "Failed: Wrong transaction parameter type.")
XCTAssertEqual(transaction.refundedById, "foobiz", "Failed: Wrong transaction refundedById.")
XCTAssertEqual(transaction.status, "pending", "Failed: Wrong transaction status.")
XCTAssertEqual(transaction.type, "transfer", "Failed: Wrong transaction type.")
Expand Down Expand Up @@ -192,6 +192,22 @@ class CardTest: UpholdTestCase {
wait()
}

func testCreateTransactionWithCommitShouldReturnTheTransaction() {
let card: Card = Fixtures.loadCard(nil)
card.adapter = MockRestAdapter(body: "{ \"id\": \"foobar\" }")
let expectation = expectationWithDescription("Card test: create transaction.")
let transactionDenominationRequest = TransactionDenominationRequest(amount: "foo", currency: "bar")
let transactionRequest = TransactionRequest(denomination: transactionDenominationRequest, destination: "foobar")

card.createTransaction(true, transactionRequest: transactionRequest).then { (transaction: Transaction) -> () in
XCTAssertEqual(transaction.id, "foobar", "Failed: Wrong transaction id.")

expectation.fulfill()
}

wait()
}

func testGetTransactionsShouldReturnTheArrayOfTransactions() {
let card: Card = Fixtures.loadCard(nil)
let transactions: [Transaction] = [Fixtures.loadTransaction(["transactionId": "foobar"]), Fixtures.loadTransaction(["transactionId": "foobiz"])]
Expand Down
Loading

0 comments on commit ed25d31

Please sign in to comment.