|
1 | | -import { Elysia, t } from '../../src' |
| 1 | +import { Elysia, t, sse } from '../../src' |
| 2 | +import { streamResponse } from '../../src/adapter/utils' |
| 3 | +import * as z from 'zod' |
2 | 4 |
|
3 | 5 | import { describe, expect, it } from 'bun:test' |
4 | 6 | import { post, req, upload } from '../utils' |
@@ -450,4 +452,114 @@ describe('Response Validator', () => { |
450 | 452 | const res = await app.handle(req('/')) |
451 | 453 | expect(res.status).toBe(200) |
452 | 454 | }) |
| 455 | + |
| 456 | + it('validate SSE response with generator', async () => { |
| 457 | + const app = new Elysia().get( |
| 458 | + '/', |
| 459 | + function* () { |
| 460 | + yield sse({ data: { name: 'Alice' } }) |
| 461 | + yield sse({ data: { name: 'Bob' } }) |
| 462 | + }, |
| 463 | + { |
| 464 | + response: t.Object({ |
| 465 | + data: t.Object({ |
| 466 | + name: t.String() |
| 467 | + }) |
| 468 | + }) |
| 469 | + } |
| 470 | + ) |
| 471 | + |
| 472 | + const res = await app.handle(req('/')) |
| 473 | + expect(res.status).toBe(200) |
| 474 | + expect(res.headers.get('content-type')).toBe('text/event-stream') |
| 475 | + |
| 476 | + // Verify the stream contains the expected SSE data |
| 477 | + const result = [] |
| 478 | + for await (const chunk of streamResponse(res)) { |
| 479 | + result.push(chunk) |
| 480 | + } |
| 481 | + |
| 482 | + expect(result.join('')).toContain('data: {"name":"Alice"}') |
| 483 | + expect(result.join('')).toContain('data: {"name":"Bob"}') |
| 484 | + }) |
| 485 | + |
| 486 | + it('validate async SSE response with generator', async () => { |
| 487 | + const app = new Elysia().get( |
| 488 | + '/', |
| 489 | + async function* () { |
| 490 | + yield sse({ data: { name: 'Charlie' } }) |
| 491 | + await Bun.sleep(1) |
| 492 | + yield sse({ data: { name: 'Diana' } }) |
| 493 | + }, |
| 494 | + { |
| 495 | + response: t.Object({ |
| 496 | + data: t.Object({ |
| 497 | + name: t.String() |
| 498 | + }) |
| 499 | + }) |
| 500 | + } |
| 501 | + ) |
| 502 | + |
| 503 | + const res = await app.handle(req('/')) |
| 504 | + expect(res.status).toBe(200) |
| 505 | + expect(res.headers.get('content-type')).toBe('text/event-stream') |
| 506 | + }) |
| 507 | + |
| 508 | + it('validate streaming response with generator', async () => { |
| 509 | + const app = new Elysia().get( |
| 510 | + '/', |
| 511 | + function* () { |
| 512 | + yield { message: 'first' } |
| 513 | + yield { message: 'second' } |
| 514 | + }, |
| 515 | + { |
| 516 | + response: t.Object({ |
| 517 | + message: t.String() |
| 518 | + }) |
| 519 | + } |
| 520 | + ) |
| 521 | + |
| 522 | + const res = await app.handle(req('/')) |
| 523 | + expect(res.status).toBe(200) |
| 524 | + |
| 525 | + const result = [] |
| 526 | + for await (const chunk of streamResponse(res)) { |
| 527 | + result.push(chunk) |
| 528 | + } |
| 529 | + |
| 530 | + expect(result.join('')).toContain('"message":"first"') |
| 531 | + expect(result.join('')).toContain('"message":"second"') |
| 532 | + }) |
| 533 | + |
| 534 | + it('validate SSE with Zod schema (bug report scenario)', async () => { |
| 535 | + // This test reproduces the exact bug report: |
| 536 | + // https://github.com/elysiajs/elysia/issues/1490 |
| 537 | + const Schema = z.object({ |
| 538 | + data: z.object({ |
| 539 | + name: z.string() |
| 540 | + }) |
| 541 | + }) |
| 542 | + |
| 543 | + const app = new Elysia().get( |
| 544 | + '/', |
| 545 | + function* () { |
| 546 | + yield sse({ data: { name: 'Name' } }) |
| 547 | + }, |
| 548 | + { response: Schema } |
| 549 | + ) |
| 550 | + |
| 551 | + const res = await app.handle(req('/')) |
| 552 | + |
| 553 | + // Should not throw validation error |
| 554 | + expect(res.status).toBe(200) |
| 555 | + expect(res.headers.get('content-type')).toBe('text/event-stream') |
| 556 | + |
| 557 | + // Verify the stream contains the expected SSE data |
| 558 | + const result = [] |
| 559 | + for await (const chunk of streamResponse(res)) { |
| 560 | + result.push(chunk) |
| 561 | + } |
| 562 | + |
| 563 | + expect(result.join('')).toContain('data: {"name":"Name"}') |
| 564 | + }) |
453 | 565 | }) |
0 commit comments