fix: audit remediation — SSE user scoping, FK transactional safety, UI error handling
- H4: scoped SSE import progress to exact userId match; non-HTTP events excluded from all subscribers - H2: moved PRAGMA foreign_key_check inside SQLite transaction before COMMIT; violations rollback preserving old tables - M1: removed dead axios-style error branch from extractErrorMessage (interceptor already unwraps) - M2: split handleSave try/catch — save errors vs reload errors shown distinctly - M3: added provider field validation before AI config test request - Added SSE scoping regression tests (import service + controller) - Added FK check failure rollback test (database-migrations.spec) - Updated controller spec expectations for userId parameter Co-authored-by: Code Review <branch-review>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
canPullAttendance,
|
||||
getAttendanceExperience,
|
||||
getSchedulePhase,
|
||||
summarizeAttendance,
|
||||
} from './attendance-workspace';
|
||||
|
||||
describe('attendance role experience', () => {
|
||||
it('routes class-scoped teachers to the teaching workspace', () => {
|
||||
expect(
|
||||
getAttendanceExperience(
|
||||
['attendance:view', 'attendance:create', 'schedule:create'],
|
||||
['老师'],
|
||||
),
|
||||
).toBe('teacher');
|
||||
});
|
||||
|
||||
it('routes users with attendance administration permission to history management', () => {
|
||||
expect(getAttendanceExperience(['attendance:view', 'attendance:edit'], ['教务管理员'])).toBe(
|
||||
'admin',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('teacher schedule phase', () => {
|
||||
it('marks a finished lesson as ready for attendance review', () => {
|
||||
expect(getSchedulePhase('08:00', '09:00', new Date('2026-07-11T10:00:00'))).toBe('ended');
|
||||
});
|
||||
|
||||
it('keeps future lessons read-only', () => {
|
||||
expect(getSchedulePhase('14:00', '15:00', new Date('2026-07-11T10:00:00'))).toBe('upcoming');
|
||||
});
|
||||
|
||||
it('allows attendance pulls once the lesson starts', () => {
|
||||
expect(canPullAttendance('ongoing')).toBe(true);
|
||||
expect(canPullAttendance('ended')).toBe(true);
|
||||
expect(canPullAttendance('upcoming')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('attendance summary', () => {
|
||||
it('summarizes status counts for an administrator history view', () => {
|
||||
expect(
|
||||
summarizeAttendance([
|
||||
{ status: 'present' },
|
||||
{ status: 'present' },
|
||||
{ status: 'late' },
|
||||
{ status: 'absent' },
|
||||
]),
|
||||
).toEqual({ total: 4, present: 2, late: 1, absent: 1, leave: 0, pending: 0 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user