krona-staff/tests/unit/work-session.test.ts
Ochenstarik 7cf5142678 style: rebuild formatting without sync behavior changes
Recreate the formatting baseline from f5ac179 using only Prettier output. Leave sync and tenant-isolation files byte-identical to the base so Antigravity and Grok retain ownership. Normalized comparison confirms all 19 changed files are formatting-only; npm run check passes. Full format check retains five upstream warnings in excluded files.
2026-09-26 17:16:51 +07:00

109 lines
3.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { reconcileWorkSession } from '../../src/domain/attendance/work-session.js';
const options = {
now: '2026-09-24T20:00:00.000Z',
openShiftThresholdMinutes: 14 * 60,
};
describe('attendance work-session reconciliation', () => {
it('sums several in/out intervals without inventing time between them', () => {
const result = reconcileWorkSession(
[
{ id: '1', type: 'check_in', occurredAt: '2026-09-24T01:00:00.000Z' },
{ id: '2', type: 'check_out', occurredAt: '2026-09-24T05:00:00.000Z' },
{ id: '3', type: 'check_in', occurredAt: '2026-09-24T06:00:00.000Z' },
{ id: '4', type: 'check_out', occurredAt: '2026-09-24T10:30:00.000Z' },
],
options,
);
expect(result).toMatchObject({
startedAt: '2026-09-24T01:00:00.000Z',
endedAt: '2026-09-24T10:30:00.000Z',
workedMinutes: 510,
status: 'pending_review',
anomalies: [],
});
});
it('keeps the first check-in and flags a repeated check-in', () => {
const result = reconcileWorkSession(
[
{ id: '1', type: 'check_in', occurredAt: '2026-09-24T01:00:00.000Z' },
{ id: '2', type: 'check_in', occurredAt: '2026-09-24T01:05:00.000Z' },
{ id: '3', type: 'check_out', occurredAt: '2026-09-24T09:00:00.000Z' },
],
options,
);
expect(result?.workedMinutes).toBe(480);
expect(result?.anomalies).toEqual(['repeated_check_in']);
});
it('keeps a recent unfinished shift open', () => {
const result = reconcileWorkSession(
[{ id: '1', type: 'check_in', occurredAt: '2026-09-24T12:00:00.000Z' }],
options,
);
expect(result).toMatchObject({
status: 'open',
endedAt: null,
workedMinutes: 0,
anomalies: [],
});
});
it('flags an old unfinished shift without estimating payable minutes', () => {
const result = reconcileWorkSession(
[{ id: '1', type: 'check_in', occurredAt: '2026-09-24T01:00:00.000Z' }],
options,
);
expect(result).toMatchObject({
status: 'pending_review',
endedAt: null,
workedMinutes: 0,
anomalies: ['missing_check_out'],
});
});
it('auto-closes only after the scheduler cutoff and leaves an audit-worthy anomaly', () => {
const result = reconcileWorkSession(
[{ id: '1', type: 'check_in', occurredAt: '2026-09-23T12:00:00.000Z' }],
{ ...options, automaticCloseAt: '2026-09-23T19:00:00.000Z' },
);
expect(result).toMatchObject({
endedAt: '2026-09-23T19:00:00.000Z',
workedMinutes: 420,
status: 'pending_review',
anomalies: ['auto_closed'],
});
});
it('records a check-out without check-in as an anomaly with zero minutes', () => {
const result = reconcileWorkSession(
[{ id: '1', type: 'check_out', occurredAt: '2026-09-24T09:00:00.000Z' }],
options,
);
expect(result).toMatchObject({
startedAt: null,
endedAt: '2026-09-24T09:00:00.000Z',
workedMinutes: 0,
status: 'pending_review',
anomalies: ['missing_check_in'],
});
});
it('rejects invalid timestamps and thresholds', () => {
expect(() =>
reconcileWorkSession([{ id: '1', type: 'check_in', occurredAt: 'not-a-date' }], options),
).toThrow('event 1 must be an ISO date-time');
expect(() => reconcileWorkSession([], { ...options, openShiftThresholdMinutes: 0 })).toThrow(
'openShiftThresholdMinutes must be a positive integer',
);
});
});