mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 23:46:35 +00:00
test(components): cover map, collections, settings, journey and admin
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// FE-ADMIN-DEVNOTIF-001 to FE-ADMIN-DEVNOTIF-010
|
||||
import { render, screen, waitFor } from '../../../tests/helpers/render';
|
||||
// FE-ADMIN-DEVNOTIF-001 to FE-ADMIN-DEVNOTIF-016
|
||||
import { render, screen, waitFor, fireEvent } from '../../../tests/helpers/render';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { server } from '../../../tests/helpers/msw/server';
|
||||
@@ -157,4 +157,141 @@ describe('DevNotificationsPanel', () => {
|
||||
await screen.findByText('User-Scoped Events');
|
||||
expect(screen.queryByText('Trip-Scoped Events')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-ADMIN-DEVNOTIF-011: the remaining self/admin type buttons each fire their own event', async () => {
|
||||
const bodies: Record<string, unknown>[] = [];
|
||||
server.use(
|
||||
http.post('/api/admin/dev/test-notification', async ({ request }) => {
|
||||
bodies.push(await request.json() as Record<string, unknown>);
|
||||
return HttpResponse.json({ ok: true });
|
||||
}),
|
||||
);
|
||||
const user = userEvent.setup();
|
||||
render(<><ToastContainer /><DevNotificationsPanel /></>);
|
||||
await screen.findByText('Type Testing');
|
||||
|
||||
await user.click(screen.getByText('Boolean → Me').closest('button')!);
|
||||
await screen.findByText('Sent: boolean-me');
|
||||
await user.click(screen.getByText('Navigate → Me').closest('button')!);
|
||||
await screen.findByText('Sent: navigate-me');
|
||||
await user.click(screen.getByText('Simple → All Admins').closest('button')!);
|
||||
await screen.findByText('Sent: simple-admins');
|
||||
await user.click(screen.getByText('version_available').closest('button')!);
|
||||
await screen.findByText('Sent: version_available');
|
||||
|
||||
expect(bodies[0]).toMatchObject({
|
||||
event: 'test_boolean',
|
||||
scope: 'user',
|
||||
targetId: ADMIN_USER.id,
|
||||
inApp: {
|
||||
type: 'boolean',
|
||||
positiveCallback: { action: 'test_approve', payload: {} },
|
||||
negativeCallback: { action: 'test_deny', payload: {} },
|
||||
},
|
||||
});
|
||||
expect(bodies[1]).toMatchObject({ event: 'test_navigate', scope: 'user', targetId: ADMIN_USER.id });
|
||||
expect(bodies[2]).toMatchObject({ event: 'test_simple', scope: 'admin', targetId: 0 });
|
||||
expect(bodies[3]).toMatchObject({ event: 'version_available', scope: 'admin', targetId: 0, params: { version: '9.9.9-test' } });
|
||||
});
|
||||
|
||||
it('FE-ADMIN-DEVNOTIF-012: every trip-scoped button carries the selected trip and the actor', async () => {
|
||||
const bodies: Record<string, unknown>[] = [];
|
||||
server.use(
|
||||
http.post('/api/admin/dev/test-notification', async ({ request }) => {
|
||||
bodies.push(await request.json() as Record<string, unknown>);
|
||||
return HttpResponse.json({ ok: true });
|
||||
}),
|
||||
);
|
||||
const user = userEvent.setup();
|
||||
render(<><ToastContainer /><DevNotificationsPanel /></>);
|
||||
await screen.findByText('Trip-Scoped Events');
|
||||
|
||||
const [tripSelect] = screen.getAllByRole('combobox');
|
||||
const tripId = Number((tripSelect as HTMLSelectElement).value);
|
||||
|
||||
for (const label of ['trip_reminder', 'photos_shared', 'collab_message', 'packing_tagged']) {
|
||||
await user.click(screen.getByText(label).closest('button')!);
|
||||
await screen.findByText(`Sent: ${label}`);
|
||||
}
|
||||
|
||||
expect(bodies.map(b => b.event)).toEqual(['trip_reminder', 'photos_shared', 'collab_message', 'packing_tagged']);
|
||||
for (const body of bodies) {
|
||||
expect(body.scope).toBe('trip');
|
||||
expect(body.targetId).toBe(tripId);
|
||||
expect(body.params).toMatchObject({ trip: 'Paris Adventure', tripId: String(tripId) });
|
||||
}
|
||||
expect(bodies[1].params).toMatchObject({ actor: 'testadmin', count: '5' });
|
||||
expect(bodies[2].params).toMatchObject({ preview: 'This is a test message preview.' });
|
||||
expect(bodies[3].params).toMatchObject({ category: 'Clothing' });
|
||||
});
|
||||
|
||||
it('FE-ADMIN-DEVNOTIF-013: user-scoped events target the picked recipient', async () => {
|
||||
const bodies: Record<string, unknown>[] = [];
|
||||
server.use(
|
||||
http.post('/api/admin/dev/test-notification', async ({ request }) => {
|
||||
bodies.push(await request.json() as Record<string, unknown>);
|
||||
return HttpResponse.json({ ok: true });
|
||||
}),
|
||||
);
|
||||
const user = userEvent.setup();
|
||||
render(<><ToastContainer /><DevNotificationsPanel /></>);
|
||||
await screen.findByText('User-Scoped Events');
|
||||
|
||||
const userSelect = screen.getAllByRole('combobox')[1] as HTMLSelectElement;
|
||||
const aliceOption = Array.from(userSelect.querySelectorAll('option')).find(
|
||||
o => (o.textContent ?? '').includes('alice'),
|
||||
)!;
|
||||
await user.selectOptions(userSelect, aliceOption.value);
|
||||
const aliceId = Number(aliceOption.value);
|
||||
|
||||
await user.click(screen.getByText('trip_invite').closest('button')!);
|
||||
await screen.findByText(`Sent: trip_invite-${aliceId}`);
|
||||
await user.click(screen.getByText('vacay_invite').closest('button')!);
|
||||
await screen.findByText(`Sent: vacay_invite-${aliceId}`);
|
||||
|
||||
expect(bodies[0]).toMatchObject({
|
||||
event: 'trip_invite',
|
||||
scope: 'user',
|
||||
targetId: aliceId,
|
||||
params: { actor: 'testadmin', invitee: 'alice@example.com' },
|
||||
});
|
||||
expect(bodies[1]).toMatchObject({
|
||||
event: 'vacay_invite',
|
||||
scope: 'user',
|
||||
targetId: aliceId,
|
||||
params: { actor: 'testadmin', planId: '1' },
|
||||
});
|
||||
});
|
||||
|
||||
it('FE-ADMIN-DEVNOTIF-014: the User-Scoped section is hidden when no users come back', async () => {
|
||||
server.use(http.get('/api/admin/users', () => HttpResponse.json({ users: [] })));
|
||||
render(<><ToastContainer /><DevNotificationsPanel /></>);
|
||||
|
||||
await screen.findByText('Trip-Scoped Events');
|
||||
expect(screen.queryByText('User-Scoped Events')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-ADMIN-DEVNOTIF-015: failing lookups leave both scoped sections out without crashing', async () => {
|
||||
server.use(
|
||||
http.get('/api/trips', () => HttpResponse.error()),
|
||||
http.get('/api/admin/users', () => HttpResponse.error()),
|
||||
);
|
||||
render(<><ToastContainer /><DevNotificationsPanel /></>);
|
||||
|
||||
expect(await screen.findByText('Type Testing')).toBeInTheDocument();
|
||||
await waitFor(() => expect(screen.queryByText('Trip-Scoped Events')).not.toBeInTheDocument());
|
||||
expect(screen.queryByText('User-Scoped Events')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Admin-Scoped Events')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('FE-ADMIN-DEVNOTIF-016: hovering a trigger paints and restores its background', async () => {
|
||||
render(<><ToastContainer /><DevNotificationsPanel /></>);
|
||||
await screen.findByText('Type Testing');
|
||||
|
||||
const btn = screen.getByText('Simple → Me').closest('button')!;
|
||||
fireEvent.mouseEnter(btn);
|
||||
expect(btn.style.background).toBe('var(--bg-hover)');
|
||||
fireEvent.mouseLeave(btn);
|
||||
expect(btn.style.background).toBe('var(--bg-card)');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user