40227-vm/backend/src/services/staff_attendance.test.ts

120 lines
3.8 KiB
TypeScript

import { afterEach, describe, mock, test } from 'node:test';
import assert from 'node:assert/strict';
import { Op } from 'sequelize';
import db from '@/db/models';
import StaffAttendanceService from '@/services/staff_attendance';
import { FEATURE_PERMISSIONS } from '@/shared/constants/product-permissions';
import { ROLE_NAMES, ROLE_SCOPES } from '@/shared/constants/roles';
import { createTestUser } from '@/test-utils';
function permission(name: string) {
return { name };
}
function isRecord(value: unknown): value is Record<PropertyKey, unknown> {
return typeof value === 'object' && value !== null;
}
afterEach(() => {
mock.restoreAll();
});
describe('StaffAttendanceService', () => {
test('includes school-owned users and school campuses in school report scope', async () => {
const schoolUser = createTestUser({
organizationId: '11111111-1111-4111-8111-111111111111',
organizations: { id: '11111111-1111-4111-8111-111111111111' },
schoolId: '22222222-2222-4222-8222-222222222222',
campusId: null,
app_role: {
name: ROLE_NAMES.REGISTRAR,
scope: ROLE_SCOPES.SCHOOL,
globalAccess: false,
permissions: [permission(FEATURE_PERMISSIONS.READ_STAFF_ATTENDANCE_REPORTS)],
},
});
let capturedWhere: unknown = null;
mock.method(db.staff_attendance_records, 'findAndCountAll', async (options: unknown) => {
if (isRecord(options)) {
capturedWhere = options.where;
}
return { rows: [], count: 0 };
});
await StaffAttendanceService.listRecords({}, schoolUser);
assert.equal(isRecord(capturedWhere), true);
if (!isRecord(capturedWhere)) {
return;
}
assert.equal(Object.getOwnPropertySymbols(capturedWhere).includes(Op.or), true);
});
test('upserts a school office staff attendance record inside school scope', async () => {
const organizationId = '11111111-1111-4111-8111-111111111111';
const schoolId = '22222222-2222-4222-8222-222222222222';
const actor = createTestUser({
id: '44444444-4444-4444-8444-444444444444',
organizationId,
organizations: { id: organizationId },
schoolId,
campusId: null,
app_role: {
name: ROLE_NAMES.PRINCIPAL,
scope: ROLE_SCOPES.SCHOOL,
globalAccess: false,
permissions: [permission(FEATURE_PERMISSIONS.FILL_ATTENDANCE)],
},
});
let userWhere: unknown = null;
mock.method(db.users, 'findOne', async (options: unknown) => {
if (isRecord(options)) {
userWhere = options.where;
}
return {
get: () => ({
id: '55555555-5555-4555-8555-555555555555',
firstName: 'Nicole',
lastName: 'Adams',
email: 'registrar@flatlogic.com',
campusId: null,
app_role: { name: ROLE_NAMES.REGISTRAR },
}),
};
});
mock.method(db.sequelize, 'transaction', async () => ({
commit: async () => undefined,
rollback: async () => undefined,
}));
mock.method(db.staff_attendance_records, 'findOne', async () => null);
mock.method(db.staff_attendance_records, 'create', async (payload: unknown) => ({
get: () => ({
id: '66666666-6666-4666-8666-666666666666',
...(isRecord(payload) ? payload : {}),
createdAt: new Date('2026-06-17T12:00:00Z'),
updatedAt: new Date('2026-06-17T12:00:00Z'),
}),
}));
await StaffAttendanceService.upsertRecord(
{
userId: '55555555-5555-4555-8555-555555555555',
date: '2026-06-17',
status: 'present',
note: '',
},
actor,
);
assert.equal(isRecord(userWhere), true);
if (!isRecord(userWhere)) {
return;
}
assert.equal(userWhere.schoolId, schoolId);
assert.equal(userWhere.campusId, null);
});
});