qwen_2.5_model / src /database /data-source.spec.ts
Muhammad Noman
Configure managed services for Hugging Face Space
b58ffca
Raw
History Blame Contribute Delete
5.22 kB
import { globSync } from 'glob';
import dataDataSource, { postgresDataSourceOptions, buildPostgresDataSourceOptions } from './data-source';
// The data CLI DataSource manages the DATA connection's migrations (session/webhook/message/
// template/engine). It must NOT pull in the auth/audit entities — those belong to the always-SQLite
// MAIN connection (data-source-main.ts). A broad '**' entity glob would sweep the main-owned
// entities into `migration:generate` against the data DB and emit spurious auth/audit DDL.
describe('data CLI DataSource', () => {
const resolveEntityFiles = (): string[] =>
(dataDataSource.options.entities as string[])
.flatMap(pattern => globSync(pattern))
.map(file => file.replace(/\\/g, '/'));
it('resolves the data-owned entities (session, webhook, message, template, engine)', () => {
const files = resolveEntityFiles();
expect(files.some(f => f.endsWith('session.entity.ts'))).toBe(true);
expect(files.some(f => f.endsWith('webhook.entity.ts'))).toBe(true);
expect(files.some(f => f.endsWith('message.entity.ts'))).toBe(true);
expect(files.some(f => f.endsWith('template.entity.ts'))).toBe(true);
expect(files.some(f => f.endsWith('lid-mapping.entity.ts'))).toBe(true);
});
it('never resolves the main-owned api-key/audit-log entities', () => {
const files = resolveEntityFiles();
expect(files.some(f => f.endsWith('api-key.entity.ts'))).toBe(false);
expect(files.some(f => f.endsWith('audit-log.entity.ts'))).toBe(false);
});
it('does not use a catch-all entity glob (guards against re-broadening)', () => {
for (const pattern of dataDataSource.options.entities as string[]) {
expect(pattern).not.toMatch(/\/\.\.\/\*\*\/\*\.entity/);
}
});
});
// The migration CLI connection runs DDL (CREATE INDEX, unique backfills) that can legitimately take
// minutes on a large table. It must carry pool/connection timeouts for resilience but MUST NOT carry a
// server-side statement_timeout, or a long migration would be aborted mid-flight.
describe('Postgres migration connection pool timeouts', () => {
const extra = postgresDataSourceOptions.extra as Record<string, number | undefined>;
it('sets idle and connection pool timeouts', () => {
expect(extra.idleTimeoutMillis).toBe(30000);
expect(extra.connectionTimeoutMillis).toBe(10000);
});
it('never sets statement_timeout (would abort long-running migrations)', () => {
expect(extra.statement_timeout).toBeUndefined();
});
});
describe('Postgres migration connection with DATABASE_URL', () => {
it('uses URL credentials and TLS instead of the split-variable defaults', () => {
const opts = buildPostgresDataSourceOptions({
DATABASE_HOST: 'localhost',
DATABASE_NAME: 'openwa',
DATABASE_URL: 'postgres://db-user:db-password@postgres.example.test:28171/defaultdb?sslmode=require',
}) as {
type?: string;
host?: string;
port?: number;
username?: string;
password?: string;
database?: string;
ssl?: unknown;
};
expect(opts).toMatchObject({
type: 'postgres',
host: 'postgres.example.test',
port: 28171,
username: 'db-user',
password: 'db-password',
database: 'defaultdb',
ssl: { rejectUnauthorized: true },
});
});
});
// POSTGRES_SCHEMA: a non-public schema sets TypeORM's `schema` option AND the session search_path (via
// pg's startup `options` param) so the project's raw, unqualified migration DDL + the typeorm_migrations
// ledger resolve to the configured schema. The default (public) path stays byte-identical to the
// pre-schema-selection behavior — no `options` key is added. The builder is tested directly so no
// process.env mutation or module reload is needed.
describe('PostgreSQL schema selection (POSTGRES_SCHEMA)', () => {
// The builder returns the broad DataSourceOptions union; narrow to the postgres-specific fields
// under test (both are optional on the union — schema only on postgres, extra on every member).
type PgOpts = { schema?: string; extra?: Record<string, unknown> };
it('defaults schema to "public" and does NOT set a search_path when POSTGRES_SCHEMA is unset', () => {
const opts = buildPostgresDataSourceOptions({}) as PgOpts;
expect(opts.schema).toBe('public');
expect(opts.extra?.options).toBeUndefined();
});
it('passes schema through and sets extra.options search_path for a non-public schema', () => {
const opts = buildPostgresDataSourceOptions({ POSTGRES_SCHEMA: 'openwa' }) as PgOpts;
expect(opts.schema).toBe('openwa');
expect(opts.extra?.options).toBe('-c search_path=openwa,public');
});
it('keeps the pool timeouts under a custom schema (only adds options; never drops them or adds statement_timeout)', () => {
const opts = buildPostgresDataSourceOptions({ POSTGRES_SCHEMA: 'openwa' }) as PgOpts;
expect(opts.extra?.max).toBe(10);
expect(opts.extra?.idleTimeoutMillis).toBe(30000);
expect(opts.extra?.connectionTimeoutMillis).toBe(10000);
// the migration connection must STILL never carry a statement_timeout
expect(opts.extra?.statement_timeout).toBeUndefined();
});
});