chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { ColumnType } from '@insforge/shared-schemas';
|
||||
import { DatabaseTableService } from '../../src/services/database/database-table.service';
|
||||
|
||||
const queryMock = vi.fn();
|
||||
const releaseMock = vi.fn();
|
||||
const connectMock = vi.fn();
|
||||
|
||||
vi.mock('../../src/infra/database/database.manager', () => ({
|
||||
DatabaseManager: {
|
||||
getInstance: vi.fn(() => ({
|
||||
getPool: vi.fn(() => ({
|
||||
connect: connectMock,
|
||||
query: queryMock,
|
||||
})),
|
||||
})),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('DatabaseTableService project_admin DDL context', () => {
|
||||
let service: DatabaseTableService;
|
||||
let tableExists = false;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
tableExists = false;
|
||||
service = DatabaseTableService.getInstance();
|
||||
|
||||
connectMock.mockResolvedValue({
|
||||
query: queryMock,
|
||||
release: releaseMock,
|
||||
});
|
||||
|
||||
queryMock.mockImplementation(async (sql: string) => {
|
||||
if (sql.includes('SELECT EXISTS')) {
|
||||
return { rows: [{ exists: tableExists }], rowCount: 1 };
|
||||
}
|
||||
|
||||
if (sql.includes('FROM information_schema.columns')) {
|
||||
return {
|
||||
rows: [
|
||||
{
|
||||
column_name: 'id',
|
||||
data_type: 'uuid',
|
||||
udt_name: 'uuid',
|
||||
is_nullable: 'NO',
|
||||
column_default: 'gen_random_uuid()',
|
||||
character_maximum_length: null,
|
||||
},
|
||||
{
|
||||
column_name: 'title',
|
||||
data_type: 'text',
|
||||
udt_name: 'text',
|
||||
is_nullable: 'YES',
|
||||
column_default: null,
|
||||
character_maximum_length: null,
|
||||
},
|
||||
],
|
||||
rowCount: 2,
|
||||
};
|
||||
}
|
||||
|
||||
if (sql.includes("tc.constraint_type = 'FOREIGN KEY'")) {
|
||||
return { rows: [], rowCount: 0 };
|
||||
}
|
||||
|
||||
if (sql.includes("AND constraint_type = 'PRIMARY KEY'")) {
|
||||
return { rows: [{ column_name: 'id' }], rowCount: 1 };
|
||||
}
|
||||
|
||||
if (sql.includes("AND tc.constraint_type = 'UNIQUE'")) {
|
||||
return { rows: [], rowCount: 0 };
|
||||
}
|
||||
|
||||
if (sql.includes('COUNT(*) as row_count')) {
|
||||
return { rows: [{ row_count: '0' }], rowCount: 1 };
|
||||
}
|
||||
|
||||
return { rows: [], rowCount: 0 };
|
||||
});
|
||||
});
|
||||
|
||||
it('creates dashboard tables as project_admin', async () => {
|
||||
await service.createTable(
|
||||
'public',
|
||||
'posts',
|
||||
[{ columnName: 'title', type: ColumnType.STRING, isNullable: false }],
|
||||
[],
|
||||
true
|
||||
);
|
||||
|
||||
const sqlCalls = queryMock.mock.calls.map(([sql]) => sql as string);
|
||||
const setRoleIndex = sqlCalls.indexOf('SET LOCAL ROLE project_admin');
|
||||
const createTableIndex = sqlCalls.findIndex((sql) =>
|
||||
sql.includes('CREATE TABLE "public"."posts"')
|
||||
);
|
||||
const resetRoleIndex = sqlCalls.indexOf('RESET ROLE');
|
||||
const commitIndex = sqlCalls.indexOf('COMMIT');
|
||||
|
||||
expect(setRoleIndex).toBeGreaterThan(-1);
|
||||
expect(createTableIndex).toBeGreaterThan(setRoleIndex);
|
||||
expect(resetRoleIndex).toBeGreaterThan(createTableIndex);
|
||||
expect(commitIndex).toBeGreaterThan(resetRoleIndex);
|
||||
});
|
||||
|
||||
it('updates dashboard table schema as project_admin', async () => {
|
||||
tableExists = true;
|
||||
|
||||
await service.updateTableSchema('public', 'posts', {
|
||||
addColumns: [{ columnName: 'summary', type: ColumnType.STRING, isNullable: true }],
|
||||
});
|
||||
|
||||
const sqlCalls = queryMock.mock.calls.map(([sql]) => sql as string);
|
||||
const setRoleIndex = sqlCalls.indexOf('SET LOCAL ROLE project_admin');
|
||||
const alterTableIndex = sqlCalls.findIndex(
|
||||
(sql) => sql.includes('ALTER TABLE "public"."posts"') && sql.includes('ADD COLUMN "summary"')
|
||||
);
|
||||
const resetRoleIndex = sqlCalls.indexOf('RESET ROLE');
|
||||
const commitIndex = sqlCalls.indexOf('COMMIT');
|
||||
|
||||
expect(setRoleIndex).toBeGreaterThan(-1);
|
||||
expect(alterTableIndex).toBeGreaterThan(setRoleIndex);
|
||||
expect(resetRoleIndex).toBeGreaterThan(alterTableIndex);
|
||||
expect(commitIndex).toBeGreaterThan(resetRoleIndex);
|
||||
});
|
||||
|
||||
it('deletes dashboard tables as project_admin', async () => {
|
||||
await service.deleteTable('public', 'posts');
|
||||
|
||||
const sqlCalls = queryMock.mock.calls.map(([sql]) => sql as string);
|
||||
const setRoleIndex = sqlCalls.indexOf('SET LOCAL ROLE project_admin');
|
||||
const dropTableIndex = sqlCalls.findIndex((sql) =>
|
||||
sql.includes('DROP TABLE IF EXISTS "public"."posts" CASCADE')
|
||||
);
|
||||
const resetRoleIndex = sqlCalls.indexOf('RESET ROLE');
|
||||
const commitIndex = sqlCalls.indexOf('COMMIT');
|
||||
|
||||
expect(setRoleIndex).toBeGreaterThan(-1);
|
||||
expect(dropTableIndex).toBeGreaterThan(setRoleIndex);
|
||||
expect(resetRoleIndex).toBeGreaterThan(dropTableIndex);
|
||||
expect(commitIndex).toBeGreaterThan(resetRoleIndex);
|
||||
});
|
||||
|
||||
it('delegates protected-schema create attempts to project_admin privileges', async () => {
|
||||
await service.createTable(
|
||||
'auth',
|
||||
'users_copy',
|
||||
[{ columnName: 'email', type: ColumnType.STRING, isNullable: false }],
|
||||
[],
|
||||
true
|
||||
);
|
||||
|
||||
const sqlCalls = queryMock.mock.calls.map(([sql]) => sql as string);
|
||||
const setRoleIndex = sqlCalls.indexOf('SET LOCAL ROLE project_admin');
|
||||
const createTableIndex = sqlCalls.findIndex((sql) =>
|
||||
sql.includes('CREATE TABLE "auth"."users_copy"')
|
||||
);
|
||||
|
||||
expect(setRoleIndex).toBeGreaterThan(-1);
|
||||
expect(createTableIndex).toBeGreaterThan(setRoleIndex);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user