Public Access
71 lines
3.0 KiB
React
71 lines
3.0 KiB
React
// @vitest-environment jsdom
|
|
import {afterEach, describe, expect, it, vi} from 'vitest';
|
|
import {cleanup, fireEvent, render, screen, waitFor} from '@testing-library/react';
|
|
import {toast} from 'sonner';
|
|
import FollowButton from './FollowButton.jsx';
|
|
import {fetchRoutes, json} from '../../test/fetchRoutes.js';
|
|
|
|
vi.mock('react-i18next', () => import('../../test/i18n-mock.js'));
|
|
vi.mock('sonner', () => ({toast: {success: vi.fn(), error: vi.fn()}}));
|
|
|
|
const noFollows = {following: [], followers: []};
|
|
const callsOf = (method) => fetch.mock.calls.filter(([, init]) => init?.method === method);
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('FollowButton', () => {
|
|
it('offersFollowAndFollowsByNameThenOffersUnfollow', async () => {
|
|
fetchRoutes({'GET /api/follows': json(200, noFollows), 'PUT /api/follows/by-name/Lobo%20Wolf': json(204)});
|
|
render(<FollowButton displayName="Lobo Wolf"/>);
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: 'FOLLOW.FOLLOW'}));
|
|
|
|
expect(await screen.findByRole('button', {name: 'FOLLOW.UNFOLLOW'})).toBeTruthy();
|
|
expect(callsOf('PUT')).toHaveLength(1);
|
|
});
|
|
|
|
it('offersUnfollowForANameAlreadyFollowedIgnoringCase', async () => {
|
|
fetchRoutes({'GET /api/follows': json(200, {following: [{id: 1, displayName: 'lobo'}], followers: []}),
|
|
'DELETE /api/follows/by-name/Lobo': json(204)});
|
|
render(<FollowButton displayName="Lobo"/>);
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: 'FOLLOW.UNFOLLOW'}));
|
|
|
|
expect(await screen.findByRole('button', {name: 'FOLLOW.FOLLOW'})).toBeTruthy();
|
|
expect(callsOf('DELETE')).toHaveLength(1);
|
|
});
|
|
|
|
it('saysSoWhenTheProfileCannotBeFollowed', async () => {
|
|
fetchRoutes({'GET /api/follows': json(200, noFollows),
|
|
'PUT /api/follows/by-name/Lobo': json(404, {code: 'PROFILE_NOT_FOUND'})});
|
|
render(<FollowButton displayName="Lobo"/>);
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: 'FOLLOW.FOLLOW'}));
|
|
|
|
expect(await screen.findByText('FOLLOW.NOT_FOLLOWABLE')).toBeTruthy();
|
|
expect(screen.queryByRole('button')).toBeNull();
|
|
});
|
|
|
|
it('toastsOnAnOtherErrorAndKeepsTheButton', async () => {
|
|
fetchRoutes({'GET /api/follows': json(200, noFollows),
|
|
'PUT /api/follows/by-name/Lobo': json(400, {code: 'FOLLOW_LIMIT'})});
|
|
render(<FollowButton displayName="Lobo"/>);
|
|
|
|
fireEvent.click(await screen.findByRole('button', {name: 'FOLLOW.FOLLOW'}));
|
|
|
|
await waitFor(() => expect(toast.error).toHaveBeenCalledWith('FOLLOW.LIMIT'));
|
|
expect(screen.getByRole('button', {name: 'FOLLOW.FOLLOW'})).toBeTruthy();
|
|
});
|
|
|
|
it('showsNoButtonWhenTheListDoesNotLoad', async () => {
|
|
fetchRoutes({'GET /api/follows': json(500, {})});
|
|
render(<FollowButton displayName="Lobo"/>);
|
|
|
|
await waitFor(() => expect(fetch).toHaveBeenCalled());
|
|
expect(screen.queryByRole('button')).toBeNull();
|
|
});
|
|
});
|