refactor: remove auto deposit penalty on no-shows, add comprehensive tests

- Remove automatic deposits_required=3 on no-shows, give admin flexibility
- Add tests for no-show deposit logic (forgiven, over 24h, under 24h)
- Add tests for reservation cleanup TTL (admin walk-in/call-in 15min)
- Add tests for EXIF GPS data stripping in portfolio images
- Add tests for contact info endpoint
- Add tests for guest account anonymization
This commit is contained in:
2026-05-03 15:59:40 +01:00
parent 6808752e0d
commit 88ee265603
11 changed files with 2479 additions and 17 deletions
+83
View File
@@ -19,6 +19,7 @@ import (
"encoding/json"
"net/http"
"testing"
"time"
"crussell/db"
"crussell/handlers/user"
@@ -473,3 +474,85 @@ func TestAdminUsers_Get_Success(t *testing.T) {
t.Errorf("expected account_role 'verified_email', got '%s'", resp.AccountRole)
}
}
// TestAdminUsers_AddPatchTest_Duplicate verifies that recording the same patch test
// twice updates the tested_at timestamp (upsert behavior).
func TestAdminUsers_AddPatchTest_Duplicate(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
// Create test user
var userID string
err := db.DB.QueryRow(context.Background(), `
INSERT INTO users (n_first_name, n_last_name, email, phone, date_of_birth, password_hash, account_role, account_type)
VALUES ('Test', 'User', 'testuser@test.com', '+447123456789', '1990-01-01', 'hash', 'verified_email', 'email')
RETURNING id
`).Scan(&userID)
if err != nil {
t.Fatalf("failed to create user: %v", err)
}
// Create a service
var serviceID string
err = db.DB.QueryRow(context.Background(), `
INSERT INTO services (name, description, price, duration_minutes, is_active, minimum_age_required)
VALUES ('Gel Polish Full Set', 'Gel polish service', 45.00, 60, true, 16)
RETURNING id
`).Scan(&serviceID)
if err != nil {
t.Fatalf("failed to create service: %v", err)
}
// Create a patch test that links to this service
var patchTestID string
err = db.DB.QueryRow(context.Background(), `
INSERT INTO patch_tests (name, description, notice_duration_hours, expiry_months, service_ids)
VALUES ('Gel Allergy Test', 'Patch test for gel products', 24, 6, $1)
RETURNING id
`, []string{serviceID}).Scan(&patchTestID)
if err != nil {
t.Fatalf("failed to create patch test: %v", err)
}
handler := http.HandlerFunc(user.AddPatchTestHandler)
// Record patch test first time - should return 201 Created
reqBody := user.AddPatchTestRequest{PatchTestID: patchTestID}
w := makeAdminRequest(handler, "POST", "/api/admin/users/"+userID+"/patch-tests", reqBody)
if w.Code != http.StatusCreated {
t.Errorf("first record: expected status 201, got %d. body: %s", w.Code, w.Body.String())
}
// Query tested_at time T1
var t1 time.Time
err = db.DB.QueryRow(context.Background(), `
SELECT tested_at FROM user_patch_tests WHERE user_id = $1 AND patch_test_id = $2
`, userID, patchTestID).Scan(&t1)
if err != nil {
t.Fatalf("failed to get tested_at: %v", err)
}
// Wait 100ms to ensure timestamp will change
time.Sleep(100 * time.Millisecond)
// Record same patch test again - should return 201 or 200 (upsert updates)
reqBody = user.AddPatchTestRequest{PatchTestID: patchTestID}
w = makeAdminRequest(handler, "POST", "/api/admin/users/"+userID+"/patch-tests", reqBody)
if w.Code != http.StatusCreated && w.Code != http.StatusOK {
t.Errorf("second record: expected status 200 or 201, got %d. body: %s", w.Code, w.Body.String())
}
// Query tested_at time T2
var t2 time.Time
err = db.DB.QueryRow(context.Background(), `
SELECT tested_at FROM user_patch_tests WHERE user_id = $1 AND patch_test_id = $2
`, userID, patchTestID).Scan(&t2)
if err != nil {
t.Fatalf("failed to get tested_at: %v", err)
}
// Assert T2 > T1 (upsert updated the timestamp)
if !t2.After(t1) {
t.Errorf("expected t2 %v after t1 %v, but it's not", t2, t1)
}
}