godcrm/backend/tests/owner-space-auto-create.test.js
GOD CRM Release f89e074dd1
Some checks failed
CI / Lint / Typecheck / Test / Build (push) Has been cancelled
CI / PostgreSQL Integration Tests (push) Has been cancelled
GOD CRM — public scrubbed snapshot
Governed substrate for autonomous agents: scoped identity (passports),
audited actions, MCP workspace. Infra IPs and secrets redacted for public release.
2026-08-10 04:01:45 +03:00

362 lines
11 KiB
JavaScript

// Owner Space Auto-Creation Tests - v0.002.007
// TDD: RED Phase - Tests должны упасть, т.к. функционал еще не реализован
process.env.TEST_MODE = 'true';
process.env.MASTER_ENCRYPTION_KEY = 'test_master_key_32_characters_long!';
import { describe, test, expect, beforeEach, afterEach } from 'vitest';
import { setupTestDatabase, cleanupTestDatabase } from './helpers/test-db.js';
import { dbGet, dbAll } from '../database/connection.js';
import { registerUser } from '../services/AuthService.js';
describe.skip('Owner Space Auto-Creation - Full TDD', () => {
beforeEach(async () => {
process.env.SKIP_DEV_USER = 'true';
await setupTestDatabase();
});
afterEach(async () => {
await cleanupTestDatabase();
});
// ============================================================
// Phase 1: Owner Registration + Admin Owner's Space
// ============================================================
describe.skip('Phase 1: Owner Registration', () => {
test('1.1: First user becomes owner with role', async () => {
const user = await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'John Owner'
});
expect(user).toBeDefined();
expect(user.id).toBe(1);
expect(user.role).toBe('owner'); // ❌ FAIL: role is undefined or 'user'
});
test('1.2: Admin Owners Space project created', async () => {
const owner = await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'John Owner'
});
const adminSpace = await dbGet(
'SELECT * FROM projects WHERE owner_id = ? AND type = ?',
[owner.id, 'admin_owner_space']
);
expect(adminSpace).toBeDefined();
expect(adminSpace.name).toBe("Admin Owner's Space");
expect(adminSpace.icon).toBe('⚙️');
expect(adminSpace.theme_primary).toBe('#ef4444'); // Red
expect(adminSpace.theme_secondary).toBe('#f97316'); // Orange
expect(adminSpace.theme_tertiary).toBe('#eab308'); // Yellow
});
test('1.3: Users system table created in Admin Space', async () => {
const owner = await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'John Owner'
});
const adminSpace = await dbGet(
'SELECT * FROM projects WHERE owner_id = ? AND type = ?',
[owner.id, 'admin_owner_space']
);
const usersTable = await dbGet(
'SELECT * FROM universal_tables WHERE project_id = ? AND name = ?',
[adminSpace.id, 'Users']
);
expect(usersTable).toBeDefined(); // ❌ FAIL: table not created
expect(usersTable.is_system).toBe(1);
expect(usersTable.sync_target).toBe('users');
expect(usersTable.icon).toBe('👥');
});
test('1.4: Users table has correct columns', async () => {
const owner = await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'John Owner'
});
const usersTable = await dbGet(
'SELECT * FROM universal_tables WHERE name = ?',
['Users']
);
const columns = await dbAll(
'SELECT * FROM table_columns WHERE table_id = ? ORDER BY order_index',
[usersTable.id]
);
// Expected columns
const expectedColumns = [
{ column_name: 'id', type: 'number', is_system: 1 },
{ column_name: 'created_at', type: 'datetime', is_system: 1 },
{ column_name: 'updated_at', type: 'datetime', is_system: 1 },
{ column_name: 'email', type: 'email', is_required: 1 },
{ column_name: 'name', type: 'text', is_required: 1 },
{ column_name: 'role', type: 'select' },
{ column_name: 'avatar', type: 'image' },
{ column_name: 'totp_enabled', type: 'checkbox' },
{ column_name: 'email_verified', type: 'checkbox' }
];
expect(columns.length).toBeGreaterThanOrEqual(expectedColumns.length);
// Check each column
for (const expected of expectedColumns) {
const col = columns.find(c => c.column_name === expected.column_name);
expect(col, `Column ${expected.column_name} should exist`).toBeDefined();
expect(col.type).toBe(expected.type);
if (expected.is_system) expect(col.is_system).toBe(1);
if (expected.is_required) expect(col.is_required).toBe(1);
}
// Check role column has options
const roleColumn = columns.find(c => c.column_name === 'role');
const config = JSON.parse(roleColumn.config || '{}');
expect(config.options).toBeDefined();
expect(config.options.length).toBe(3); // owner, admin, user
expect(config.options.map(o => o.value)).toContain('owner');
expect(config.options.map(o => o.value)).toContain('admin');
expect(config.options.map(o => o.value)).toContain('user');
});
test('1.5: Projects system table created', async () => {
const owner = await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'John Owner'
});
const adminSpace = await dbGet(
'SELECT * FROM projects WHERE type = ?',
['admin_owner_space']
);
const projectsTable = await dbGet(
'SELECT * FROM universal_tables WHERE project_id = ? AND name = ?',
[adminSpace.id, 'Projects']
);
expect(projectsTable).toBeDefined(); // ❌ FAIL
expect(projectsTable.is_system).toBe(1);
expect(projectsTable.sync_target).toBe('projects');
expect(projectsTable.icon).toBe('📁');
});
test('1.6: Projects table has correct columns', async () => {
const owner = await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'John Owner'
});
const projectsTable = await dbGet(
'SELECT * FROM universal_tables WHERE name = ?',
['Projects']
);
const columns = await dbAll(
'SELECT * FROM table_columns WHERE table_id = ?',
[projectsTable.id]
);
const columnNames = columns.map(c => c.column_name);
expect(columnNames).toContain('id');
expect(columnNames).toContain('name');
expect(columnNames).toContain('type');
expect(columnNames).toContain('owner_id');
expect(columnNames).toContain('icon');
expect(columnNames).toContain('theme_primary');
// Check owner column is 'user' type (relation)
const ownerColumn = columns.find(c => c.column_name === 'owner_id');
expect(ownerColumn.type).toBe('user');
});
test('1.7: Tables system table created', async () => {
const owner = await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'John Owner'
});
const adminSpace = await dbGet(
'SELECT * FROM projects WHERE type = ?',
['admin_owner_space']
);
const tablesTable = await dbGet(
'SELECT * FROM universal_tables WHERE project_id = ? AND name = ?',
[adminSpace.id, 'Tables']
);
expect(tablesTable).toBeDefined(); // ❌ FAIL
expect(tablesTable.is_system).toBe(1);
expect(tablesTable.sync_target).toBe('universal_tables');
expect(tablesTable.icon).toBe('📊');
});
test('1.8: Second user does NOT become owner', async () => {
// First user
await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'Owner'
});
// Second user
const user2 = await registerUser({
email: 'user2@test.com',
password: 'Pass123!',
name: 'User 2'
});
expect(user2.role).toBe('user'); // Should be 'user', not 'owner'
});
test('1.9: Second user does NOT get Admin Space', async () => {
await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'Owner'
});
const user2 = await registerUser({
email: 'user2@test.com',
password: 'Pass123!',
name: 'User 2'
});
const adminSpaces = await dbAll(
'SELECT * FROM projects WHERE owner_id = ? AND type = ?',
[user2.id, 'admin_owner_space']
);
expect(adminSpaces.length).toBe(0); // No admin space for regular users
});
});
// ============================================================
// Phase 2: System Tables Structure Validation
// ============================================================
describe.skip('Phase 2: System Tables Structure', () => {
test('2.1: All 3 system tables created together', async () => {
await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'Owner'
});
const adminSpace = await dbGet(
'SELECT * FROM projects WHERE type = ?',
['admin_owner_space']
);
const systemTables = await dbAll(
'SELECT * FROM universal_tables WHERE project_id = ? AND is_system = 1',
[adminSpace.id]
);
expect(systemTables.length).toBe(3); // Users, Projects, Tables
const tableNames = systemTables.map(t => t.name).sort();
expect(tableNames).toEqual(['Projects', 'Tables', 'Users']);
});
test('2.2: System tables have correct sync targets', async () => {
await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'Owner'
});
const systemTables = await dbAll(
'SELECT * FROM universal_tables WHERE is_system = 1'
);
const syncMap = {};
systemTables.forEach(t => {
syncMap[t.name] = t.sync_target;
});
expect(syncMap['Users']).toBe('users');
expect(syncMap['Projects']).toBe('projects');
expect(syncMap['Tables']).toBe('universal_tables');
});
test('2.3: All system tables have icons', async () => {
await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'Owner'
});
const systemTables = await dbAll(
'SELECT * FROM universal_tables WHERE is_system = 1'
);
for (const table of systemTables) {
expect(table.icon, `Table ${table.name} should have icon`).toBeDefined();
expect(table.icon.length).toBeGreaterThan(0);
}
});
});
// ============================================================
// Phase 3: Edge Cases & Error Handling
// ============================================================
describe.skip('Phase 3: Edge Cases', () => {
test('3.1: Cannot create duplicate Users table', async () => {
await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'Owner'
});
const usersTable = await dbGet(
'SELECT * FROM universal_tables WHERE name = ?',
['Users']
);
// Try to create duplicate
try {
await dbAll(
'INSERT INTO universal_tables (project_id, name, is_system, sync_target) VALUES (?, ?, 1, ?)',
[usersTable.project_id, 'Users', 'users']
);
expect.fail('Should not allow duplicate Users table');
} catch (error) {
// Should throw constraint error
expect(error).toBeDefined();
}
});
test('3.2: System tables are read-only (is_system = 1)', async () => {
await registerUser({
email: 'owner@test.com',
password: 'Pass123!',
name: 'Owner'
});
const systemTables = await dbAll(
'SELECT * FROM universal_tables WHERE is_system = 1'
);
for (const table of systemTables) {
expect(table.is_system).toBe(1);
}
});
});
});