MotorSignal-App/website/tests/founder-moderation.test.tsx

76 lines
3.1 KiB
TypeScript

import React from 'react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { fireEvent, render, screen } from '@testing-library/react';
const mocks = vi.hoisted(() => ({
user: { uid: 'owner', isAnonymous: false } as { uid: string; isAnonymous: boolean } | null,
auth: vi.fn(),
context: vi.fn(),
}));
vi.mock('firebase/auth', () => ({ onAuthStateChanged: mocks.auth }));
vi.mock('../lib/firebase-client', () => ({ firebaseAuth: {} }));
vi.mock('next/navigation', () => ({
useRouter: () => ({ push: vi.fn() }),
useSearchParams: () => new URLSearchParams(),
}));
vi.mock('../lib/club-data', () => ({
fetchFounderClubContext: mocks.context,
sanitizePortalError: () => 'Could not load club moderation.',
}));
vi.mock('../components/founder-portal/founder-portal-shell', () => ({
FounderPortalShell: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
}));
vi.mock('../components/founder-portal/founder-applications', () => ({
FounderApplications: () => <div>Real applications review</div>,
}));
vi.mock('../components/founder-portal/founder-wall', () => ({
FounderWall: () => <div>Real Wall moderation</div>,
}));
vi.mock('../components/founder-portal/founder-members', () => ({
FounderMembers: () => <div>Real member access review</div>,
}));
import { FounderModerationPage } from '../components/founder-portal/founder-moderation-page';
const context = {
club: { id: 'ClubID', name: 'Riders Club' },
currentUser: { uid: 'owner', role: 'owner' },
permissions: { role: 'owner', canManageSettings: true },
isDemoFixture: false,
};
describe('Founder Moderation', () => {
beforeEach(() => {
vi.clearAllMocks();
mocks.user = { uid: 'owner', isAnonymous: false };
mocks.auth.mockImplementation((_auth, deliver) => { deliver(mocks.user); return vi.fn(); });
mocks.context.mockResolvedValue(context);
});
it('makes existing moderation flows available to an authorized owner', async () => {
render(<FounderModerationPage clubId="club-slug" />);
await screen.findByText('Real applications review');
expect(mocks.context).toHaveBeenCalledWith('club-slug', 'owner', { allowDemoPreview: false });
fireEvent.click(screen.getByRole('tab', { name: 'Wall posts' }));
expect(screen.getByText('Real Wall moderation')).toBeDefined();
fireEvent.click(screen.getByRole('tab', { name: 'Members' }));
expect(screen.getByText('Real member access review')).toBeDefined();
expect(screen.getByText(/Post reports are not collected yet/)).toBeDefined();
});
it('does not load club data when signed out', async () => {
mocks.user = null;
render(<FounderModerationPage clubId="club-slug" />);
await screen.findByText('Authentication Required');
expect(mocks.context).not.toHaveBeenCalled();
});
it('does not render moderation controls for an ordinary member', async () => {
mocks.context.mockResolvedValue({ ...context, permissions: { role: 'member', canManageSettings: false } });
render(<FounderModerationPage clubId="club-slug" />);
await screen.findByText('Management Access Restricted');
expect(screen.queryByRole('tab', { name: 'Wall posts' })).toBeNull();
});
});