feat(test-setup): 🎸 run afterOrgCreated for test org and persist stable pkey to env
createTestOrg now calls the production afterOrgCreated hook directly so the test org goes through the same bootstrap as real orgs (Stripe Connect, Svix, OrgService.update). Both org branches gate createStripeAccount on the existing test_stripe_connect to stay idempotent across re-runs. Pins TEST_ORG_PUBLISHABLE_KEY (a real KSUID-generated am_pk_test_* value) and persists UNIT_TEST_AUTUMN_PUBLIC_KEY plus the auto-generated UNIT_TEST_AUTUMN_SECRET_KEY to server/.env.local + server/.env so test clients pick them up. Deletes ensureDefaultStripeAccount.ts (replaced by the gated afterOrgCreated call).
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
import chalk from "chalk";
|
||||
import inquirer from "inquirer";
|
||||
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import {
|
||||
createTestOrg,
|
||||
TEST_ORG_CONFIG,
|
||||
TEST_ORG_PUBLISHABLE_KEY,
|
||||
} from "../setupTestUtils/createTestOrg.js";
|
||||
import { mergeEnvFile } from "../dw/helpers/env-files.js";
|
||||
import { PROJECT_ROOT } from "../dw/constants.js";
|
||||
|
||||
// Worktree .env.local loading happens in scripts/preload-env.ts (auto-run by
|
||||
// Bun via bunfig.toml's `preload`). DATABASE_URL flips to the worktree branch
|
||||
@@ -57,9 +62,34 @@ async function main() {
|
||||
}
|
||||
|
||||
try {
|
||||
const hadKey = Boolean(process.env.UNIT_TEST_AUTUMN_SECRET_KEY);
|
||||
const { db } = await import("@server/db/initDrizzle.js");
|
||||
const autumnSecretKey = await createTestOrg({ db });
|
||||
|
||||
if (!hadKey) {
|
||||
const envPath = join(PROJECT_ROOT, "server", ".env.local");
|
||||
const existing = existsSync(envPath) ? readFileSync(envPath, "utf-8") : null;
|
||||
const merged = mergeEnvFile(existing, {
|
||||
UNIT_TEST_AUTUMN_SECRET_KEY: autumnSecretKey,
|
||||
});
|
||||
writeFileSync(envPath, merged);
|
||||
process.env.UNIT_TEST_AUTUMN_SECRET_KEY = autumnSecretKey;
|
||||
console.log(
|
||||
chalk.cyan(`[setup-test] persisted UNIT_TEST_AUTUMN_SECRET_KEY to server/.env.local`),
|
||||
);
|
||||
}
|
||||
|
||||
const envPath = join(PROJECT_ROOT, "server", ".env.local");
|
||||
const existing = existsSync(envPath) ? readFileSync(envPath, "utf-8") : null;
|
||||
const merged = mergeEnvFile(existing, {
|
||||
UNIT_TEST_AUTUMN_PUBLIC_KEY: TEST_ORG_PUBLISHABLE_KEY,
|
||||
});
|
||||
writeFileSync(envPath, merged);
|
||||
process.env.UNIT_TEST_AUTUMN_PUBLIC_KEY = TEST_ORG_PUBLISHABLE_KEY;
|
||||
console.log(
|
||||
chalk.cyan(`[setup-test] persisted UNIT_TEST_AUTUMN_PUBLIC_KEY to server/.env.local`),
|
||||
);
|
||||
|
||||
console.log(chalk.greenBright("\n✅ setup-test complete"));
|
||||
console.log(chalk.cyan("Org:"));
|
||||
console.log(chalk.whiteBright(` slug: ${TEST_ORG_CONFIG.slug}`));
|
||||
|
||||
@@ -15,7 +15,7 @@ import chalk from "chalk";
|
||||
import { and, eq, inArray } from "drizzle-orm";
|
||||
import { clearOrgDbOnly } from "@tests/utils/setup/clearOrg.js";
|
||||
import { setupOrg } from "@tests/utils/setup/setupOrg.js";
|
||||
import { ensureDefaultStripeAccount } from "./ensureDefaultStripeAccount.js";
|
||||
import { afterOrgCreated } from "@server/utils/authUtils/afterOrgCreated.js";
|
||||
|
||||
const TEST_ORG_CONFIG = {
|
||||
id: "org_2sWv2S8LJ9iaTjLI6UtNsfL88Kt",
|
||||
@@ -25,6 +25,8 @@ const TEST_ORG_CONFIG = {
|
||||
created_at: 1738583937426,
|
||||
};
|
||||
|
||||
export const TEST_ORG_PUBLISHABLE_KEY = "am_pk_test_3DoBu1cmlgxWqEXYiKaBKOPHqsu";
|
||||
|
||||
// Synthetic inviter pinned to the test org; satisfies invitation.inviter_id
|
||||
// NOT-NULL FK without needing a real human user in a fresh worktree branch.
|
||||
const TEST_INVITER_USER = {
|
||||
@@ -69,8 +71,14 @@ export async function createTestOrg({
|
||||
),
|
||||
);
|
||||
|
||||
await afterOrgCreated({
|
||||
org: { ...existingOrg, slug: TEST_ORG_CONFIG.slug } as any,
|
||||
user: TEST_INVITER_USER as any,
|
||||
createStripeAccount: !existingOrg.test_stripe_connect?.default_account_id,
|
||||
pkey: TEST_ORG_PUBLISHABLE_KEY,
|
||||
});
|
||||
|
||||
await seedTeamInvites({ db });
|
||||
await ensureDefaultStripeAccount({ db, orgId: TEST_ORG_CONFIG.id });
|
||||
await clearOrgDbOnly({ db, orgId: TEST_ORG_CONFIG.id, env: AppEnv.Sandbox });
|
||||
await setupOrg({ orgId: TEST_ORG_CONFIG.id, env: AppEnv.Sandbox });
|
||||
|
||||
@@ -138,8 +146,19 @@ export async function createTestOrg({
|
||||
),
|
||||
);
|
||||
|
||||
const insertedOrg = {
|
||||
id: TEST_ORG_CONFIG.id,
|
||||
slug: TEST_ORG_CONFIG.slug,
|
||||
createdAt: new Date(TEST_ORG_CONFIG.created_at),
|
||||
};
|
||||
await afterOrgCreated({
|
||||
org: insertedOrg as any,
|
||||
user: TEST_INVITER_USER as any,
|
||||
createStripeAccount: true,
|
||||
pkey: TEST_ORG_PUBLISHABLE_KEY,
|
||||
});
|
||||
|
||||
await seedTeamInvites({ db });
|
||||
await ensureDefaultStripeAccount({ db, orgId: TEST_ORG_CONFIG.id });
|
||||
await clearOrgDbOnly({ db, orgId: TEST_ORG_CONFIG.id, env: AppEnv.Sandbox });
|
||||
await setupOrg({ orgId: TEST_ORG_CONFIG.id, env: AppEnv.Sandbox });
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import chalk from "chalk";
|
||||
import type { DrizzleCli } from "@server/db/initDrizzle.js";
|
||||
import { OrgService } from "@server/internal/orgs/OrgService.js";
|
||||
import { createConnectAccount } from "@server/internal/orgs/orgUtils/createConnectAccount.js";
|
||||
|
||||
const DUMMY_USER = {
|
||||
id: "setup-test-stripe-user",
|
||||
email: "setup-test@autumn.test",
|
||||
name: "Setup Test User",
|
||||
};
|
||||
|
||||
/**
|
||||
* Idempotently ensure the test org has a default Stripe Connect sandbox
|
||||
* account. Creates one only if `test_stripe_connect.default_account_id`
|
||||
* is missing.
|
||||
*/
|
||||
export async function ensureDefaultStripeAccount({
|
||||
db,
|
||||
orgId,
|
||||
}: {
|
||||
db: DrizzleCli;
|
||||
orgId: string;
|
||||
}): Promise<void> {
|
||||
const org = await OrgService.get({ db, orgId });
|
||||
|
||||
const existingAccountId = org.test_stripe_connect?.default_account_id;
|
||||
if (existingAccountId) {
|
||||
console.log(
|
||||
chalk.yellowBright(
|
||||
`Stripe default account already connected (${existingAccountId}). Skipping.`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(chalk.blue(" 🔄 Creating default Stripe sandbox account..."));
|
||||
|
||||
const newAccount = await createConnectAccount({
|
||||
org: org as any,
|
||||
user: DUMMY_USER as any,
|
||||
});
|
||||
|
||||
await OrgService.update({
|
||||
db,
|
||||
orgId,
|
||||
updates: {
|
||||
test_stripe_connect: {
|
||||
...org.test_stripe_connect,
|
||||
default_account_id: newAccount.id,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(
|
||||
chalk.greenBright(
|
||||
` ✅ Created default Stripe sandbox account: ${newAccount.id}`,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import chalk from "chalk";
|
||||
import { config } from "dotenv";
|
||||
import { TEST_ORG_PUBLISHABLE_KEY } from "./createTestOrg.js";
|
||||
|
||||
// Get the directory of this script file
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
@@ -94,6 +95,7 @@ export function updateEnvFile({
|
||||
// Update with new test variables
|
||||
envVars.set("TESTS_ORG", testOrgSlug);
|
||||
envVars.set("TESTS_ORG_ID", testOrgId);
|
||||
envVars.set("UNIT_TEST_AUTUMN_PUBLIC_KEY", TEST_ORG_PUBLISHABLE_KEY);
|
||||
|
||||
// Only update the secret key if a new one was generated
|
||||
if (autumnSecretKey) {
|
||||
@@ -127,6 +129,7 @@ export function updateEnvFile({
|
||||
// Skip test-related vars from existing content - we'll add them fresh
|
||||
if (
|
||||
trimmed.startsWith("TESTS_ORG") ||
|
||||
trimmed.startsWith("UNIT_TEST_AUTUMN_PUBLIC_KEY") ||
|
||||
trimmed.startsWith("UNIT_TEST_AUTUMN_SECRET_KEY") ||
|
||||
trimmed.startsWith("STRIPE_TEST_KEY") ||
|
||||
trimmed.startsWith("UPSTASH_REDIS_REST") ||
|
||||
@@ -148,6 +151,7 @@ export function updateEnvFile({
|
||||
"# Test Configuration",
|
||||
`TESTS_ORG=${testOrgSlug}`,
|
||||
`TESTS_ORG_ID=${testOrgId}`,
|
||||
`UNIT_TEST_AUTUMN_PUBLIC_KEY=${TEST_ORG_PUBLISHABLE_KEY}`,
|
||||
];
|
||||
|
||||
// Only add secret key if it was generated/updated
|
||||
|
||||
Reference in New Issue
Block a user