Skip to the code
cf.

Fix the order counter

The tea shop's order counter has two bugs, and the starter is the buggy code. It shows Orders: 0 and three buttons. +1 adds one order. +3 adds three at once, for a table of three. +1 later adds one order a second after you click it, for orders phoned in.

The first bug: +3 only adds one. The second: +1 later adds one to the count as it was when you clicked, so anything that happened during that second is lost. Click +1 later, then +3, and a second later the count drops to 1 instead of reaching 4.

Fix both so every click counts. Keep the same text and buttons: +1 adds 1, +3 adds 3, and +1 later adds 1, after 1000 ms, to whatever the count is then. Clicking +1 later twice adds 2.

<p>Orders: 4</p>
<button>+1</button>
<button>+3</button>
<button>+1 later</button>

What the tests check

  1. starts at 0 and +1 adds one
    render(<App />);
    expect(screen.getByText("Orders: 0")).toBeInTheDocument();
    await user.click(screen.getByRole("button", { name: "+1" }));
    expect(screen.getByText("Orders: 1")).toBeInTheDocument();
    
  2. +3 adds three
    render(<App />);
    await user.click(screen.getByRole("button", { name: "+3" }));
    expect(screen.getByText("Orders: 3")).toBeInTheDocument();
    
  3. +3 twice adds six
    render(<App />);
    await user.click(screen.getByRole("button", { name: "+3" }));
    await user.click(screen.getByRole("button", { name: "+3" }));
    expect(screen.getByText("Orders: 6")).toBeInTheDocument();
    
  4. +1 later adds one after a second, not before
    const clock = useFakeTimers();
    render(<App />);
    await user.click(screen.getByRole("button", { name: "+1 later" }));
    await clock.advance(999);
    expect(screen.getByText("Orders: 0")).toBeInTheDocument();
    await clock.advance(1);
    expect(screen.getByText("Orders: 1")).toBeInTheDocument();
    
  5. +1 later adds to the count as it is a second later
    const clock = useFakeTimers();
    render(<App />);
    await user.click(screen.getByRole("button", { name: "+1 later" }));
    await user.click(screen.getByRole("button", { name: "+3" }));
    expect(screen.getByText("Orders: 3")).toBeInTheDocument();
    await clock.advance(1000);
    expect(screen.getByText("Orders: 4")).toBeInTheDocument();
    
  6. +1 later keeps the +1 clicks made while it waits
    const clock = useFakeTimers();
    render(<App />);
    await user.click(screen.getByRole("button", { name: "+1 later" }));
    await user.click(screen.getByRole("button", { name: "+1" }));
    await user.click(screen.getByRole("button", { name: "+1" }));
    await clock.advance(1000);
    expect(screen.getByText("Orders: 3")).toBeInTheDocument();
    
  7. two +1 later clicks add two
    const clock = useFakeTimers();
    render(<App />);
    await user.click(screen.getByRole("button", { name: "+1 later" }));
    await user.click(screen.getByRole("button", { name: "+1 later" }));
    await clock.advance(1000);
    expect(screen.getByText("Orders: 2")).toBeInTheDocument();
    

Learn more

App.jsxSaved in this browser

Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.

Ctrl + Enter runs the tests (⌘ + Enter on a Mac).