From 91ee53e3899aca998eb9658111c498833ba545ee Mon Sep 17 00:00:00 2001 From: Cassius Pacheco Date: Mon, 14 Nov 2022 16:41:08 +1100 Subject: [PATCH] feat: expose mint api methods - Get details of a mint with the given ID - Get a list of mints --- Sources/ImmutableXCore/ImmutableX.swift | 79 ++++++++++++++++++- .../ImmutableXCoreTests/ImmutableXTests.swift | 45 ++++++++++- .../Mocks/API/MintsAPIMock.swift | 71 +++++++++++++++++ .../Mocks/Stubs/Models.swift | 14 ++++ 4 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 Tests/ImmutableXCoreTests/Mocks/API/MintsAPIMock.swift diff --git a/Sources/ImmutableXCore/ImmutableX.swift b/Sources/ImmutableXCore/ImmutableX.swift index 196d9e5..ad8907e 100644 --- a/Sources/ImmutableXCore/ImmutableX.swift +++ b/Sources/ImmutableXCore/ImmutableX.swift @@ -42,6 +42,7 @@ public struct ImmutableX { private let collectionsAPI: CollectionsAPI.Type private let projectsAPI: ProjectsAPI.Type private let balancesAPI: BalancesAPI.Type + private let mintsAPI: MintsAPI.Type /// Internal init method that includes dependencies. For the public facing API use ``initialize(base:logLevel:)`` /// instead. @@ -59,7 +60,8 @@ public struct ImmutableX { assetsAPI: AssetsAPI.Type = AssetsAPI.self, collectionsAPI: CollectionsAPI.Type = CollectionsAPI.self, projectsAPI: ProjectsAPI.Type = ProjectsAPI.self, - balancesAPI: BalancesAPI.Type = BalancesAPI.self + balancesAPI: BalancesAPI.Type = BalancesAPI.self, + mintsAPI: MintsAPI.Type = MintsAPI.self ) { self.base = base self.logLevel = logLevel @@ -75,6 +77,7 @@ public struct ImmutableX { self.collectionsAPI = collectionsAPI self.projectsAPI = projectsAPI self.balancesAPI = balancesAPI + self.mintsAPI = mintsAPI } /// Initializes the SDK with the given ``base`` and ``logLevel`` by assigning a shared instance accessible via @@ -490,4 +493,78 @@ public struct ImmutableX { try await self.balancesAPI.listBalances(owner: owner) } } + + /// Get details of a mint with the given ID + /// + /// - Parameter id: Mint ID. This is the transaction_id returned from listMints + /// - Returns: ``Mint`` + /// - Throws: A variation of ``ImmutableXError`` + public func getMint(id: String) async throws -> Mint { + try await APIErrorMapper.map(caller: "Get Mint") { + try await self.mintsAPI.getMint(id: id) + } + } + + /// Get a list of mints + /// + /// - Parameters: + /// - pageSize: Page size of the result (optional) + /// - cursor: Cursor (optional) + /// - orderBy: Property to sort by (optional) + /// - direction: Direction to sort (asc/desc) (optional) + /// - user: Ethereum address of the user who submitted this mint (optional) + /// - status: Status of this mint (optional) + /// - minTimestamp: Minimum timestamp for this mint, in ISO 8601 UTC format. + /// Example: '2022-05-27T00:10:22Z' (optional) + /// - maxTimestamp: Maximum timestamp for this mint, in ISO 8601 UTC format. + /// Example: '2022-05-27T00:10:22Z' (optional) + /// - tokenType: Token type of the minted asset (optional) + /// - tokenId: ERC721 Token ID of the minted asset (optional) + /// - assetId: Internal IMX ID of the minted asset (optional) + /// - tokenName: Token Name of the minted asset (optional) + /// - tokenAddress: Token address of the minted asset (optional) + /// - minQuantity: Min quantity for the minted asset (optional) + /// - maxQuantity: Max quantity for the minted asset (optional) + /// - metadata: JSON-encoded metadata filters for the minted asset (optional) + /// - Returns: ``ListMintsResponse`` + /// - Throws: A variation of ``ImmutableXError`` + public func listMints( + pageSize: Int? = nil, + cursor: String? = nil, + orderBy: String? = nil, + direction: String? = nil, + user: String? = nil, + status: String? = nil, + minTimestamp: String? = nil, + maxTimestamp: String? = nil, + tokenType: String? = nil, + tokenId: String? = nil, + assetId: String? = nil, + tokenName: String? = nil, + tokenAddress: String? = nil, + minQuantity: String? = nil, + maxQuantity: String? = nil, + metadata: String? = nil + ) async throws -> ListMintsResponse { + try await APIErrorMapper.map(caller: "List Mints") { + try await self.mintsAPI.listMints( + pageSize: pageSize, + cursor: cursor, + orderBy: orderBy, + direction: direction, + user: user, + status: status, + minTimestamp: minTimestamp, + maxTimestamp: maxTimestamp, + tokenType: tokenType, + tokenId: tokenId, + assetId: assetId, + tokenName: tokenName, + tokenAddress: tokenAddress, + minQuantity: minQuantity, + maxQuantity: maxQuantity, + metadata: metadata + ) + } + } } diff --git a/Tests/ImmutableXCoreTests/ImmutableXTests.swift b/Tests/ImmutableXCoreTests/ImmutableXTests.swift index 125793a..3d9924f 100644 --- a/Tests/ImmutableXCoreTests/ImmutableXTests.swift +++ b/Tests/ImmutableXCoreTests/ImmutableXTests.swift @@ -14,6 +14,7 @@ final class ImmutableXTests: XCTestCase { let collectionsAPIMock = CollectionsAPIMock.self let projectsAPIMock = ProjectsAPIMock.self let balancesAPIMock = BalancesAPIMock.self + let mintsAPIMock = MintsAPIMock.self lazy var core = ImmutableX( buyWorkflow: buyWorkflow, @@ -27,7 +28,8 @@ final class ImmutableXTests: XCTestCase { assetsAPI: assetsAPIMock, collectionsAPI: collectionsAPIMock, projectsAPI: projectsAPIMock, - balancesAPI: balancesAPIMock + balancesAPI: balancesAPIMock, + mintsAPI: mintsAPIMock ) override func setUp() { @@ -44,6 +46,7 @@ final class ImmutableXTests: XCTestCase { collectionsAPIMock.resetMock() projectsAPIMock.resetMock() balancesAPIMock.resetMock() + mintsAPIMock.resetMock() ImmutableX.initialize() @@ -118,6 +121,14 @@ final class ImmutableXTests: XCTestCase { let listBalancesCompanion = BalancesAPIMock.ListBalancesCompanion() listBalancesCompanion.returnValue = listBalancesResponseStub1 balancesAPIMock.mock(listBalancesCompanion) + + let getMintCompanion = MintsAPIMock.GetMintCompanion() + getMintCompanion.returnValue = mintStub1 + mintsAPIMock.mock(getMintCompanion) + + let listMintsCompanion = MintsAPIMock.ListMintsCompanion() + listMintsCompanion.returnValue = listMintsResponseStub1 + mintsAPIMock.mock(listMintsCompanion) } func testSdkVersion() { @@ -428,4 +439,36 @@ final class ImmutableXTests: XCTestCase { _ = try await core.listBalances(owner: "owner") } } + + // MARK: - Mint + + func testGetMintSuccess() async throws { + let response = try await core.getMint(id: "id") + XCTAssertEqual(response, mintStub1) + } + + func testGetMintFailure() async { + let companion = MintsAPIMock.GetMintCompanion() + companion.throwableError = DummyError.something + mintsAPIMock.mock(companion) + + await XCTAssertThrowsErrorAsync { + _ = try await core.getMint(id: "id") + } + } + + func testListMintsSuccess() async throws { + let response = try await core.listMints() + XCTAssertEqual(response, listMintsResponseStub1) + } + + func testListMintsFailure() async { + let companion = MintsAPIMock.ListMintsCompanion() + companion.throwableError = DummyError.something + mintsAPIMock.mock(companion) + + await XCTAssertThrowsErrorAsync { + _ = try await core.listMints() + } + } } diff --git a/Tests/ImmutableXCoreTests/Mocks/API/MintsAPIMock.swift b/Tests/ImmutableXCoreTests/Mocks/API/MintsAPIMock.swift new file mode 100644 index 0000000..7e2da25 --- /dev/null +++ b/Tests/ImmutableXCoreTests/Mocks/API/MintsAPIMock.swift @@ -0,0 +1,71 @@ +import Foundation +@testable import ImmutableXCore + +final class MintsAPIMock: MintsAPI { + class GetMintCompanion { + var throwableError: Error? + var callsCount = 0 + var returnValue: Mint! + } + + class ListMintsCompanion { + var throwableError: Error? + var callsCount = 0 + var returnValue: ListMintsResponse! + } + + static var getMintCompanion: GetMintCompanion? + static var listMintsCompanion: ListMintsCompanion? + + static func mock(_ companion: GetMintCompanion) { + getMintCompanion = companion + } + + static func mock(_ companion: ListMintsCompanion) { + listMintsCompanion = companion + } + + static func resetMock() { + getMintCompanion = nil + listMintsCompanion = nil + } + + override class func getMint(id: String) async throws -> Mint { + let companion = getMintCompanion! + companion.callsCount += 1 + + if let error = companion.throwableError { + throw error + } + + return companion.returnValue + } + + override class func listMints( + pageSize: Int? = nil, + cursor: String? = nil, + orderBy: String? = nil, + direction: String? = nil, + user: String? = nil, + status: String? = nil, + minTimestamp: String? = nil, + maxTimestamp: String? = nil, + tokenType: String? = nil, + tokenId: String? = nil, + assetId: String? = nil, + tokenName: String? = nil, + tokenAddress: String? = nil, + minQuantity: String? = nil, + maxQuantity: String? = nil, + metadata: String? = nil + ) async throws -> ListMintsResponse { + let companion = listMintsCompanion! + companion.callsCount += 1 + + if let error = companion.throwableError { + throw error + } + + return companion.returnValue + } +} diff --git a/Tests/ImmutableXCoreTests/Mocks/Stubs/Models.swift b/Tests/ImmutableXCoreTests/Mocks/Stubs/Models.swift index b72fb1b..fd238e0 100644 --- a/Tests/ImmutableXCoreTests/Mocks/Stubs/Models.swift +++ b/Tests/ImmutableXCoreTests/Mocks/Stubs/Models.swift @@ -270,3 +270,17 @@ let listBalancesResponseStub1 = ListBalancesResponse( cursor: "", result: [balanceStub1] ) + +let mintStub1 = Mint( + status: "status", + timestamp: "", + token: tokenETHStub1, + transactionId: 1, + user: "user" +) + +let listMintsResponseStub1 = ListMintsResponse( + cursor: "", + remaining: 1, + result: [mintStub1] +)