package db import ( "context" "os" "path/filepath" "testing" "veola/internal/crypto" "veola/internal/models" ) func newTestStore(t *testing.T) *Store { t.Helper() dir := t.TempDir() conn, err := Open(filepath.Join(dir, "test.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { conn.Close() }) key, _ := crypto.DeriveKey([]byte("0123456789abcdef0123456789abcdef-aaa")) return NewStore(conn, key) } func TestDedupByItemAndURL(t *testing.T) { if os.Getenv("CI_SKIP_SQLITE") != "" { t.Skip() } s := newTestStore(t) ctx := context.Background() id, err := s.CreateItem(ctx, &models.Item{ Name: "TwinBee", NtfyTopic: "veola", Active: true, PollIntervalMinutes: 60, NtfyPriority: "default", }) if err != nil { t.Fatal(err) } r := &models.Result{ ItemID: id, Title: "TwinBee Famicom", Currency: "USD", URL: "https://example.com/listing/1", } if _, err := s.InsertResult(ctx, r); err != nil { t.Fatal(err) } exists, err := s.ResultExists(ctx, id, "https://example.com/listing/1") if err != nil { t.Fatal(err) } if !exists { t.Error("expected result to be detected as duplicate") } missing, _ := s.ResultExists(ctx, id, "https://example.com/listing/2") if missing { t.Error("expected unknown URL to not be flagged as duplicate") } // Different item, same URL should not collide. id2, _ := s.CreateItem(ctx, &models.Item{Name: "Other", NtfyTopic: "veola", PollIntervalMinutes: 60, NtfyPriority: "default"}) other, _ := s.ResultExists(ctx, id2, "https://example.com/listing/1") if other { t.Error("dedup should be scoped to item_id") } // Empty URL should not collide. emptyExists, _ := s.ResultExists(ctx, id, "") if emptyExists { t.Error("empty URL should never be flagged as duplicate") } } func TestCJKRoundTrip(t *testing.T) { s := newTestStore(t) ctx := context.Background() id, err := s.CreateItem(ctx, &models.Item{ Name: "ツインビー", SearchQuery: "ツインビー グラディウス パロディウス", NtfyTopic: "veola", Active: true, PollIntervalMinutes: 60, NtfyPriority: "default", }) if err != nil { t.Fatal(err) } got, err := s.GetItem(ctx, id) if err != nil { t.Fatal(err) } if got.Name != "ツインビー" || got.SearchQuery != "ツインビー グラディウス パロディウス" { t.Errorf("CJK round-trip failed: name=%q query=%q", got.Name, got.SearchQuery) } }