import { NotificationRuleAuthorization } from '../notification-rule.authz';
import { AuthorizationError } from '../types';

const ctx = (role: 'ADMIN' | 'ADMIN_READ_ONLY' | 'EDITOR' | 'VIEWER') => ({
    userId: 1,
    role,
});

describe('NotificationRuleAuthorization', () => {
    describe('canRead', () => {
        it.each([
            ['ADMIN', true],
            ['ADMIN_READ_ONLY', true],
            ['EDITOR', false],
            ['VIEWER', false],
        ] as const)('role=%s -> %s', (role, expected) => {
            expect(NotificationRuleAuthorization.canRead(ctx(role))).toBe(expected);
        });
    });

    describe('canWrite', () => {
        it.each([
            ['ADMIN', true],
            ['ADMIN_READ_ONLY', false],
            ['EDITOR', false],
            ['VIEWER', false],
        ] as const)('role=%s -> %s', (role, expected) => {
            expect(NotificationRuleAuthorization.canWrite(ctx(role))).toBe(expected);
        });
    });

    describe('assertCanRead', () => {
        it('passes for ADMIN', () => {
            expect(() => NotificationRuleAuthorization.assertCanRead(ctx('ADMIN'))).not.toThrow();
        });
        it('passes for ADMIN_READ_ONLY', () => {
            expect(() => NotificationRuleAuthorization.assertCanRead(ctx('ADMIN_READ_ONLY'))).not.toThrow();
        });
        it('throws AuthorizationError for EDITOR', () => {
            expect(() => NotificationRuleAuthorization.assertCanRead(ctx('EDITOR'))).toThrow(AuthorizationError);
        });
        it('throws AuthorizationError for VIEWER', () => {
            expect(() => NotificationRuleAuthorization.assertCanRead(ctx('VIEWER'))).toThrow(AuthorizationError);
        });
    });

    describe('assertCanWrite', () => {
        it('passes for ADMIN', () => {
            expect(() => NotificationRuleAuthorization.assertCanWrite(ctx('ADMIN'))).not.toThrow();
        });
        it.each(['ADMIN_READ_ONLY', 'EDITOR', 'VIEWER'] as const)('throws for %s', (role) => {
            expect(() => NotificationRuleAuthorization.assertCanWrite(ctx(role))).toThrow(AuthorizationError);
        });
    });
});
