diff --git a/integration/websockets/e2e/gateway-ack.spec.ts b/integration/websockets/e2e/gateway-ack.spec.ts index 034a7ae29..6ae5658b5 100644 --- a/integration/websockets/e2e/gateway-ack.spec.ts +++ b/integration/websockets/e2e/gateway-ack.spec.ts @@ -41,5 +41,38 @@ describe('WebSocketGateway (ack)', () => { ); }); + it('should handle manual ack for async operations when @Ack() is used (success case)', async () => { + app = await createNestApp(AckGateway); + await app.listen(3000); + + ws = io('http://localhost:8080'); + const payload = { shouldSucceed: true }; + + await new Promise(resolve => + ws.emit('manual-ack', payload, response => { + expect(response).to.eql({ status: 'success', data: payload }); + resolve(); + }), + ); + }); + + it('should handle manual ack for async operations when @Ack() is used (error case)', async () => { + app = await createNestApp(AckGateway); + await app.listen(3000); + + ws = io('http://localhost:8080'); + const payload = { shouldSucceed: false }; + + await new Promise(resolve => + ws.emit('manual-ack', payload, response => { + expect(response).to.eql({ + status: 'error', + message: 'Operation failed', + }); + resolve(); + }), + ); + }); + afterEach(() => app.close()); }); diff --git a/integration/websockets/src/ack.gateway.ts b/integration/websockets/src/ack.gateway.ts index d1855058d..54942d74d 100644 --- a/integration/websockets/src/ack.gateway.ts +++ b/integration/websockets/src/ack.gateway.ts @@ -1,4 +1,9 @@ -import { SubscribeMessage, WebSocketGateway } from '@nestjs/websockets'; +import { + Ack, + MessageBody, + SubscribeMessage, + WebSocketGateway, +} from '@nestjs/websockets'; @WebSocketGateway(8080) export class AckGateway { @@ -6,4 +11,19 @@ export class AckGateway { onPush() { return 'pong'; } + + @SubscribeMessage('manual-ack') + async handleManualAck( + @MessageBody() data: any, + @Ack() ack: (response: any) => void, + ) { + await new Promise(resolve => setTimeout(resolve, 20)); + + if (data.shouldSucceed) { + ack({ status: 'success', data }); + } else { + ack({ status: 'error', message: 'Operation failed' }); + } + return { status: 'ignored' }; + } }