diff --git a/packages/cli/src/commands/database/seed/index.ts b/packages/cli/src/commands/database/seed/index.ts index fd5ae1281..c718fda5f 100644 --- a/packages/cli/src/commands/database/seed/index.ts +++ b/packages/cli/src/commands/database/seed/index.ts @@ -7,9 +7,9 @@ import { consoleLog, oraPromise } from '../../../utils.js'; import { getLatestAlterationTimestamp } from '../alteration/index.js'; import { getAlterationDirectory } from '../alteration/utils.js'; -import { createTables, seedCloud, seedTables } from './tables.js'; +import { createTables, seedCloud, seedTables, seedTest } from './tables.js'; -export const seedByPool = async (pool: DatabasePool, cloud = false) => { +export const seedByPool = async (pool: DatabasePool, cloud = false, test = false) => { await pool.transaction(async (connection) => { // Check alteration scripts available in order to insert correct timestamp const latestTimestamp = await getLatestAlterationTimestamp(); @@ -29,10 +29,17 @@ export const seedByPool = async (pool: DatabasePool, cloud = false) => { if (cloud) { await seedCloud(connection); } + + if (test) { + await seedTest(connection); + } }); }; -const seed: CommandModule, { swe?: boolean; cloud?: boolean }> = { +const seed: CommandModule< + Record, + { swe?: boolean; cloud?: boolean; test?: boolean } +> = { command: 'seed [type]', describe: 'Create database then seed tables and data', builder: (yargs) => @@ -45,9 +52,12 @@ const seed: CommandModule, { swe?: boolean; cloud?: bool .option('cloud', { describe: 'Seed additional cloud data', type: 'boolean', - hidden: true, + }) + .option('test', { + describe: 'Seed additional test data', + type: 'boolean', }), - handler: async ({ swe, cloud }) => { + handler: async ({ swe, cloud, test }) => { const pool = await createPoolAndDatabaseIfNeeded(); if (swe && (await doesConfigsTableExist(pool))) { @@ -58,7 +68,7 @@ const seed: CommandModule, { swe?: boolean; cloud?: bool } try { - await seedByPool(pool, cloud); + await seedByPool(pool, cloud, test); } catch (error: unknown) { consoleLog.error(error); consoleLog.error( diff --git a/packages/cli/src/commands/database/seed/tables.ts b/packages/cli/src/commands/database/seed/tables.ts index 29714f2c3..9e5a15047 100644 --- a/packages/cli/src/commands/database/seed/tables.ts +++ b/packages/cli/src/commands/database/seed/tables.ts @@ -14,8 +14,12 @@ import { createCloudApi, createTenantApplicationRole, CloudScope, + Roles, + type Role, + UsersRoles, } from '@logto/schemas'; import { Tenants } from '@logto/schemas/models'; +import { convertToIdentifiers, generateStandardId } from '@logto/shared'; import type { DatabaseTransactionConnection } from 'slonik'; import { sql } from 'slonik'; import { raw } from 'slonik-sql-tag-raw'; @@ -176,3 +180,52 @@ export const seedCloud = async (connection: DatabaseTransactionConnection) => { seedTenantCloudServiceApplication(connection, adminTenantId), ]); }; + +/** + * Seed additional test data for integration or alteration tests. + * + * It will create two users to the admin tenant (`test-1` and `test-2`), and do the following: + * + * - `test-1` will be assigned the management roles for both `default` and `admin` tenant. + * - `test-2` will be assigned the management role for `default` tenant. + */ +export const seedTest = async (connection: DatabaseTransactionConnection) => { + const roles = convertToIdentifiers(Roles); + const getManagementRole = async (tenantId: string) => + connection.one(sql` + select ${roles.fields.id} + from ${roles.table} + where ${roles.fields.tenantId} = ${adminTenantId} + and ${roles.fields.name} = ${`${tenantId}:admin`} + `); + + const assignRoleToUser = async (userId: string, roleId: string) => + connection.query( + insertInto( + { id: generateStandardId(), userId, roleId, tenantId: adminTenantId }, + UsersRoles.table + ) + ); + + await Promise.all([ + connection.query( + insertInto({ id: 'test-1', username: 'test1', tenantId: adminTenantId }, 'users') + ), + connection.query( + insertInto({ id: 'test-2', username: 'test2', tenantId: adminTenantId }, 'users') + ), + ]); + + consoleLog.succeed('Created test users'); + + const adminTenantRole = await getManagementRole(adminTenantId); + const defaultTenantRole = await getManagementRole(defaultTenantId); + + await Promise.all([ + assignRoleToUser('test-1', adminTenantRole.id), + assignRoleToUser('test-1', defaultTenantRole.id), + assignRoleToUser('test-2', defaultTenantRole.id), + ]); + + consoleLog.succeed('Assigned tenant management roles to the test users'); +};