);
};
const { getByTestId } = render(
,
);
// Should not be loading when initialAuth is provided
expect(getByTestId('loading')).toHaveTextContent('false');
expect(getByTestId('email')).toHaveTextContent('test@example.com');
expect(getByTestId('session')).toHaveTextContent('test-session');
expect(getByTestId('org')).toHaveTextContent('test-org');
expect(getByTestId('role')).toHaveTextContent('admin');
expect(getByTestId('impersonator')).toHaveTextContent('admin@example.com');
});
it('should call getAuthAction when initialAuth is not provided', async () => {
(getAuthAction as Mock).mockResolvedValueOnce({
user: { email: 'test@example.com' },
sessionId: 'test-session',
});
render(
Test Child
,
);
await waitFor(() => {
expect(getAuthAction).toHaveBeenCalledTimes(1);
});
});
it('should do nothing if onSessionExpired is false', async () => {
vi.spyOn(window, 'addEventListener');
await act(async () => {
render(
Test Child
,
);
});
// expect window to not have an event listener
expect(window.addEventListener).not.toHaveBeenCalled();
});
it('should call onSessionExpired when session is expired', async () => {
(checkSessionAction as Mock).mockRejectedValueOnce(new Error('Failed to fetch'));
const onSessionExpired = vi.fn();
render(
Test Child
,
);
act(() => {
// Simulate visibility change
window.dispatchEvent(new Event('visibilitychange'));
});
await waitFor(() => {
expect(onSessionExpired).toHaveBeenCalled();
});
});
it('should only call onSessionExpired once if multiple visibility changes occur', async () => {
(checkSessionAction as Mock).mockRejectedValueOnce(new Error('Failed to fetch'));
const onSessionExpired = vi.fn();
render(
Test Child
,
);
act(() => {
// Simulate visibility change twice
window.dispatchEvent(new Event('visibilitychange'));
window.dispatchEvent(new Event('visibilitychange'));
});
await waitFor(() => {
expect(onSessionExpired).toHaveBeenCalledTimes(1);
});
});
it('should pass through if checkSessionAction does not throw "Failed to fetch"', async () => {
(checkSessionAction as Mock).mockResolvedValueOnce(false);
const onSessionExpired = vi.fn();
render(
Test Child
,
);
act(() => {
// Simulate visibility change
window.dispatchEvent(new Event('visibilitychange'));
});
await waitFor(() => {
expect(onSessionExpired).not.toHaveBeenCalled();
});
});
describe('window.location.reload behavior', () => {
let originalLocationDescriptor: PropertyDescriptor | undefined;
beforeEach(() => {
originalLocationDescriptor = Object.getOwnPropertyDescriptor(window, 'location');
Object.defineProperty(window, 'location', {
writable: true,
value: { reload: vi.fn() },
});
});
afterEach(() => {
if (originalLocationDescriptor) {
Object.defineProperty(window, 'location', originalLocationDescriptor);
}
});
it('should reload the page when session is expired and no onSessionExpired handler is provided', async () => {
(checkSessionAction as Mock).mockRejectedValueOnce(new Error('Failed to fetch'));
render(
Test Child
,
);
act(() => {
// Simulate visibility change
window.dispatchEvent(new Event('visibilitychange'));
});
await waitFor(() => {
expect(window.location.reload).toHaveBeenCalled();
});
});
it('should not call onSessionExpired or reload the page if session is valid', async () => {
(checkSessionAction as Mock).mockResolvedValueOnce(true);
const onSessionExpired = vi.fn();
render(
Test Child
,
);
act(() => {
// Simulate visibility change
window.dispatchEvent(new Event('visibilitychange'));
});
await waitFor(() => {
expect(onSessionExpired).not.toHaveBeenCalled();
expect(window.location.reload).not.toHaveBeenCalled();
});
});
});
});
describe('useAuth', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('should call getAuth when a user is not returned when ensureSignedIn is true', async () => {
// First and second calls return no user, second call returns a user
(getAuthAction as Mock)
.mockResolvedValueOnce({ user: null, loading: true })
.mockResolvedValueOnce({ user: { email: 'test@example.com' }, loading: false });
const TestComponent = () => {
const auth = useAuth({ ensureSignedIn: true });
return