Return response instead of data

This commit is contained in:
cdricms
2025-12-06 17:53:51 +01:00
parent bc1abfdebc
commit fd493ce546
3 changed files with 31 additions and 14 deletions

View File

@@ -20,7 +20,7 @@ public actor OpenFoodFactsClient {
/// - barcode: The product barcode.
/// - fields: Optional list of fields to fetch (optimizes network usage).
public func product(barcode: String, fields: [ProductField]? = nil)
async throws -> Product?
async throws -> ProductResponseEnvelope
{
var url = config.apiURL.appendingPathComponent("/product/\(barcode)")
@@ -48,13 +48,13 @@ public actor OpenFoodFactsClient {
let envelope = try JSONDecoder().decode(
ProductResponseEnvelope.self, from: data)
return envelope.product
return envelope
}
/// Search for products using V2 API.
public func search(
_ parameters: SearchParameter..., fields: [ProductField]? = nil
) async throws -> [Product] {
) async throws -> SearchResponseEnvelope {
guard
var components = URLComponents(
url: config.apiURL.appendingPathComponent("/search"),
@@ -106,7 +106,7 @@ public actor OpenFoodFactsClient {
let envelope = try JSONDecoder().decode(
SearchResponseEnvelope.self, from: data)
return envelope.products ?? []
return envelope
}
// MARK: - Private Helpers
@@ -124,14 +124,26 @@ public enum OFFError: Error {
case invalidURL, invalidResponse
}
// Internal Envelopes for Decoding
struct ProductResponseEnvelope: Decodable {
let code: String?
let product: Product?
let status: Int?
public struct ProductResponseEnvelope: Sendable, Decodable {
public let code: String?
public let product: Product?
public let status: Int?
public let statusVerbose: String?
private enum CodingKeys: String, CodingKey {
case code, product, status
case statusVerbose = "status_verbose"
}
}
struct SearchResponseEnvelope: Decodable {
let count: Int?
let products: [Product]?
public struct SearchResponseEnvelope: Sendable, Decodable {
public let count: Int?
public let page: Int?
public let pageSize: Int?
public let products: [Product]?
private enum CodingKeys: String, CodingKey {
case count, page, products
case pageSize = "page_size"
}
}

View File

@@ -18,11 +18,13 @@ final class OpenFoodFactsTests: XCTestCase {
func testProductFetch() async throws {
// Fetch specific fields only
let product = try await client.product(
let response = try await client.product(
barcode: "3017620422003", // Nutella
fields: [.code, .productName, .nutriscoreGrade, .nutriments]
)
let product = response.product
XCTAssertEqual(product?.code, "3017620422003")
XCTAssertNotNil(product?.productName)
XCTAssertNotNil(product?.nutriscoreGrade)
@@ -31,13 +33,15 @@ final class OpenFoodFactsTests: XCTestCase {
}
func testSearch() async throws {
let results = try await client.search(
let response = try await client.search(
.query("chocolate"),
.tag(tag: .brands, value: "milka"),
.pageSize(5),
.sort(.popularity),
)
let results = response.products ?? []
let jsonResults = try JSONEncoder().encode(results)
try jsonResults.write(to: .init(filePath: "./jsonResults.json"))

1
jsonResults.json Normal file

File diff suppressed because one or more lines are too long