mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-10-29 18:28:28 -04:00
101 lines
4.0 KiB
React
101 lines
4.0 KiB
React
import {render, screen, waitFor} from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import {afterEach, describe, expect, it, vi} from 'vitest';
|
|
|
|
import * as api from '../api';
|
|
import CardPhotoDialog from './CardPhotoDialog';
|
|
|
|
const photos = [
|
|
{id: 1, title: 'Fermenting jar', thumbnail_url: '/jar-thumb.jpg', fullsize_url: '/jar.jpg'},
|
|
{id: 2, title: 'Drying on a plate', thumbnail_url: '/plate-thumb.jpg', fullsize_url: '/plate.jpg'},
|
|
];
|
|
|
|
const props = {url: '/posts/7', photos, subject: 'Saving tomato seed', excerpt: 'The tomatoes', byline: 'by brenda'};
|
|
|
|
async function openDialog(extra = {}) {
|
|
const user = userEvent.setup();
|
|
render(<CardPhotoDialog {...props} {...extra} />);
|
|
await user.click(screen.getByRole('button', {name: 'Change'}));
|
|
return user;
|
|
}
|
|
|
|
describe('CardPhotoDialog', () => {
|
|
afterEach(() => vi.restoreAllMocks());
|
|
|
|
it('is closed until Change is clicked', () => {
|
|
render(<CardPhotoDialog {...props} />);
|
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('lists the photos in the post', async () => {
|
|
await openDialog();
|
|
expect(screen.getAllByRole('radio')).toHaveLength(2);
|
|
});
|
|
|
|
it('selects the current card photo', async () => {
|
|
await openDialog({selectedId: 2});
|
|
expect(screen.getByRole('radio', {name: /Drying on a plate/})).toBeChecked();
|
|
});
|
|
|
|
it('selects the first photo when none is chosen', async () => {
|
|
await openDialog();
|
|
expect(screen.getByRole('radio', {name: /Fermenting jar/})).toBeChecked();
|
|
});
|
|
|
|
it('previews the chosen photo', async () => {
|
|
const user = await openDialog();
|
|
await user.click(screen.getByRole('radio', {name: /Drying on a plate/}));
|
|
expect(screen.getByAltText('Preview of the card photo')).toHaveAttribute('src', '/plate.jpg');
|
|
});
|
|
|
|
it('saves the chosen photo on the post', async () => {
|
|
const patch = vi.spyOn(api, 'patchJson').mockResolvedValue({ok: false, status: 422, data: null});
|
|
const user = await openDialog();
|
|
await user.click(screen.getByRole('radio', {name: /Drying on a plate/}));
|
|
await user.click(screen.getByRole('button', {name: 'Use this photo'}));
|
|
await waitFor(() => expect(patch).toHaveBeenCalledWith('/posts/7', {post: {card_photo_id: 2}}));
|
|
});
|
|
|
|
it('shows an error when saving fails', async () => {
|
|
vi.spyOn(api, 'patchJson').mockResolvedValue({ok: false, status: 422, data: null});
|
|
const user = await openDialog();
|
|
await user.click(screen.getByRole('button', {name: 'Use this photo'}));
|
|
expect(await screen.findByRole('alert')).toHaveTextContent('could not be saved');
|
|
});
|
|
|
|
it('asks for a photo first when the post has none', async () => {
|
|
await openDialog({photos: []});
|
|
expect(screen.getByText(/Pick a photo from Flickr for this post first/)).toBeInTheDocument();
|
|
});
|
|
|
|
it('closes on Cancel', async () => {
|
|
const user = await openDialog();
|
|
await user.click(screen.getByRole('button', {name: 'Cancel'}));
|
|
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
});
|
|
it('says where the photos come from', async () => {
|
|
await openDialog();
|
|
expect(screen.getByText(/Photos come from your Flickr account/)).toBeInTheDocument();
|
|
});
|
|
|
|
it('links to the page photo dialog for another photo', async () => {
|
|
await openDialog({addPhotoUrl: '/photos/new?id=7&type=post'});
|
|
expect(screen.getByRole('link', {name: 'Pick a different photo from Flickr'})).toHaveAttribute('data-photo-dialog');
|
|
});
|
|
|
|
it('offers no other photo link without an address', async () => {
|
|
await openDialog();
|
|
expect(screen.queryByRole('link', {name: /Flickr/})).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('tags the chosen photo as selected', async () => {
|
|
await openDialog({selectedId: 2});
|
|
expect(screen.getAllByText('✓ Selected')).toHaveLength(2); // shown by CSS only for the checked one
|
|
});
|
|
|
|
it('stars the current card photo', async () => {
|
|
await openDialog({selectedId: 2});
|
|
expect(screen.getByRole('radio', {name: /★\s*Drying on a plate/})).toBeInTheDocument();
|
|
});
|
|
});
|