40227-vm/frontend/src/business/top-bar/selectors.test.ts

187 lines
5.6 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
buildTopBarNotifications,
countUnreadTopBarNotifications,
getTopBarCampusLabel,
getTopBarInitials,
getTopBarRoleLabel,
} from '@/business/top-bar/selectors';
import { APP_ROUTE_PATHS } from '@/shared/constants/routes';
import type { CommunicationEventDto } from '@/shared/types/communications';
import type { PolicyAcknowledgmentDto } from '@/shared/types/policyDocuments';
function createCommunicationEvent(overrides: Partial<CommunicationEventDto> = {}): CommunicationEventDto {
return {
id: 'event-1',
title: 'Campus meeting',
date: '2026-06-15',
type: 'meeting',
targetLevel: 'campus',
roles: ['director'],
organizationId: 'org-1',
campusId: 'campus-1',
schoolId: null,
classId: null,
canceledEventId: null,
createdById: 'user-1',
updatedById: null,
createdAt: '2026-06-15T00:00:00Z',
updatedAt: '2026-06-15T00:00:00Z',
...overrides,
};
}
function createPolicyAcknowledgment(
overrides: Partial<PolicyAcknowledgmentDto> = {},
): PolicyAcknowledgmentDto {
return {
id: 'ack-1',
policyDocumentId: 'handbook-1',
version: 1,
userId: 'user-1',
acknowledgedAt: '2026-06-15T00:00:00Z',
organizationId: 'org-1',
campusId: null,
createdAt: '2026-06-15T00:00:00Z',
updatedAt: '2026-06-15T00:00:00Z',
...overrides,
};
}
describe('top bar selectors', () => {
it('surfaces an unread zone check-in nudge (linking to the zones page) only when needed', () => {
expect(buildTopBarNotifications({ needsZoneCheckIn: false })).toEqual([]);
const withNudge = buildTopBarNotifications({ needsZoneCheckIn: true });
expect(withNudge).toHaveLength(1);
expect(withNudge[0]).toMatchObject({ unread: true, href: APP_ROUTE_PATHS.zones });
expect(countUnreadTopBarNotifications(withNudge)).toBe(1);
});
it('surfaces an unread QBS quiz reminder when the weekly quiz is incomplete', () => {
expect(buildTopBarNotifications({
needsZoneCheckIn: false,
needsSafetyQuiz: false,
})).toEqual([]);
const withReminder = buildTopBarNotifications({
needsZoneCheckIn: false,
needsSafetyQuiz: true,
});
expect(withReminder).toEqual([{
id: 'safety-quiz-weekly',
text: "You haven't completed this week's QBS safety quiz",
time: 'This week',
unread: true,
href: APP_ROUTE_PATHS.qbs,
}]);
});
it('surfaces EI self-assessment and personality quiz completion reminders', () => {
const reminders = buildTopBarNotifications({
needsZoneCheckIn: false,
needsEiSelfAssessment: true,
needsPersonalityQuiz: true,
});
expect(reminders).toEqual([
{
id: 'ei-self-assessment',
text: "You haven't completed your EI self-assessment",
time: 'This week',
unread: true,
href: APP_ROUTE_PATHS.ei,
},
{
id: 'ei-personality-quiz',
text: "You haven't completed your personality type quiz",
time: 'Once',
unread: true,
href: APP_ROUTE_PATHS.ei,
},
]);
});
it('builds initials from display names', () => {
expect(getTopBarInitials('Guest')).toBe('G');
expect(getTopBarInitials('Ada Lovelace')).toBe('AL');
expect(getTopBarInitials(' Grace Hopper ')).toBe('GH');
});
it('surfaces unacknowledged internal alerts in the notifications menu', () => {
const unread = buildTopBarNotifications({
needsZoneCheckIn: false,
communicationEvents: [createCommunicationEvent()],
acknowledgedCommunicationEventIds: new Set(),
});
expect(unread).toHaveLength(1);
expect(unread[0]).toMatchObject({
text: 'Internal alert: Campus meeting',
href: APP_ROUTE_PATHS.internalComm,
unread: true,
});
expect(buildTopBarNotifications({
needsZoneCheckIn: false,
communicationEvents: [createCommunicationEvent()],
acknowledgedCommunicationEventIds: new Set(['event-1']),
})).toEqual([]);
});
it('surfaces unread handbook policies and safety protocols by document version', () => {
const unread = buildTopBarNotifications({
needsZoneCheckIn: false,
handbookPolicies: [{
id: 'handbook-1',
title: 'Parent Communication',
category: 'Communication',
content: 'Document families contact.',
version: 2,
lastUpdated: '2026-06-15',
updatedBy: 'Director',
}],
safetyProtocols: [{
id: 'safety-1',
title: 'Fire Drill',
tag: 'fire',
steps: ['Line up'],
autismConsiderations: [],
version: 1,
lastUpdated: '2026-06-15',
author: 'Director',
}],
policyAcknowledgments: [
createPolicyAcknowledgment({ policyDocumentId: 'handbook-1', version: 1 }),
createPolicyAcknowledgment({ id: 'ack-2', policyDocumentId: 'safety-1', version: 1 }),
],
});
expect(unread).toEqual([{
id: 'handbook-policy-handbook-1-v2',
text: 'Unread handbook policy: Parent Communication',
time: 'Version 2',
unread: true,
href: APP_ROUTE_PATHS.handbook,
}]);
});
it('falls back to default campus label', () => {
expect(getTopBarCampusLabel()).toBe('Current Campus');
});
it('uses shared auth role labels', () => {
expect(getTopBarRoleLabel('support_staff')).toBe('Support Staff');
expect(getTopBarRoleLabel('office_manager')).toBe('Office Manager');
});
it('counts unread notifications', () => {
expect(countUnreadTopBarNotifications([
{ id: '1', text: 'One', time: 'Now', unread: true },
{ id: '2', text: 'Two', time: 'Earlier', unread: false },
])).toBe(1);
});
});