migration

This commit is contained in:
Daniel Arantes Loverde
2026-08-11 13:22:02 -03:00
parent c4d6998595
commit 7702836fe7
231 changed files with 4329 additions and 1958 deletions

View File

@@ -0,0 +1,151 @@
import Foundation
import Testing
@testable import PediFoods
private func decode<T: Decodable>(_ type: T.Type, _ json: String) throws -> T {
try JSONDecoder().decode(T.self, from: Data(json.utf8))
}
private func makeOrder(
status: String? = nil,
paymentStatus: String? = nil,
paymentConfirmed: Bool? = nil,
customerOtp: String? = nil,
otp: String? = nil,
confirmOtp: String? = nil,
timeline: [PublicOrderTimelineEvent] = []
) -> PublicOrderResult {
PublicOrderResult(
id: "order-1",
status: status,
paymentStatus: paymentStatus,
paymentConfirmed: paymentConfirmed,
otp: otp,
customerOtp: customerOtp,
confirmOtp: confirmOtp,
timeline: timeline
)
}
// MARK: - displayOtpCode
@Test("PublicOrderResult.displayOtpCode prefers customerOtp, then otp, then confirmOtp")
func displayOtpCodePriorityOrder() {
let allThree = makeOrder(customerOtp: "1111", otp: "2222", confirmOtp: "3333")
#expect(allThree.displayOtpCode == "1111")
let otpAndConfirm = makeOrder(otp: "2222", confirmOtp: "3333")
#expect(otpAndConfirm.displayOtpCode == "2222")
let confirmOnly = makeOrder(confirmOtp: "3333")
#expect(confirmOnly.displayOtpCode == "3333")
}
@Test("PublicOrderResult.displayOtpCode skips blank/whitespace-only values")
func displayOtpCodeSkipsBlankValues() {
let order = makeOrder(customerOtp: " ", otp: "2222")
#expect(order.displayOtpCode == "2222")
}
@Test("PublicOrderResult.displayOtpCode is nil when no OTP field is set")
func displayOtpCodeNilWhenAbsent() {
#expect(makeOrder().displayOtpCode == nil)
}
// MARK: - isInDeliveryRoute / isFinalStatus
@Test("PublicOrderResult.isInDeliveryRoute recognizes OUT_FOR_DELIVERY and Portuguese equivalents")
func isInDeliveryRouteRecognizesKnownStatuses() {
#expect(makeOrder(status: "OUT_FOR_DELIVERY").isInDeliveryRoute)
#expect(makeOrder(status: "em_rota").isInDeliveryRoute)
#expect(makeOrder(status: "ON_ROUTE").isInDeliveryRoute)
#expect(makeOrder(status: "PREPARING").isInDeliveryRoute == false)
}
@Test("PublicOrderResult.isFinalStatus matches COMPLETED, CANCELED, and REFUNDED exactly")
func isFinalStatusMatchesTerminalStatuses() {
#expect(makeOrder(status: "COMPLETED").isFinalStatus)
#expect(makeOrder(status: "CANCELED").isFinalStatus)
#expect(makeOrder(status: "REFUNDED").isFinalStatus)
#expect(makeOrder(status: "PREPARING").isFinalStatus == false)
}
// MARK: - isPaymentConfirmed
@Test("PublicOrderResult.isPaymentConfirmed trusts the explicit paymentConfirmed flag first")
func isPaymentConfirmedTrustsExplicitFlag() {
#expect(makeOrder(paymentStatus: "PENDING", paymentConfirmed: true).isPaymentConfirmed)
#expect(makeOrder(paymentStatus: "PAID", paymentConfirmed: false).isPaymentConfirmed == false)
}
@Test("PublicOrderResult.isPaymentConfirmed infers from a paymentStatus that looks confirmed")
func isPaymentConfirmedInfersFromPaymentStatus() {
#expect(makeOrder(paymentStatus: "CONFIRMED").isPaymentConfirmed)
#expect(makeOrder(paymentStatus: "approved").isPaymentConfirmed)
#expect(makeOrder(paymentStatus: "PENDING").isPaymentConfirmed == false)
#expect(makeOrder(paymentStatus: "PAYMENT_FAILED").isPaymentConfirmed == false)
}
@Test("PublicOrderResult.isPaymentConfirmed falls back to the timeline when status fields don't confirm")
func isPaymentConfirmedFallsBackToTimeline() {
let confirmingEvent = PublicOrderTimelineEvent(status: "PAYMENT_APPROVED", message: nil, time: nil)
let order = makeOrder(status: "PROCESSING", timeline: [confirmingEvent])
#expect(order.isPaymentConfirmed)
}
@Test("PublicOrderResult.isPaymentConfirmed is false with no confirming signal anywhere")
func isPaymentConfirmedFalseWithNoSignal() {
#expect(makeOrder(status: "PROCESSING").isPaymentConfirmed == false)
}
// MARK: - CreateOrderResult -> PublicOrderResult mapping
@Test("CreateOrderResult.asPublicOrderResult maps every carried-over field")
func createOrderResultMapsToPublicOrderResult() throws {
let created = try decode(CreateOrderResult.self, #"{"id":"o1","shortId":"S1","status":"PENDING","paymentMethod":"PIX"}"#)
let mapped = created.asPublicOrderResult()
#expect(mapped.id == "o1")
#expect(mapped.shortId == "S1")
#expect(mapped.status == "PENDING")
#expect(mapped.paymentMethod == "PIX")
}
// MARK: - Nested decode fallbacks
@Test("PublicOrderDeliveryAddress falls back through street/address and zip/zipCode/zipcode key names")
func publicOrderDeliveryAddressKeyFallback() throws {
let viaAddress = try decode(PublicOrderDeliveryAddress.self, #"{"address":"Rua A","zipcode":"01000-000"}"#)
#expect(viaAddress.street == "Rua A")
#expect(viaAddress.zip == "01000-000")
}
@Test("PublicOrderItem falls back from qty to the legacy quantity key")
func publicOrderItemQuantityKeyFallback() throws {
let item = try decode(PublicOrderItem.self, #"{"quantity":3,"price":9.9}"#)
#expect(item.qty == 3)
}
@Test("PublicOrderTimelineEvent falls back from message to event, and from time to createdAt/updatedAt")
func publicOrderTimelineEventKeyFallback() throws {
let viaEvent = try decode(PublicOrderTimelineEvent.self, #"{"status":"S","event":"Order placed"}"#)
#expect(viaEvent.message == "Order placed")
let viaCreatedAt = try decode(PublicOrderTimelineEvent.self, #"{"status":"S","createdAt":"2026-01-01T00:00:00Z"}"#)
#expect(viaCreatedAt.time == "2026-01-01T00:00:00Z")
}
@Test("AppOrderSummary falls back through orderId/realId/id for its own id, and through many keys for storeLogoURL")
func appOrderSummaryIdAndLogoFallback() throws {
let viaRealId = try decode(AppOrderSummary.self, #"{"realId":"real-1"}"#)
#expect(viaRealId.id == "real-1")
let viaLogo = try decode(AppOrderSummary.self, #"{"orderId":"o1","store_logo":"logo.png"}"#)
#expect(viaLogo.storeLogoURL == "logo.png")
}
@Test("AppOrderSummary falls back to the shared date key when createdAt/updatedAt are absent")
func appOrderSummaryDateFallback() throws {
let summary = try decode(AppOrderSummary.self, #"{"orderId":"o1","date":"2026-01-01"}"#)
#expect(summary.createdAt == "2026-01-01")
#expect(summary.updatedAt == "2026-01-01")
}