mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-10-29 10:18:29 -04:00
92 lines
3.4 KiB
React
92 lines
3.4 KiB
React
import {render, screen} from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import {describe, expect, it, vi} from 'vitest';
|
|
|
|
import MarkFinishedModal from './MarkFinishedModal';
|
|
|
|
const planting = {id: 1, url: '/plantings/1', crop: {name: 'Tomato'}, today: '2025-06-10', planted_at: '2025-05-01'};
|
|
|
|
function stubFetch(response) {
|
|
const fetch = vi.fn(async () => ({ok: response.ok, status: response.status, json: async () => response.data || {}}));
|
|
vi.stubGlobal('fetch', fetch);
|
|
return fetch;
|
|
}
|
|
|
|
function setup(props = {}) {
|
|
const onSaved = vi.fn();
|
|
render(<MarkFinishedModal planting={{...planting, ...props}} onClose={vi.fn()} onSaved={onSaved} />);
|
|
return onSaved;
|
|
}
|
|
|
|
describe('MarkFinishedModal', () => {
|
|
it('is titled for the crop', () => {
|
|
setup();
|
|
expect(screen.getByRole('dialog', {name: 'Mark Tomato as finished'})).toBeInTheDocument();
|
|
});
|
|
|
|
it('finishes it today to start with', () => {
|
|
setup();
|
|
expect(screen.getByLabelText('Today')).toBeChecked();
|
|
});
|
|
|
|
it('saves the finish date', async () => {
|
|
const fetch = stubFetch({ok: true, status: 200, data: {garden: {}}});
|
|
setup();
|
|
await userEvent.click(screen.getByRole('button', {name: 'Mark as finished'}));
|
|
expect(fetch).toHaveBeenCalledWith('/plantings/1', expect.objectContaining({
|
|
method: 'PATCH',
|
|
body: JSON.stringify({planting: {finished: true, finished_at: '2025-06-10'}}),
|
|
}));
|
|
});
|
|
|
|
it('hands the refreshed garden to onSaved', async () => {
|
|
stubFetch({ok: true, status: 200, data: {garden: {id: 4}}});
|
|
const onSaved = setup();
|
|
await userEvent.click(screen.getByRole('button', {name: 'Mark as finished'}));
|
|
expect(onSaved).toHaveBeenCalledWith({id: 4});
|
|
});
|
|
|
|
it('starts the date box the day after it was planted', async () => {
|
|
setup();
|
|
await userEvent.click(screen.getByLabelText('Enter date'));
|
|
expect(screen.getByLabelText('Date')).toHaveAttribute('min', '2025-05-02');
|
|
});
|
|
|
|
describe('for a planting made today', () => {
|
|
it('does not offer today', () => {
|
|
setup({planted_at: '2025-06-10'});
|
|
expect(screen.queryByLabelText('Today')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('starts on the day after', () => {
|
|
setup({planted_at: '2025-06-10'});
|
|
expect(screen.getByLabelText('Date')).toHaveValue('2025-06-11');
|
|
});
|
|
});
|
|
|
|
describe('when the server refuses', () => {
|
|
it('lists the problems', async () => {
|
|
stubFetch({ok: false, status: 422, data: {errors: {finished_at: ['is before planting']}}});
|
|
setup();
|
|
await userEvent.click(screen.getByRole('button', {name: 'Mark as finished'}));
|
|
expect(await screen.findByText('Finished at is before planting')).toBeInTheDocument();
|
|
});
|
|
|
|
it('says when the member is not allowed', async () => {
|
|
stubFetch({ok: false, status: 403});
|
|
setup();
|
|
await userEvent.click(screen.getByRole('button', {name: 'Mark as finished'}));
|
|
expect(await screen.findByText('You can\'t change this planting.')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
describe('when the server cannot be reached', () => {
|
|
it('says so', async () => {
|
|
vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('offline')));
|
|
setup();
|
|
await userEvent.click(screen.getByRole('button', {name: 'Mark as finished'}));
|
|
expect(await screen.findByText(/Couldn't reach the server/)).toBeInTheDocument();
|
|
});
|
|
});
|
|
});
|