Skip to content

Commit

Permalink
feat(core): Add removeHeader, removeHeaders, and allow empty headers (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
offirgolan authored Feb 1, 2019
1 parent a41b18b commit 1dfae5a
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 12 deletions.
36 changes: 33 additions & 3 deletions docs/server/request.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ req.getHeader('Content-Type'); // → application/json

### setHeader

Set a header with a given name. If the value is falsy, the header will be
Set a header with a given name. If the value is `null` or `undefined`, the header will be
removed.

| Param | Type | Description |
Expand All @@ -36,8 +36,8 @@ req.setHeader('Content-Length', 42);

### setHeaders

Add multiple headers at once. A falsy header value will remove that header
altogether.
Add multiple headers at once. If a value is `null` or `undefined`, the header will be
removed.

| Param | Type | Description |
| ----------- | ------------------------- | --------------------------------- |
Expand All @@ -53,6 +53,36 @@ req.setHeaders({
});
```

### removeHeader

Remove a header with the given name.

| Param | Type | Description |
| ----------- | ------------------------- | ---------------------- |
| name | `String` | The name of the header |
| **Returns** | [Request](server/request) | The current request |

**Example**

```js
req.removeHeader('Content-Length');
```

### removeHeaders

Remove multiple headers at once.

| Param | Type | Description |
| ----------- | ------------------------- | -------------------------------------- |
| headers | `Array` | The headers to remove from the request |
| **Returns** | [Request](server/request) | The current request |

**Example**

```js
req.removeHeaders(['Content-Type' 'Content-Length']);
```

### hasHeader

Returns 'true' or 'false' depending on if the request has the given header.
Expand Down
36 changes: 33 additions & 3 deletions docs/server/response.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ res.getHeader('Content-Type'); // → application/json

### setHeader

Set a header with a given name. If the value is falsy, the header will be
Set a header with a given name. If the value is `null` or `undefined`, the header will be
removed.

| Param | Type | Description |
Expand All @@ -74,8 +74,8 @@ res.setHeader('Content-Length', 42);

### setHeaders

Add multiple headers at once. A falsy header value will remove that header
altogether.
Add multiple headers at once. If a value is `null` or `undefined`, the header will be
removed.

| Param | Type | Description |
| ----------- | --------------------------- | ---------------------------------- |
Expand All @@ -91,6 +91,36 @@ res.setHeaders({
});
```

### removeHeader

Remove a header with the given name.

| Param | Type | Description |
| ----------- | --------------------------- | ---------------------- |
| name | `String` | The name of the header |
| **Returns** | [Response](server/response) | The current response |

**Example**

```js
res.removeHeader('Content-Length');
```

### removeHeaders

Remove multiple headers at once.

| Param | Type | Description |
| ----------- | --------------------------- | --------------------------------------- |
| headers | `Array` | The headers to remove from the response |
| **Returns** | [Response](server/response) | The current response |

**Example**

```js
res.removeHeaders(['Content-Type' 'Content-Length']);
```

### hasHeader

Returns 'true' or 'false' depending on if the response has the given header.
Expand Down
14 changes: 14 additions & 0 deletions packages/@pollyjs/core/src/-private/http-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ export default class HTTPBase {
return this;
}

removeHeader(name) {
this.setHeader(name, null);

return this;
}

removeHeaders(headers = []) {
for (const name of headers) {
this.removeHeader(name);
}

return this;
}

hasHeader(name) {
return !!this.getHeader(name);
}
Expand Down
12 changes: 11 additions & 1 deletion packages/@pollyjs/core/src/utils/http-headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,22 @@ const HANDLER = {
return false;
}

if (!value) {
if (value === null || typeof value === 'undefined') {
delete obj[prop.toLowerCase()];
} else {
obj[prop.toLowerCase()] = value;
}

return true;
},

deleteProperty(obj, prop) {
if (typeof prop !== 'string') {
return false;
}

delete obj[prop.toLowerCase()];

return true;
}
};
Expand Down
29 changes: 25 additions & 4 deletions packages/@pollyjs/core/tests/unit/-private/http-base-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('Unit | HTTPBase', function() {
expect(base.getHeader('one')).to.equal('1');
expect(base.getHeader('Two')).to.be.undefined;

base.setHeader('One', '');
base.removeHeader('One');
expect(base.getHeader('One')).to.be.undefined;
expect(base.getHeader('one')).to.be.undefined;
});
Expand All @@ -40,7 +40,7 @@ describe('Unit | HTTPBase', function() {
expect(base.hasHeader('one')).to.be.true;
expect(base.hasHeader('Two')).to.be.false;

base.setHeader('One', '');
base.removeHeader('One');
expect(base.hasHeader('One')).to.be.false;
expect(base.hasHeader('one')).to.be.false;
});
Expand All @@ -54,7 +54,7 @@ describe('Unit | HTTPBase', function() {
base.setHeader('two', '2');
expect(headers).to.deep.equal({ one: '1', two: '2' });

base.setHeader('Two', '');
base.setHeader('Two', null);
expect(headers).to.deep.equal({ one: '1' });
});

Expand All @@ -67,10 +67,31 @@ describe('Unit | HTTPBase', function() {
base.setHeaders({ Three: '3' });
expect(headers).to.deep.equal({ one: '1', two: '2', three: '3' });

base.setHeaders({ Three: '' });
base.setHeaders({ Three: null });
expect(headers).to.deep.equal({ one: '1', two: '2' });
});

it('.removeHeader()', function() {
const { headers } = base;

base.setHeaders({ One: '1', Two: '2' });

base.removeHeader('One');
expect(headers).to.deep.equal({ two: '2' });

base.removeHeader('two');
expect(headers).to.deep.equal({});
});

it('.removeHeaders()', function() {
const { headers } = base;

base.setHeaders({ One: '1', Two: '2' });

base.removeHeaders(['One', 'two']);
expect(headers).to.deep.equal({});
});

it('.type()', function() {
base.type('text/plain');
expect(base.getHeader('Content-Type')).to.equal('text/plain');
Expand Down
38 changes: 37 additions & 1 deletion packages/@pollyjs/core/tests/unit/utils/http-headers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,44 @@ describe('Unit | Utils | HTTPHeaders', function() {
expect(headers['CONTENT-TYPE']).to.equal('application/json');
});

it('should delete header when set with a falsy value', function() {
it('should allow an empty header value', function() {
const headers = new HTTPHeaders();

headers['Content-Type'] = '';

expect(headers['Content-Type']).to.equal('');
});

it('should delete header regardless of case', function() {
const headers = new HTTPHeaders();

headers['Content-Type'] = 'application/json';
expect(keys(headers)).to.deep.equal(['content-type']);

delete headers['Content-Type'];
expect(keys(headers)).to.deep.equal([]);

headers['Content-Type'] = 'application/json';
expect(keys(headers)).to.deep.equal(['content-type']);

delete headers['CONTENT-TYPE'];
expect(keys(headers)).to.deep.equal([]);
});

it('should delete header when set with a null/undefined value', function() {
const headers = new HTTPHeaders();

headers['Content-Type'] = 'application/json';
expect(keys(headers)).to.deep.equal(['content-type']);

headers['Content-Type'] = null;
expect(keys(headers)).to.deep.equal([]);

headers['Content-Type'] = 'application/json';
expect(keys(headers)).to.deep.equal(['content-type']);

headers['Content-Type'] = undefined;
expect(keys(headers)).to.deep.equal([]);
});

it('should handle a non string getter', function() {
Expand All @@ -49,4 +79,10 @@ describe('Unit | Utils | HTTPHeaders', function() {

expect(() => (headers[Symbol()] = 'Foo')).to.throw(TypeError);
});

it('should not allow deleting a non string header key', function() {
const headers = new HTTPHeaders();

expect(() => delete headers[Symbol()]).to.throw(TypeError);
});
});

0 comments on commit 1dfae5a

Please sign in to comment.