Add separate production, testserver, and demo deployments
CI / test (push) Failing after 10s

This commit is contained in:
2026-09-14 19:58:31 +02:00
parent b87aa0aa17
commit d06ff4a94a
37 changed files with 1293 additions and 121 deletions
+60
View File
@@ -22,6 +22,8 @@ type fakeAdminStore struct {
setRoleCalls int
addMemberCalls int
lastRole string
demoResetCalls int
demoResetInput demoResetInput
}
func (s *fakeAdminStore) Ping(context.Context) error { return nil }
@@ -71,6 +73,11 @@ func (s *fakeAdminStore) AddGardenMember(_ context.Context, gardenID int, email,
s.lastRole = role
return gardenMemberView{GardenID: gardenID, UserID: 42, Email: email, Role: role}, nil
}
func (s *fakeAdminStore) ResetDemo(_ context.Context, input demoResetInput) (demoResetResult, error) {
s.demoResetCalls++
s.demoResetInput = input
return demoResetResult{Email: input.Email, Garden: "Sonnengarten", Images: 3, Locations: 8, Species: 12, Plants: 16, Tasks: 16, Journal: 6, Attachments: 1}, nil
}
func newTestApplication(t *testing.T, stdin string, store adminStore) (*application, *bytes.Buffer, *bytes.Buffer) {
t.Helper()
@@ -124,6 +131,59 @@ func TestCreateInvitedUserGeneratesCredentialsAndJSON(t *testing.T) {
}
}
func TestDemoResetRequiresExplicitEnablement(t *testing.T) {
store := new(fakeAdminStore)
app, _, _ := newTestApplication(t, "correct horse battery staple\n", store)
err := app.run(context.Background(), []string{"--yes", "demo", "reset", "--password-stdin"})
if err == nil || !strings.Contains(err.Error(), "GARDOMATIC_DEMO_RESET_ENABLED") {
t.Fatalf("run() error = %v, want disabled demo reset error", err)
}
if store.demoResetCalls != 0 {
t.Fatalf("ResetDemo calls = %d, want 0", store.demoResetCalls)
}
}
func TestDemoResetRequiresYes(t *testing.T) {
store := new(fakeAdminStore)
app, _, _ := newTestApplication(t, "correct horse battery staple\n", store)
t.Setenv("GARDOMATIC_DEMO_RESET_ENABLED", "true")
err := app.run(context.Background(), []string{"demo", "reset", "--password-stdin"})
if err == nil || !strings.Contains(err.Error(), "--yes") {
t.Fatalf("run() error = %v, want --yes error", err)
}
if store.demoResetCalls != 0 {
t.Fatalf("ResetDemo calls = %d, want 0", store.demoResetCalls)
}
}
func TestDemoResetHashesPasswordAndWritesSummary(t *testing.T) {
store := new(fakeAdminStore)
app, stdout, _ := newTestApplication(t, "correct horse battery staple\n", store)
t.Setenv("GARDOMATIC_DEMO_RESET_ENABLED", "true")
err := app.run(context.Background(), []string{
"--yes", "demo", "reset", "--password-stdin",
"--name", " Schaugarten ", "--email", "besuch@example.com",
})
if err != nil {
t.Fatalf("run() returned an error: %v", err)
}
if store.demoResetCalls != 1 {
t.Fatalf("ResetDemo calls = %d, want 1", store.demoResetCalls)
}
if store.demoResetInput.Name != "Schaugarten" || store.demoResetInput.Email != "besuch@example.com" {
t.Errorf("ResetDemo input = %+v", store.demoResetInput)
}
if err = bcrypt.CompareHashAndPassword(store.demoResetInput.PasswordHash, []byte("correct horse battery staple")); err != nil {
t.Errorf("stored password hash does not match input: %v", err)
}
if !strings.Contains(stdout.String(), "Demo reset complete") || !strings.Contains(stdout.String(), "Plants: 16") {
t.Errorf("output = %q", stdout.String())
}
}
func TestCreateUserRequiresExactlyOneAccountMode(t *testing.T) {
store := new(fakeAdminStore)
app, _, _ := newTestApplication(t, "", store)