kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
166 wiersze
5.3 KiB
TypeScript
166 wiersze
5.3 KiB
TypeScript
import userEvent from '@testing-library/user-event';
|
|
import { Map as ImmutableMap } from 'immutable';
|
|
import React from 'react';
|
|
|
|
import { __stub } from 'soapbox/api';
|
|
|
|
import { render, screen, waitFor } from '../../../jest/test-helpers';
|
|
import FeedCarousel from '../feed-carousel';
|
|
|
|
vi.mock('../../../hooks/useDimensions', () => ({
|
|
useDimensions: () => [{ scrollWidth: 190 }, null, { width: 300 }],
|
|
}));
|
|
|
|
(window as any).ResizeObserver = class ResizeObserver {
|
|
|
|
observe() { }
|
|
disconnect() { }
|
|
|
|
};
|
|
|
|
describe('<FeedCarousel />', () => {
|
|
let store: any;
|
|
|
|
describe('with "carousel" enabled', () => {
|
|
beforeEach(() => {
|
|
store = {
|
|
instance: {
|
|
version: '3.4.1 (compatible; TruthSocial 1.0.0)',
|
|
pleroma: ImmutableMap({
|
|
metadata: ImmutableMap({
|
|
features: [],
|
|
}),
|
|
}),
|
|
},
|
|
};
|
|
});
|
|
|
|
describe('with avatars', () => {
|
|
beforeEach(() => {
|
|
__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 },
|
|
]);
|
|
|
|
mock.onGet('/api/v1/accounts/1/statuses').reply(200, [], {
|
|
link: '<https://example.com/api/v1/accounts/1/statuses?since_id=1>; rel=\'prev\'',
|
|
});
|
|
|
|
mock.onPost('/api/v1/truth/carousels/avatars/seen').reply(200);
|
|
});
|
|
});
|
|
|
|
it('should render the Carousel', async() => {
|
|
render(<FeedCarousel />, undefined, store);
|
|
|
|
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');
|
|
});
|
|
|
|
// 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');
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('with 0 avatars', () => {
|
|
beforeEach(() => {
|
|
__stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').reply(200, []));
|
|
});
|
|
|
|
it('renders nothing', async() => {
|
|
render(<FeedCarousel />, undefined, store);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(0);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('with a failed request to the API', () => {
|
|
beforeEach(() => {
|
|
__stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').networkError());
|
|
});
|
|
|
|
it('renders the error message', async() => {
|
|
render(<FeedCarousel />, undefined, store);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId('feed-carousel-error')).toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('with multiple pages of avatars', () => {
|
|
beforeEach(() => {
|
|
__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' },
|
|
]);
|
|
});
|
|
|
|
Element.prototype.getBoundingClientRect = vi.fn(() => {
|
|
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();
|
|
render(<FeedCarousel />, undefined, store);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId('prev-page')).toHaveAttribute('disabled');
|
|
expect(screen.getByTestId('next-page')).not.toHaveAttribute('disabled');
|
|
});
|
|
|
|
await user.click(screen.getByTestId('next-page'));
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId('prev-page')).not.toHaveAttribute('disabled');
|
|
// expect(screen.getByTestId('next-page')).toHaveAttribute('disabled');
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|