1- import { describe , expect , it , vi } from "vitest" ;
1+ import { beforeEach , describe , expect , it , vi } from "vitest" ;
22import {
33 createDiscordHandlerParams ,
44 createDiscordPreflightContext ,
@@ -17,7 +17,7 @@ vi.mock("./message-handler.process.js", () => ({
1717 processDiscordMessage : processDiscordMessageMock ,
1818} ) ) ;
1919
20- const { createDiscordMessageHandler } = await import ( "./message-handler.js" ) ;
20+ const { createDiscordMessageHandler, resetDiscordInboundMessageDedupe } = await import ( "./message-handler.js" ) ;
2121
2222function createDeferred < T = void > ( ) {
2323 let resolve : ( value : T | PromiseLike < T > ) => void = ( ) => { } ;
@@ -83,6 +83,10 @@ async function createLifecycleStopScenario(params: {
8383}
8484
8585describe ( "createDiscordMessageHandler queue behavior" , ( ) => {
86+ beforeEach ( ( ) => {
87+ resetDiscordInboundMessageDedupe ( ) ;
88+ } ) ;
89+
8690 it ( "resets busy counters when the handler is created" , ( ) => {
8791 preflightDiscordMessageMock . mockReset ( ) ;
8892 processDiscordMessageMock . mockReset ( ) ;
@@ -98,6 +102,30 @@ describe("createDiscordMessageHandler queue behavior", () => {
98102 ) ;
99103 } ) ;
100104
105+ it ( "drops duplicate inbound Discord messages with the same message id" , async ( ) => {
106+ preflightDiscordMessageMock . mockReset ( ) ;
107+ processDiscordMessageMock . mockReset ( ) ;
108+
109+ preflightDiscordMessageMock . mockImplementation (
110+ async ( params : { data : { channel_id : string } } ) =>
111+ createPreflightContext ( params . data . channel_id ) ,
112+ ) ;
113+ processDiscordMessageMock . mockResolvedValue ( undefined ) ;
114+
115+ const handler = createDiscordMessageHandler ( createDiscordHandlerParams ( ) ) ;
116+
117+ await expect ( handler ( createMessageData ( "dup-1" ) as never , { } as never ) ) . resolves . toBeUndefined ( ) ;
118+ await vi . waitFor ( ( ) => {
119+ expect ( processDiscordMessageMock ) . toHaveBeenCalledTimes ( 1 ) ;
120+ } ) ;
121+
122+ await expect ( handler ( createMessageData ( "dup-1" ) as never , { } as never ) ) . resolves . toBeUndefined ( ) ;
123+ await Promise . resolve ( ) ;
124+
125+ expect ( preflightDiscordMessageMock ) . toHaveBeenCalledTimes ( 1 ) ;
126+ expect ( processDiscordMessageMock ) . toHaveBeenCalledTimes ( 1 ) ;
127+ } ) ;
128+
101129 it ( "returns immediately and tracks busy status while queued runs execute" , async ( ) => {
102130 preflightDiscordMessageMock . mockReset ( ) ;
103131 processDiscordMessageMock . mockReset ( ) ;
0 commit comments