//go:build dbtest // seed_db_test.go — seedDemoData 的 DB-backed(dbBacked=true)整合測試。 // // Owner: testing agent(補測任務 — cmd/api-server 可測部分,DB 分支) // // build tag `dbtest`:只在 `go test -tags=dbtest` 時編譯/執行(需 Docker)。 // 本機無 Docker,由 Orchestrator 在 130 跑: // // DOCKER_HOST=tcp://192.168.0.130:2375 TESTCONTAINERS_RYUK_DISABLED=true \ // go test -tags=dbtest ./cmd/api-server/ -run TestSeedDemoData_DBBacked -count=1 // // 對齊 seed.go docstring 的 DB-backed 契約: // - 先 upsert demoSeedUserID 對應 users 列(滿足 models/devices/pairing_tokens 的 owner FK)。 // - model/device id 改用合法 UUID(非雛形字串),owner 統一為 demoSeedUserID。 // - 全部落 Postgres(用真 PG repository,非 in-memory)。 package main import ( "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "visiona-backend/internal/auth" "visiona-backend/internal/db/testsupport" "visiona-backend/internal/device" "visiona-backend/internal/model" "visiona-backend/internal/user" ) // TestSeedDemoData_DBBacked_UpsertsUserAndSeedsAll:DB-backed seed 應 // 1. upsert demoSeedUserID 進 users(滿足 FK) // 2. 用 demoSeedUserID 當 owner 建 device + model + pairing token(全落 PG) func TestSeedDemoData_DBBacked_UpsertsUserAndSeedsAll(t *testing.T) { tdb := testsupport.SetupTestDB(t) tdb.Truncate(t, "pairing_tokens", "session_tokens", "models", "devices", "users") ctx := context.Background() devRepo := device.NewPostgresRepository(tdb.Pool) mdlRepo := model.NewPostgresRepository(tdb.Pool) pairings := auth.NewPostgresPairingStore(tdb.Pool) userStore := user.NewPostgresStore(tdb.Pool) // userID 傳入雛形 StaticUserID(非 UUID)—— DB-backed 分支應忽略它、改用 demoSeedUserID。 require.NoError(t, seedDemoData( devRepo, mdlRepo, pairings, userStore, "demo-user", true /* dbBacked */, discardLog(), )) // 1. demo user 已 upsert(owner FK 前提) u, err := userStore.Get(ctx, demoSeedUserID) require.NoError(t, err, "DB-backed seed 應 upsert demoSeedUserID") assert.Equal(t, "demo@visiona.local", u.Email) // 2. device:owner = demoSeedUserID(非傳入的 demo-user) devs, err := devRepo.List(ctx, demoSeedUserID) require.NoError(t, err) require.Len(t, devs, 1, "DB-backed seed 應建 1 個 device 掛在 demoSeedUserID") assert.Equal(t, demoSeedUserID, devs[0].OwnerUserID) assert.Equal(t, "kl520", devs[0].DeviceType) // 註:device 確實掛在 demoSeedUserID(上方斷言已證),且 owner_user_id 為 UUID 欄位, // 傳入的非-UUID "demo-user" 在型別上不可能成為任何 device 的 owner,故無需另查(查了反而會被 PG reject)。 // 3. model:owner = demoSeedUserID mdls, err := mdlRepo.List(ctx, model.ListFilter{OwnerUserID: demoSeedUserID}) require.NoError(t, err) require.Len(t, mdls, 1, "DB-backed seed 應建 1 個 model 掛在 demoSeedUserID") assert.Equal(t, demoSeedUserID, mdls[0].OwnerUserID) assert.Equal(t, model.SourceUploaded, mdls[0].Source) // 4. pairing token:owner = demoSeedUserID tokens, err := pairings.List(ctx, demoSeedUserID) require.NoError(t, err) require.Len(t, tokens, 1, "DB-backed seed 應建 1 個 pairing token 掛在 demoSeedUserID") assert.Equal(t, demoSeedUserID, tokens[0].UserID) } // TestSeedDemoData_DBBacked_GeneratesUUIDIDs:DB-backed 分支的 model/device id 必須是合法 UUID // (schema 的 id 欄位為 UUID + FK;雛形的 "demo-model-xxx" 字串會違反型別)。 func TestSeedDemoData_DBBacked_GeneratesUUIDIDs(t *testing.T) { tdb := testsupport.SetupTestDB(t) tdb.Truncate(t, "pairing_tokens", "session_tokens", "models", "devices", "users") ctx := context.Background() devRepo := device.NewPostgresRepository(tdb.Pool) mdlRepo := model.NewPostgresRepository(tdb.Pool) pairings := auth.NewPostgresPairingStore(tdb.Pool) userStore := user.NewPostgresStore(tdb.Pool) require.NoError(t, seedDemoData( devRepo, mdlRepo, pairings, userStore, "demo-user", true, discardLog(), )) devs, err := devRepo.List(ctx, demoSeedUserID) require.NoError(t, err) require.Len(t, devs, 1) assert.Regexp(t, `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`, devs[0].ID, "DB-backed device id 應為合法 UUID") mdls, err := mdlRepo.List(ctx, model.ListFilter{OwnerUserID: demoSeedUserID}) require.NoError(t, err) require.Len(t, mdls, 1) assert.Regexp(t, `^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`, mdls[0].ID, "DB-backed model id 應為合法 UUID") }