Hanlde trading212 inconsistent date formats (#31)
Badges / coveralls (push) Successful in 30s

Reviewed-on: #31
Co-authored-by: Natercio Moniz <[email protected]>
This commit was merged in pull request #31.
This commit is contained in:
2026-09-06 18:44:22 +01:00
committed by natercio
parent 3c404699e5
commit ccef829832
2 changed files with 129 additions and 1 deletions
+104
View File
@@ -104,6 +104,39 @@ func TestRecordReader_ReadRecord(t *testing.T) {
r: bytes.NewBufferString(`Market sell,,IE000GA3D489,ABXY,"Aspargus Broccoli",EOF987654321,2.4387014200,7.9999999999,USD,1.17995999,,"EUR",15.25,"EUR",,,0.02,"EUR",,`),
wantErr: true,
},
{
name: "well-formed buy with new offset format +00:00",
r: bytes.NewBufferString(`Market buy,2025-07-03 10:44:29+00:00,XX1234567890,ABXY,"Aspargus Broccoli",EOF987654321,2.4387014200,7.3690000000,USD,1.17995999,,"EUR",15.25,"EUR",0.25,"EUR",0.02,"EUR",,`),
want: Record{
symbol: "XX1234567890",
kind: internal.KindBuy,
quantity: ShouldParseDecimal(t, "2.4387014200"),
price: ShouldParseDecimal(t, "7.3690000000"),
timestamp: time.Date(2025, 7, 3, 10, 44, 29, 0, time.FixedZone("UTC", 0)),
fees: ShouldParseDecimal(t, "0.02"),
taxes: ShouldParseDecimal(t, "0.25"),
natureGetter: func() internal.Nature { return internal.NatureG01 },
},
},
{
name: "well-formed buy with new offset format +01:00",
r: bytes.NewBufferString(`Market buy,2025-07-03 10:44:29+01:00,XX1234567890,ABXY,"Aspargus Broccoli",EOF987654321,2.4387014200,7.3690000000,USD,1.17995999,,"EUR",15.25,"EUR",0.25,"EUR",0.02,"EUR",,`),
want: Record{
symbol: "XX1234567890",
kind: internal.KindBuy,
quantity: ShouldParseDecimal(t, "2.4387014200"),
price: ShouldParseDecimal(t, "7.3690000000"),
timestamp: time.Date(2025, 7, 3, 10, 44, 29, 0, time.FixedZone("+01:00", 1*60*60)),
fees: ShouldParseDecimal(t, "0.02"),
taxes: ShouldParseDecimal(t, "0.25"),
natureGetter: func() internal.Nature { return internal.NatureG01 },
},
},
{
name: "well-formed buy with garbage timestamp returns error",
r: bytes.NewBufferString(`Market buy,not-a-timestamp,IE000GA3D489,ABXY,"Aspargus Broccoli",EOF987654321,2.4387014200,7.3690000000,USD,1.17995999,,"EUR",15.25,"EUR",0.25,"EUR",0.02,"EUR",,`),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -219,6 +252,77 @@ func TestRecordReader_ReadRecord_Split(t *testing.T) {
})
}
func TestParseTimestamp(t *testing.T) {
utc := time.FixedZone("UTC", 0)
plusOne := time.FixedZone("+01:00", 1*60*60)
minusFive := time.FixedZone("-05:00", -5*60*60)
tests := []struct {
name string
input string
want time.Time
wantErr bool
}{
{
name: "legacy format without offset parses as UTC",
input: "2025-05-22 13:15:52",
want: time.Date(2025, 5, 22, 13, 15, 52, 0, time.UTC),
},
{
name: "new format with +00:00 offset",
input: "2025-05-22 13:15:52+00:00",
want: time.Date(2025, 5, 22, 13, 15, 52, 0, utc),
},
{
name: "new format with +01:00 offset",
input: "2025-05-22 13:15:52+01:00",
want: time.Date(2025, 5, 22, 13, 15, 52, 0, plusOne),
},
{
name: "new format with -05:00 offset",
input: "2025-05-22 13:15:52-05:00",
want: time.Date(2025, 5, 22, 13, 15, 52, 0, minusFive),
},
{
name: "explicit Z UTC marker",
input: "2025-05-22 13:15:52Z",
want: time.Date(2025, 5, 22, 13, 15, 52, 0, time.UTC),
},
{
name: "garbage input returns error",
input: "not-a-timestamp",
wantErr: true,
},
{
name: "RFC3339 with T separator is rejected",
input: "2025-05-22T13:15:52Z",
wantErr: true,
},
{
name: "empty string returns error",
input: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseTimestamp(tt.input)
if err != nil {
if !tt.wantErr {
t.Fatalf("parseTimestamp(%q) returned error: %v", tt.input, err)
}
return
}
if tt.wantErr {
t.Fatalf("parseTimestamp(%q) expected an error", tt.input)
}
if !got.Equal(tt.want) {
t.Fatalf("parseTimestamp(%q) = %v, want %v", tt.input, got, tt.want)
}
})
}
}
func Test_figiNatureGetter(t *testing.T) {
tests := []struct {
name string // description of this test case