Skip to content

Commit

Permalink
test: cover card quantity updates
Browse files Browse the repository at this point in the history
  • Loading branch information
fspoettel committed Jun 16, 2024
1 parent 9d26150 commit 2a207b6
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 164 deletions.
4 changes: 2 additions & 2 deletions src/components/card-list/card-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function CardList({ slotLeft, slotRight }: Props) {
const data = useStore(selectListCards);

const canEdit = useStore(selectCanEditDeck);
const changeCardQuantity = useStore((state) => state.changeCardQuantity);
const updateCardQuantity = useStore((state) => state.updateCardQuantity);
const quantities = useStore(selectCardQuantities);
const search = useStore(selectActiveListSearch);
const metadata = useStore((state) => state.metadata);
Expand Down Expand Up @@ -204,7 +204,7 @@ export function CardList({ slotLeft, slotRight }: Props) {
isActive={index === currentTop}
key={data.cards[index].code}
onChangeCardQuantity={
canEdit ? changeCardQuantity : undefined
canEdit ? updateCardQuantity : undefined
}
quantities={quantities}
/>
Expand Down
12 changes: 6 additions & 6 deletions src/components/card-modal/card-modal-quantities.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,21 @@ export function CardModalQuantities({
[onClickBackground],
);

const changeCardQuantity = useStore((state) => state.changeCardQuantity);
const updateCardQuantity = useStore((state) => state.updateCardQuantity);

useEffect(() => {
if (!canEdit) return;

function onKeyDown(evt: KeyboardEvent) {
if (evt.key === "ArrowRight") {
evt.preventDefault();
changeCardQuantity(card.code, 1, "slots");
updateCardQuantity(card.code, 1, "slots");
} else if (evt.key === "ArrowLeft") {
evt.preventDefault();
changeCardQuantity(card.code, -1, "slots");
updateCardQuantity(card.code, -1, "slots");
} else if (Number.parseInt(evt.key) >= 0) {
evt.preventDefault();
changeCardQuantity(card.code, Number.parseInt(evt.key), "slots", "set");
updateCardQuantity(card.code, Number.parseInt(evt.key), "slots", "set");
onClickBackground?.();
}
}
Expand All @@ -59,7 +59,7 @@ export function CardModalQuantities({
return () => {
window.removeEventListener("keydown", onKeyDown);
};
}, [canEdit, card.code, changeCardQuantity, onClickBackground]);
}, [canEdit, card.code, updateCardQuantity, onClickBackground]);

const quantities = useStore((state) =>
selectCardQuantitiesForSlot(state, "slots"),
Expand All @@ -82,7 +82,7 @@ export function CardModalQuantities({
);

const onChangeQuantity = (quantity: number, slot: Slot) => {
changeCardQuantity(card.code, quantity, slot);
updateCardQuantity(card.code, quantity, slot);
};

const showIgnoreDeckLimitSlots = useStore((state) =>
Expand Down
4 changes: 2 additions & 2 deletions src/components/decklist/decklist-groups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export function DecklistGroup({
const forbiddenCards = useStore(selectForbiddenCards);
const canEdit = useStore(selectCanEditDeck) && mapping !== "bonded";
const canCheckOwnership = useStore(selectCanCheckOwnership);
const changeCardQuantity = useStore((state) => state.changeCardQuantity);
const updateCardQuantity = useStore((state) => state.updateCardQuantity);

return (
<ol>
Expand All @@ -130,7 +130,7 @@ export function DecklistGroup({
isIgnored={ignoredCounts?.[card.code]}
key={card.code}
omitBorders
onChangeCardQuantity={canEdit ? changeCardQuantity : undefined}
onChangeCardQuantity={canEdit ? updateCardQuantity : undefined}
owned={ownershipCounts[card.code]}
quantities={quantities}
size="sm"
Expand Down
5 changes: 5 additions & 0 deletions src/store/slices/data.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { afterEach } from "node:test";
import { beforeAll, describe, expect, it } from "vitest";
import type { StoreApi } from "zustand";

Expand Down Expand Up @@ -29,6 +30,10 @@ describe("data slice", () => {
},
};

afterEach(async () => {
store = await getMockStore();
});

it("does not delete decks with upgrades", () => {
store.setState(mockState);

Expand Down
4 changes: 1 addition & 3 deletions src/store/slices/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ export const createDataSlice: StateCreator<StoreState, [], [], DataSlice> = (
deck.tags = deck.tags.replaceAll(", ", " ");
}

if (state.data.decks[deck.id]) {
throw new Error(`Deck ${deck.id} already exists.`);
}
assert(!state.data.decks[deck.id], `Deck ${deck.id} already exists.`);

const deckHistory =
type === "deck" && deck.previous_deck
Expand Down
119 changes: 119 additions & 0 deletions src/store/slices/deck-view.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { afterEach } from "node:test";
import { beforeAll, beforeEach, describe, expect, it } from "vitest";
import type { StoreApi } from "zustand";

import deckExtraSlots from "@/test/fixtures/decks/extra_slots.json";
import { getMockStore } from "@/test/get-mock-store";

import type { StoreState } from ".";
import { selectActiveDeck } from "../selectors/decks";

describe("deck-view slice", () => {
let store: StoreApi<StoreState>;

beforeAll(async () => {
store = await getMockStore();
});

describe("updateCardQuantity", () => {
beforeEach(() => {
store.setState({
data: {
decks: {
"deck-id": deckExtraSlots,
},
history: {
"deck-id": [],
},
},
});
});

afterEach(async () => {
store = await getMockStore();
});

it("throws an error if there is no active deck", () => {
store.setState({
deckView: null,
});

expect(() => {
store.getState().updateCardQuantity("01000", 1, "slots");
}).toThrowErrorMatchingInlineSnapshot(
`[Error: assertion failed: trying to edit deck, but state does not have an active deck.]`,
);
});

it("throws an error if the active deck is not in edit mode", () => {
store.setState({
deckView: {
id: "deck-id",
mode: "view",
},
});

expect(() => {
store.getState().updateCardQuantity("01000", 1, "slots");
}).toThrowErrorMatchingInlineSnapshot(
`[Error: assertion failed: trying to edit deck, but not in edit mode.]`,
);
});

it("throws an error if the active deck does not exist", () => {
store.getState().setActiveDeck("non-existent-deck", "edit");

expect(() => {
store.getState().updateCardQuantity("01000", 1, "slots");
}).toThrowErrorMatchingInlineSnapshot(
`[Error: assertion failed: trying to edit deck, but deck does not exist.]`,
);
});

it("increments the quantity of a card", () => {
const state = store.getState();
state.setActiveDeck("deck-id", "edit");
state.updateCardQuantity("01000", 1, "slots", "increment");
expect(selectActiveDeck(store.getState())?.slots["01000"]).toEqual(2);
});

it("decrements the quantity of a card", () => {
const state = store.getState();
state.setActiveDeck("deck-id", "edit");
state.updateCardQuantity("01000", -1, "slots", "increment");
expect(selectActiveDeck(store.getState())?.slots["01000"]).toEqual(0);
});

it("sets the quantity of a card", () => {
const state = store.getState();
state.setActiveDeck("deck-id", "edit");
state.updateCardQuantity("01000", 5, "slots", "set");
expect(selectActiveDeck(store.getState())?.slots["01000"]).toEqual(5);
});

it("does not set the quantity of a card to a negative value", () => {
const state = store.getState();
state.setActiveDeck("deck-id", "edit");
state.updateCardQuantity("01000", -5, "slots", "set");
state.updateCardQuantity("01000", -5, "slots", "increment");
expect(selectActiveDeck(store.getState())?.slots["01000"]).toEqual(0);
});

it("does not set the quantity of a card exceeding the limit", () => {
const state = store.getState();
state.setActiveDeck("deck-id", "edit");
state.updateCardQuantity("06021", 5, "slots", "set");
state.updateCardQuantity("06021", 5, "slots", "increment");
expect(selectActiveDeck(store.getState())?.slots["06021"]).toEqual(3);
});

it("adjusts cards in side slots", () => {
const state = store.getState();
state.setActiveDeck("deck-id", "edit");
state.updateCardQuantity("06021", 1, "sideSlots", "increment");
expect(selectActiveDeck(store.getState())?.sideSlots?.["06021"]).toEqual(
1,
);
});
});
});
Loading

0 comments on commit 2a207b6

Please sign in to comment.