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 { 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); }); });