package main import ( "os" "path/filepath" "testing" ) func newTestStore(t *testing.T) *Store { t.Helper() s, err := NewStore(filepath.Join(t.TempDir(), "test.db")) if err != nil { t.Fatalf("NewStore() failed: %v", err) } t.Cleanup(func() { s.Close() }) return s } func TestStore_CreateAndFindByCode(t *testing.T) { s := newTestStore(t) originalURL := "https://example.com/create-and-find" if err := s.Create("testabc", originalURL); err != nil { t.Fatalf("Create() failed: %v", err) } rec, err := s.FindByCode("testabc") if err != nil { t.Fatalf("FindByCode() failed: %v", err) } if rec == nil { t.Fatal("FindByCode() returned nil, expected a record") } if rec.OriginalURL != originalURL { t.Fatalf("expected OriginalURL %q, got %q", originalURL, rec.OriginalURL) } if rec.Code != "testabc" { t.Fatalf("expected Code %q, got %q", "testabc", rec.Code) } } func TestStore_FindByCode_NonExistent(t *testing.T) { s := newTestStore(t) rec, err := s.FindByCode("nonexist") if err != nil { t.Fatalf("FindByCode() for non-existent code failed: %v", err) } if rec != nil { t.Fatal("expected nil for non-existent code, got a record") } } func TestStore_Create_Duplicate(t *testing.T) { s := newTestStore(t) url := "https://example.com/dup" if err := s.Create("dupcode", url); err != nil { t.Fatalf("first Create() failed: %v", err) } if err := s.Create("dupcode", url); err == nil { t.Fatal("second Create() with same code should fail") } } func TestStore_Persistence(t *testing.T) { tmpFile, err := os.CreateTemp("", "shortlink-*.json") if err != nil { t.Fatal(err) } tmpPath := tmpFile.Name() tmpFile.Close() defer os.Remove(tmpPath) s1, err := NewStore(tmpPath) if err != nil { t.Fatalf("NewStore() failed: %v", err) } s1.Create("persist", "https://example.com/persist") s1.Close() s2, err := NewStore(tmpPath) if err != nil { t.Fatalf("reopen store failed: %v", err) } defer s2.Close() rec, err := s2.FindByCode("persist") if err != nil { t.Fatalf("FindByCode() after reopen failed: %v", err) } if rec == nil { t.Fatal("expected record after reopening store") } if rec.OriginalURL != "https://example.com/persist" { t.Fatalf("unexpected OriginalURL: %q", rec.OriginalURL) } } func TestGenerateCode(t *testing.T) { seen := make(map[string]bool) for i := 0; i < 100; i++ { code, err := generateCode() if err != nil { t.Fatalf("generateCode() failed: %v", err) } if len(code) != codeLength { t.Fatalf("expected code length %d, got %d: %q", codeLength, len(code), code) } for _, c := range code { if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { t.Fatalf("invalid character %c in code %q", c, code) } } if seen[code] { t.Fatal("unexpected collision: duplicate code generated") } seen[code] = true } }