package console import ( "bytes" "context" "log" "os" "path/filepath" "strings" "testing" ) // captureLog redirects the global logger for one test. Callers must not be // parallel. func captureLog(t *testing.T) *bytes.Buffer { t.Helper() var buf bytes.Buffer prev := log.Writer() log.SetOutput(&buf) t.Cleanup(func() { log.SetOutput(prev) }) return &buf } func TestClaimCheckFailureIsLogged(t *testing.T) { cases := []struct { op string breakStore func(t *testing.T, fx *consoleFixture) }{ {"HasAppIn", func(t *testing.T, fx *consoleFixture) { if _, err := fx.st.db.Exec(`DROP TABLE apps`); err != nil { t.Fatal(err) } }}, {"HasOwners", func(t *testing.T, fx *consoleFixture) { if _, err := fx.st.db.Exec(`DROP TABLE owners`); err != nil { t.Fatal(err) } }}, {"apexHolder", func(t *testing.T, fx *consoleFixture) { // A registry path whose parent is a regular file cannot be opened. file := filepath.Join(t.TempDir(), "file") if err := os.WriteFile(file, nil, 0o600); err != nil { t.Fatal(err) } fx.srv.cfg.AppsDomain = "apps.test" fx.srv.cfg.Registry = filepath.Join(file, "registry.db") }}, } for _, tc := range cases { t.Run(tc.op, func(t *testing.T) { fx := newConsoleFixture(t) acct := opsAccount(t, fx) tc.breakStore(t, fx) buf := captureLog(t) outcome, placed, held := fx.srv.claimApp(context.Background(), acct, "logged-site", "paul@keymail.dev", "", true, regionReq{}) if outcome != claimCheckFailed || placed != "" || held != nil { t.Fatalf("claimApp = %v, %q, %v; want claimCheckFailed", outcome, placed, held) } out := buf.String() for _, want := range []string{ `account="` + acct.Sqid + `"`, `app="logged-site"`, `op="` + tc.op + `"`, "err=", } { if !strings.Contains(out, want) { t.Errorf("log %q lacks %s", out, want) } } if n := strings.Count(out, "claim check failed"); n != 1 { t.Errorf("claim check failed logged %d times: %q", n, out) } }) } }