field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

TeraFoodDecimalEntryTests.swift (6559B)


      1 import Foundation
      2 @testable import TeraApp
      3 import XCTest
      4 
      5 final class TeraFoodDecimalEntryTests: XCTestCase {
      6   func testExactLocaleTranslationNeverRoundsOrInfersUnits() {
      7     for (locale, raw, expected) in [
      8       ("fr_FR", "0004,500", "4.5"), ("de_DE", "0,000000000000000000000000001", "0.000000000000000000000000001"),
      9       ("en_US", "12345678901234567890.12345678", "12345678901234567890.12345678"),
     10       ("en_US", "000.000", "0"), ("ar_EG", "٤٫٥٠", "4.5"), ("fa_IR", "۱۲٫۵۰", "12.5"),
     11       ("fr_FR", "4.5", "4.5"), ("en_US", "9.9900", "9.99"),
     12     ] {
     13       XCTAssertEqual(TeraFoodDecimalEntry.canonicalOrRaw(raw, locale: Locale(identifier: locale)), expected, raw)
     14     }
     15   }
     16 
     17   func testIncompleteOrAmbiguousEntriesStayUnchangedForSharedValidation() {
     18     for raw in ["", "-", "1,", ",5", "1.000,5", "1,000.5", "1,2,3", "1 000", "1\u{202F}000", "1e3", "+1", " 1 ", "⅕", "²"] {
     19       XCTAssertEqual(TeraFoodDecimalEntry.canonicalOrRaw(raw, locale: Locale(identifier: "fr_FR")), raw)
     20     }
     21     XCTAssertNil(TeraFoodDecimalEntry.canonicalOrRaw(nil, locale: Locale(identifier: "en_US")))
     22     XCTAssertEqual(TeraFoodDecimalEntry.canonicalOrRaw("1,5", locale: Locale(identifier: "en_US")), "1,5")
     23   }
     24 
     25   func testOnlyFoodAmountsAreTranslatedAndContractFieldsArePreserved() {
     26     var form = TeraAddForm.empty(.createFoodAvailability)
     27     form.priceAmount = "4,50"
     28     form.quantity = "0002,00"
     29     form.unit = "bag"
     30     form.currency = "ZZZ"
     31     form.foodStatus = "sold"
     32     var expected = form
     33     expected.priceAmount = "4.5"
     34     expected.quantity = "2"
     35     XCTAssertEqual(TeraFoodDecimalEntry.form(form, locale: Locale(identifier: "fr_FR")), expected)
     36     form.commandType = .createUpdate
     37     XCTAssertEqual(TeraFoodDecimalEntry.form(form, locale: Locale(identifier: "fr_FR")), form)
     38   }
     39 }
     40 
     41 extension TeraAddStoreTests {
     42   @MainActor
     43   func testAutomaticRevisionPreservationKeepsRawEntryAndItsRetryInterlock() async throws {
     44     let backend = AddBackend()
     45     let client = try await Self.startedClient(backend)
     46     let store = TeraAddStore(runtimeClient: client, initialType: .createFoodAvailability)
     47     await store.configure(snapshot: backend.snapshot())
     48     await store.start()
     49     configure(store, type: .createFoodAvailability)
     50     let original = try await backend.saveAddIntent(input: TeraAddRuntimeInput(form: store.form, media: []),
     51                                                    existingDraftID: nil, expectedRevision: nil)
     52     await store.retractAndRevise(Self.card(localOperationID: original.id))
     53     store.updateForm(\.priceAmount, "4.50")
     54     await backend.failNextRevisionReceipt()
     55     store.newDraft(type: .createUpdate)
     56     await TeraScopeFixtures.eventually { !store.protection.isWorking }
     57     XCTAssertTrue(store.protection.failed)
     58     XCTAssertTrue(store.revisionPreparation.isCaptured)
     59     XCTAssertEqual(store.form.priceAmount, "4.50")
     60     store.protection.retry()
     61     await TeraScopeFixtures.eventually { !store.protection.isWorking }
     62     XCTAssertFalse(store.protection.failed)
     63     XCTAssertEqual(store.form.commandType, .createUpdate)
     64     let retained = await backend.values
     65     XCTAssertEqual(retained.values.first(where: \.isRevision)?.form?.priceAmount, "4.50")
     66     let count = await backend.revisionPlanCount()
     67     XCTAssertEqual(count, 1)
     68     store.stop()
     69     _ = try await client.stop()
     70   }
     71 
     72   @MainActor
     73   func testFoodRevisionSaveTranslatesOnceAndLostReceiptRetainsExactAmounts() async throws {
     74     let backend = AddBackend()
     75     let client = try await Self.startedClient(backend)
     76     let store = TeraAddStore(runtimeClient: client, initialType: .createFoodAvailability)
     77     await store.configure(snapshot: backend.snapshot())
     78     await store.start()
     79     configure(store, type: .createFoodAvailability)
     80     let original = try await backend.saveAddIntent(input: TeraAddRuntimeInput(form: store.form, media: []),
     81                                                    existingDraftID: nil, expectedRevision: nil)
     82     await store.retractAndRevise(Self.card(localOperationID: original.id))
     83     store.updateForm(\.priceAmount, "4,50")
     84     store.updateForm(\.quantity, "002,00")
     85     await backend.failNextRevisionReceipt()
     86     await store.save(locale: Locale(identifier: "fr_FR"))
     87     XCTAssertTrue(store.revisionPreparation.isCaptured)
     88     XCTAssertEqual(store.form.priceAmount, "4.5")
     89     XCTAssertEqual(store.form.quantity, "2")
     90     store.updateForm(\.priceAmount, "9,00")
     91     await store.save(locale: Locale(identifier: "en_US"))
     92     XCTAssertTrue(store.activeDraft?.isRevision == true)
     93     XCTAssertEqual(store.activeDraft?.form?.priceAmount, "4.5")
     94     XCTAssertEqual(store.activeDraft?.form?.quantity, "2")
     95     let count = await backend.revisionPlanCount()
     96     XCTAssertEqual(count, 1)
     97     store.stop()
     98     _ = try await client.stop()
     99   }
    100 
    101   @MainActor
    102   func testFoodDraftStaysRawUntilNewSubmitAndRetryRetainsCapturedAmounts() async throws {
    103     let backend = AddBackend()
    104     let client = try await Self.startedClient(backend)
    105     let store = TeraAddStore(runtimeClient: client, initialType: .createFoodAvailability)
    106     await store.configure(snapshot: backend.snapshot())
    107     await store.start()
    108     configure(store, type: .createFoodAvailability)
    109     store.updateForm(\.priceAmount, "4,50")
    110     store.updateForm(\.quantity, "002,00")
    111     await store.save()
    112     XCTAssertEqual(store.savedComposer?.form.priceAmount, "4,50")
    113     XCTAssertEqual(store.form.quantity, "002,00")
    114     await store.submit(locale: Locale(identifier: "fr_FR"))
    115     let captured = try XCTUnwrap(store.submissions.status?.captured)
    116     XCTAssertEqual(captured.form.priceAmount, "4.5")
    117     XCTAssertEqual(captured.form.quantity, "2")
    118     XCTAssertEqual(captured.form.editingValue, store.form)
    119     store.updateForm(\.priceAmount, "9,00")
    120     await store.submit(locale: Locale(identifier: "en_US"))
    121     XCTAssertEqual(store.submissions.status?.captured, captured)
    122     XCTAssertEqual(store.form.priceAmount, "9,00")
    123     store.newDraft(type: .createFoodAvailability)
    124     await TeraScopeFixtures.eventually { !store.protection.isWorking }
    125     configure(store, type: .createFoodAvailability)
    126     store.updateForm(\.priceAmount, "4,50")
    127     store.updateForm(\.quantity, "002,00")
    128     await store.submit(locale: Locale(identifier: "fr_FR"))
    129     let next = try XCTUnwrap(store.submissions.status?.captured)
    130     XCTAssertNotEqual(next.id, captured.id)
    131     XCTAssertNotEqual(next.form.identifier, captured.form.identifier)
    132     XCTAssertEqual(next.form.priceAmount, captured.form.priceAmount)
    133     store.stop()
    134     _ = try await client.stop()
    135   }
    136 }