maestro/src/bridge/visibility.test.ts
2026-06-03 05:08:00 +00:00

87 lines
3.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { buildVisibilityWhere, canUserSeeTask } from './visibility.js';
function makeUser(overrides: Partial<Express.User> = {}): Express.User {
return {
id: 'user-1', email: 'u@x.com', name: 'u', avatarUrl: null,
role: 'user', status: 'active',
orgIds: [], defaultVisibility: 'private', defaultVisibilityOrgId: null,
...overrides,
};
}
describe('buildVisibilityWhere', () => {
it('admin sees everything (1=1)', () => {
const w = buildVisibilityWhere(makeUser({ role: 'admin' }), 'lt');
expect(w.clause).toBe('1=1');
expect(w.params).toEqual([]);
});
it('user with no orgs: owner or public only', () => {
const w = buildVisibilityWhere(makeUser(), 'lt');
expect(w.clause).toContain('lt.owner_id = ?');
expect(w.clause).toContain("lt.visibility = 'public'");
expect(w.clause).toContain('IN (NULL)'); // empty orgs → never matches
expect(w.params).toEqual(['user-1']);
});
it('user with orgs: owner or public or same-org', () => {
const w = buildVisibilityWhere(makeUser({ orgIds: ['10', '20'] }), 'lt');
expect(w.clause).toMatch(/lt\.visibility_scope_org_id IN \(\?,\?\)/);
expect(w.params).toEqual(['user-1', '10', '20']);
});
it('respects custom table alias', () => {
const w = buildVisibilityWhere(makeUser(), 'j');
expect(w.clause).toContain('j.owner_id');
expect(w.clause).not.toContain('lt.');
});
});
describe('canUserSeeTask', () => {
const adminUser = makeUser({ role: 'admin' });
const aliceNoOrg = makeUser({ id: 'alice' });
const bobOrg10 = makeUser({ id: 'bob', orgIds: ['10'] });
it('admin sees private tasks of others', () => {
const t = { ownerId: 'someone-else', visibility: 'private' as const, visibilityScopeOrgId: null };
expect(canUserSeeTask(adminUser, t)).toBe(true);
});
it('owner sees own private task', () => {
const t = { ownerId: 'alice', visibility: 'private' as const, visibilityScopeOrgId: null };
expect(canUserSeeTask(aliceNoOrg, t)).toBe(true);
});
it('non-owner cannot see another user\'s private task', () => {
const t = { ownerId: 'someone-else', visibility: 'private' as const, visibilityScopeOrgId: null };
expect(canUserSeeTask(aliceNoOrg, t)).toBe(false);
});
it('public task is visible to anyone', () => {
const t = { ownerId: 'someone-else', visibility: 'public' as const, visibilityScopeOrgId: null };
expect(canUserSeeTask(aliceNoOrg, t)).toBe(true);
});
it('org task: same org member can see', () => {
const t = { ownerId: 'someone-else', visibility: 'org' as const, visibilityScopeOrgId: '10' };
expect(canUserSeeTask(bobOrg10, t)).toBe(true);
});
it('org task: different org member cannot see', () => {
const t = { ownerId: 'someone-else', visibility: 'org' as const, visibilityScopeOrgId: '99' };
expect(canUserSeeTask(bobOrg10, t)).toBe(false);
});
it('org task with null scope: only owner can see', () => {
const t = { ownerId: 'alice', visibility: 'org' as const, visibilityScopeOrgId: null };
expect(canUserSeeTask(aliceNoOrg, t)).toBe(true);
expect(canUserSeeTask(bobOrg10, t)).toBe(false);
});
it('owner with null ownerId: not matched (null !== null check skipped)', () => {
const t = { ownerId: null, visibility: 'private' as const, visibilityScopeOrgId: null };
expect(canUserSeeTask(aliceNoOrg, t)).toBe(false);
});
});