From 9441b39a8d97f1ac3cdb03f3989b1f37f14f7653 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Tue, 5 May 2020 20:25:33 +0100 Subject: [PATCH] add methods scoed to http methods --- .eslintrc.js | 2 +- README.md | 12 +- __tests__/jest-extensions-delete.spec.js | 252 ++++++++++++++++++++++ __tests__/jest-extensions-get.spec.js | 252 ++++++++++++++++++++++ __tests__/jest-extensions-head.spec.js | 256 +++++++++++++++++++++++ __tests__/jest-extensions-patch.spec.js | 252 ++++++++++++++++++++++ __tests__/jest-extensions-post.spec.js | 252 ++++++++++++++++++++++ __tests__/jest-extensions-put.spec.js | 252 ++++++++++++++++++++++ jest-extensions.js | 31 ++- package-lock.json | 6 +- package.json | 2 +- 11 files changed, 1561 insertions(+), 8 deletions(-) create mode 100644 __tests__/jest-extensions-delete.spec.js create mode 100644 __tests__/jest-extensions-get.spec.js create mode 100644 __tests__/jest-extensions-head.spec.js create mode 100644 __tests__/jest-extensions-patch.spec.js create mode 100644 __tests__/jest-extensions-post.spec.js create mode 100644 __tests__/jest-extensions-put.spec.js diff --git a/.eslintrc.js b/.eslintrc.js index 75f4b75..f882bd8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,7 +6,7 @@ module.exports = { "node": true }, "parserOptions": { - "ecmaVersion": 2017 + "ecmaVersion": 2018 }, "globals": { "expect": true diff --git a/README.md b/README.md index a631ce7..fcbe9c2 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,12 @@ The following custom jest expectation methods, proxying through to `fetch-mock`' - `expect(fetchMock).toHaveFetchedTimes(n, filter, options)` - `expect(fetchMock).toBeDone(filter)` -`filter` and `options` are the same as those used by [`fetch-mock`'s inspection methods](http://www.wheresrhys.co.uk/fetch-mock/#api-inspectionfundamentals) +### Notes + +- `filter` and `options` are the same as those used by [`fetch-mock`'s inspection methods](http://www.wheresrhys.co.uk/fetch-mock/#api-inspectionfundamentals) +- The obove methods can have `Fetched` replaced by any of the following verbs to scope to a particular method: + Got + Posted + Put + Deleted + FetchedHead + Patched + +e.g. `expect(fetchMock).toHaveLastPatched(filter, options)` ## Tearing down mocks @@ -56,6 +61,8 @@ The following custom jest expectation methods, proxying through to `fetch-mock`' `fetchMock.mockReset()` can be used to remove all configured mocks +Please report any bugs in resetting mocks on the [issues board](https://github.com/wheresrhys/fetch-mock-jest/issues) + # Example ```js @@ -81,7 +88,8 @@ test(async () => { ); expect(await userManager.getAll()).toEqual([{ name: 'bob' }]); - expect(fetchMock).toHaveLastFetched('http://example.com/users', 'get'); + expect(fetchMock).toHaveLastFetched('http://example.com/users + get'); await userManager.create({ name: true }); expect(fetchMock).toHaveLastFetched( { diff --git a/__tests__/jest-extensions-delete.spec.js b/__tests__/jest-extensions-delete.spec.js new file mode 100644 index 0000000..b0e6214 --- /dev/null +++ b/__tests__/jest-extensions-delete.spec.js @@ -0,0 +1,252 @@ +/*global jest, beforeAll, afterAll */ +jest.mock('node-fetch', () => require('../server').sandbox()); +const fetch = require('node-fetch'); +describe('jest extensions - delete', () => { + describe('when no calls', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://lala'); + }); + afterAll(() => fetch.reset()); + it('toHaveDeleted should be falsy', () => { + expect(fetch).not.toHaveDeleted('http://example.com/path'); + }); + + it('toHaveLastDeleted should be falsy', () => { + expect(fetch).not.toHaveLastDeleted('http://example.com/path'); + }); + + it('toHaveNthDeleted should be falsy', () => { + expect(fetch).not.toHaveNthDeleted(1, 'http://example.com/path'); + }); + + it('toHaveDeletedTimes should be falsy', () => { + expect(fetch).not.toHaveDeletedTimes(1, 'http://example.com/path'); + }); + + it('toBeDone should be falsy', () => { + expect(fetch).not.toBeDone(); + expect(fetch).not.toBeDone('http://example.com/path'); + }); + }); + describe('toHaveDeleted', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path2', { + method: 'delete', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveDeleted('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveDeleted('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveDeleted('http://example.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveDeleted('http://example.com/path', { + method: 'delete', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveDeleted('http://example-no.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + }); + describe('toHaveLastDeleted', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveLastDeleted('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveLastDeleted('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveLastDeleted('http://example.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveLastDeleted('http://example.com/path', { + method: 'delete', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveLastDeleted('http://example-no.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + }); + + describe('toHaveNthDeleted', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example1.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + fetch('http://example2.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveNthDeleted(2, 'http://example2.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveNthDeleted(2, 'begin:http://example2.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveNthDeleted(2, 'http://example2.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveNthDeleted(2, 'http://example2.com/path', { + method: 'delete', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveNthDeleted(2, 'http://example-no.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if wrong n", () => { + expect(fetch).not.toHaveNthDeleted(1, 'http://example2.com/path'); + }); + }); + + describe('toHaveDeletedTimes', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveDeletedTimes(2, 'http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveDeletedTimes(2, 'begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveDeletedTimes(2, 'http://example.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveDeletedTimes(2, 'http://example.com/path', { + method: 'delete', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveDeletedTimes(2, 'http://example-no.com/path', { + method: 'delete', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if too few calls", () => { + expect(fetch).not.toHaveDeletedTimes(1, 'http://example.com/path'); + }); + + it("doesn't match if too many calls", () => { + expect(fetch).not.toHaveDeletedTimes(3, 'http://example.com/path'); + }); + }); +}); diff --git a/__tests__/jest-extensions-get.spec.js b/__tests__/jest-extensions-get.spec.js new file mode 100644 index 0000000..db23ed0 --- /dev/null +++ b/__tests__/jest-extensions-get.spec.js @@ -0,0 +1,252 @@ +/*global jest, beforeAll, afterAll */ +jest.mock('node-fetch', () => require('../server').sandbox()); +const fetch = require('node-fetch'); +describe('jest extensions - get', () => { + describe('when no calls', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://lala', { method: 'post' }); + }); + afterAll(() => fetch.reset()); + it('toHaveGot should be falsy', () => { + expect(fetch).not.toHaveGot('http://example.com/path'); + }); + + it('toHaveLastGot should be falsy', () => { + expect(fetch).not.toHaveLastGot('http://example.com/path'); + }); + + it('toHaveNthGot should be falsy', () => { + expect(fetch).not.toHaveNthGot(1, 'http://example.com/path'); + }); + + it('toHaveGotTimes should be falsy', () => { + expect(fetch).not.toHaveGotTimes(1, 'http://example.com/path'); + }); + + it('toBeDone should be falsy', () => { + expect(fetch).not.toBeDone(); + expect(fetch).not.toBeDone('http://example.com/path'); + }); + }); + describe('toHaveGot', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path2', { + method: 'get', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveGot('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveGot('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveGot('http://example.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveGot('http://example.com/path', { + method: 'get', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveGot('http://example-no.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + }); + describe('toHaveLastGot', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveLastGot('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveLastGot('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveLastGot('http://example.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveLastGot('http://example.com/path', { + method: 'get', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveLastGot('http://example-no.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + }); + + describe('toHaveNthGot', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example1.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + fetch('http://example2.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveNthGot(2, 'http://example2.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveNthGot(2, 'begin:http://example2.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveNthGot(2, 'http://example2.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveNthGot(2, 'http://example2.com/path', { + method: 'get', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveNthGot(2, 'http://example-no.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if wrong n", () => { + expect(fetch).not.toHaveNthGot(1, 'http://example2.com/path'); + }); + }); + + describe('toHaveGotTimes', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveGotTimes(2, 'http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveGotTimes(2, 'begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveGotTimes(2, 'http://example.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveGotTimes(2, 'http://example.com/path', { + method: 'get', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveGotTimes(2, 'http://example-no.com/path', { + method: 'get', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if too few calls", () => { + expect(fetch).not.toHaveGotTimes(1, 'http://example.com/path'); + }); + + it("doesn't match if too many calls", () => { + expect(fetch).not.toHaveGotTimes(3, 'http://example.com/path'); + }); + }); +}); diff --git a/__tests__/jest-extensions-head.spec.js b/__tests__/jest-extensions-head.spec.js new file mode 100644 index 0000000..18d3d61 --- /dev/null +++ b/__tests__/jest-extensions-head.spec.js @@ -0,0 +1,256 @@ +/*global jest, beforeAll, afterAll */ +jest.mock('node-fetch', () => require('../server').sandbox()); +const fetch = require('node-fetch'); +describe('jest extensions - head', () => { + describe('when no calls', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://lala'); + }); + afterAll(() => fetch.reset()); + it('toHaveFetchedHead should be falsy', () => { + expect(fetch).not.toHaveFetchedHead('http://example.com/path'); + }); + + it('toHaveLastFetchedHead should be falsy', () => { + expect(fetch).not.toHaveLastFetchedHead('http://example.com/path'); + }); + + it('toHaveNthFetchedHead should be falsy', () => { + expect(fetch).not.toHaveNthFetchedHead(1, 'http://example.com/path'); + }); + + it('toHaveFetchedHeadTimes should be falsy', () => { + expect(fetch).not.toHaveFetchedHeadTimes(1, 'http://example.com/path'); + }); + + it('toBeDone should be falsy', () => { + expect(fetch).not.toBeDone(); + expect(fetch).not.toBeDone('http://example.com/path'); + }); + }); + describe('toHaveFetchedHead', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path2', { + method: 'head', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveFetchedHead('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveFetchedHead('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveFetchedHead('http://example.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveFetchedHead('http://example.com/path', { + method: 'head', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveFetchedHead('http://example-no.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + }); + describe('toHaveLastFetchedHead', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveLastFetchedHead('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveLastFetchedHead('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveLastFetchedHead('http://example.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveLastFetchedHead('http://example.com/path', { + method: 'head', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveLastFetchedHead('http://example-no.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + }); + + describe('toHaveNthFetchedHead', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example1.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + fetch('http://example2.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveNthFetchedHead(2, 'http://example2.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveNthFetchedHead(2, 'begin:http://example2.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveNthFetchedHead(2, 'http://example2.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveNthFetchedHead(2, 'http://example2.com/path', { + method: 'head', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveNthFetchedHead(2, 'http://example-no.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if wrong n", () => { + expect(fetch).not.toHaveNthFetchedHead(1, 'http://example2.com/path'); + }); + }); + + describe('toHaveFetchedHeadTimes', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveFetchedHeadTimes(2, 'http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveFetchedHeadTimes(2, 'begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveFetchedHeadTimes(2, 'http://example.com/path', { + method: 'head', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveFetchedHeadTimes(2, 'http://example.com/path', { + method: 'head', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveFetchedHeadTimes( + 2, + 'http://example-no.com/path', + { + method: 'head', + headers: { + test: 'header', + }, + } + ); + }); + + it("doesn't match if too few calls", () => { + expect(fetch).not.toHaveFetchedHeadTimes(1, 'http://example.com/path'); + }); + + it("doesn't match if too many calls", () => { + expect(fetch).not.toHaveFetchedHeadTimes(3, 'http://example.com/path'); + }); + }); +}); diff --git a/__tests__/jest-extensions-patch.spec.js b/__tests__/jest-extensions-patch.spec.js new file mode 100644 index 0000000..9248cc5 --- /dev/null +++ b/__tests__/jest-extensions-patch.spec.js @@ -0,0 +1,252 @@ +/*global jest, beforeAll, afterAll */ +jest.mock('node-fetch', () => require('../server').sandbox()); +const fetch = require('node-fetch'); +describe('jest extensions - patch', () => { + describe('when no calls', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://lala'); + }); + afterAll(() => fetch.reset()); + it('toHavePatched should be falsy', () => { + expect(fetch).not.toHavePatched('http://example.com/path'); + }); + + it('toHaveLastPatched should be falsy', () => { + expect(fetch).not.toHaveLastPatched('http://example.com/path'); + }); + + it('toHaveNthPatched should be falsy', () => { + expect(fetch).not.toHaveNthPatched(1, 'http://example.com/path'); + }); + + it('toHavePatchedTimes should be falsy', () => { + expect(fetch).not.toHavePatchedTimes(1, 'http://example.com/path'); + }); + + it('toBeDone should be falsy', () => { + expect(fetch).not.toBeDone(); + expect(fetch).not.toBeDone('http://example.com/path'); + }); + }); + describe('toHavePatched', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path2', { + method: 'patch', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHavePatched('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHavePatched('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHavePatched('http://example.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHavePatched('http://example.com/path', { + method: 'patch', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHavePatched('http://example-no.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + }); + describe('toHaveLastPatched', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveLastPatched('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveLastPatched('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveLastPatched('http://example.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveLastPatched('http://example.com/path', { + method: 'patch', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveLastPatched('http://example-no.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + }); + + describe('toHaveNthPatched', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example1.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + fetch('http://example2.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveNthPatched(2, 'http://example2.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveNthPatched(2, 'begin:http://example2.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveNthPatched(2, 'http://example2.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveNthPatched(2, 'http://example2.com/path', { + method: 'patch', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveNthPatched(2, 'http://example-no.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if wrong n", () => { + expect(fetch).not.toHaveNthPatched(1, 'http://example2.com/path'); + }); + }); + + describe('toHavePatchedTimes', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHavePatchedTimes(2, 'http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHavePatchedTimes(2, 'begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHavePatchedTimes(2, 'http://example.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHavePatchedTimes(2, 'http://example.com/path', { + method: 'patch', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHavePatchedTimes(2, 'http://example-no.com/path', { + method: 'patch', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if too few calls", () => { + expect(fetch).not.toHavePatchedTimes(1, 'http://example.com/path'); + }); + + it("doesn't match if too many calls", () => { + expect(fetch).not.toHavePatchedTimes(3, 'http://example.com/path'); + }); + }); +}); diff --git a/__tests__/jest-extensions-post.spec.js b/__tests__/jest-extensions-post.spec.js new file mode 100644 index 0000000..efa2ff9 --- /dev/null +++ b/__tests__/jest-extensions-post.spec.js @@ -0,0 +1,252 @@ +/*global jest, beforeAll, afterAll */ +jest.mock('node-fetch', () => require('../server').sandbox()); +const fetch = require('node-fetch'); +describe('jest extensions - post', () => { + describe('when no calls', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://lala'); + }); + afterAll(() => fetch.reset()); + it('toHavePosted should be falsy', () => { + expect(fetch).not.toHavePosted('http://example.com/path'); + }); + + it('toHaveLastPosted should be falsy', () => { + expect(fetch).not.toHaveLastPosted('http://example.com/path'); + }); + + it('toHaveNthPosted should be falsy', () => { + expect(fetch).not.toHaveNthPosted(1, 'http://example.com/path'); + }); + + it('toHavePostedTimes should be falsy', () => { + expect(fetch).not.toHavePostedTimes(1, 'http://example.com/path'); + }); + + it('toBeDone should be falsy', () => { + expect(fetch).not.toBeDone(); + expect(fetch).not.toBeDone('http://example.com/path'); + }); + }); + describe('toHavePosted', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path2', { + method: 'post', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHavePosted('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHavePosted('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHavePosted('http://example.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHavePosted('http://example.com/path', { + method: 'post', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHavePosted('http://example-no.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + }); + describe('toHaveLastPosted', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveLastPosted('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveLastPosted('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveLastPosted('http://example.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveLastPosted('http://example.com/path', { + method: 'post', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveLastPosted('http://example-no.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + }); + + describe('toHaveNthPosted', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example1.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + fetch('http://example2.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveNthPosted(2, 'http://example2.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveNthPosted(2, 'begin:http://example2.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveNthPosted(2, 'http://example2.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveNthPosted(2, 'http://example2.com/path', { + method: 'post', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveNthPosted(2, 'http://example-no.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if wrong n", () => { + expect(fetch).not.toHaveNthPosted(1, 'http://example2.com/path'); + }); + }); + + describe('toHavePostedTimes', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHavePostedTimes(2, 'http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHavePostedTimes(2, 'begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHavePostedTimes(2, 'http://example.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHavePostedTimes(2, 'http://example.com/path', { + method: 'post', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHavePostedTimes(2, 'http://example-no.com/path', { + method: 'post', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if too few calls", () => { + expect(fetch).not.toHavePostedTimes(1, 'http://example.com/path'); + }); + + it("doesn't match if too many calls", () => { + expect(fetch).not.toHavePostedTimes(3, 'http://example.com/path'); + }); + }); +}); diff --git a/__tests__/jest-extensions-put.spec.js b/__tests__/jest-extensions-put.spec.js new file mode 100644 index 0000000..3483e54 --- /dev/null +++ b/__tests__/jest-extensions-put.spec.js @@ -0,0 +1,252 @@ +/*global jest, beforeAll, afterAll */ +jest.mock('node-fetch', () => require('../server').sandbox()); +const fetch = require('node-fetch'); +describe('jest extensions - put', () => { + describe('when no calls', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://lala'); + }); + afterAll(() => fetch.reset()); + it('toHavePut should be falsy', () => { + expect(fetch).not.toHavePut('http://example.com/path'); + }); + + it('toHaveLastPut should be falsy', () => { + expect(fetch).not.toHaveLastPut('http://example.com/path'); + }); + + it('toHaveNthPut should be falsy', () => { + expect(fetch).not.toHaveNthPut(1, 'http://example.com/path'); + }); + + it('toHavePutTimes should be falsy', () => { + expect(fetch).not.toHavePutTimes(1, 'http://example.com/path'); + }); + + it('toBeDone should be falsy', () => { + expect(fetch).not.toBeDone(); + expect(fetch).not.toBeDone('http://example.com/path'); + }); + }); + describe('toHavePut', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path2', { + method: 'put', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHavePut('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHavePut('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHavePut('http://example.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHavePut('http://example.com/path', { + method: 'put', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHavePut('http://example-no.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + }); + describe('toHaveLastPut', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveLastPut('http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveLastPut('begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveLastPut('http://example.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveLastPut('http://example.com/path', { + method: 'put', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveLastPut('http://example-no.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + }); + + describe('toHaveNthPut', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example1.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + fetch('http://example2.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHaveNthPut(2, 'http://example2.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHaveNthPut(2, 'begin:http://example2.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHaveNthPut(2, 'http://example2.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHaveNthPut(2, 'http://example2.com/path', { + method: 'put', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHaveNthPut(2, 'http://example-no.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if wrong n", () => { + expect(fetch).not.toHaveNthPut(1, 'http://example2.com/path'); + }); + }); + + describe('toHavePutTimes', () => { + beforeAll(() => { + fetch.mock('*', 200); + fetch('http://example.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + fetch('http://example.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + afterAll(() => fetch.reset()); + + it('matches with just url', () => { + expect(fetch).toHavePutTimes(2, 'http://example.com/path'); + }); + + it('matches with fetch-mock matcher', () => { + expect(fetch).toHavePutTimes(2, 'begin:http://example.com/path'); + }); + + it('matches with matcher and options', () => { + expect(fetch).toHavePutTimes(2, 'http://example.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if matcher but not options is correct", () => { + expect(fetch).not.toHavePutTimes(2, 'http://example.com/path', { + method: 'put', + headers: { + test: 'not-header', + }, + }); + }); + + it("doesn't match if options but not matcher is correct", () => { + expect(fetch).not.toHavePutTimes(2, 'http://example-no.com/path', { + method: 'put', + headers: { + test: 'header', + }, + }); + }); + + it("doesn't match if too few calls", () => { + expect(fetch).not.toHavePutTimes(1, 'http://example.com/path'); + }); + + it("doesn't match if too many calls", () => { + expect(fetch).not.toHavePutTimes(3, 'http://example.com/path'); + }); + }); +}); diff --git a/jest-extensions.js b/jest-extensions.js index 77a27f5..d028f8d 100644 --- a/jest-extensions.js +++ b/jest-extensions.js @@ -1,4 +1,4 @@ -expect.extend({ +const methodlessExtensions = { toHaveFetched: (fetchMock, url, options) => { if (fetchMock.called(url, options)) { return { pass: true }; @@ -52,7 +52,10 @@ expect.extend({ `fetch should have been called with a URL of ${url} ${times} times, but it was called ${calls.length} times`, }; }, +}; +expect.extend(methodlessExtensions); +expect.extend({ toBeDone: (fetchMock, matcher) => { const done = fetchMock.done(matcher); if (done) { @@ -67,3 +70,29 @@ expect.extend({ }; }, }); + +[ + 'Got:get', + 'Posted:post', + 'Put:put', + 'Deleted:delete', + 'FetchedHead:head', + 'Patched:patch', +].forEach((verbs) => { + const [humanVerb, method] = verbs.split(':'); + + const extensions = Object.entries(methodlessExtensions) + .map(([name, func]) => { + return [ + (name = name.replace('Fetched', humanVerb)), + (...args) => { + const opts = args[func.length - 1] || {}; + args[func.length - 1] = { ...opts, method }; + return func(...args); + }, + ]; + }) + .reduce((obj, [name, func]) => ({ ...obj, [name]: func }), {}); + + expect.extend(extensions); +}); diff --git a/package-lock.json b/package-lock.json index 2a8c86f..b3cd5ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1788,9 +1788,9 @@ } }, "eslint-config-origami-component": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-origami-component/-/eslint-config-origami-component-1.0.0.tgz", - "integrity": "sha1-xqHXWLIns51QZ5b41ENFZTpwXkY=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-origami-component/-/eslint-config-origami-component-2.0.1.tgz", + "integrity": "sha512-H7qxqmOeVxop3bG+xsf51Ho+gmNN2hKtsBqDlgXRk5gIaieuP3l/dPSYGQ4FQxU2ktdPesS5dOVTuuQAIuQpMw==", "dev": true }, "eslint-config-prettier": { diff --git a/package.json b/package.json index c68f094..ce751d1 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ }, "devDependencies": { "eslint": "^6.6.0", - "eslint-config-origami-component": "^1.0.0", + "eslint-config-origami-component": "^2.0.0", "eslint-config-prettier": "^6.5.0", "eslint-plugin-prettier": "^3.1.1", "jest": "^25.0.0",