diff --git a/apps/api/src/services/dailyChallenges.ts b/apps/api/src/services/dailyChallenges.ts index 4c4aad1..598ebc3 100644 --- a/apps/api/src/services/dailyChallenges.ts +++ b/apps/api/src/services/dailyChallenges.ts @@ -71,8 +71,7 @@ const shuffleWithSeed = (array: Array, seed: number): Array => { return result; }; -const challengeTypes: Array = [ - "clicks", +const progressionChallengeTypes: Array = [ "bossesDefeated", "questsCompleted", "prestige", @@ -80,7 +79,8 @@ const challengeTypes: Array = [ /** * Generates 3 daily challenges for the given date string, deterministically. - * Picks one challenge from 3 different randomly-selected types. + * Always includes a "clicks" challenge (always completable regardless of + * progression), then picks 2 more from the remaining types. * @param dateString - The date string (YYYY-MM-DD) to generate challenges for. * @returns An array of 3 DailyChallenge objects. */ @@ -88,8 +88,10 @@ const generateDailyChallenges = ( dateString: string, ): Array => { const seed = dateSeed(dateString); - const selectedTypes = shuffleWithSeed([ ...challengeTypes ], seed). - slice(0, 3); + const selectedTypes: Array = [ + "clicks", + ...shuffleWithSeed([ ...progressionChallengeTypes ], seed).slice(0, 2), + ]; return selectedTypes.map((type, index) => { const templates = dailyChallengeTemplates.filter((template) => { diff --git a/apps/api/test/services/dailyChallenges.spec.ts b/apps/api/test/services/dailyChallenges.spec.ts index ee5cd8a..d0b43a9 100644 --- a/apps/api/test/services/dailyChallenges.spec.ts +++ b/apps/api/test/services/dailyChallenges.spec.ts @@ -46,13 +46,24 @@ describe("generateDailyChallenges", () => { expect(a.map((c) => c.id)).toEqual(b.map((c) => c.id)); }); + it("always includes a clicks challenge regardless of date", async () => { + vi.setSystemTime(LA_MIDNIGHT_2024_01_15); + const { generateDailyChallenges } = await import("../../src/services/dailyChallenges.js"); + const day1 = generateDailyChallenges("2024-01-15"); + const day2 = generateDailyChallenges("2024-01-16"); + expect(day1.some((c) => c.type === "clicks")).toBe(true); + expect(day2.some((c) => c.type === "clicks")).toBe(true); + }); + it("generates different challenges for different dates", async () => { vi.setSystemTime(LA_MIDNIGHT_2024_01_15); const { generateDailyChallenges } = await import("../../src/services/dailyChallenges.js"); const day1 = generateDailyChallenges("2024-01-15"); const day2 = generateDailyChallenges("2024-01-16"); - // They should differ in at least one challenge ID (types vary by seed) - expect(day1.map((c) => c.type)).not.toEqual(day2.map((c) => c.type)); + // The 2 non-clicks types should vary by seed between dates + const day1NonClicks = day1.filter((c) => c.type !== "clicks").map((c) => c.type); + const day2NonClicks = day2.filter((c) => c.type !== "clicks").map((c) => c.type); + expect(day1NonClicks).not.toEqual(day2NonClicks); }); });