Files

108 lines
3.9 KiB
React
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {render, screen} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {describe, expect, it, vi} from 'vitest';
import GardenCard from './GardenCard';
const planting = (id, name, extra = {}) => ({
id, url: `/plantings/${id}`, crop: {name, icon_url: '/i.png'}, actions: [], can_edit: false, planted_at: null,
badges: [], progress_note: null, percentage_grown: null, harvests: [], ...extra,
});
const garden = {
id: 1, name: 'Back yard', url: '/gardens/back-yard', image_url: '/g.jpg', layout_url: '/gardens/back-yard/layout',
plant_url: '/plantings/new?garden_id=1', plantings_count: 2, harvesting_now: 1, owner: null,
actions: [{key: 'edit', label: 'Edit', href: '/gardens/back-yard/edit'}, {key: 'photo', label: 'Add photo', href: '/photos/new?type=garden&id=1'}],
perennials: [planting(1, 'Rhubarb')], annuals: [planting(2, 'Tomato')],
};
function setup(props = {}, gardenProps = {}) {
return render(<GardenCard garden={{...garden, ...gardenProps}} defaultIconUrl="/d.png" {...props} />);
}
describe('GardenCard', () => {
it('shows the garden\'s name', () => {
setup();
expect(screen.getByText('Back yard', {selector: 'b'})).toBeInTheDocument();
});
it('summarises the plantings and harvests', () => {
setup();
expect(screen.getByText('2 plantings · harvesting now: 1')).toBeInTheDocument();
});
it('says planting, singular', () => {
setup({}, {plantings_count: 1, harvesting_now: 0});
expect(screen.getByText('1 planting')).toBeInTheDocument();
});
it('names the owner on a garden that is not yours', () => {
setup({}, {owner: {login_name: 'sam'}});
expect(screen.getByText(/owner: sam/)).toBeInTheDocument();
});
it('opens when asked', () => {
const {container} = setup({defaultOpen: true});
expect(container.querySelector('details')).toHaveAttribute('open');
});
it('lists perennials', () => {
setup();
expect(screen.getByRole('link', {name: /Rhubarb/})).toHaveAttribute('href', '/plantings/1');
});
it('links to the garden', () => {
setup();
expect(screen.getByRole('link', {name: 'Open Back yard ›'})).toHaveAttribute('href', '/gardens/back-yard');
});
it('links to the layout', () => {
setup();
expect(screen.getByRole('link', {name: /Layout/})).toHaveAttribute('href', '/gardens/back-yard/layout');
});
it('leaves out the layout button without a layout', () => {
setup({}, {layout_url: null});
expect(screen.queryByRole('link', {name: /Layout/})).not.toBeInTheDocument();
});
it('leaves out Add planting for a garden you cannot plant in', () => {
setup({}, {plant_url: null});
expect(screen.queryByRole('link', {name: /Add planting/})).not.toBeInTheDocument();
});
it('opens the plant dialog from Add planting', async () => {
const onPlant = vi.fn();
setup({onPlant});
await userEvent.click(screen.getByRole('link', {name: /Add planting/}));
expect(onPlant).toHaveBeenCalledWith(expect.objectContaining({id: 1}));
});
it('opens the edit dialog from the garden menu', async () => {
const onEditGarden = vi.fn();
setup({onEditGarden});
await userEvent.click(screen.getByRole('link', {name: 'Edit'}));
expect(onEditGarden).toHaveBeenCalledWith(expect.objectContaining({id: 1}));
});
it('opens the photo dialog from the garden menu', async () => {
const onAddPhoto = vi.fn();
setup({onAddPhoto});
await userEvent.click(screen.getByRole('link', {name: 'Add photo'}));
expect(onAddPhoto).toHaveBeenCalledWith({label: 'Back yard garden', href: '/photos/new?type=garden&id=1'});
});
describe('with nothing planted', () => {
it('says so', () => {
setup({}, {perennials: [], annuals: []});
expect(screen.getByText('Nothing planted here yet.')).toBeInTheDocument();
});
});
describe('without perennials', () => {
it('says none', () => {
setup({}, {perennials: []});
expect(screen.getByText('None')).toBeInTheDocument();
});
});
});