| index 24ddf82aa..15e887bf7 100644 |
| --- a/internal/console/plancaps_doors_test.go |
| +++ b/internal/console/plancaps_doors_test.go |
| @@ -223,3 +223,64 @@ func TestInstanceAndSidecarCreateWithoutACatalogUnchanged(t *testing.T) { |
| t.Fatalf("sidecar create with no catalog = %d %s", status, out) |
| } |
| } |
| + |
| +func accountCount(t *testing.T, fx *consoleFixture) int { |
| + t.Helper() |
| + all, err := fx.st.Accounts() |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + return len(all) |
| +} |
| + |
| +func TestNewAccountRefusedForASecondFreeAccount(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.srv.cfg.PlanCatalog = examplePlanCatalog(t) |
| + before := accountCount(t, fx) |
| + token := cliToken(t, fx, "paul@keymail.dev", "code-cap-acct") |
| + status, out := postJSON(t, fx.ts.URL+"/auth/cli/accounts", map[string]string{"name": "second"}, token) |
| + if status != http.StatusConflict || out["code"] != "cap" { |
| + t.Fatalf("CLI second free account = %d %v, want 409 cap", status, out) |
| + } |
| + c := signInPaul(t, fx) |
| + st, loc, _ := postForm(t, c, fx.ts.URL+"/accounts/new", url.Values{"csrf": {sessionToken(t, fx, c)}, "name": {"thirdtry"}}) |
| + if st != http.StatusSeeOther || loc != "/accounts/new" { |
| + t.Fatalf("browser second free account = %d -> %q, want the flash redirect back to /accounts/new", st, loc) |
| + } |
| + if after := accountCount(t, fx); after != before { |
| + t.Fatalf("accounts %d -> %d: one was minted past the cap", before, after) |
| + } |
| +} |
| + |
| +func TestFirstAccountIsNeverRefused(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.srv.cfg.PlanCatalog = examplePlanCatalog(t) |
| + signInAs(t, fx, "newcomer@keymail.dev", "code-cap-first") |
| + accts, err := fx.st.AccountsFor("newcomer@keymail.dev") |
| + if err != nil || len(accts) != 1 { |
| + t.Fatalf("first sign-in with plans on: %d accounts, %v; want the auto-minted one", len(accts), err) |
| + } |
| +} |
| + |
| +func TestNewAccountAllowedWhenTheOtherIsPaid(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + fx.srv.cfg.PlanCatalog = examplePlanCatalog(t) |
| + ops, _ := fx.st.AccountBySqid(fx.sqid) |
| + if _, err := fx.st.SetAccountPlan(ops.ID, "personal", nil, PlanSourceOperator, nil, "r", "ops@example.com", planNow); err != nil { |
| + t.Fatal(err) |
| + } |
| + token := cliToken(t, fx, "paul@keymail.dev", "code-cap-acct-paid") |
| + if status, out := postJSON(t, fx.ts.URL+"/auth/cli/accounts", map[string]string{"name": "second"}, token); status != http.StatusOK { |
| + t.Fatalf("a first free account beside a paid one = %d %v", status, out) |
| + } |
| +} |
| + |
| +func TestNewAccountWithoutACatalogUnchanged(t *testing.T) { |
| + fx := newConsoleFixture(t) |
| + token := cliToken(t, fx, "paul@keymail.dev", "code-cap-acct-nocat") |
| + for _, name := range []string{"one", "two"} { |
| + if status, out := postJSON(t, fx.ts.URL+"/auth/cli/accounts", map[string]string{"name": name}, token); status != http.StatusOK { |
| + t.Fatalf("account %s with no catalog = %d %v", name, status, out) |
| + } |
| + } |
| +} |