Files
gongxue-base/apps/admin/src/auth/permission-state.integration.test.tsx
wangziqi a7a7af1667 fix: close permission review gaps
fix: harden permission-gated UI — minimum-org endpoint, modal/Popconfirm fail-closed on revocation
2026-07-23 14:28:58 +08:00

66 lines
2.1 KiB
TypeScript

import { act } from 'react';
import { createRoot } from 'react-dom/client';
import { afterEach, beforeAll, describe, expect, it } from 'vitest';
import PermissionButton from '../components/PermissionButton';
import {
beginPermissionVerification,
clearPermissions,
readPermissionState,
writePermissions,
} from './permission-store';
let container: HTMLDivElement | null = null;
let root: ReturnType<typeof createRoot> | null = null;
beforeAll(() => {
(
globalThis as typeof globalThis & { IS_REACT_ACT_ENVIRONMENT: boolean }
).IS_REACT_ACT_ENVIRONMENT = true;
});
async function renderPermissionButton() {
container = document.createElement('div');
document.body.appendChild(container);
root = createRoot(container);
await act(async () => {
root?.render(<PermissionButton permission="student:edit"></PermissionButton>);
});
}
afterEach(async () => {
if (root) await act(async () => root?.unmount());
container?.remove();
root = null;
container = null;
clearPermissions();
});
describe('permission state', () => {
it('ignores cached localStorage permissions until profile verification succeeds', async () => {
localStorage.setItem('permissions', JSON.stringify(['student:edit']));
beginPermissionVerification();
expect(readPermissionState()).toEqual({ permissions: [], status: 'loading' });
await renderPermissionButton();
expect(container?.textContent).not.toContain('编辑学生');
});
it('renders permission actions only after verified permissions are written', async () => {
beginPermissionVerification();
await renderPermissionButton();
expect(container?.textContent).not.toContain('编辑学生');
await act(async () => writePermissions(['student:edit']));
expect(container?.textContent).toContain('编辑学生');
});
it('stays fail-closed while profile verification is retried after a failure', async () => {
writePermissions(['student:edit']);
beginPermissionVerification();
expect(readPermissionState()).toEqual({ permissions: [], status: 'loading' });
await renderPermissionButton();
expect(container?.textContent).not.toContain('编辑学生');
});
});