test: improve branch coverage with edge cases

This commit is contained in:
张翔
2026-03-10 12:44:17 +08:00
parent 4141843b9d
commit 29ec90d2cc
2 changed files with 722 additions and 0 deletions
+276
View File
@@ -0,0 +1,276 @@
import { describe, it, expect } from '@jest/globals';
import { PERMISSIONS, hasPermission, Role, Resource, Action } from './permissions';
describe('permissions', () => {
describe('PERMISSIONS constant', () => {
it('should have admin permissions', () => {
expect(PERMISSIONS.admin).toBeDefined();
expect(PERMISSIONS.admin.content).toContain('create');
expect(PERMISSIONS.admin.content).toContain('read');
expect(PERMISSIONS.admin.content).toContain('update');
expect(PERMISSIONS.admin.content).toContain('delete');
expect(PERMISSIONS.admin.content).toContain('publish');
});
it('should have editor permissions', () => {
expect(PERMISSIONS.editor).toBeDefined();
expect(PERMISSIONS.editor.content).toContain('create');
expect(PERMISSIONS.editor.content).toContain('read');
expect(PERMISSIONS.editor.content).toContain('update');
expect(PERMISSIONS.editor.content).toContain('publish');
expect(PERMISSIONS.editor.content).not.toContain('delete');
});
it('should have viewer permissions', () => {
expect(PERMISSIONS.viewer).toBeDefined();
expect(PERMISSIONS.viewer.content).toContain('read');
expect(PERMISSIONS.viewer.content).not.toContain('create');
expect(PERMISSIONS.viewer.content).not.toContain('update');
expect(PERMISSIONS.viewer.content).not.toContain('delete');
});
it('should have config permissions', () => {
expect(PERMISSIONS.admin.config).toContain('read');
expect(PERMISSIONS.admin.config).toContain('update');
expect(PERMISSIONS.editor.config).toContain('read');
expect(PERMISSIONS.editor.config).not.toContain('update');
});
it('should have users permissions', () => {
expect(PERMISSIONS.admin.users).toContain('create');
expect(PERMISSIONS.admin.users).toContain('read');
expect(PERMISSIONS.admin.users).toContain('update');
expect(PERMISSIONS.admin.users).toContain('delete');
expect(PERMISSIONS.editor.users).toEqual([]);
expect(PERMISSIONS.viewer.users).toEqual([]);
});
it('should have logs permissions', () => {
expect(PERMISSIONS.admin.logs).toContain('read');
expect(PERMISSIONS.editor.logs).toContain('read');
expect(PERMISSIONS.viewer.logs).toEqual([]);
});
});
describe('hasPermission', () => {
describe('admin role', () => {
it('should allow all content actions', () => {
const role: Role = 'admin';
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'create')).toBe(true);
expect(hasPermission(role, resource, 'read')).toBe(true);
expect(hasPermission(role, resource, 'update')).toBe(true);
expect(hasPermission(role, resource, 'delete')).toBe(true);
expect(hasPermission(role, resource, 'publish')).toBe(true);
});
it('should allow config actions', () => {
const role: Role = 'admin';
const resource: Resource = 'config';
expect(hasPermission(role, resource, 'read')).toBe(true);
expect(hasPermission(role, resource, 'update')).toBe(true);
});
it('should allow all users actions', () => {
const role: Role = 'admin';
const resource: Resource = 'users';
expect(hasPermission(role, resource, 'create')).toBe(true);
expect(hasPermission(role, resource, 'read')).toBe(true);
expect(hasPermission(role, resource, 'update')).toBe(true);
expect(hasPermission(role, resource, 'delete')).toBe(true);
});
it('should allow logs read', () => {
const role: Role = 'admin';
const resource: Resource = 'logs';
expect(hasPermission(role, resource, 'read')).toBe(true);
});
});
describe('editor role', () => {
it('should allow content actions except delete', () => {
const role: Role = 'editor';
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'create')).toBe(true);
expect(hasPermission(role, resource, 'read')).toBe(true);
expect(hasPermission(role, resource, 'update')).toBe(true);
expect(hasPermission(role, resource, 'delete')).toBe(false);
expect(hasPermission(role, resource, 'publish')).toBe(true);
});
it('should allow config read only', () => {
const role: Role = 'editor';
const resource: Resource = 'config';
expect(hasPermission(role, resource, 'read')).toBe(true);
expect(hasPermission(role, resource, 'update')).toBe(false);
});
it('should not allow users actions', () => {
const role: Role = 'editor';
const resource: Resource = 'users';
expect(hasPermission(role, resource, 'create')).toBe(false);
expect(hasPermission(role, resource, 'read')).toBe(false);
expect(hasPermission(role, resource, 'update')).toBe(false);
expect(hasPermission(role, resource, 'delete')).toBe(false);
});
it('should allow logs read', () => {
const role: Role = 'editor';
const resource: Resource = 'logs';
expect(hasPermission(role, resource, 'read')).toBe(true);
});
});
describe('viewer role', () => {
it('should only allow content read', () => {
const role: Role = 'viewer';
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'read')).toBe(true);
expect(hasPermission(role, resource, 'create')).toBe(false);
expect(hasPermission(role, resource, 'update')).toBe(false);
expect(hasPermission(role, resource, 'delete')).toBe(false);
expect(hasPermission(role, resource, 'publish')).toBe(false);
});
it('should allow config read only', () => {
const role: Role = 'viewer';
const resource: Resource = 'config';
expect(hasPermission(role, resource, 'read')).toBe(true);
expect(hasPermission(role, resource, 'update')).toBe(false);
});
it('should not allow users actions', () => {
const role: Role = 'viewer';
const resource: Resource = 'users';
expect(hasPermission(role, resource, 'create')).toBe(false);
expect(hasPermission(role, resource, 'read')).toBe(false);
expect(hasPermission(role, resource, 'update')).toBe(false);
expect(hasPermission(role, resource, 'delete')).toBe(false);
});
it('should not allow logs actions', () => {
const role: Role = 'viewer';
const resource: Resource = 'logs';
expect(hasPermission(role, resource, 'read')).toBe(false);
});
});
describe('edge cases', () => {
it('should return false for invalid role', () => {
const role = 'invalid' as Role;
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should return false for invalid resource', () => {
const role: Role = 'admin';
const resource = 'invalid' as Resource;
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should return false for invalid action', () => {
const role: Role = 'admin';
const resource: Resource = 'content';
const action = 'invalid' as Action;
expect(hasPermission(role, resource, action)).toBe(false);
});
it('should handle null role', () => {
const role = null as any;
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should handle undefined resource', () => {
const role: Role = 'admin';
const resource = undefined as any;
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should handle empty action string', () => {
const role: Role = 'admin';
const resource: Resource = 'content';
const action = '' as Action;
expect(hasPermission(role, resource, action)).toBe(false);
});
it('should handle case sensitivity for roles', () => {
const role = 'ADMIN' as Role;
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should handle case sensitivity for resources', () => {
const role: Role = 'admin';
const resource = 'CONTENT' as Resource;
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should handle case sensitivity for actions', () => {
const role: Role = 'admin';
const resource: Resource = 'content';
const action = 'READ' as Action;
expect(hasPermission(role, resource, action)).toBe(false);
});
it('should handle undefined role', () => {
const role = undefined as any;
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should handle numeric role', () => {
const role = 123 as any;
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'read')).toBe(false);
});
it('should handle object role', () => {
const role = {} as any;
const resource: Resource = 'content';
expect(hasPermission(role, resource, 'read')).toBe(false);
});
});
});
describe('Type Exports', () => {
it('should export Role type', () => {
const role: Role = 'admin';
expect(role).toBeDefined();
});
it('should export Resource type', () => {
const resource: Resource = 'content';
expect(resource).toBeDefined();
});
it('should export Action type', () => {
const action: Action = 'read';
expect(action).toBeDefined();
});
});
});