package storage import ( "path/filepath" "testing" "time" ) func classifyTestStore(t *testing.T) *Store { t.Helper() s, err := Open(filepath.Join(t.TempDir(), "c.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { s.Close() }) return s } func TestClassifications_InsertListReview(t *testing.T) { s := classifyTestStore(t) insertReceipt(t, s, "r1") if err := s.InsertClassification("r1", "haiku", `{"model":"haiku"}`, time.Now().UTC()); err != nil { t.Fatal(err) } rows, err := s.ListUnreviewedClassifications() if err != nil { t.Fatal(err) } if len(rows) != 1 || rows[0].ReceiptID != "r1" || rows[0].Model != "haiku" { t.Fatalf("ListUnreviewedClassifications = %+v", rows) } if rows[0].FinalAmountCents != 100 { // insertReceipt sets 100 cents t.Errorf("joined final amount = %d, want 100", rows[0].FinalAmountCents) } // Review it, crediting a note as the fix. noteID, _ := s.AddNote("the fix") if err := s.MarkClassificationReviewed("r1", "fixed", []int64{noteID}); err != nil { t.Fatal(err) } rows, _ = s.ListUnreviewedClassifications() if len(rows) != 0 { t.Errorf("reviewed row still in unreviewed queue: %+v", rows) } got, err := s.GetClassification("r1") if err != nil { t.Fatal(err) } if !got.Reviewed || got.Resolution != "fixed" || got.ReviewedAt == nil { t.Errorf("review state not persisted: %+v", got) } } func TestClassifications_DeletedReceiptDropsFromQueue(t *testing.T) { s := classifyTestStore(t) insertReceipt(t, s, "r1") if err := s.InsertClassification("r1", "m", `{}`, time.Now().UTC()); err != nil { t.Fatal(err) } if err := s.SoftDelete("r1"); err != nil { t.Fatal(err) } rows, _ := s.ListUnreviewedClassifications() if len(rows) != 0 { t.Errorf("soft-deleted receipt should not appear in review queue: %+v", rows) } }