fix(access): respect read-only permission boundary

This commit is contained in:
lingniu
2026-07-16 08:08:06 +08:00
parent 7cf856fd51
commit 7346cd0891
2 changed files with 24 additions and 5 deletions

View File

@@ -10,11 +10,13 @@ const mocks = vi.hoisted(() => ({
accessSummary: vi.fn(), accessVehicles: vi.fn(), accessUnresolvedIdentities: vi.fn(),
accessThresholds: vi.fn(), updateAccessThresholds: vi.fn()
}));
const auth = vi.hoisted(() => ({ role: 'admin' }));
vi.mock('../../api/client', () => ({ api: mocks }));
vi.mock('../auth/AuthGate', () => ({ usePlatformSession: () => ({ session: { role: 'admin' } }) }));
vi.mock('../auth/AuthGate', () => ({ usePlatformSession: () => ({ session: { role: auth.role } }) }));
afterEach(() => {
cleanup();
auth.role = 'admin';
Object.values(mocks).forEach((mock) => mock.mockReset());
});
@@ -76,3 +78,20 @@ test('reports and independently retries unresolved identity and threshold failur
expect(mocks.accessUnresolvedIdentities).toHaveBeenCalledTimes(2);
expect(mocks.accessThresholds).toHaveBeenCalledTimes(2);
});
test('does not request or render admin-only thresholds for a read-only session', async () => {
auth.role = 'viewer';
prepareBaseData();
mocks.accessVehicles.mockResolvedValue({ items: [accessRow('VIN001', '粤A00001')], total: 1, limit: 50, offset: 0 });
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
render(<QueryClientProvider client={client}><MemoryRouter future={ROUTER_FUTURE} initialEntries={['/access']}><AccessPage /></MemoryRouter></QueryClientProvider>);
expect(await screen.findByText('粤A00001')).toBeInTheDocument();
expect(mocks.accessThresholds).not.toHaveBeenCalled();
expect(screen.queryByText(/在线判定阈值/)).not.toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: /刷新/ }));
await waitFor(() => expect(mocks.accessSummary).toHaveBeenCalledTimes(2));
expect(mocks.accessThresholds).not.toHaveBeenCalled();
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
});