forked from syntaxbullet/aurorabot
feat: Implement flexible quest event matching to allow generic triggers to match specific event instances.
This commit is contained in:
@@ -189,6 +189,68 @@ describe("questService", () => {
|
||||
expect(mockSet).toHaveBeenCalledWith({ completedAt: expect.any(Date) });
|
||||
});
|
||||
|
||||
it("should progress a quest with generic events", async () => {
|
||||
const mockUserQuest = {
|
||||
userId: 1n,
|
||||
questId: 102,
|
||||
progress: 0,
|
||||
completedAt: null,
|
||||
quest: { triggerEvent: "ITEM_COLLECT", requirements: { target: 5 } }
|
||||
};
|
||||
mockFindMany.mockResolvedValue([mockUserQuest]);
|
||||
mockReturning.mockResolvedValue([{ userId: 1n, questId: 102, progress: 1 }]);
|
||||
|
||||
await questService.handleEvent("1", "ITEM_COLLECT:505", 1);
|
||||
|
||||
expect(mockUpdate).toHaveBeenCalled();
|
||||
expect(mockSet).toHaveBeenCalledWith({ progress: 1 });
|
||||
});
|
||||
|
||||
it("should ignore events that are not prefix matches", async () => {
|
||||
const mockUserQuest = {
|
||||
userId: 1n,
|
||||
questId: 103,
|
||||
progress: 0,
|
||||
completedAt: null,
|
||||
quest: { triggerEvent: "ITEM_COLLECT", requirements: { target: 5 } }
|
||||
};
|
||||
mockFindMany.mockResolvedValue([mockUserQuest]);
|
||||
|
||||
await questService.handleEvent("1", "ITEM_COLLECT_UNRELATED", 1);
|
||||
|
||||
expect(mockUpdate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not progress a specific quest with a different specific event", async () => {
|
||||
const mockUserQuest = {
|
||||
userId: 1n,
|
||||
questId: 104,
|
||||
progress: 0,
|
||||
completedAt: null,
|
||||
quest: { triggerEvent: "ITEM_COLLECT:101", requirements: { target: 5 } }
|
||||
};
|
||||
mockFindMany.mockResolvedValue([mockUserQuest]);
|
||||
|
||||
await questService.handleEvent("1", "ITEM_COLLECT:202", 1);
|
||||
|
||||
expect(mockUpdate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not progress a specific quest with a generic event", async () => {
|
||||
const mockUserQuest = {
|
||||
userId: 1n,
|
||||
questId: 105,
|
||||
progress: 0,
|
||||
completedAt: null,
|
||||
quest: { triggerEvent: "ITEM_COLLECT:101", requirements: { target: 5 } }
|
||||
};
|
||||
mockFindMany.mockResolvedValue([mockUserQuest]);
|
||||
|
||||
await questService.handleEvent("1", "ITEM_COLLECT", 1);
|
||||
|
||||
expect(mockUpdate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should ignore irrelevant events", async () => {
|
||||
const mockUserQuest = {
|
||||
userId: 1n,
|
||||
|
||||
@@ -46,9 +46,12 @@ export const questService = {
|
||||
}
|
||||
});
|
||||
|
||||
const relevant = activeUserQuests.filter(uq =>
|
||||
uq.quest.triggerEvent === eventName && !uq.completedAt
|
||||
);
|
||||
const relevant = activeUserQuests.filter(uq => {
|
||||
const trigger = uq.quest.triggerEvent;
|
||||
// Exact match or prefix match (e.g. ITEM_COLLECT matches ITEM_COLLECT:101)
|
||||
const isMatch = eventName === trigger || eventName.startsWith(trigger + ":");
|
||||
return isMatch && !uq.completedAt;
|
||||
});
|
||||
|
||||
for (const uq of relevant) {
|
||||
const requirements = uq.quest.requirements as { target?: number };
|
||||
|
||||
Reference in New Issue
Block a user