package api_test import ( "encoding/json" "net/http" "testing" "atlas9.dev/c/core/assert" "atlas9.dev/c/demo/api" "atlas9.dev/c/demo/store" ) // After registering, verifying, and logging in, a fresh user should be able // to list the tenants they belong to (at minimum, their personal tenant). func TestAccountApi_RegisterVerifyLogin_ListTenants(t *testing.T) { s := startServer(t) s.logout(t) email, password := "new@test", "pass" var reg api.Account_RegisterRes regRes := s.call(t, "/Account_Register", api.Account_RegisterReq{ Email: email, Password: password, }, ®) assert.Eq(t, regRes.StatusCode, http.StatusOK) token := fetchEmailVerificationToken(t, s) verifyRes := s.call(t, "/Account_Verify", api.Account_VerifyReq{Token: token}, nil) assert.Eq(t, verifyRes.StatusCode, http.StatusOK) s.login(t, email, password) // A provisioned user gets an owner grant in their personal tenant. var list api.Grants_ListByTenantRes listRes := s.call(t, "/Grants_ListByTenant", api.Grants_ListByTenantReq{ Tenant: reg.UserID, }, &list) assert.Eq(t, listRes.StatusCode, http.StatusOK) if len(list.Page.Items) != 1 { t.Fatalf("len(items) = %d, want 1", len(list.Page.Items)) } assert.Eq(t, list.Page.Items[0].Tenant, reg.UserID) assert.Eq(t, list.Page.Items[0].Principal, reg.UserID.String()) assert.Eq(t, list.Page.Items[0].Role, "owner") } // A token from a resent verification email must work the same as the one // from registration. Regression test: ResendVerification used to queue only // the token key (not key.secret), producing links that always failed. func TestAccountApi_ResendVerification_TokenVerifies(t *testing.T) { s := startServer(t) s.logout(t) email, password := "resend@test", "pass" regRes := s.call(t, "/Account_Register", api.Account_RegisterReq{ Email: email, Password: password, }, nil) assert.Eq(t, regRes.StatusCode, http.StatusOK) resendRes := s.call(t, "/Account_ResendVerification", api.Account_ResendVerificationReq{ Email: email, }, nil) assert.Eq(t, resendRes.StatusCode, http.StatusOK) token := fetchEmailVerificationToken(t, s) verifyRes := s.call(t, "/Account_Verify", api.Account_VerifyReq{Token: token}, nil) assert.Eq(t, verifyRes.StatusCode, http.StatusOK) } // fetchEmailVerificationToken pulls the most recent email verification task // payload from the queue and returns the token the user would receive by email. func fetchEmailVerificationToken(t *testing.T, s *testServer) string { t.Helper() var payload string err := s.DB.QueryRowContext(t.Context(), `SELECT payload FROM email_verification_tasks ORDER BY id DESC LIMIT 1`, ).Scan(&payload) assert.Ok(t, err) var task store.EmailVerificationTask assert.Ok(t, json.Unmarshal([]byte(payload), &task)) return task.Token }