Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

Commit

Permalink
feat: add Cancel (#100)
Browse files Browse the repository at this point in the history
* add `Cancel`

* add `createCancel` in `DevTools`

* update `CloseTests` to always make pfi the sender

* add `CancelTests`
  • Loading branch information
ethanwlee authored Aug 8, 2024
1 parent 1234102 commit 0e23e5d
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 11 deletions.
38 changes: 37 additions & 1 deletion Sources/tbDEX/Protocol/DevTools.swift
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,43 @@ enum DevTools {
}
}

/// Creates a mock `Cancel`. Optionally override the `CancelData`
/// - Parameters:
/// - from: The DID the `Cancel` should be from. Included in the metadata.
/// - to: The DID the `Cancel` should be sent to. Included in the metadata.
/// - exchangeID: The exchangeID of the associated exchange. Included in the metadata.
/// - protocol: Optional. The protocol version to use if different from the default. Included in the metadata.
/// - Returns: The `Cancel`
static func createCancel(
from: String,
to: String,
exchangeID: String = "exchange_123",
data: CancelData? = nil,
protocol: String? = nil
) -> Cancel {
let cancelData = data ?? CancelData(
reason: "test reason"
)

if let `protocol` = `protocol` {
return Cancel(
from: from,
to: to,
exchangeID: exchangeID,
data: cancelData,
protocol: `protocol`
)
} else {
return Cancel(
from: from,
to: to,
exchangeID: exchangeID,
data: cancelData
)
}
}


/// Creates a mock `Close`. Optionally override the `CloseData`
/// - Parameters:
/// - from: The DID the `Close` should be from. Included in the metadata.
Expand Down Expand Up @@ -305,7 +342,6 @@ enum DevTools {
data: closeData
)
}

}
}

Expand Down
1 change: 1 addition & 0 deletions Sources/tbDEX/Protocol/Models/Message.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public struct Message<D: MessageData>: Codable, Equatable {
/// [Specification Reference](https://github.com/TBD54566975/tbdex/tree/main/specs/protocol#message-kinds)
public enum MessageKind: String, Codable {
case rfq
case cancel
case close
case quote
case order
Expand Down
3 changes: 3 additions & 0 deletions Sources/tbDEX/Protocol/Models/Messages/AnyMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Foundation
/// Example: When calling an endpoint that returns `Message`s, but it's impossible to know exactly
/// what kind of `Message` it is until the JSON response is parsed.
public enum AnyMessage {
case cancel(Cancel)
case close(Close)
case order(Order)
case orderInstructions(OrderInstructions)
Expand Down Expand Up @@ -55,6 +56,8 @@ extension AnyMessage: Decodable {

// Decode the message itself into it's strongly-typed representation, indicated by the `metadata.kind` field
switch metadata.kind {
case .cancel:
self = .cancel(try container.decode(Cancel.self))
case .close:
self = .close(try container.decode(Close.self))
case .order:
Expand Down
24 changes: 24 additions & 0 deletions Sources/tbDEX/Protocol/Models/Messages/Cancel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation

public typealias Cancel = Message<CancelData>

/// Data that makes up a Cancel Message.
///
/// [Specification Reference](https://github.com/TBD54566975/tbdex/blob/main/specs/protocol/README.md#cancel)
public struct CancelData: MessageData {

/// An explanation of why the exchange is being cancelled
public let reason: String?

/// Returns the MessageKind of cancel
public func kind() -> MessageKind {
return .cancel
}

/// Default Initializer
public init(
reason: String? = nil
) {
self.reason = reason
}
}
53 changes: 53 additions & 0 deletions Tests/tbDEXTests/Protocol/Models/Messages/CancelTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Web5
import XCTest

@testable import tbDEX

final class CancelTests: XCTestCase {

let did = try! DIDJWK.create(keyManager: InMemoryKeyManager())
let pfi = try! DIDJWK.create(keyManager: InMemoryKeyManager())

func test_init() {
let cancel = DevTools.createCancel(from: did.uri, to: pfi.uri)

XCTAssertEqual(cancel.metadata.id.prefix, "cancel")
XCTAssertEqual(cancel.metadata.from, did.uri)
XCTAssertEqual(cancel.metadata.to, pfi.uri)
XCTAssertEqual(cancel.metadata.exchangeID, "exchange_123")
XCTAssertEqual(cancel.data.reason, "test reason")
XCTAssertEqual(cancel.metadata.protocol, "1.0")
}

func test_overrideProtocolVersion() {
let cancel = DevTools.createCancel(
from: did.uri,
to: pfi.uri,
protocol: "2.0"
)

XCTAssertEqual(cancel.metadata.protocol, "2.0")
}

func test_signSuccess() async throws {
var cancel = DevTools.createCancel(from: did.uri, to: pfi.uri)

XCTAssertNil(cancel.signature)
try cancel.sign(did: did)
XCTAssertNotNil(cancel.signature)
}

func test_verifySuccess() async throws {
var cancel = DevTools.createCancel(from: did.uri, to: pfi.uri)
try cancel.sign(did: did)

let isValid = try await cancel.verify()
XCTAssertTrue(isValid)
}

func test_verifyWithoutSigningFailure() async throws {
let cancel = DevTools.createCancel(from: did.uri, to: pfi.uri)

await XCTAssertThrowsErrorAsync(try await cancel.verify())
}
}
20 changes: 10 additions & 10 deletions Tests/tbDEXTests/Protocol/Models/Messages/CloseTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ final class CloseTests: XCTestCase {
let pfi = try! DIDJWK.create(keyManager: InMemoryKeyManager())

func test_init() {
let close = DevTools.createClose(from: did.uri, to: pfi.uri)
let close = DevTools.createClose(from: pfi.uri, to: did.uri)

XCTAssertEqual(close.metadata.id.prefix, "close")
XCTAssertEqual(close.metadata.from, did.uri)
XCTAssertEqual(close.metadata.to, pfi.uri)
XCTAssertEqual(close.metadata.from, pfi.uri)
XCTAssertEqual(close.metadata.to, did.uri)
XCTAssertEqual(close.metadata.exchangeID, "exchange_123")
XCTAssertEqual(close.data.reason, "test reason")
XCTAssertEqual(close.metadata.protocol, "1.0")
Expand All @@ -22,32 +22,32 @@ final class CloseTests: XCTestCase {

func test_overrideProtocolVersion() {
let close = DevTools.createClose(
from: did.uri,
to: pfi.uri,
from: pfi.uri,
to: did.uri,
protocol: "2.0"
)

XCTAssertEqual(close.metadata.protocol, "2.0")
}

func test_signSuccess() async throws {
var close = DevTools.createClose(from: did.uri, to: pfi.uri)
var close = DevTools.createClose(from: pfi.uri, to: did.uri)

XCTAssertNil(close.signature)
try close.sign(did: did)
try close.sign(did: pfi)
XCTAssertNotNil(close.signature)
}

func test_verifySuccess() async throws {
var close = DevTools.createClose(from: did.uri, to: pfi.uri)
try close.sign(did: did)
var close = DevTools.createClose(from: pfi.uri, to: did.uri)
try close.sign(did: pfi)

let isValid = try await close.verify()
XCTAssertTrue(isValid)
}

func test_verifyWithoutSigningFailure() async throws {
let close = DevTools.createClose(from: did.uri, to: pfi.uri)
let close = DevTools.createClose(from: pfi.uri, to: did.uri)

await XCTAssertThrowsErrorAsync(try await close.verify())
}
Expand Down

0 comments on commit 0e23e5d

Please sign in to comment.