rewrite game manager tests for new prediction model
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,12 +9,14 @@ describe("GameManager", () => {
|
||||
})
|
||||
|
||||
describe("lineup", () => {
|
||||
it("returns the ESC 2026 lineup", () => {
|
||||
it("returns the ESC 2025 lineup", () => {
|
||||
const lineup = gm.getLineup()
|
||||
expect(lineup.year).toBe(2026)
|
||||
expect(lineup.countries.length).toBeGreaterThan(20)
|
||||
expect(lineup.countries[0]).toHaveProperty("code")
|
||||
expect(lineup.countries[0]).toHaveProperty("name")
|
||||
expect(lineup.year).toBe(2025)
|
||||
expect(lineup.entries.length).toBeGreaterThan(20)
|
||||
expect(lineup.entries[0]).toHaveProperty("country")
|
||||
expect(lineup.entries[0]).toHaveProperty("artist")
|
||||
expect(lineup.entries[0]).toHaveProperty("song")
|
||||
expect(lineup.entries[0]?.country).toHaveProperty("flag")
|
||||
})
|
||||
|
||||
it("validates country codes", () => {
|
||||
@@ -25,142 +27,77 @@ describe("GameManager", () => {
|
||||
|
||||
describe("predictions", () => {
|
||||
it("accepts a valid prediction", () => {
|
||||
const result = gm.submitPrediction("p1", "SE", ["DE", "IT", "FR"], "GB")
|
||||
const result = gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
expect(result).toEqual({ success: true })
|
||||
expect(gm.getPrediction("p1")).toEqual({
|
||||
playerId: "p1",
|
||||
predictedWinner: "SE",
|
||||
top3: ["DE", "IT", "FR"],
|
||||
nulPointsPick: "GB",
|
||||
first: "SE",
|
||||
second: "DE",
|
||||
third: "IT",
|
||||
last: "GB",
|
||||
})
|
||||
})
|
||||
|
||||
it("rejects prediction with invalid country", () => {
|
||||
const result = gm.submitPrediction("p1", "XX", ["DE", "IT", "FR"], "GB")
|
||||
const result = gm.submitPrediction("p1", "XX", "DE", "IT", "GB")
|
||||
expect(result).toEqual({ error: "Invalid country: XX" })
|
||||
})
|
||||
|
||||
it("rejects winner in top 3", () => {
|
||||
const result = gm.submitPrediction("p1", "SE", ["SE", "IT", "FR"], "GB")
|
||||
expect(result).toEqual({ error: "Winner cannot also be in top 3" })
|
||||
it("rejects duplicate picks", () => {
|
||||
const result = gm.submitPrediction("p1", "SE", "SE", "IT", "GB")
|
||||
expect(result).toEqual({ error: "All 4 picks must be different countries" })
|
||||
})
|
||||
|
||||
it("rejects duplicate top 3", () => {
|
||||
const result = gm.submitPrediction("p1", "SE", ["DE", "DE", "FR"], "GB")
|
||||
expect(result).toEqual({ error: "Top 3 must be unique countries" })
|
||||
it("rejects last same as first", () => {
|
||||
const result = gm.submitPrediction("p1", "SE", "DE", "IT", "SE")
|
||||
expect(result).toEqual({ error: "All 4 picks must be different countries" })
|
||||
})
|
||||
|
||||
it("allows overwriting a prediction", () => {
|
||||
gm.submitPrediction("p1", "SE", ["DE", "IT", "FR"], "GB")
|
||||
gm.submitPrediction("p1", "NO", ["DE", "IT", "FR"], "GB")
|
||||
expect(gm.getPrediction("p1")?.predictedWinner).toBe("NO")
|
||||
gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
gm.submitPrediction("p1", "NO", "DE", "IT", "GB")
|
||||
expect(gm.getPrediction("p1")?.first).toBe("NO")
|
||||
})
|
||||
|
||||
it("rejects prediction when locked", () => {
|
||||
gm.lockPredictions()
|
||||
const result = gm.submitPrediction("p1", "SE", ["DE", "IT", "FR"], "GB")
|
||||
const result = gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
expect(result).toEqual({ error: "Predictions are locked" })
|
||||
})
|
||||
})
|
||||
|
||||
describe("dishes", () => {
|
||||
it("adds a dish", () => {
|
||||
const result = gm.addDish("Köttbullar", "SE")
|
||||
expect("dish" in result).toBe(true)
|
||||
if ("dish" in result) {
|
||||
expect(result.dish.name).toBe("Köttbullar")
|
||||
expect(result.dish.correctCountry).toBe("SE")
|
||||
expect(result.dish.revealed).toBe(false)
|
||||
}
|
||||
})
|
||||
|
||||
it("rejects dish with invalid country", () => {
|
||||
const result = gm.addDish("Mystery", "XX")
|
||||
expect(result).toEqual({ error: "Invalid country: XX" })
|
||||
})
|
||||
|
||||
it("accepts a dish guess", () => {
|
||||
const addResult = gm.addDish("Köttbullar", "SE")
|
||||
if (!("dish" in addResult)) throw new Error("unexpected")
|
||||
const result = gm.submitDishGuess("p1", addResult.dish.id, "SE")
|
||||
expect(result).toEqual({ success: true })
|
||||
})
|
||||
|
||||
it("rejects guess for nonexistent dish", () => {
|
||||
const result = gm.submitDishGuess("p1", "fake-id", "SE")
|
||||
expect(result).toEqual({ error: "Dish not found" })
|
||||
})
|
||||
|
||||
it("rejects guess after reveal", () => {
|
||||
const addResult = gm.addDish("Köttbullar", "SE")
|
||||
if (!("dish" in addResult)) throw new Error("unexpected")
|
||||
gm.revealDishes()
|
||||
const result = gm.submitDishGuess("p1", addResult.dish.id, "SE")
|
||||
expect(result).toEqual({ error: "Dish already revealed" })
|
||||
})
|
||||
|
||||
it("replaces an existing guess for the same dish", () => {
|
||||
const addResult = gm.addDish("Köttbullar", "SE")
|
||||
if (!("dish" in addResult)) throw new Error("unexpected")
|
||||
gm.submitDishGuess("p1", addResult.dish.id, "DE")
|
||||
gm.submitDishGuess("p1", addResult.dish.id, "SE")
|
||||
const guesses = gm.getDishGuesses("p1")
|
||||
expect(guesses).toHaveLength(1)
|
||||
expect(guesses[0]?.guessedCountry).toBe("SE")
|
||||
})
|
||||
|
||||
it("reveals dishes and produces results", () => {
|
||||
const addResult = gm.addDish("Köttbullar", "SE")
|
||||
if (!("dish" in addResult)) throw new Error("unexpected")
|
||||
gm.submitDishGuess("p1", addResult.dish.id, "SE")
|
||||
gm.submitDishGuess("p2", addResult.dish.id, "DE")
|
||||
gm.revealDishes()
|
||||
|
||||
const lookup = new Map([
|
||||
["p1", "Alice"],
|
||||
["p2", "Bob"],
|
||||
])
|
||||
const results = gm.getDishResults(lookup)
|
||||
expect(results).toHaveLength(1)
|
||||
expect(results[0]?.guesses).toHaveLength(2)
|
||||
|
||||
const aliceGuess = results[0]?.guesses.find((g) => g.playerId === "p1")
|
||||
expect(aliceGuess?.correct).toBe(true)
|
||||
|
||||
const bobGuess = results[0]?.guesses.find((g) => g.playerId === "p2")
|
||||
expect(bobGuess?.correct).toBe(false)
|
||||
it("tracks prediction submission status", () => {
|
||||
gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
expect(gm.hasPrediction("p1")).toBe(true)
|
||||
expect(gm.hasPrediction("p2")).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("getGameStateForPlayer", () => {
|
||||
it("hides correct country for unrevealed dishes", () => {
|
||||
gm.addDish("Köttbullar", "SE")
|
||||
const lookup = new Map<string, string>()
|
||||
const state = gm.getGameStateForPlayer("p1", lookup, false)
|
||||
expect(state.dishes[0]?.correctCountry).toBe("")
|
||||
})
|
||||
|
||||
it("shows correct country after reveal", () => {
|
||||
gm.addDish("Köttbullar", "SE")
|
||||
gm.revealDishes()
|
||||
const lookup = new Map<string, string>()
|
||||
const state = gm.getGameStateForPlayer("p1", lookup, false)
|
||||
expect(state.dishes[0]?.correctCountry).toBe("SE")
|
||||
})
|
||||
|
||||
it("shows correct country to host for unrevealed dishes", () => {
|
||||
gm.addDish("Köttbullar", "SE")
|
||||
const lookup = new Map<string, string>()
|
||||
const state = gm.getGameStateForPlayer("p1", lookup, true)
|
||||
expect(state.dishes[0]?.correctCountry).toBe("SE")
|
||||
})
|
||||
|
||||
it("includes only the requesting player's prediction", () => {
|
||||
gm.submitPrediction("p1", "SE", ["DE", "IT", "FR"], "GB")
|
||||
gm.submitPrediction("p2", "NO", ["DE", "IT", "FR"], "GB")
|
||||
const lookup = new Map<string, string>()
|
||||
const state = gm.getGameStateForPlayer("p1", lookup, false)
|
||||
expect(state.myPrediction?.predictedWinner).toBe("SE")
|
||||
gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
gm.submitPrediction("p2", "NO", "DE", "IT", "GB")
|
||||
const state = gm.getGameStateForPlayer("p1", ["p1", "p2"])
|
||||
expect(state.myPrediction?.first).toBe("SE")
|
||||
})
|
||||
|
||||
it("includes predictionSubmitted for all players", () => {
|
||||
gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
const state = gm.getGameStateForPlayer("p1", ["p1", "p2"])
|
||||
expect(state.predictionSubmitted).toEqual({ p1: true, p2: false })
|
||||
})
|
||||
})
|
||||
|
||||
describe("getGameStateForDisplay", () => {
|
||||
it("returns null myPrediction", () => {
|
||||
gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
const state = gm.getGameStateForDisplay(["p1"])
|
||||
expect(state.myPrediction).toBeNull()
|
||||
})
|
||||
|
||||
it("includes predictionSubmitted", () => {
|
||||
gm.submitPrediction("p1", "SE", "DE", "IT", "GB")
|
||||
const state = gm.getGameStateForDisplay(["p1", "p2"])
|
||||
expect(state.predictionSubmitted).toEqual({ p1: true, p2: false })
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user