BoardDocumentView.empty.test.tsx3.3 KBView on GitHub
/**
 * A board with no schema at all — the one state where every control on the surface is
 * downstream of one missing thing.
 *
 * A board created today never lands here (`createBoard` seeds the starter axis); this is the
 * older board, or the one something emptied. What it must offer is COLUMNS: a card filed onto a
 * board with no axis has nowhere to be, so "Add a card" was the one action that could not fix
 * what was actually missing.
 */
import { fireEvent, render, screen } from '@testing-library/react';

const mockPatchSchema = jest.fn();
const mockAddCard = jest.fn();

jest.mock('@/modules/documents/board/useYBoard', () => ({
  useYBoard: () => ({
    schema: { version: 1, visibility: 'team', fields: [] },
    isLoading: false,
    patchSchema: mockPatchSchema,
    addField: jest.fn(),
    updateField: jest.fn(),
    removeField: jest.fn(),
    setView: jest.fn(),
    undo: jest.fn(),
    redo: jest.fn(),
  }),
  BOARD_ORIGIN: 'board',
}));

jest.mock('@/modules/documents/yjs', () => ({ useDocEvents: () => undefined }));

jest.mock('@/providers/query-provider', () => ({
  useTRPC: () => ({
    boards: {
      listCards: {
        queryKey: () => ['boards.listCards'],
        queryOptions: () => ({ queryKey: ['boards.listCards'] }),
      },
      moveCard: { mutationOptions: () => ({}) },
      addCard: { mutationOptions: () => ({}) },
    },
  }),
}));

jest.mock('@tanstack/react-query', () => ({
  useQueryClient: () => ({
    invalidateQueries: jest.fn(),
    cancelQueries: jest.fn(),
    getQueryData: jest.fn(),
    setQueryData: jest.fn(),
  }),
  useQuery: () => ({ data: { cards: [] }, isLoading: false, isError: false }),
  useMutation: () => ({ mutate: mockAddCard, isPending: false }),
}));

jest.mock('@/modules/documents/board/CardDocumentView', () => ({
  CardDocumentView: () => <div data-testid="ticket" />,
}));

import { BoardDocumentView } from '@/modules/documents/board/BoardDocumentView';

describe('BoardDocumentView — a board with no columns', () => {
  beforeEach(() => {
    mockPatchSchema.mockClear();
    render(<BoardDocumentView documentId="b1" />);
  });

  it('offers COLUMNS, not a card', () => {
    expect(screen.getByRole('button', { name: 'Add columns' })).toBeInTheDocument();
    expect(screen.queryByRole('button', { name: /add a card/i })).not.toBeInTheDocument();
  });

  it('seeds the SAME starter axis the server creates a board with', () => {
    // Re-typed placeholder values here would be a board repaired onto a different field key
    // from the one an agent files cards into — the columns would draw and the cards would not
    // land in them.
    fireEvent.click(screen.getByRole('button', { name: 'Add columns' }));
    expect(mockPatchSchema).toHaveBeenCalledTimes(1);
    const patch = mockPatchSchema.mock.calls[0]![0];
    expect(patch.fields.map((f: { key=[redacted] }) => f.key)).toEqual(['column']);
    expect(patch.fields[0].options).toEqual(['Column 1', 'Column 2', 'Column 3']);
    expect(patch.view.groupByField).toBe('column');
  });

  it('lights the Schema pill, because a board with no attributes can hold nothing', () => {
    // `bg-action` is the app's "this is the thing to do next" fill, and here it is literally
    // true — no attributes means no columns, no card face and nothing to write into.
    expect(screen.getByRole('button', { name: 'Schema' }).className).toContain('bg-action');
  });
});