soapbox/app/soapbox/features/feed-filtering/__tests__/feed-carousel.test.tsx

166 wiersze
5.3 KiB
TypeScript
Czysty Zwykły widok Historia

2022-06-23 15:51:18 +00:00
import userEvent from '@testing-library/user-event';
import { Map as ImmutableMap } from 'immutable';
import React from 'react';
2022-08-09 16:00:44 +00:00
import { __stub } from 'soapbox/api';
import { render, screen, waitFor } from '../../../jest/test-helpers';
2022-06-23 15:51:18 +00:00
import FeedCarousel from '../feed-carousel';
2023-09-16 20:16:59 +00:00
vi.mock('../../../hooks/useDimensions', () => ({
2022-12-22 17:02:17 +00:00
useDimensions: () => [{ scrollWidth: 190 }, null, { width: 300 }],
2022-06-23 15:51:18 +00:00
}));
(window as any).ResizeObserver = class ResizeObserver {
observe() { }
disconnect() { }
};
describe('<FeedCarousel />', () => {
2022-07-06 17:31:11 +00:00
let store: any;
2022-06-23 15:51:18 +00:00
describe('with "carousel" enabled', () => {
2022-06-23 15:51:18 +00:00
beforeEach(() => {
store = {
instance: {
version: '3.4.1 (compatible; TruthSocial 1.0.0)',
pleroma: ImmutableMap({
metadata: ImmutableMap({
features: [],
}),
}),
},
};
});
2022-08-08 19:53:21 +00:00
describe('with avatars', () => {
beforeEach(() => {
2022-08-09 16:00:44 +00:00
__stub((mock) => {
mock.onGet('/api/v1/truth/carousels/avatars')
.reply(200, [
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg', seen: false },
{ account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg', seen: false },
{ account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg', seen: false },
{ account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg', seen: false },
2022-08-09 16:00:44 +00:00
]);
mock.onGet('/api/v1/accounts/1/statuses').reply(200, [], {
link: '<https://example.com/api/v1/accounts/1/statuses?since_id=1>; rel=\'prev\'',
});
2022-12-14 19:28:41 +00:00
mock.onPost('/api/v1/truth/carousels/avatars/seen').reply(200);
2022-08-09 16:00:44 +00:00
});
2022-08-08 19:53:21 +00:00
});
2022-07-11 13:10:10 +00:00
2022-08-08 19:53:21 +00:00
it('should render the Carousel', async() => {
render(<FeedCarousel />, undefined, store);
2022-06-23 15:51:18 +00:00
2022-08-08 19:53:21 +00:00
await waitFor(() => {
expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(1);
expect(screen.queryAllByTestId('carousel-item')).toHaveLength(4);
});
});
it('should handle the "seen" state', async() => {
render(<FeedCarousel />, undefined, store);
// Unseen
await waitFor(() => {
expect(screen.queryAllByTestId('carousel-item')).toHaveLength(4);
});
expect(screen.getAllByTestId('carousel-item-avatar')[0]).toHaveClass('ring-accent-500');
// Selected
await userEvent.click(screen.getAllByTestId('carousel-item-avatar')[0]);
await waitFor(() => {
expect(screen.getAllByTestId('carousel-item-avatar')[0]).toHaveClass('ring-primary-600');
});
2023-01-05 23:58:01 +00:00
// HACK: wait for state change
await new Promise((r) => setTimeout(r, 0));
// Marked as seen, not selected
await userEvent.click(screen.getAllByTestId('carousel-item-avatar')[0]);
await waitFor(() => {
expect(screen.getAllByTestId('carousel-item-avatar')[0]).toHaveClass('ring-transparent');
2022-08-08 19:53:21 +00:00
});
});
2022-07-11 13:10:10 +00:00
});
describe('with 0 avatars', () => {
beforeEach(() => {
2022-08-09 16:00:44 +00:00
__stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').reply(200, []));
2022-07-11 13:10:10 +00:00
});
2022-08-08 19:53:21 +00:00
it('renders nothing', async() => {
2022-07-11 13:10:10 +00:00
render(<FeedCarousel />, undefined, store);
2022-08-08 19:53:21 +00:00
await waitFor(() => {
expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(0);
});
2022-07-11 13:10:10 +00:00
});
2022-06-23 15:51:18 +00:00
});
describe('with a failed request to the API', () => {
beforeEach(() => {
2022-08-09 16:00:44 +00:00
__stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').networkError());
2022-06-23 15:51:18 +00:00
});
2022-08-08 19:53:21 +00:00
it('renders the error message', async() => {
2022-07-06 17:31:11 +00:00
render(<FeedCarousel />, undefined, store);
2022-06-23 15:51:18 +00:00
2022-08-08 19:53:21 +00:00
await waitFor(() => {
expect(screen.getByTestId('feed-carousel-error')).toBeInTheDocument();
});
2022-06-23 15:51:18 +00:00
});
});
describe('with multiple pages of avatars', () => {
beforeEach(() => {
2022-08-09 16:00:44 +00:00
__stub((mock) => {
mock.onGet('/api/v1/truth/carousels/avatars')
.reply(200, [
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' },
{ account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg' },
{ account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg' },
{ account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg' },
]);
});
2022-06-23 15:51:18 +00:00
2023-09-16 20:16:59 +00:00
Element.prototype.getBoundingClientRect = vi.fn(() => {
2022-06-23 15:51:18 +00:00
return {
width: 200,
height: 120,
x: 0,
y: 0,
toJSON: () => null,
top: 0,
left: 0,
bottom: 0,
right: 0,
};
});
});
it('should render the correct prev/next buttons', async() => {
const user = userEvent.setup();
2022-07-06 17:31:11 +00:00
render(<FeedCarousel />, undefined, store);
2022-06-23 15:51:18 +00:00
await waitFor(() => {
2022-12-22 17:02:17 +00:00
expect(screen.getByTestId('prev-page')).toHaveAttribute('disabled');
expect(screen.getByTestId('next-page')).not.toHaveAttribute('disabled');
2022-06-23 15:51:18 +00:00
});
await user.click(screen.getByTestId('next-page'));
2022-06-23 15:51:18 +00:00
await waitFor(() => {
2022-12-22 17:02:17 +00:00
expect(screen.getByTestId('prev-page')).not.toHaveAttribute('disabled');
2023-07-20 21:41:45 +00:00
// expect(screen.getByTestId('next-page')).toHaveAttribute('disabled');
2022-06-23 15:51:18 +00:00
});
});
});
});
});