Add tests for the cart reducer
React · React · advanced · greenfield
Adds the missing test suite for the cart reducer: concrete-value assertions for every action type, a structuredClone-based purity check, clamp boundaries on both ends, and a same-reference assertion for unknown actions. The reducer itself is included unchanged for context.
Requirements
- Cover the existing `cartReducer` with unit tests (Vitest). The reducer contract: `add-item` adds `{ productId, unitPriceCents, quantity: 1 }` or increments the quantity of an existing line; `set-quantity` clamps an integer into 1–99 for the given line (no-op for an unknown `productId`); `remove-item` drops the line; `apply-coupon` stores the code; unknown action types return the state unchanged.
- Action payloads are produced by the app's own dispatch helpers: `quantity` is always an integer, ids are strings.
- Tests must assert concrete resulting state (no snapshot files, no `toBeDefined`-style assertions).
- The reducer must be pure: at least one test must prove a dispatch does not mutate the previous state object.
- Unknown action types must be proven to return the **same reference**, so `useReducer` consumers don't re-render.
Files touched
- src/state/cartReducer.js
- src/state/cartReducer.test.js
--- src/state/cartReducer.js
+export const initialCart = { items: [], couponCode: null };
+
+export function cartReducer(state, action) {
+ switch (action.type) {
+ case 'add-item': {
+ const { productId, unitPriceCents } = action;
+ const existing = state.items.find((item) => item.productId === productId);
+ if (existing) {
+ return {
+ ...state,
+ items: state.items.map((item) =>
+ item.productId === productId ? { ...item, quantity: item.quantity + 1 } : item,
+ ),
+ };
+ }
+ return { ...state, items: [...state.items, { productId, unitPriceCents, quantity: 1 }] };
+ }
+ case 'set-quantity': {
+ const quantity = Math.max(1, Math.min(99, action.quantity));
+ return {
+ ...state,
+ items: state.items.map((item) =>
+ item.productId === action.productId ? { ...item, quantity } : item,
+ ),
+ };
+ }
+ case 'remove-item':
+ return {
+ ...state,