- Rename module path from github.com/patbritton/sojorn-backend to gitlab.com/patrickbritton3/sojorn/go-backend - Updated 78 references across 41 files - Matches new GitLab repository structure
104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"gitlab.com/patrickbritton3/sojorn/go-backend/internal/models"
|
|
)
|
|
|
|
func TestCreatePost_TransactionRollback(t *testing.T) {
|
|
dbURL := os.Getenv("TEST_DATABASE_URL")
|
|
if dbURL == "" {
|
|
t.Skip("TEST_DATABASE_URL not set")
|
|
}
|
|
|
|
authorIDStr := os.Getenv("TEST_AUTHOR_ID")
|
|
if authorIDStr == "" {
|
|
t.Skip("TEST_AUTHOR_ID not set")
|
|
}
|
|
|
|
authorID, err := uuid.Parse(authorIDStr)
|
|
if err != nil {
|
|
t.Fatalf("invalid TEST_AUTHOR_ID: %v", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
pool, err := pgxpool.New(ctx, dbURL)
|
|
if err != nil {
|
|
t.Fatalf("failed to connect to db: %v", err)
|
|
}
|
|
defer pool.Close()
|
|
|
|
var exists bool
|
|
if err := pool.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM public.profiles WHERE id = $1)`, authorID).Scan(&exists); err != nil {
|
|
t.Fatalf("failed to verify author profile: %v", err)
|
|
}
|
|
if !exists {
|
|
t.Skip("TEST_AUTHOR_ID not found in profiles")
|
|
}
|
|
|
|
triggerBase := strings.ReplaceAll(uuid.NewString(), "-", "")
|
|
triggerName := fmt.Sprintf("test_fail_post_metrics_%s", triggerBase)
|
|
funcName := fmt.Sprintf("test_fail_post_metrics_fn_%s", triggerBase)
|
|
|
|
createFunction := fmt.Sprintf(`
|
|
CREATE OR REPLACE FUNCTION %s() RETURNS trigger AS $$
|
|
BEGIN
|
|
RAISE EXCEPTION 'post_metrics insert blocked';
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
`, funcName)
|
|
|
|
if _, err := pool.Exec(ctx, createFunction); err != nil {
|
|
t.Skipf("skipping: failed to create trigger function: %v", err)
|
|
}
|
|
|
|
createTrigger := fmt.Sprintf(`
|
|
CREATE TRIGGER %s BEFORE INSERT ON public.post_metrics
|
|
FOR EACH ROW EXECUTE FUNCTION %s();
|
|
`, triggerName, funcName)
|
|
|
|
if _, err := pool.Exec(ctx, createTrigger); err != nil {
|
|
_ = pool.Exec(ctx, fmt.Sprintf(`DROP FUNCTION IF EXISTS %s()`, funcName))
|
|
t.Skipf("skipping: failed to create trigger: %v", err)
|
|
}
|
|
|
|
t.Cleanup(func() {
|
|
_, _ = pool.Exec(ctx, fmt.Sprintf(`DROP TRIGGER IF EXISTS %s ON public.post_metrics`, triggerName))
|
|
_, _ = pool.Exec(ctx, fmt.Sprintf(`DROP FUNCTION IF EXISTS %s()`, funcName))
|
|
})
|
|
|
|
repo := NewPostRepository(pool)
|
|
post := &models.Post{
|
|
AuthorID: authorID,
|
|
Body: "rollback test",
|
|
Status: "active",
|
|
BodyFormat: "plain",
|
|
Tags: []string{},
|
|
IsBeacon: false,
|
|
Confidence: 0.5,
|
|
IsActiveBeacon: false,
|
|
AllowChain: true,
|
|
Visibility: "public",
|
|
}
|
|
|
|
err = repo.CreatePost(ctx, post)
|
|
if err == nil {
|
|
t.Fatalf("expected CreatePost to fail due to trigger, got nil")
|
|
}
|
|
|
|
var count int
|
|
if err := pool.QueryRow(ctx, `SELECT COUNT(*) FROM public.posts WHERE id = $1`, post.ID).Scan(&count); err != nil {
|
|
t.Fatalf("failed to verify rollback: %v", err)
|
|
}
|
|
if count != 0 {
|
|
t.Fatalf("expected post rollback, found %d rows", count)
|
|
}
|
|
}
|