import Foundation import Testing @testable import PediFoods /// Covers the public-locator distance contract documented in /// docs/plans/public-store-distance-consumer.md: the server sends /// `distance` as a number (never null) where `0` means "unavailable", and /// the app collapses that to `nil` so a single representation of "unknown" /// reaches the card label and the max-distance filter. private func decode(_ type: T.Type, _ json: String) throws -> T { try JSONDecoder().decode(T.self, from: Data(json.utf8)) } @Test("PublicStoreListItem decodes the distance field") func publicStoreListItemDecodesDistance() throws { let item = try decode(PublicStoreListItem.self, #"{"id":"1","distance":3.4}"#) #expect(item.distance == 3.4) } /// The field ships on the backend after the app - a response without it /// must still decode rather than throwing. @Test("PublicStoreListItem still decodes a response with no distance field") func publicStoreListItemDecodesWithoutDistance() throws { let item = try decode(PublicStoreListItem.self, #"{"id":"1"}"#) #expect(item.distance == nil) } @Test("PublicStoreDetail decodes the distance field") func publicStoreDetailDecodesDistance() throws { let detail = try decode(PublicStoreDetail.self, #"{"id":"1","distance":1.2}"#) #expect(detail.distance == 1.2) let without = try decode(PublicStoreDetail.self, #"{"id":"1"}"#) #expect(without.distance == nil) } @Test("StoreSummary carries a real public distance through") func storeSummaryKeepsPublicDistance() throws { let item = try decode(PublicStoreListItem.self, #"{"id":"1","name":"A","distance":2.5}"#) #expect(StoreSummary(publicItem: item).distance == 2.5) } @Test("StoreSummary maps the unavailable sentinel and a missing distance to nil") func storeSummaryNormalizesUnavailableDistance() throws { let zero = try decode(PublicStoreListItem.self, #"{"id":"1","name":"A","distance":0}"#) #expect(StoreSummary(publicItem: zero).distance == nil) let absent = try decode(PublicStoreListItem.self, #"{"id":"1","name":"A"}"#) #expect(StoreSummary(publicItem: absent).distance == nil) }