diff --git a/Sources/AmiiboService/Public/Models/Amiibo.swift b/Sources/AmiiboService/Public/Models/Amiibo.swift index 239bc8e..a158943 100644 --- a/Sources/AmiiboService/Public/Models/Amiibo.swift +++ b/Sources/AmiiboService/Public/Models/Amiibo.swift @@ -52,7 +52,32 @@ public struct Amiibo: Sendable, Hashable { public let type: String // MARK: Initializers - + + /// Initializes this model. + package init( + head: String, + tail: String, + name: String, + type: String, + series: String, + gameCharacter: String, + gameSeries: String, + image: String, + release: Release = .init(), + platform: Platform? = nil + ) { + self.gameCharacter = gameCharacter + self.gameSeries = gameSeries + self.head = head + self.image = image + self.name = name + self.platform = platform + self.release = release + self.series = series + self.tail = tail + self.type = type + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: Components.Schemas.Amiibo) { diff --git a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Game.swift b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Game.swift index 2fa719a..84bb9ea 100644 --- a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Game.swift +++ b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Game.swift @@ -29,6 +29,17 @@ extension Amiibo { // MARK: Initializers + /// Initializes this model. + package init( + identifiers: [String], + name: String, + usages: [Usage]? = nil + ) { + self.identifiers = identifiers + self.name = name + self.usages = usages + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: Components.Schemas.AmiiboGame) { diff --git a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Platform.swift b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Platform.swift index 88e548f..22b8af6 100644 --- a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Platform.swift +++ b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Platform.swift @@ -31,8 +31,21 @@ extension Amiibo { public let wiiU: [Game] // MARK: Initializers - + /// Initializes this model. + package init( + `switch`: [Game] = [], + switch2: [Game] = [], + threeDS: [Game] = [], + wiiU: [Game] = [] + ) { + self.switch = `switch` + self.switch2 = switch2 + self.threeDS = threeDS + self.wiiU = wiiU + } + + /// Initializes this model from the given payloads. /// /// > important: In case no data is provided, then an instance of this model is not created. /// diff --git a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Release.swift b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Release.swift index 627e5b7..109c5e2 100644 --- a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Release.swift +++ b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Release.swift @@ -36,6 +36,19 @@ extension Amiibo { // MARK: Initializers + /// Initializes this model. + package init( + america: Date? = nil, + australia: Date? = nil, + europe: Date? = nil, + japan: Date? = nil + ) { + self.america = america + self.australia = australia + self.europe = europe + self.japan = japan + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: Components.Schemas.AmiiboRelease) { diff --git a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Usage.swift b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Usage.swift index a04fbda..ca9ca08 100644 --- a/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Usage.swift +++ b/Sources/AmiiboService/Public/Models/Amiibo/Amiibo+Usage.swift @@ -26,6 +26,12 @@ extension Amiibo { // MARK: Initializers + /// Initializes this model. + package init(explanation: String, isWriteable: Bool) { + self.explanation = explanation + self.isWriteable = isWriteable + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: Components.Schemas.AmiiboUsage) { diff --git a/Sources/AmiiboService/Public/Models/AmiiboSeries.swift b/Sources/AmiiboService/Public/Models/AmiiboSeries.swift index 27128ee..21986fb 100644 --- a/Sources/AmiiboService/Public/Models/AmiiboSeries.swift +++ b/Sources/AmiiboService/Public/Models/AmiiboSeries.swift @@ -24,7 +24,13 @@ public struct AmiiboSeries: KeyNameModel { public let name: String // MARK: Initializers - + + /// Initializes this model. + package init(key: String, name: String) { + self.key = key + self.name = name + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: some KeyNamePayload) { diff --git a/Sources/AmiiboService/Public/Models/AmiiboType.swift b/Sources/AmiiboService/Public/Models/AmiiboType.swift index f2d1a38..8067b4d 100644 --- a/Sources/AmiiboService/Public/Models/AmiiboType.swift +++ b/Sources/AmiiboService/Public/Models/AmiiboType.swift @@ -24,7 +24,13 @@ public struct AmiiboType: KeyNameModel { public let name: String // MARK: Initializers - + + /// Initializes this model. + package init(key: String, name: String) { + self.key = key + self.name = name + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: some KeyNamePayload) { diff --git a/Sources/AmiiboService/Public/Models/GameCharacter.swift b/Sources/AmiiboService/Public/Models/GameCharacter.swift index e3c2020..bcf2229 100644 --- a/Sources/AmiiboService/Public/Models/GameCharacter.swift +++ b/Sources/AmiiboService/Public/Models/GameCharacter.swift @@ -25,6 +25,12 @@ public struct GameCharacter: KeyNameModel { // MARK: Initializers + /// Initializes this model. + package init(key: String, name: String) { + self.key = key + self.name = name + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: some KeyNamePayload) { diff --git a/Sources/AmiiboService/Public/Models/GameSeries.swift b/Sources/AmiiboService/Public/Models/GameSeries.swift index 120c5c7..7150394 100644 --- a/Sources/AmiiboService/Public/Models/GameSeries.swift +++ b/Sources/AmiiboService/Public/Models/GameSeries.swift @@ -24,7 +24,13 @@ public struct GameSeries: KeyNameModel { public let name: String // MARK: Initializers - + + /// Initializes this model. + package init(key: String, name: String) { + self.key = key + self.name = name + } + /// Initializes this model from a given payload. /// - Parameter payload: A payload that contains the values for the model. init(_ payload: some KeyNamePayload) { diff --git a/Tests/AmiiboService/Cases/Public/Services/AmiiboServiceMockTests.swift b/Tests/AmiiboService/Cases/Public/Services/AmiiboServiceMockTests.swift index 3cdf2f7..e1a4373 100644 --- a/Tests/AmiiboService/Cases/Public/Services/AmiiboServiceMockTests.swift +++ b/Tests/AmiiboService/Cases/Public/Services/AmiiboServiceMockTests.swift @@ -32,7 +32,21 @@ struct AmiiboServiceMockTests { // THEN #expect(amiibos.isEmpty) } - + + @Test("returns amiibos when mock provides a list") + func getAmiibosList() async throws { + // GIVEN + let service = AmiiboService(client: AmiiboMockClient(amiibos: Fixtures.amiibos)) + + // WHEN + let amiibos = try await service.getAmiibos() + + // THEN + #expect(amiibos == Fixtures.amiibos) + #expect(amiibos.first?.identifier == "0100000000040002") + #expect(amiibos.first?.imageURL != nil) + } + @Test("throws notFound when mock provides no amiibos") func getAmiibosNotFound() async { // GIVEN @@ -70,7 +84,19 @@ struct AmiiboServiceMockTests { // THEN #expect(amiiboSeries.isEmpty) } - + + @Test("returns amiibo series when mock provides a list") + func getAmiiboSeriesList() async throws { + // GIVEN + let service = AmiiboService(client: AmiiboMockClient(amiiboSeries: Fixtures.amiiboSeries)) + + // WHEN + let amiiboSeries = try await service.getAmiiboSeries() + + // THEN + #expect(amiiboSeries == Fixtures.amiiboSeries) + } + @Test("throws notFound when mock provides no amiibo series") func getAmiiboSeriesNotFound() async { // GIVEN @@ -108,7 +134,19 @@ struct AmiiboServiceMockTests { // THEN #expect(amiiboTypes.isEmpty) } - + + @Test("returns amiibo types when mock provides a list") + func getAmiiboTypesList() async throws { + // GIVEN + let service = AmiiboService(client: AmiiboMockClient(amiiboTypes: Fixtures.amiiboTypes)) + + // WHEN + let amiiboTypes = try await service.getAmiiboTypes() + + // THEN + #expect(amiiboTypes == Fixtures.amiiboTypes) + } + @Test("throws notFound when mock provides no amiibo types") func getAmiiboTypesNotFound() async { // GIVEN @@ -146,7 +184,19 @@ struct AmiiboServiceMockTests { // THEN #expect(gameCharacters.isEmpty) } - + + @Test("returns game characters when mock provides a list") + func getGameCharactersList() async throws { + // GIVEN + let service = AmiiboService(client: AmiiboMockClient(gameCharacters: Fixtures.gameCharacters)) + + // WHEN + let gameCharacters = try await service.getGameCharacters() + + // THEN + #expect(gameCharacters == Fixtures.gameCharacters) + } + @Test("throws notFound when mock provides no game characters") func getGameCharactersNotFound() async { // GIVEN @@ -184,7 +234,19 @@ struct AmiiboServiceMockTests { // THEN #expect(gameSeries.isEmpty) } - + + @Test("returns game series when mock provides a list") + func getGameSeriesList() async throws { + // GIVEN + let service = AmiiboService(client: AmiiboMockClient(gameSeries: Fixtures.gameSeries)) + + // WHEN + let gameSeries = try await service.getGameSeries() + + // THEN + #expect(gameSeries == Fixtures.gameSeries) + } + @Test("throws notFound when mock provides no game series") func getGameSeriesNotFound() async { // GIVEN @@ -264,3 +326,71 @@ private enum Errors { .unknown("An underlying error description.") ] } + +private enum Fixtures { + /// Amiibo items; the first one has release dates and related games with usages. + static let amiibos: [Amiibo] = [ + .init( + head: "01000000", + tail: "00040002", + name: "Zelda", + type: "Figure", + series: "Super Smash Bros.", + gameCharacter: "Zelda", + gameSeries: "The Legend of Zelda", + image: "https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/images/icon_01000000-00040002.png", + release: .init( + america: Date(timeIntervalSince1970: 1_416_441_600), + australia: Date(timeIntervalSince1970: 1_417_564_800), + europe: Date(timeIntervalSince1970: 1_417_132_800), + japan: Date(timeIntervalSince1970: 1_417_564_800) + ), + platform: .init( + switch: [ + .init( + identifiers: ["01007EF00011E000"], + name: "The Legend of Zelda: Breath of the Wild", + usages: [.init(explanation: "Spawns a random selection of items.", isWriteable: false)] + ) + ], + wiiU: [ + .init( + identifiers: ["0005000010145000"], + name: "Super Smash Bros. for Wii U", + usages: [.init(explanation: "Unlocks a figure player.", isWriteable: true)] + ) + ] + ) + ), + .init( + head: "00000000", + tail: "00000002", + name: "Mario", + type: "Figure", + series: "Super Smash Bros.", + gameCharacter: "Mario", + gameSeries: "Super Mario", + image: "https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/images/icon_00000000-00000002.png" + ) + ] + /// Amiibo series. + static let amiiboSeries: [AmiiboSeries] = [ + .init(key: "0x00", name: "Super Smash Bros."), + .init(key: "0x01", name: "Super Mario") + ] + /// Amiibo types. + static let amiiboTypes: [AmiiboType] = [ + .init(key: "0x00", name: "Figure"), + .init(key: "0x01", name: "Card") + ] + /// Game characters. + static let gameCharacters: [GameCharacter] = [ + .init(key: "0x0000", name: "Mario"), + .init(key: "0x0100", name: "Zelda") + ] + /// Game series. + static let gameSeries: [GameSeries] = [ + .init(key: "0x000", name: "Super Mario"), + .init(key: "0x010", name: "The Legend of Zelda") + ] +}