89 lines
3.4 KiB
TypeScript
89 lines
3.4 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import type { Database } from '@atlas/database';
|
|
import { describe, it } from 'vitest';
|
|
import {
|
|
attributeBatchInputSchema,
|
|
parseInput,
|
|
refreshPolicyInputSchema,
|
|
sourceInputSchema,
|
|
syncInputSchema,
|
|
} from '../src/platform-catalog-admin/platform-catalog-admin.models.js';
|
|
import { hasSystemAdminGrant } from '../src/platform-catalog-admin/system-admin.guard.js';
|
|
|
|
describe('平台目录系统管理员边界', () => {
|
|
it('只有未撤销且用户有效的数据库授权才被视为系统管理员', async () => {
|
|
const queries: Array<{ sql: string; parameters: unknown[] }> = [];
|
|
const database = {
|
|
query: async (sql: string, parameters: unknown[]) => {
|
|
queries.push({ sql, parameters });
|
|
return { rowCount: 1, rows: [{ '?column?': 1 }] };
|
|
},
|
|
} as unknown as Database;
|
|
|
|
assert.equal(await hasSystemAdminGrant(database, 'user-1'), true);
|
|
assert.deepEqual(queries[0].parameters, ['user-1']);
|
|
assert.match(queries[0].sql, /revoked_at IS NULL/);
|
|
assert.match(queries[0].sql, /user_row\.status = 'active'/);
|
|
});
|
|
|
|
it('同步请求不能混入其他作用域字段', () => {
|
|
assert.throws(() => parseInput(syncInputSchema, {
|
|
scope: 'tree',
|
|
category_id: '3f7e8462-c23c-4a38-ae86-0f3d78503870',
|
|
}));
|
|
assert.throws(() => parseInput(syncInputSchema, {
|
|
scope: 'dictionary',
|
|
attribute_id: 'not-a-uuid',
|
|
}));
|
|
});
|
|
|
|
it('同步来源仅接受 Client-Id 与 Api-Key', () => {
|
|
assert.deepEqual(parseInput(sourceInputSchema, {
|
|
client_id: ' 12345 ',
|
|
api_key: ' secret ',
|
|
}), { client_id: '12345', api_key: 'secret' });
|
|
assert.throws(() => parseInput(sourceInputSchema, {
|
|
client_id: '12345',
|
|
api_key: 'secret',
|
|
workspace_id: 'forbidden',
|
|
}));
|
|
});
|
|
|
|
it('刷新策略要求过期天数严格大于新鲜天数', () => {
|
|
assert.deepEqual(parseInput(refreshPolicyInputSchema, {
|
|
attribute_fresh_days: 14,
|
|
attribute_expire_days: 21,
|
|
dictionary_fresh_days: 14,
|
|
dictionary_expire_days: 21,
|
|
}), {
|
|
attribute_fresh_days: 14,
|
|
attribute_expire_days: 21,
|
|
dictionary_fresh_days: 14,
|
|
dictionary_expire_days: 21,
|
|
});
|
|
assert.throws(() => parseInput(refreshPolicyInputSchema, {
|
|
attribute_fresh_days: 21,
|
|
attribute_expire_days: 21,
|
|
dictionary_fresh_days: 14,
|
|
dictionary_expire_days: 21,
|
|
}));
|
|
assert.throws(() => parseInput(refreshPolicyInputSchema, {
|
|
attribute_fresh_days: 14,
|
|
attribute_expire_days: 21,
|
|
dictionary_fresh_days: 0,
|
|
dictionary_expire_days: 21,
|
|
}));
|
|
});
|
|
|
|
it('属性同步批次只接受三种冻结范围', () => {
|
|
for (const mode of ['missing_expired', 'missing_stale_expired', 'all'] as const) {
|
|
assert.deepEqual(parseInput(attributeBatchInputSchema, { mode }), { mode });
|
|
}
|
|
assert.throws(() => parseInput(attributeBatchInputSchema, { mode: 'stale_only' }));
|
|
assert.throws(() => parseInput(attributeBatchInputSchema, {
|
|
mode: 'all',
|
|
category_id: '3f7e8462-c23c-4a38-ae86-0f3d78503870',
|
|
}));
|
|
});
|
|
});
|