All checks were successful
Deploy to K8s / deploy (push) Successful in 6s
SHA-256 dedup hash from sync_fio_to_sheets.py generate_sync_id. Key subtlety: Python str(float) emits "500.0" for whole-valued floats and switches to scientific notation at |f|>=1e16 or |f|<1e-4 — replicated via formatAmount using 'f'/'e' format selection. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
120 lines
3.7 KiB
Go
120 lines
3.7 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|