From 9867003c74677613a11c5e0a9dafb1eaa4ac6bb5 Mon Sep 17 00:00:00 2001 From: Adam Young Date: Tue, 5 Nov 2024 21:02:41 +0000 Subject: [PATCH] BUG: Fix model decoding errors --- Sources/TMDb/Domain/Models/Company.swift | 45 +++++++++++++++++-- .../TMDb/Domain/Models/PersonListItem.swift | 4 +- .../Domain/Models/CompanyTests.swift | 4 +- .../Mocks/Models/Company+Mocks.swift | 6 +-- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/Sources/TMDb/Domain/Models/Company.swift b/Sources/TMDb/Domain/Models/Company.swift index 8624899b..c9b8af6e 100644 --- a/Sources/TMDb/Domain/Models/Company.swift +++ b/Sources/TMDb/Domain/Models/Company.swift @@ -47,7 +47,7 @@ public struct Company: Identifiable, Codable, Equatable, Hashable, Sendable { /// /// Company's homepage. /// - public let homepage: URL + public let homepageURL: URL? /// /// Company's logo path. @@ -74,7 +74,7 @@ public struct Company: Identifiable, Codable, Equatable, Hashable, Sendable { /// - name: Company name. /// - description: Description of company. /// - headquarters: Location of the company's headquarters. - /// - homepage: Company's homepage. + /// - homepageURL: Company's homepage. /// - logoPath: Company's logo path. /// - originCountry: Origin country. /// - parentCompany: Parent company. @@ -84,7 +84,7 @@ public struct Company: Identifiable, Codable, Equatable, Hashable, Sendable { name: String, description: String, headquarters: String, - homepage: URL, + homepageURL: URL? = nil, logoPath: URL, originCountry: String, parentCompany: Parent? = nil @@ -93,7 +93,7 @@ public struct Company: Identifiable, Codable, Equatable, Hashable, Sendable { self.name = name self.description = description self.headquarters = headquarters - self.homepage = homepage + self.homepageURL = homepageURL self.logoPath = logoPath self.originCountry = originCountry self.parentCompany = parentCompany @@ -101,6 +101,43 @@ public struct Company: Identifiable, Codable, Equatable, Hashable, Sendable { } +extension Company { + + private enum CodingKeys: String, CodingKey { + case id + case name + case description + case headquarters + case homepageURL = "homepage" + case logoPath + case originCountry + case parentCompany + } + + public init(from decoder: any Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let container2 = try decoder.container(keyedBy: CodingKeys.self) + + self.id = try container.decode(Int.self, forKey: .id) + self.name = try container.decode(String.self, forKey: .name) + self.description = try container.decode(String.self, forKey: .description) + self.headquarters = try container.decode(String.self, forKey: .headquarters) + // Need to deal with empty strings - URL decoding will fail with an empty string + let homepageURLString = try container.decodeIfPresent(String.self, forKey: .homepageURL) + self.homepageURL = try { + guard let homepageURLString, !homepageURLString.isEmpty else { + return nil + } + + return try container2.decodeIfPresent(URL.self, forKey: .homepageURL) + }() + self.logoPath = try container.decode(URL.self, forKey: .logoPath) + self.originCountry = try container.decode(String.self, forKey: .originCountry) + self.parentCompany = try container.decodeIfPresent(Parent.self, forKey: .parentCompany) + } + +} + public extension Company { /// diff --git a/Sources/TMDb/Domain/Models/PersonListItem.swift b/Sources/TMDb/Domain/Models/PersonListItem.swift index 536128bb..4a6bd479 100644 --- a/Sources/TMDb/Domain/Models/PersonListItem.swift +++ b/Sources/TMDb/Domain/Models/PersonListItem.swift @@ -64,7 +64,7 @@ public struct PersonListItem: Identifiable, Codable, Equatable, Hashable, Sendab /// /// Person's movies and TV series they're known for. /// - public let knownFor: [Show] + public let knownFor: [Show]? /// /// Is the Person only suitable for adults. @@ -93,7 +93,7 @@ public struct PersonListItem: Identifiable, Codable, Equatable, Hashable, Sendab gender: Gender, profilePath: URL? = nil, popularity: Double? = nil, - knownFor: [Show] = [], + knownFor: [Show]? = nil, isAdultOnly: Bool = false ) { self.id = id diff --git a/Tests/TMDbTests/Domain/Models/CompanyTests.swift b/Tests/TMDbTests/Domain/Models/CompanyTests.swift index 6b084a8d..e1486931 100644 --- a/Tests/TMDbTests/Domain/Models/CompanyTests.swift +++ b/Tests/TMDbTests/Domain/Models/CompanyTests.swift @@ -32,7 +32,7 @@ struct CompanyTests { #expect(result.name == company.name) #expect(result.description == company.description) #expect(result.headquarters == company.headquarters) - #expect(result.homepage == company.homepage) + #expect(result.homepageURL == company.homepageURL) #expect(result.logoPath == company.logoPath) #expect(result.originCountry == company.originCountry) let parentCompany = try #require(result.parentCompany) @@ -46,7 +46,7 @@ struct CompanyTests { name: "Pixar", description: "", headquarters: "Emeryville, California", - homepage: URL(string: "http://www.pixar.com")!, + homepageURL: URL(string: "http://www.pixar.com")!, logoPath: URL(string: "/1TjvGVDMYsj6JBxOAkUHpPEwLf7.png")!, originCountry: "US", parentCompany: Company.Parent( diff --git a/Tests/TMDbTests/Mocks/Models/Company+Mocks.swift b/Tests/TMDbTests/Mocks/Models/Company+Mocks.swift index 38447e8d..6b58c4ce 100644 --- a/Tests/TMDbTests/Mocks/Models/Company+Mocks.swift +++ b/Tests/TMDbTests/Mocks/Models/Company+Mocks.swift @@ -27,7 +27,7 @@ extension Company { name: String = .randomString, description: String = .randomString, headquarters: String = .randomString, - homepage: URL = .randomWebSite, + homepageURL: URL = .randomWebSite, logoPath: URL = .randomImagePath, originCountry: String = "US", parentCompany: Company.Parent? = nil @@ -37,7 +37,7 @@ extension Company { name: name, description: description, headquarters: headquarters, - homepage: homepage, + homepageURL: homepageURL, logoPath: logoPath, originCountry: originCountry, parentCompany: parentCompany @@ -50,7 +50,7 @@ extension Company { name: "Lucasfilm Ltd.", description: "Some description", headquarters: "San Francisco, California", - homepage: URL(string: "https://www.lucasfilm.com")!, + homepageURL: URL(string: "https://www.lucasfilm.com")!, logoPath: URL(string: "/o86DbpburjxrqAzEDhXZcyE8pDb.png")!, originCountry: "US" )