package synch import ( "testing" ) // All expected digests verified against the live Python implementation on 2026-05-06: // // PYTHONPATH=scripts:. python -c ' // from sync_fio_to_sheets import generate_sync_id // cases = [ // {"date":"2026-01-15","amount":500.0,"currency":"CZK","sender":"Jan Novak","vs":"123","message":"clenske 1/2026","bank_id":"abc123"}, // {"date":"2026-01-15","amount":500.0,"sender":"Jan Novak","vs":"123","message":"clenske 1/2026","bank_id":"abc123"}, // {"date":"2026-02-10","amount":1234.56,"currency":"CZK","sender":"ABC SRO","vs":"","message":"FAKTURA 42","bank_id":"xyz"}, // {"date":"2026-03-01","amount":-500.0,"currency":"CZK","sender":"refund","vs":"","message":"","bank_id":""}, // {"date":"2026-04-01","amount":0.0,"currency":"CZK","sender":"","vs":"","message":"","bank_id":""}, // {"date":"","amount":0.0,"currency":"CZK","sender":"","vs":"","message":"","bank_id":""}, // ] // for c in cases: print(generate_sync_id(c)) // ' func TestGenerateSyncID(t *testing.T) { t.Parallel() cases := []struct { name string tx Transaction want string }{ { name: "all fields set", tx: Transaction{ Date: "2026-01-15", Amount: 500.0, Currency: "CZK", Sender: "Jan Novak", VS: "123", Message: "clenske 1/2026", BankID: "abc123", }, want: "4ac26598b6f23965380690172156a438a7e97a97dcedf222e5afe1afbe2c1bc4", }, { name: "currency empty defaults to CZK", tx: Transaction{ Date: "2026-01-15", Amount: 500.0, Currency: "", Sender: "Jan Novak", VS: "123", Message: "clenske 1/2026", BankID: "abc123", }, want: "4ac26598b6f23965380690172156a438a7e97a97dcedf222e5afe1afbe2c1bc4", }, { name: "mixed-case fields lowercased before hashing", tx: Transaction{ Date: "2026-02-10", Amount: 1234.56, Currency: "CZK", Sender: "ABC SRO", VS: "", Message: "FAKTURA 42", BankID: "xyz", }, want: "d40fa224d4fa572ffcd58e308e5c6508c4d5ca087b24ef6ff9284528fc128250", }, { name: "negative amount", tx: Transaction{ Date: "2026-03-01", Amount: -500.0, Currency: "CZK", Sender: "refund", VS: "", Message: "", BankID: "", }, want: "0c630a407160367c396a2beec08efb94c319b4d84a8b90cc2be89e6ea10c391f", }, { name: "zero amount", tx: Transaction{ Date: "2026-04-01", Amount: 0.0, Currency: "CZK", Sender: "", VS: "", Message: "", BankID: "", }, want: "6a23ce53717cd539064d550d2c2ec5de2e9bf81016d16852820ca9b8e259331f", }, { // Python equivalent: {"date":"","amount":0.0,"currency":"CZK","sender":"","vs":"","message":"","bank_id":""} // Note: Python generate_sync_id({}) hashes "" for missing amount, not "0.0". name: "zero-value Transaction", tx: Transaction{}, want: "d33d7e391f5a43f0192bb5a34c0ec15715139125678ecef8e1324af7d943b21d", }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { t.Parallel() got := GenerateSyncID(tc.tx) if got != tc.want { t.Errorf("GenerateSyncID(%+v) = %q, want %q", tc.tx, got, tc.want) } }) } } // All expected strings verified against the live Python implementation on 2026-05-06: // // PYTHONPATH=scripts:. python -c ' // for v in [0.0, 500.0, -500.0, 0.1, 1234.56, 99999.99, 1500000.0, 1e16, 1e-5]: // print(repr(v), "->", repr(str(v))) // ' func TestFormatAmount(t *testing.T) { t.Parallel() cases := []struct { in float64 want string }{ {0.0, "0.0"}, {500.0, "500.0"}, {-500.0, "-500.0"}, {0.1, "0.1"}, {1234.56, "1234.56"}, {99999.99, "99999.99"}, {1500000.0, "1500000.0"}, {1e16, "1e+16"}, {1e-5, "1e-05"}, } for _, tc := range cases { got := formatAmount(tc.in) if got != tc.want { t.Errorf("formatAmount(%v) = %q, want %q", tc.in, got, tc.want) } } }