openCard.test.ts2.3 KBView on GitHub
/**
 * Opening a card — the shared definition every surface calls.
 *
 * The sibling of the task's `open-task` tests, and it covers the same two claims: that one
 * click means one thing everywhere, and that the open survives a reload because it is written
 * to the URL.
 */

import { closeCard, openCard, type OpenCardDeps } from '@/modules/documents/board/open-card';

function deps() {
  const setSelectedArtifact = jest.fn();
  const setCardParam = jest.fn();
  return {
    setSelectedArtifact,
    setCardParam,
    all: { setSelectedArtifact, setCardParam } as OpenCardDeps,
  };
}

describe('openCard', () => {
  it('opens the card as a FILE artifact — a card is a document, not a new kind', () => {
    // `DisplayArtifactPanel` dispatches `kind: 'file'` on the row's documentType, the way it
    // already does for a table. A `card` ContextKind would mean teaching every context-item
    // consumer about a kind that is a file wearing a hat.
    const d = deps();
    openCard('card-1', d.all);
    expect(d.setSelectedArtifact).toHaveBeenCalledWith({ kind: 'file', id: 'card-1' });
  });

  it('writes the URL param, so the ticket survives a reload and can be pasted', () => {
    const d = deps();
    openCard('card-1', d.all);
    expect(d.setCardParam).toHaveBeenCalledWith('card-1');
  });

  it('writes the param BEFORE the artifact', () => {
    // A reload landing mid-open must resolve to the ticket the artifact is about to show, not
    // to whatever was open before.
    const order: string[] = [];
    openCard('card-1', {
      setCardParam: () => void order.push('param'),
      setSelectedArtifact: () => void order.push('artifact'),
    });
    expect(order).toEqual(['param', 'artifact']);
  });

  it('closeCard clears the param and touches nothing else', () => {
    const d = deps();
    closeCard(d.all);
    expect(d.setCardParam).toHaveBeenCalledWith(null);
    expect(d.setSelectedArtifact).not.toHaveBeenCalled();
  });

  it('is idempotent — opening the same card twice is the same two writes', () => {
    const d = deps();
    openCard('card-1', d.all);
    openCard('card-1', d.all);
    expect(d.setCardParam).toHaveBeenNthCalledWith(1, 'card-1');
    expect(d.setCardParam).toHaveBeenNthCalledWith(2, 'card-1');
    expect(d.setSelectedArtifact).toHaveBeenCalledTimes(2);
  });
});