u
This commit is contained in:
92
scripts/test-companyuser-roles.js
Normal file
92
scripts/test-companyuser-roles.js
Normal file
@@ -0,0 +1,92 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { mkdtempSync, rmSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import LibDashStore from '../src/index.js';
|
||||
import { BetterSqlite3Provider } from '../src/providers/sqlite3/index.js';
|
||||
|
||||
async function open(tempDir) {
|
||||
const provider = new BetterSqlite3Provider({ filename: join(tempDir, 'test.db'), storageDir: join(tempDir, 'storage') });
|
||||
await provider.initialize();
|
||||
return { provider, store: await new LibDashStore(provider) };
|
||||
}
|
||||
|
||||
const tempDir = mkdtempSync(join(tmpdir(), 'test-cu-roles-'));
|
||||
try {
|
||||
console.log('--- Testing companyuser roles + autoinvite ---');
|
||||
let { provider, store } = await open(tempDir);
|
||||
|
||||
const adminId = await store.google_auth.add('admin@example.com');
|
||||
const userId = await store.google_auth.add('user@example.com');
|
||||
const company = await store.company.create({ name: 'Roles Corp', iso639: 'de', taxrate: 19, reducedtaxrate: 7, googleAuthId: adminId });
|
||||
await store.google_auth.setSelectedCompany(adminId, company.id);
|
||||
|
||||
// creator is admin
|
||||
let members = await store.companyuser.list(adminId);
|
||||
assert.deepEqual(members.map((m) => [m.email, m.role]), [['admin@example.com', 'admin']]);
|
||||
assert.equal((await store.company.list(adminId))[0].role, 'admin');
|
||||
|
||||
// non-member cannot select the company
|
||||
await assert.rejects(store.google_auth.setSelectedCompany(userId, company.id), /Not authorized/);
|
||||
|
||||
// admin adds existing user
|
||||
await assert.rejects(store.companyuser.addByEmail(adminId, { email: 'nobody@example.com' }), /User not found/);
|
||||
await assert.rejects(store.companyuser.addByEmail(adminId, { email: 'user@example.com', role: 'root' }), /Invalid role/);
|
||||
const added = await store.companyuser.addByEmail(adminId, { email: 'User@Example.com' });
|
||||
assert.equal(added.role, 'user');
|
||||
await assert.rejects(store.companyuser.addByEmail(adminId, { email: 'user@example.com' }), /already in company/);
|
||||
|
||||
// user can now select it, but is not admin
|
||||
await store.google_auth.setSelectedCompany(userId, company.id);
|
||||
await assert.rejects(store.companyuser.list(userId), /Not authorized/);
|
||||
await assert.rejects(store.companyuser.addByEmail(userId, { email: 'admin@example.com' }), /Not authorized/);
|
||||
await assert.rejects(store.companyuser.setRole(userId, added.id, 'admin'), /Not authorized/);
|
||||
await assert.rejects(store.companyuser.remove(userId, added.id), /Not authorized/);
|
||||
await assert.rejects(store.autoinvite.add(userId, { email: 'x@example.com' }), /Not authorized/);
|
||||
|
||||
// last admin guard
|
||||
const adminCu = members[0].id;
|
||||
await assert.rejects(store.companyuser.setRole(adminId, adminCu, 'user'), /last admin/);
|
||||
await assert.rejects(store.companyuser.remove(adminId, adminCu), /last admin/);
|
||||
await store.companyuser.setRole(adminId, added.id, 'admin');
|
||||
await store.companyuser.setRole(adminId, adminCu, 'user');
|
||||
await store.companyuser.setRole(userId, adminCu, 'admin');
|
||||
await store.companyuser.setRole(userId, added.id, 'user');
|
||||
await assert.rejects(store.companyuser.setRole(adminId, 99999, 'user'), /Company user not found/);
|
||||
|
||||
// autoinvite
|
||||
await assert.rejects(store.autoinvite.add(adminId, { email: 'user@example.com' }), /already registered/);
|
||||
await assert.rejects(store.autoinvite.add(adminId, { email: 'bad' }), /Invalid email/);
|
||||
await store.autoinvite.add(adminId, { email: 'New@Example.com', role: 'admin' });
|
||||
await assert.rejects(store.autoinvite.add(adminId, { email: 'new@example.com' }), /already exists/);
|
||||
await store.autoinvite.add(adminId, { email: 'gone@example.com' });
|
||||
assert.equal((await store.autoinvite.list(adminId)).length, 2);
|
||||
await store.autoinvite.remove(adminId, (await store.autoinvite.list(adminId)).find((i) => i.email === 'gone@example.com').id);
|
||||
await assert.rejects(store.autoinvite.remove(adminId, 99999), /Invitation not found/);
|
||||
|
||||
const newId = await store.google_auth.add('new@example.com');
|
||||
assert.deepEqual(await store.autoinvite.list(adminId), []);
|
||||
await store.google_auth.setSelectedCompany(newId, company.id);
|
||||
members = await store.companyuser.list(adminId);
|
||||
assert.equal(members.find((m) => m.email === 'new@example.com').role, 'admin');
|
||||
|
||||
// remove clears selection
|
||||
const userCu = members.find((m) => m.email === 'user@example.com');
|
||||
await store.companyuser.remove(adminId, userCu.id);
|
||||
assert.equal((await store.google_auth.getById(userId)).selectedCompanyId, null);
|
||||
|
||||
// downgrade → upgrade through the migration engine
|
||||
await provider.close?.();
|
||||
const env = { ...process.env, DB_PROVIDER: 'sqlite', SQLITE_PATH: join(tempDir, 'test.db') };
|
||||
execFileSync('node', ['scripts/downgrade.js', '5'], { env, stdio: 'inherit' });
|
||||
({ provider, store } = await open(tempDir).catch((e) => { throw e; }));
|
||||
// opening upgrades to latest again; roles reset to admin for all members
|
||||
const rows = (await provider.query('SELECT role FROM companyuser')).rows;
|
||||
assert.ok(rows.length > 0 && rows.every((r) => r.role === 'admin'));
|
||||
assert.deepEqual((await provider.query('SELECT * FROM autoinvite')).rows, []);
|
||||
await provider.close?.();
|
||||
console.log('OK');
|
||||
} finally {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
Reference in New Issue
Block a user