Files
tehran_tala/apps/api/src/modules/auth/guards.spec.ts
T

86 lines
2.8 KiB
TypeScript

import { ForbiddenException, type ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { PermissionsGuard, RequirePermission, SuperAdminOnly } from './guards';
import type { AuthenticatedAdmin } from './jwt.strategy';
import { SUPER_ADMIN_MOBILE, withSuperAdminRids } from './super-admin';
class Routes {
@SuperAdminOnly()
@RequirePermission('config.wallet')
superOnly() {}
@SuperAdminOnly({ allowBranch: true })
@RequirePermission('order.list')
superOrBranch() {}
@RequirePermission('order.list', 'order.omde', 'order.tamin')
anyOf() {}
open() {}
}
function admin(over: Partial<AuthenticatedAdmin> = {}): AuthenticatedAdmin {
return {
id: 'a1',
fullName: 'x',
mobile: '09120000000',
role: 'SUPER_ADMIN',
userTypeId: 85,
branchId: null,
permissions: ['config.wallet', 'order.list', 'order.omde'],
...over,
};
}
function run(handler: keyof Routes, user: AuthenticatedAdmin) {
const ctx = {
getHandler: () => Routes.prototype[handler],
getClass: () => Routes,
switchToHttp: () => ({ getRequest: () => ({ user }) }),
} as unknown as ExecutionContext;
return new PermissionsGuard(new Reflector()).canActivate(ctx);
}
describe('PermissionsGuard — super-admin-only routes', () => {
it('admits the super admin', () => {
expect(run('superOnly', admin({ mobile: SUPER_ADMIN_MOBILE }))).toBe(true);
});
it('refuses any other admin, even one holding the rid and the SUPER_ADMIN role', () => {
expect(() => run('superOnly', admin())).toThrow(ForbiddenException);
});
it('refuses a branch admin unless the route allows branches', () => {
expect(() => run('superOnly', admin({ branchId: 'b1' }))).toThrow(ForbiddenException);
expect(run('superOrBranch', admin({ branchId: 'b1' }))).toBe(true);
expect(() => run('superOrBranch', admin())).toThrow(ForbiddenException);
});
it('still requires the rid from a branch admin', () => {
expect(() => run('superOrBranch', admin({ branchId: 'b1', permissions: [] }))).toThrow(
ForbiddenException,
);
});
it('leaves routes without the decorator alone', () => {
expect(run('open', admin({ permissions: [] }))).toBe(true);
});
});
describe('PermissionsGuard — several rids', () => {
it('admits a holder of any one of them', () => {
expect(run('anyOf', admin({ permissions: ['order.tamin'] }))).toBe(true);
});
it('refuses a holder of none', () => {
expect(() => run('anyOf', admin({ permissions: ['product.list'] }))).toThrow(ForbiddenException);
});
});
describe('withSuperAdminRids', () => {
it('adds the super-admin rids for the super admin only', () => {
expect(withSuperAdminRids(SUPER_ADMIN_MOBILE, [])).toContain('config.wallet');
expect(withSuperAdminRids('09120000000', ['product.list'])).toEqual(['product.list']);
});
});