Public Access
feat(ui): add follow button, follows card, and inbox page
This commit is contained in:
1 parent
3aed243e35
commit
43c4862606
23 files changed
+603
-2
No files matched your search
@@ -0,0 +1,70 @@
|
||||
// @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();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user