Browse Source

fix: property _headersSent should be set synchronously

e22m4u 3 weeks ago
parent
commit
dfc8b9d408
3 changed files with 16 additions and 7 deletions
  1. 5 1
      dist/cjs/index.cjs
  2. 9 1
      src/utils/create-response-mock.js
  3. 2 5
      src/utils/create-response-mock.spec.js

+ 5 - 1
dist/cjs/index.cjs

@@ -605,9 +605,13 @@ function patchBody(res) {
   res.on("data", (c) => data.push(c));
   res.on("error", (e) => reject(e));
   res.on("end", () => {
-    res._headersSent = true;
     resolve(Buffer.concat(data));
   });
+  const originalEnd = res.end.bind(res);
+  res.end = function(...args) {
+    this._headersSent = true;
+    return originalEnd(...args);
+  };
   Object.defineProperty(res, "getBody", {
     configurable: true,
     value: /* @__PURE__ */ __name(function() {

+ 9 - 1
src/utils/create-response-mock.js

@@ -103,9 +103,17 @@ function patchBody(res) {
   res.on('data', c => data.push(c));
   res.on('error', e => reject(e));
   res.on('end', () => {
-    res._headersSent = true;
     resolve(Buffer.concat(data));
   });
+  // флаг _headersSent должен быть установлен синхронно
+  // после вызова метода res.end, так как асинхронная
+  // установка (к примеру в res.on('end')) не позволит
+  // отследить отправку ответа при синхронном выполнении
+  const originalEnd = res.end.bind(res);
+  res.end = function (...args) {
+    this._headersSent = true;
+    return originalEnd(...args);
+  };
   Object.defineProperty(res, 'getBody', {
     configurable: true,
     value: function () {

+ 2 - 5
src/utils/create-response-mock.spec.js

@@ -116,14 +116,11 @@ describe('createResponseMock', function () {
   });
 
   describe('Stream', function () {
-    it('sets "headerSent" to true when the stream ends', function (done) {
+    it('sets "headerSent" to true when the stream ends', function () {
       const res = createResponseMock();
       expect(res.headersSent).to.be.false;
-      res.on('end', () => {
-        expect(res.headersSent).to.be.true;
-        done();
-      });
       res.end('test');
+      expect(res.headersSent).to.be.true;
     });
   });
 });