package store import ( "path/filepath" "testing" "golang.org/x/crypto/bcrypt" ) func TestMigrateUpdatesAdminCredentials(t *testing.T) { st, err := Open(filepath.Join(t.TempDir(), "app.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = st.Close() }) if err := st.Migrate("admin", "old-password"); err != nil { t.Fatal(err) } if err := st.Migrate("owner", "new-password"); err != nil { t.Fatal(err) } user, err := st.AdminByUsername(t.Context(), "owner") if err != nil { t.Fatal(err) } if err := bcrypt.CompareHashAndPassword(user.PasswordHash, []byte("new-password")); err != nil { t.Fatalf("expected updated password hash: %v", err) } if _, err := st.AdminByUsername(t.Context(), "admin"); !IsNotFound(err) { t.Fatalf("expected old username to be removed, got %v", err) } } func TestContactRequestsSupportQualificationFields(t *testing.T) { st, err := Open(filepath.Join(t.TempDir(), "app.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = st.Close() }) if err := st.Migrate("admin", "password"); err != nil { t.Fatal(err) } err = st.SaveContact(t.Context(), ContactRequest{ Name: "Jane", Email: "jane@example.com", Phone: "123", ProjectType: "Renovation", ProjectLocation: "London", BudgetRange: "GBP 250k-500k", Timeline: "3-6 months", Message: "Project notes", }) if err != nil { t.Fatal(err) } requests, err := st.ContactRequests(t.Context()) if err != nil { t.Fatal(err) } if len(requests) != 1 || requests[0].ProjectLocation != "London" || requests[0].Status != "new" { t.Fatalf("unexpected request fields: %+v", requests) } } func TestSiteContentIncludesPhaseTwoFields(t *testing.T) { st, err := Open(filepath.Join(t.TempDir(), "app.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = st.Close() }) if err := st.Migrate("admin", "password"); err != nil { t.Fatal(err) } content, err := st.SiteContent(t.Context()) if err != nil { t.Fatal(err) } if content.Positioning == "" || content.HeroCTALabel == "" || content.ServiceOneTitle == "" || content.StudioPhilosophy == "" { t.Fatalf("expected seeded phase two content, got %+v", content) } } func TestServicesAndFAQsAreSeeded(t *testing.T) { st, err := Open(filepath.Join(t.TempDir(), "app.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = st.Close() }) if err := st.Migrate("admin", "password"); err != nil { t.Fatal(err) } services, err := st.Services(t.Context(), true) if err != nil { t.Fatal(err) } faqs, err := st.FAQs(t.Context(), true) if err != nil { t.Fatal(err) } if len(services) < 4 || len(faqs) < 3 { t.Fatalf("expected seeded services and FAQs, got services=%d faqs=%d", len(services), len(faqs)) } } func TestSeededProjectsIncludeDepthFields(t *testing.T) { st, err := Open(filepath.Join(t.TempDir(), "app.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { _ = st.Close() }) if err := st.Migrate("admin", "password"); err != nil { t.Fatal(err) } project, err := st.ProjectBySlug(t.Context(), "courtyard-house") if err != nil { t.Fatal(err) } if project.Summary == "" || project.Scope == "" || project.Status == "" || project.Position == 0 { t.Fatalf("expected project depth fields, got %+v", project) } }