diff --git a/src/utils/response.ts b/src/utils/response.ts index 3d36a97c..b7f6ca5c 100644 --- a/src/utils/response.ts +++ b/src/utils/response.ts @@ -36,6 +36,11 @@ export function sendNoContent(event: H3Event, code?: number) { if (event.handled) { return; } + + if (!code && event.node.res.statusCode !== 200) { + // status code was set with setResponseStatus + code = event.node.res.statusCode; + } const _code = sanitizeStatusCode(code, 204); // 204 responses MUST NOT have a Content-Length header field // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 diff --git a/test/status.test.ts b/test/status.test.ts new file mode 100644 index 00000000..7d62661e --- /dev/null +++ b/test/status.test.ts @@ -0,0 +1,113 @@ +import { describe, it, expect, beforeEach } from "vitest"; +import { + createApp, + App, + toPlainHandler, + PlainHandler, + eventHandler, + setResponseStatus, +} from "../src"; + +describe("setResponseStatus", () => { + let app: App; + let handler: PlainHandler; + + beforeEach(() => { + app = createApp({ debug: true }); + handler = toPlainHandler(app); + }); + + describe("content response", () => { + it("sets status 200 as default", async () => { + app.use( + "/test", + eventHandler(() => { + return "text"; + }), + ); + + const res = await handler({ + method: "POST", + path: "/test", + headers: [], + }); + + expect(res).toMatchObject({ + status: 200, + statusText: "", + body: "text", + headers: [["content-type", "text/html"]], + }); + }); + it("override status and statusText with setResponeStatus method", async () => { + app.use( + "/test", + eventHandler((event) => { + setResponseStatus(event, 418, "status-text"); + return "text"; + }), + ); + + const res = await handler({ + method: "POST", + path: "/test", + headers: [], + body: "", + }); + + expect(res).toMatchObject({ + status: 418, + statusText: "status-text", + body: "text", + headers: [["content-type", "text/html"]], + }); + }); + }); + + describe("no content response", () => { + it("sets status 204 as default", async () => { + app.use( + "/test", + eventHandler(() => { + return null; + }), + ); + + const res = await handler({ + method: "POST", + path: "/test", + headers: [], + }); + + expect(res).toMatchObject({ + status: 204, + statusText: "", + body: undefined, + headers: [], + }); + }); + it("override status and statusText with setResponeStatus method", async () => { + app.use( + "/test", + eventHandler((event) => { + setResponseStatus(event, 418, "status-text"); + return null; + }), + ); + + const res = await handler({ + method: "POST", + path: "/test", + headers: [], + body: "", + }); + + expect(res).toMatchObject({ + status: 418, + statusText: "status-text", + body: undefined, + headers: [], + }); + }); + }); +});