Files
warmbly/internal/repository/tester_sample_data_live_test.go
T
Matthew MeszarosandDevin AI f52ef240b4 feat: add audited repeat-safe sample data provisioning for active dedicated Test workspaces in Admin Testers
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-06 09:23:31 +00:00

220 lines
8.7 KiB
Go

package repository
import (
"context"
"errors"
"net/mail"
"sync"
"testing"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/warmbly/warmbly/internal/models"
)
type testerSampleFixture struct {
orgID, userID uuid.UUID
orgs OrganizationRepository
users UserRepository
}
func newTesterSampleFixture(t *testing.T, pool *pgxpool.Pool, users UserRepository) testerSampleFixture {
t.Helper()
ctx := context.Background()
until := time.Now().Add(24 * time.Hour).Truncate(time.Microsecond)
u, err := users.CreateExemptUser(ctx, &mail.Address{Address: uuid.NewString() + "@example.test"}, "hash", "sample review", nil, until)
if err != nil {
t.Fatal(err)
}
orgs := NewOrganizationRepository(pool)
slug := uuid.NewString()
org := &models.Organization{ID: uuid.New(), OwnerUserID: u.ID, Name: "Sample review workspace", Slug: &slug}
t.Cleanup(func() {
_, _ = pool.Exec(ctx, `DELETE FROM admin_audit_logs WHERE target_id = $1`, org.ID)
_, _ = pool.Exec(ctx, `DELETE FROM organizations WHERE id = $1`, org.ID)
_, _ = pool.Exec(ctx, `DELETE FROM users WHERE id = $1`, u.ID)
})
if err := orgs.Create(ctx, org); err != nil {
t.Fatal(err)
}
if err := orgs.ProvisionTesterWorkspace(ctx, org.ID, u.ID, u.ID, "sample review", until); err != nil {
t.Fatal(err)
}
return testerSampleFixture{org.ID, u.ID, orgs, users}
}
func sampleCount(t *testing.T, pool *pgxpool.Pool, query string, args ...any) int {
t.Helper()
var count int
if err := pool.QueryRow(context.Background(), query, args...).Scan(&count); err != nil {
t.Fatal(err)
}
return count
}
func assertTesterSampleCounts(t *testing.T, pool *pgxpool.Pool, orgID uuid.UUID, multiplier int) {
t.Helper()
for _, tc := range []struct {
query string
count int
}{
{`SELECT count(*) FROM contacts WHERE organization_id = $1`, 6},
{`SELECT count(*) FROM categories WHERE organization_id = $1`, 1},
{`SELECT count(*) FROM campaigns WHERE organization_id = $1`, 1},
{`SELECT count(*) FROM sequences WHERE organization_id = $1`, 2},
{`SELECT count(*) FROM reply_templates WHERE organization_id = $1`, 2},
{`SELECT count(*) FROM pipelines WHERE organization_id = $1`, 1},
{`SELECT count(*) FROM deals WHERE organization_id = $1`, 2},
{`SELECT count(*) FROM crm_tasks WHERE organization_id = $1`, 1},
{`SELECT count(*) FROM contact_notes WHERE organization_id = $1`, 1},
{`SELECT count(*) FROM admin_audit_logs WHERE target_id = $1 AND action = 'seed_tester_workspace'`, 1},
} {
if got := sampleCount(t, pool, tc.query, orgID); got != tc.count*multiplier {
t.Errorf("%s: got %d, want %d", tc.query, got, tc.count*multiplier)
}
}
}
func TestLiveTesterSampleDataIsSafeAndPreservesEdits(t *testing.T) {
db, pool := liveContactDB(t)
requireSchemaVersion(t, pool, 264)
ctx := context.Background()
f := newTesterSampleFixture(t, pool, NewUserRepostory(db, nil))
other := newTesterSampleFixture(t, pool, f.users)
result, err := f.orgs.SeedTesterWorkspace(ctx, f.orgID, f.userID, "127.0.0.1", "sample-review")
if err != nil || result == nil || !result.Created || result.SeededAt.IsZero() {
t.Fatalf("seed = %+v, %v", result, err)
}
assertTesterSampleCounts(t, pool, f.orgID, 1)
assertTesterSampleCounts(t, pool, other.orgID, 0)
contact, xerr := NewContactRepostory(db).GetByEmailAndOrganization(ctx, f.orgID, "avery@review.invalid")
if xerr != nil || contact == nil || contact.CustomFields["sample_data"] != "true" {
t.Fatalf("sample contact cannot be read: %+v, %v", contact, xerr)
}
for _, query := range []string{
`SELECT count(*) FROM contacts WHERE organization_id = $1 AND (subscribed OR email NOT LIKE '%@review.invalid')`,
`SELECT count(*) FROM campaigns WHERE organization_id = $1 AND (status <> 'draft' OR open_tracking OR link_tracking)`,
`SELECT count(*) FROM email_accounts WHERE organization_id = $1`,
`SELECT count(*) FROM campaign_tasks t JOIN campaigns c ON c.id = t.campaign_id WHERE c.organization_id = $1`,
`SELECT count(*) FROM campaign_contact_progress p JOIN campaigns c ON c.id = p.campaign_id WHERE c.organization_id = $1`,
} {
if got := sampleCount(t, pool, query, f.orgID); got != 0 {
t.Errorf("unexpected side effect: %s = %d", query, got)
}
}
var conditions models.BranchConditions
var next uuid.UUID
if err := pool.QueryRow(ctx, `SELECT conditions FROM sequences WHERE organization_id = $1 AND position = 0`, f.orgID).Scan(&conditions); err != nil {
t.Fatal(err)
}
if err := pool.QueryRow(ctx, `SELECT id FROM sequences WHERE organization_id = $1 AND position = 1`, f.orgID).Scan(&next); err != nil {
t.Fatal(err)
}
if len(conditions.Branches) != 1 || conditions.Branches[0].TargetSequenceID == nil || *conditions.Branches[0].TargetSequenceID != next {
t.Fatal("sample campaign steps are not connected")
}
var ip, agent string
if err := pool.QueryRow(ctx, `SELECT ip_address, user_agent FROM admin_audit_logs WHERE target_id = $1 AND action = 'seed_tester_workspace'`, f.orgID).Scan(&ip, &agent); err != nil || ip != "127.0.0.1" || agent != "sample-review" {
t.Fatalf("audit attribution: %s, %s, %v", ip, agent, err)
}
if got := sampleCount(t, pool, `SELECT balance FROM credit_ledger WHERE org_id = $1`, f.orgID); got != 100 {
t.Fatalf("seeding changed test credits: %d", got)
}
list, err := f.users.ListLoginCodeExempt(ctx)
if err != nil {
t.Fatal(err)
}
found := false
for _, tester := range list {
if tester.UserID == f.userID {
found = tester.TestWorkspaceID != nil && *tester.TestWorkspaceID == f.orgID && tester.SampleDataSeededAt != nil && tester.SampleDataSeededAt.Equal(result.SeededAt)
}
}
if !found {
t.Fatal("tester list does not expose the seeded workspace")
}
if _, err := pool.Exec(ctx, `UPDATE campaigns SET name = 'Edited sample' WHERE organization_id = $1`, f.orgID); err != nil {
t.Fatal(err)
}
if _, err := pool.Exec(ctx, `DELETE FROM contacts WHERE organization_id = $1 AND email = 'taylor@review.invalid'`, f.orgID); err != nil {
t.Fatal(err)
}
retry, err := f.orgs.SeedTesterWorkspace(ctx, f.orgID, f.userID, "", "")
if err != nil || retry == nil || retry.Created || !retry.SeededAt.Equal(result.SeededAt) {
t.Fatalf("retry = %+v, %v", retry, err)
}
if got := sampleCount(t, pool, `SELECT count(*) FROM campaigns WHERE organization_id = $1 AND name = 'Edited sample'`, f.orgID); got != 1 {
t.Fatal("retry overwrote edited sample data")
}
if got := sampleCount(t, pool, `SELECT count(*) FROM contacts WHERE organization_id = $1`, f.orgID); got != 5 {
t.Fatal("retry restored deleted sample data")
}
}
func TestLiveTesterSampleDataRollsBackAndSerializesRetries(t *testing.T) {
db, pool := liveContactDB(t)
requireSchemaVersion(t, pool, 264)
ctx := context.Background()
f := newTesterSampleFixture(t, pool, NewUserRepostory(db, nil))
if _, err := f.orgs.SeedTesterWorkspace(ctx, f.orgID, uuid.New(), "", ""); err == nil {
t.Fatal("invalid audit actor must fail the entire transaction")
}
assertTesterSampleCounts(t, pool, f.orgID, 0)
results := make(chan *models.TesterSampleData, 8)
errors := make(chan error, 8)
var wg sync.WaitGroup
for range 8 {
wg.Go(func() {
result, err := f.orgs.SeedTesterWorkspace(ctx, f.orgID, f.userID, "", "")
results <- result
errors <- err
})
}
wg.Wait()
close(results)
close(errors)
for err := range errors {
if err != nil {
t.Fatal(err)
}
}
created := 0
for result := range results {
if result.Created {
created++
}
}
if created != 1 {
t.Fatalf("concurrent actions created %d datasets", created)
}
assertTesterSampleCounts(t, pool, f.orgID, 1)
}
func TestLiveTesterSampleDataRejectsNonTestAndInactiveWorkspaces(t *testing.T) {
db, pool := liveContactDB(t)
requireSchemaVersion(t, pool, 264)
ctx := context.Background()
for _, tc := range []struct {
name, query string
}{
{"standard workspace", `UPDATE organizations SET category = 'standard' WHERE id = $1`},
{"expired password", `UPDATE users SET password_expires_at = now() - interval '1 hour' WHERE id = (SELECT owner_user_id FROM organizations WHERE id = $1)`},
{"revoked exemption", `UPDATE users SET login_code_exempt = false WHERE id = (SELECT owner_user_id FROM organizations WHERE id = $1)`},
{"expired grant", `UPDATE subscriptions SET managed_until = now() - interval '1 hour' WHERE organization_id = $1`},
{"different managed plan", `UPDATE subscriptions SET managed_plan_id = '00000000-0000-0000-0000-000000000001' WHERE organization_id = $1`},
} {
t.Run(tc.name, func(t *testing.T) {
f := newTesterSampleFixture(t, pool, NewUserRepostory(db, nil))
if _, err := pool.Exec(ctx, tc.query, f.orgID); err != nil {
t.Fatal(err)
}
if _, err := f.orgs.SeedTesterWorkspace(ctx, f.orgID, f.userID, "", ""); !errors.Is(err, ErrTesterWorkspaceInactive) {
t.Fatalf("ineligible workspace returned %v", err)
}
assertTesterSampleCounts(t, pool, f.orgID, 0)
})
}
}