diff --git a/lib/datasource/crate/__snapshots__/index.spec.ts.snap b/lib/datasource/crate/__snapshots__/index.spec.ts.snap index 8cab958d1b4e40..63116b90b90601 100644 --- a/lib/datasource/crate/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/crate/__snapshots__/index.spec.ts.snap @@ -65,6 +65,83 @@ Object { } `; +exports[`datasource/crate getReleases processes real data: amethyst 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/li/bc/libc", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/am/et/amethyst", + }, +] +`; + exports[`datasource/crate getReleases processes real data: libc 1`] = ` Object { "releases": Array [ @@ -269,4 +346,472 @@ Object { } `; +exports[`datasource/crate getReleases processes real data: libc 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/li/bc/libc", + }, +] +`; + +exports[`datasource/crate getReleases returns null for 404 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, +] +`; + +exports[`datasource/crate getReleases returns null for empty list 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, +] +`; + +exports[`datasource/crate getReleases returns null for empty result 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, +] +`; + +exports[`datasource/crate getReleases returns null for invalid crate data 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/li/bc/libc", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/am/et/amethyst", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/in/va/invalid-crate-name", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, +] +`; + +exports[`datasource/crate getReleases returns null for missing fields 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, +] +`; + +exports[`datasource/crate getReleases returns null for unknown error 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, +] +`; + +exports[`datasource/crate getReleases returns null if crate name is invalid 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/li/bc/libc", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/am/et/amethyst", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/in/va/invalid-crate-name", + }, +] +`; + exports[`datasource/crate getReleases throws for 5xx 1`] = `[Error: registry-failure]`; + +exports[`datasource/crate getReleases throws for 5xx 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/no/n_/non_existent_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "raw.githubusercontent.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://raw.githubusercontent.com/rust-lang/crates.io-index/master/so/me/some_crate", + }, +] +`; diff --git a/lib/datasource/crate/index.spec.ts b/lib/datasource/crate/index.spec.ts index d30952f093532c..bd9708266aa12f 100644 --- a/lib/datasource/crate/index.spec.ts +++ b/lib/datasource/crate/index.spec.ts @@ -1,10 +1,8 @@ import fs from 'fs'; +import * as httpMock from '../../../test/httpMock'; -import _got from '../../util/got'; import { getReleases } from '.'; -const got: any = _got; - const res1 = fs.readFileSync('lib/datasource/crate/__fixtures__/libc', 'utf8'); const res2 = fs.readFileSync( 'lib/datasource/crate/__fixtures__/amethyst', @@ -15,46 +13,42 @@ const res3 = fs.readFileSync( 'utf8' ); -jest.mock('../../util/got'); +const baseUrl = + 'https://raw.githubusercontent.com/rust-lang/crates.io-index/master/'; describe('datasource/crate', () => { describe('getReleases', () => { it('returns null for empty result', async () => { - got.mockReturnValueOnce(null); + httpMock.scope(baseUrl).get('/no/n_/non_existent_crate').reply(200, {}); expect( await getReleases({ lookupName: 'non_existent_crate' }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for missing fields', async () => { - got.mockReturnValueOnce({ - body: undefined, - }); + httpMock + .scope(baseUrl) + .get('/no/n_/non_existent_crate') + .reply(200, undefined); expect( await getReleases({ lookupName: 'non_existent_crate' }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for empty list', async () => { - got.mockReturnValueOnce({ - body: '\n', - }); + httpMock.scope(baseUrl).get('/no/n_/non_existent_crate').reply(200, '\n'); expect( await getReleases({ lookupName: 'non_existent_crate' }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock.scope(baseUrl).get('/so/me/some_crate').reply(404); expect(await getReleases({ lookupName: 'some_crate' })).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws for 5xx', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 502, - }) - ); + httpMock.scope(baseUrl).get('/so/me/some_crate').reply(502); let e; try { await getReleases({ lookupName: 'some_crate' }); @@ -63,44 +57,40 @@ describe('datasource/crate', () => { } expect(e).toBeDefined(); expect(e).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock.scope(baseUrl).get('/so/me/some_crate').replyWithError(''); expect(await getReleases({ lookupName: 'some_crate' })).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data: libc', async () => { - got.mockReturnValueOnce({ - body: res1, - }); + httpMock.scope(baseUrl).get('/li/bc/libc').reply(200, res1); const res = await getReleases({ lookupName: 'libc' }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); expect(res).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data: amethyst', async () => { - got.mockReturnValueOnce({ - body: res2, - }); + httpMock.scope(baseUrl).get('/am/et/amethyst').reply(200, res2); const res = await getReleases({ lookupName: 'amethyst' }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); expect(res).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null if crate name is invalid', async () => { - got.mockReturnValueOnce({ - body: res2, - }); + httpMock.scope(baseUrl).get('/in/va/invalid-crate-name').reply(200, res2); const res = await getReleases({ lookupName: 'invalid-crate-name' }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for invalid crate data', async () => { - got.mockReturnValueOnce({ - body: res3, - }); + httpMock.scope(baseUrl).get('/so/me/some_crate').reply(200, res3); const res = await getReleases({ lookupName: 'some_crate' }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/dart/__snapshots__/index.spec.ts.snap b/lib/datasource/dart/__snapshots__/index.spec.ts.snap index f293d01d445383..52477f48413e04 100644 --- a/lib/datasource/dart/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/dart/__snapshots__/index.spec.ts.snap @@ -60,4 +60,104 @@ Object { } `; +exports[`datasource/dart getReleases processes real data 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "pub.dartlang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://pub.dartlang.org/api/packages/shared_preferences", + }, +] +`; + +exports[`datasource/dart getReleases returns null for 404 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "pub.dartlang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://pub.dartlang.org/api/packages/shared_preferences", + }, +] +`; + +exports[`datasource/dart getReleases returns null for empty fields 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "pub.dartlang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://pub.dartlang.org/api/packages/shared_preferences", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "pub.dartlang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://pub.dartlang.org/api/packages/shared_preferences", + }, +] +`; + +exports[`datasource/dart getReleases returns null for empty result 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "pub.dartlang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://pub.dartlang.org/api/packages/non_sense", + }, +] +`; + +exports[`datasource/dart getReleases returns null for unknown error 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "pub.dartlang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://pub.dartlang.org/api/packages/shared_preferences", + }, +] +`; + exports[`datasource/dart getReleases throws for 5xx 1`] = `[Error: registry-failure]`; + +exports[`datasource/dart getReleases throws for 5xx 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "pub.dartlang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://pub.dartlang.org/api/packages/shared_preferences", + }, +] +`; diff --git a/lib/datasource/dart/index.spec.ts b/lib/datasource/dart/index.spec.ts index 95124ba2e25f1e..317274b6ea931d 100644 --- a/lib/datasource/dart/index.spec.ts +++ b/lib/datasource/dart/index.spec.ts @@ -1,9 +1,7 @@ import fs from 'fs'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import { getReleases } from '.'; -const got: any = _got; - const body: any = JSON.parse( fs.readFileSync( 'lib/datasource/dart/__fixtures__/shared_preferences.json', @@ -11,20 +9,32 @@ const body: any = JSON.parse( ) ); -jest.mock('../../util/got'); +const baseUrl = 'https://pub.dartlang.org/api/packages/'; describe('datasource/dart', () => { + beforeEach(() => { + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); + }); + describe('getReleases', () => { it('returns null for empty result', async () => { - got.mockReturnValueOnce(null); + httpMock.scope(baseUrl).get('/non_sense').reply(200, null); expect(await getReleases({ lookupName: 'non_sense' })).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for empty fields', async () => { const withoutVersions = { ...body, versions: undefined, }; - got.mockReturnValueOnce({ body: withoutVersions }); + httpMock + .scope(baseUrl) + .get('/shared_preferences') + .reply(200, withoutVersions); expect( await getReleases({ lookupName: 'shared_preferences' }) ).toBeNull(); @@ -33,27 +43,25 @@ describe('datasource/dart', () => { ...body, latest: undefined, }; - got.mockReturnValueOnce({ body: withoutLatest }); + httpMock + .scope(baseUrl) + .get('/shared_preferences') + .reply(200, withoutLatest); expect( await getReleases({ lookupName: 'shared_preferences' }) ).toBeNull(); + + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock.scope(baseUrl).get('/shared_preferences').reply(404); expect( await getReleases({ lookupName: 'shared_preferences' }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws for 5xx', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 502, - }) - ); + httpMock.scope(baseUrl).get('/shared_preferences').reply(502); let e; try { await getReleases({ lookupName: 'shared_preferences' }); @@ -62,21 +70,22 @@ describe('datasource/dart', () => { } expect(e).toBeDefined(); expect(e).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock.scope(baseUrl).get('/shared_preferences').replyWithError(''); expect( await getReleases({ lookupName: 'shared_preferences' }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data', async () => { - got.mockReturnValueOnce({ body }); + httpMock.scope(baseUrl).get('/shared_preferences').reply(200, body); const res = await getReleases({ lookupName: 'shared_preferences', }); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/docker/index.spec.ts b/lib/datasource/docker/index.spec.ts index 6ca136f7d126d8..ebf61ddf0dc01d 100644 --- a/lib/datasource/docker/index.spec.ts +++ b/lib/datasource/docker/index.spec.ts @@ -486,7 +486,6 @@ describe('api/docker', () => { datasource: docker.id, depName: 'k8s.gcr.io/kubernetes-dashboard-amd64', }); - httpMock.getTrace(); expect(res.releases).toHaveLength(1); expect(httpMock.getTrace()).toMatchSnapshot(); }); diff --git a/lib/datasource/galaxy/index.spec.ts b/lib/datasource/galaxy/index.spec.ts index 046fe2a05df8f2..8558281257b1d8 100644 --- a/lib/datasource/galaxy/index.spec.ts +++ b/lib/datasource/galaxy/index.spec.ts @@ -87,7 +87,6 @@ describe('datasource/galaxy', () => { .get('/api/v1/roles/?owner__username=foo&name=bar') .reply(200, empty); const res = await getReleases({ lookupName: 'foo.bar' }); - httpMock.getTrace(); expect(res).toBeNull(); expect(httpMock.getTrace()).toMatchSnapshot(); }); diff --git a/lib/datasource/gitlab-tags/index.spec.ts b/lib/datasource/gitlab-tags/index.spec.ts index c7f4a9af5393fe..17f10660dfb77e 100644 --- a/lib/datasource/gitlab-tags/index.spec.ts +++ b/lib/datasource/gitlab-tags/index.spec.ts @@ -31,7 +31,6 @@ describe('datasource/gitlab-tags', () => { registryUrls: ['https://gitlab.company.com/api/v4/'], lookupName: 'some/dep2', }); - httpMock.getTrace(); expect(res).toMatchSnapshot(); expect(res.releases).toHaveLength(3); expect(httpMock.getTrace()).toMatchSnapshot(); diff --git a/lib/datasource/helm/__snapshots__/index.spec.ts.snap b/lib/datasource/helm/__snapshots__/index.spec.ts.snap index ce20b09edf64d7..d0ed6d6ecf7676 100644 --- a/lib/datasource/helm/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/helm/__snapshots__/index.spec.ts.snap @@ -1,5 +1,19 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`datasource/helm getReleases adds trailing slash to subdirectories 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/subdir/index.yaml", + }, +] +`; + exports[`datasource/helm getReleases returns list of versions for normal response 1`] = ` Object { "homepage": "https://www.getambassador.io/", @@ -118,4 +132,130 @@ Object { } `; +exports[`datasource/helm getReleases returns list of versions for normal response 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + +exports[`datasource/helm getReleases returns null for 404 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + +exports[`datasource/helm getReleases returns null for empty response 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + +exports[`datasource/helm getReleases returns null for missing response body 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + +exports[`datasource/helm getReleases returns null for unknown error 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + +exports[`datasource/helm getReleases returns null if index.yaml in response is empty 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + +exports[`datasource/helm getReleases returns null if index.yaml in response is invalid 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + +exports[`datasource/helm getReleases returns null if lookupName is not in index.yaml 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; + exports[`datasource/helm getReleases throws for 5xx 1`] = `[Error: registry-failure]`; + +exports[`datasource/helm getReleases throws for 5xx 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example-repository.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example-repository.com/index.yaml", + }, +] +`; diff --git a/lib/datasource/helm/index.spec.ts b/lib/datasource/helm/index.spec.ts index b86199f2450e5c..671643ba06f801 100644 --- a/lib/datasource/helm/index.spec.ts +++ b/lib/datasource/helm/index.spec.ts @@ -1,22 +1,24 @@ import fs from 'fs'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import { getReleases } from '.'; -const got: any = _got; - // Truncated index.yaml file const indexYaml = fs.readFileSync( 'lib/datasource/helm/__fixtures__/index.yaml', 'utf8' ); -jest.mock('../../util/got'); - describe('datasource/helm', () => { describe('getReleases', () => { beforeEach(() => { jest.resetAllMocks(); + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); }); + it('returns null if lookupName was not provided', async () => { expect( await getReleases({ @@ -34,44 +36,49 @@ describe('datasource/helm', () => { ).toBeNull(); }); it('returns null for empty response', async () => { - got.mockReturnValueOnce(null); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(200, null); expect( await getReleases({ lookupName: 'non_existent_chart', registryUrls: ['https://example-repository.com'], }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for missing response body', async () => { - got.mockReturnValueOnce({ - body: undefined, - }); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(200, undefined); expect( await getReleases({ lookupName: 'non_existent_chart', registryUrls: ['https://example-repository.com'], }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(404); expect( await getReleases({ lookupName: 'some_chart', registryUrls: ['https://example-repository.com'], }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws for 5xx', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 502, - }) - ); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(502); let e; try { await getReleases({ @@ -83,26 +90,32 @@ describe('datasource/helm', () => { } expect(e).toBeDefined(); expect(e).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .replyWithError(''); expect( await getReleases({ lookupName: 'some_chart', registryUrls: ['https://example-repository.com'], }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null if index.yaml in response is empty', async () => { - const res = { body: '# A comment' }; - got.mockReturnValueOnce(res); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(200, '# A comment'); const releases = await getReleases({ lookupName: 'non_existent_chart', registryUrls: ['https://example-repository.com'], }); expect(releases).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null if index.yaml in response is invalid', async () => { const res = { @@ -111,39 +124,56 @@ describe('datasource/helm', () => { [ yaml`, }; - got.mockReturnValueOnce(res); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(200, res); const releases = await getReleases({ lookupName: 'non_existent_chart', registryUrls: ['https://example-repository.com'], }); expect(releases).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null if lookupName is not in index.yaml', async () => { - got.mockReturnValueOnce({ body: indexYaml }); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(200, indexYaml); const releases = await getReleases({ lookupName: 'non_existent_chart', registryUrls: ['https://example-repository.com'], }); expect(releases).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns list of versions for normal response', async () => { - got.mockReturnValueOnce({ body: indexYaml }); + httpMock + .scope('https://example-repository.com') + .get('/index.yaml') + .reply(200, indexYaml); const releases = await getReleases({ lookupName: 'ambassador', registryUrls: ['https://example-repository.com'], }); expect(releases).not.toBeNull(); expect(releases).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('adds trailing slash to subdirectories', async () => { - got.mockReturnValueOnce({ body: indexYaml }); + httpMock + .scope('https://example-repository.com') + .get('/subdir/index.yaml') + .reply(200, indexYaml); await getReleases({ lookupName: 'ambassador', registryUrls: ['https://example-repository.com/subdir'], }); - expect(got.mock.calls[0][0]).toEqual( + const trace = httpMock.getTrace(); + expect(trace[0].url).toEqual( 'https://example-repository.com/subdir/index.yaml' ); + expect(trace).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/hex/__snapshots__/index.spec.ts.snap b/lib/datasource/hex/__snapshots__/index.spec.ts.snap index 668e54458d8bcc..44a0e16be30f12 100644 --- a/lib/datasource/hex/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/hex/__snapshots__/index.spec.ts.snap @@ -88,6 +88,21 @@ Object { } `; +exports[`datasource/hex getReleases process public repo without auth 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/certifi", + }, +] +`; + exports[`datasource/hex getReleases processes real data 1`] = ` Object { "homepage": "https://hex.pm/packages/certifi", @@ -175,3 +190,139 @@ Object { "sourceUrl": "https://github.com/certifi/erlang-certifi", } `; + +exports[`datasource/hex getReleases processes real data 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/certifi", + }, +] +`; + +exports[`datasource/hex getReleases returns null for 401 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/some_package", + }, +] +`; + +exports[`datasource/hex getReleases returns null for 404 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/some_package", + }, +] +`; + +exports[`datasource/hex getReleases returns null for empty result 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/non_existent_package", + }, +] +`; + +exports[`datasource/hex getReleases returns null for missing fields 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/non_existent_package", + }, +] +`; + +exports[`datasource/hex getReleases returns null for unknown error 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/some_package", + }, +] +`; + +exports[`datasource/hex getReleases returns null with wrong auth token 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer this_simple_token", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/certifi", + }, +] +`; + +exports[`datasource/hex getReleases throws for 5xx 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/some_crate", + }, +] +`; + +exports[`datasource/hex getReleases throws for 429 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "hex.pm", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://hex.pm/api/packages/some_crate", + }, +] +`; diff --git a/lib/datasource/hex/index.spec.ts b/lib/datasource/hex/index.spec.ts index b0d8e3e51a9195..8c439c343d7ecb 100644 --- a/lib/datasource/hex/index.spec.ts +++ b/lib/datasource/hex/index.spec.ts @@ -1,10 +1,9 @@ import fs from 'fs'; +import * as httpMock from '../../../test/httpMock'; import { DATASOURCE_FAILURE } from '../../constants/error-messages'; -import _got from '../../util/got'; import * as _hostRules from '../../util/host-rules'; import { getReleases } from '.'; -const got: any = _got; const hostRules: any = _hostRules; let res1 = fs.readFileSync( @@ -13,98 +12,86 @@ let res1 = fs.readFileSync( ); res1 = JSON.parse(res1); -jest.mock('../../util/got'); jest.mock('../../util/host-rules'); +const baseUrl = 'https://hex.pm/api/packages/'; + describe('datasource/hex', () => { + beforeEach(() => { + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); + }); + describe('getReleases', () => { it('returns null for empty result', async () => { - got.mockReturnValueOnce(null); + httpMock.scope(baseUrl).get('/non_existent_package').reply(200, null); expect( await getReleases({ lookupName: 'non_existent_package' }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for missing fields', async () => { - got.mockReturnValueOnce({}); - expect( - await getReleases({ lookupName: 'non_existent_package' }) - ).toBeNull(); - - got.mockReturnValueOnce({ body: {} }); + httpMock.scope(baseUrl).get('/non_existent_package').reply(200, {}); expect( await getReleases({ lookupName: 'non_existent_package' }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock.scope(baseUrl).get('/some_package').reply(404); expect(await getReleases({ lookupName: 'some_package' })).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 401', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 401, - }) - ); + httpMock.scope(baseUrl).get('/some_package').reply(401); expect(await getReleases({ lookupName: 'some_package' })).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws for 429', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 429, - }) - ); + httpMock.scope(baseUrl).get('/some_crate').reply(429); await expect(getReleases({ lookupName: 'some_crate' })).rejects.toThrow( DATASOURCE_FAILURE ); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws for 5xx', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 502, - }) - ); + httpMock.scope(baseUrl).get('/some_crate').reply(502); await expect(getReleases({ lookupName: 'some_crate' })).rejects.toThrow( DATASOURCE_FAILURE ); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock.scope(baseUrl).get('/some_package').replyWithError(''); expect(await getReleases({ lookupName: 'some_package' })).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null with wrong auth token', async () => { + httpMock.scope(baseUrl).get('/certifi').reply(401); hostRules.find.mockReturnValueOnce({ token: 'this_simple_token' }); - got.mockReturnValueOnce( - Promise.reject({ - statusCode: 401, - }) - ); const res = await getReleases({ lookupName: 'certifi' }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data', async () => { - got.mockReturnValueOnce({ - body: res1, - }); + httpMock.scope(baseUrl).get('/certifi').reply(200, res1); const res = await getReleases({ lookupName: 'certifi' }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); expect(res).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('process public repo without auth', async () => { + httpMock.scope(baseUrl).get('/certifi').reply(200, res1); hostRules.find.mockReturnValueOnce({}); - got.mockReturnValueOnce({ - body: res1, - }); const res = await getReleases({ lookupName: 'certifi' }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); expect(res).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/npm/__snapshots__/get.spec.ts.snap b/lib/datasource/npm/__snapshots__/get.spec.ts.snap new file mode 100644 index 00000000000000..579efc3629c359 --- /dev/null +++ b/lib/datasource/npm/__snapshots__/get.spec.ts.snap @@ -0,0 +1,484 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`datasource/npm/get cover all paths 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/none", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest2", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/error-401", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/error-402", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/error-404", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/error4", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "cache-control": "no-cache", + "host": "registry.npmjs.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.npmjs.org/npm-parse-error", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "cache-control": "no-cache", + "host": "registry.npmjs.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.npmjs.org/npm-error-402", + }, +] +`; + +exports[`datasource/npm/get has basic auth "@myco:registry=https://test.org +//test.org/:_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "@myco:registry=https://test.org +_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "registry=https://test.org +//test.org/:_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "registry=https://test.org +//test.org/:username=test +//test.org/:_password=dGVzdA==" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "registry=https://test.org +_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "registry=https://test.org +_auth=dGVzdDp0ZXN0" 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "registry=https://test.org/sub +//test.org/:_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/sub/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "registry=https://test.org/sub +//test.org/sub/:_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/sub/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has basic auth "registry=https://test.org/sub +_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic dGVzdDp0ZXN0", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/sub/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has bearer auth "@myco:registry=https://test.org +//test.org/:_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has bearer auth "registry=https://test.org +//test.org/:_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has bearer auth "registry=https://test.org +_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has bearer auth "registry=https://test.org +_authToken=XXX" 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has bearer auth "registry=https://test.org/sub +//test.org/:_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/sub/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has bearer auth "registry=https://test.org/sub +//test.org/sub/:_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/sub/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get has bearer auth "registry=https://test.org/sub +_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Bearer XXX", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/sub/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get no auth "@myco:registry=https://test.org +//test.org/sub/:_auth=dGVzdDp0ZXN0" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get no auth "@myco:registry=https://test.org +//test.org/sub/:_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get no auth "@myco:registry=https://test.org +_authToken=XXX" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get no auth "@myco:registry=https://test.org" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; + +exports[`datasource/npm/get no auth "registry=https://test.org" 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "cache-control": "no-cache", + "host": "test.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://test.org/@myco%2Ftest", + }, +] +`; diff --git a/lib/datasource/npm/get.spec.ts b/lib/datasource/npm/get.spec.ts index b18f5fd3effb3d..2d394b010d4ade 100644 --- a/lib/datasource/npm/get.spec.ts +++ b/lib/datasource/npm/get.spec.ts @@ -1,25 +1,24 @@ -import got from 'got'; -import { getName, partial } from '../../../test/util'; -import * as _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; +import { getName } from '../../../test/util'; import { DatasourceError } from '../common'; import { getDependency, resetMemCache } from './get'; import { setNpmrc } from './npmrc'; -jest.mock('../../util/got'); - -const api: jest.Mock> = _got.api as never; +function getPath(s = ''): string { + const [x] = s.split('\n'); + const prePath = x.replace(/^.*https:\/\/test\.org/, ''); + return `${prePath}/@myco%2Ftest`; +} describe(getName(__filename), () => { - function mock(body: object): void { - api.mockResolvedValueOnce( - partial>({ body }) - ); - } - beforeEach(() => { jest.clearAllMocks(); resetMemCache(); - mock({ body: { name: '@myco/test' } }); + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); }); describe('has bearer auth', () => { @@ -34,11 +33,18 @@ describe(getName(__filename), () => { ]; it.each(configs)('%p', async (npmrc) => { - expect.assertions(1); + expect.assertions(2); + httpMock + .scope('https://test.org') + .get(getPath(npmrc)) + .reply(200, { name: '@myco/test' }); + setNpmrc(npmrc); await getDependency('@myco/test', 0); - expect(api.mock.calls[0][1].headers.authorization).toEqual('Bearer XXX'); + const trace = httpMock.getTrace(); + expect(trace[0].headers.authorization).toEqual('Bearer XXX'); + expect(trace).toMatchSnapshot(); }); }); @@ -56,13 +62,17 @@ describe(getName(__filename), () => { ]; it.each(configs)('%p', async (npmrc) => { - expect.assertions(1); + expect.assertions(2); + httpMock + .scope('https://test.org') + .get(getPath(npmrc)) + .reply(200, { name: '@myco/test' }); setNpmrc(npmrc); await getDependency('@myco/test', 0); - expect(api.mock.calls[0][1].headers.authorization).toEqual( - 'Basic dGVzdDp0ZXN0' - ); + const trace = httpMock.getTrace(); + expect(trace[0].headers.authorization).toEqual('Basic dGVzdDp0ZXN0'); + expect(trace).toMatchSnapshot(); }); }); @@ -76,53 +86,79 @@ describe(getName(__filename), () => { ]; it.each(configs)('%p', async (npmrc) => { - expect.assertions(1); + expect.assertions(2); + httpMock + .scope('https://test.org') + .get(getPath(npmrc)) + .reply(200, { name: '@myco/test' }); setNpmrc(npmrc); await getDependency('@myco/test', 0); - expect(api.mock.calls[0][1].headers.authorization).toBeUndefined(); + const trace = httpMock.getTrace(); + expect(trace[0].headers.authorization).toBeUndefined(); + expect(trace).toMatchSnapshot(); }); }); it('cover all paths', async () => { - expect.assertions(9); + expect.assertions(10); setNpmrc('registry=https://test.org\n_authToken=XXX'); + httpMock + .scope('https://test.org') + .get('/none') + .reply(200, { name: '@myco/test' }); expect(await getDependency('none', 0)).toBeNull(); - mock({ - name: '@myco/test', - repository: {}, - versions: { '1.0.0': {} }, - 'dist-tags': { latest: '1.0.0' }, - }); + httpMock + .scope('https://test.org') + .get('/@myco%2Ftest') + .reply(200, { + name: '@myco/test', + repository: {}, + versions: { '1.0.0': {} }, + 'dist-tags': { latest: '1.0.0' }, + }); expect(await getDependency('@myco/test', 0)).toBeDefined(); - mock({ - name: '@myco/test2', - versions: { '1.0.0': {} }, - 'dist-tags': { latest: '1.0.0' }, - }); + httpMock + .scope('https://test.org') + .get('/@myco%2Ftest2') + .reply(200, { + name: '@myco/test2', + versions: { '1.0.0': {} }, + 'dist-tags': { latest: '1.0.0' }, + }); expect(await getDependency('@myco/test2', 0)).toBeDefined(); - api.mockRejectedValueOnce({ statusCode: 401 }); + httpMock.scope('https://test.org').get('/error-401').reply(401); expect(await getDependency('error-401', 0)).toBeNull(); - api.mockRejectedValueOnce({ statusCode: 402 }); + + httpMock.scope('https://test.org').get('/error-402').reply(402); expect(await getDependency('error-402', 0)).toBeNull(); - api.mockRejectedValueOnce({ statusCode: 404 }); + + httpMock.scope('https://test.org').get('/error-404').reply(404); expect(await getDependency('error-404', 0)).toBeNull(); - api.mockRejectedValueOnce({}); + httpMock.scope('https://test.org').get('/error4').reply(200, null); expect(await getDependency('error4', 0)).toBeNull(); setNpmrc(); - api.mockRejectedValueOnce({ name: 'ParseError', body: 'parse-error' }); + httpMock + .scope('https://registry.npmjs.org') + .get('/npm-parse-error') + .reply(200, 'not-a-json'); await expect(getDependency('npm-parse-error', 0)).rejects.toThrow( DatasourceError ); - api.mockRejectedValueOnce({ statusCode: 402 }); + httpMock + .scope('https://registry.npmjs.org') + .get('/npm-error-402') + .reply(402); expect(await getDependency('npm-error-402', 0)).toBeNull(); + + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); diff --git a/lib/datasource/npm/get.ts b/lib/datasource/npm/get.ts index f465675b7a8edd..d2f0e2ab362cc6 100644 --- a/lib/datasource/npm/get.ts +++ b/lib/datasource/npm/get.ts @@ -276,6 +276,7 @@ export async function getDependency( await delay(1000 * delaySeconds); return getDependency(packageName, retries - 1); } + // istanbul ignore if if (err.name === 'ParseError' && err.body) { err.body = 'err.body deleted by Renovate'; } diff --git a/lib/datasource/nuget/__snapshots__/index.spec.ts.snap b/lib/datasource/nuget/__snapshots__/index.spec.ts.snap index ff43c28a2fddd7..730bf6e187ff08 100644 --- a/lib/datasource/nuget/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/nuget/__snapshots__/index.spec.ts.snap @@ -1,5 +1,70 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`datasource/nuget getReleases can't get packages list (v3) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true", + }, +] +`; + +exports[`datasource/nuget getReleases empty packages list (v3) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true", + }, +] +`; + +exports[`datasource/nuget getReleases extracts feed version from registry URL hash 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "my-registry", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://my-registry/", + }, +] +`; + exports[`datasource/nuget getReleases handles paginated results (v2) 1`] = ` Object { "pkgName": "nunit", @@ -14,6 +79,29 @@ Object { } `; +exports[`datasource/nuget getReleases handles paginated results (v2) 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "example.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://example.org/", + }, +] +`; + exports[`datasource/nuget getReleases processes real data (v2) 1`] = ` Object { "pkgName": "nunit", @@ -152,6 +240,20 @@ Object { } `; +exports[`datasource/nuget getReleases processes real data (v2) 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + exports[`datasource/nuget getReleases processes real data (v3) feed is a nuget.org 1`] = ` Object { "pkgName": "nunit", @@ -248,6 +350,40 @@ Object { } `; +exports[`datasource/nuget getReleases processes real data (v3) feed is a nuget.org 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3-flatcontainer/nunit/3.11.0/nunit.nuspec", + }, +] +`; + exports[`datasource/nuget getReleases processes real data (v3) feed is not a nuget.org 1`] = ` Object { "pkgName": "nunit", @@ -344,6 +480,70 @@ Object { } `; +exports[`datasource/nuget getReleases processes real data (v3) feed is not a nuget.org 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "myprivatefeed", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://myprivatefeed/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=nunit", + }, +] +`; + +exports[`datasource/nuget getReleases processes real data (v3) feed is not a nuget.org with mismatch 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "myprivatefeed", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://myprivatefeed/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=nun", + }, +] +`; + +exports[`datasource/nuget getReleases processes real data no relase (v2) 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + exports[`datasource/nuget getReleases processes real data with no github project url (v2) 1`] = ` Object { "pkgName": "nunit", @@ -356,6 +556,20 @@ Object { } `; +exports[`datasource/nuget getReleases processes real data with no github project url (v2) 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + exports[`datasource/nuget getReleases processes real data with no github project url (v3) 1`] = ` Object { "pkgName": "nunit", @@ -368,6 +582,31 @@ Object { } `; +exports[`datasource/nuget getReleases processes real data with no github project url (v3) 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "myprivatefeed", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://myprivatefeed/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=nunit", + }, +] +`; + exports[`datasource/nuget getReleases processes real data without project url (v2) 1`] = ` Object { "pkgName": "nunit", @@ -505,6 +744,20 @@ Object { } `; +exports[`datasource/nuget getReleases processes real data without project url (v2) 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + exports[`datasource/nuget getReleases processes real data without project url (v3) 1`] = ` Object { "pkgName": "nunit", @@ -600,6 +853,31 @@ Object { } `; +exports[`datasource/nuget getReleases processes real data without project url (v3) 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "myprivatefeed", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://myprivatefeed/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=nunit", + }, +] +`; + exports[`datasource/nuget getReleases returns deduplicated results 1`] = ` Object { "pkgName": "nunit", @@ -698,3 +976,241 @@ Object { "sourceUrl": "https://github.com/nunit/nunit", } `; + +exports[`datasource/nuget getReleases returns deduplicated results 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3-flatcontainer/nunit/3.11.0/nunit.nuspec", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "myprivatefeed", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://myprivatefeed/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=nunit", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for empty result (v2) 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for empty result (v3) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for empty result (v3v2) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for non 200 (v2) 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for non 200 (v3) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for non 200 (v3v2) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for unknown error (v2) 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for unknown error (v3v2) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.nuget.org/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for unknown error in getQueryUrlForV3Feed (v3) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api-v2v3search-0.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api-v2v3search-0.nuget.org/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true", + }, +] +`; + +exports[`datasource/nuget getReleases returns null for unknown error in getReleasesFromV3Feed (v3) 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "api.nuget.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://api.nuget.org/v3/index.json", + }, +] +`; diff --git a/lib/datasource/nuget/index.spec.ts b/lib/datasource/nuget/index.spec.ts index 8ebf2d1aeec665..b39e391e20481b 100644 --- a/lib/datasource/nuget/index.spec.ts +++ b/lib/datasource/nuget/index.spec.ts @@ -1,15 +1,12 @@ import fs from 'fs'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import * as _hostRules from '../../util/host-rules'; import * as nuget from '.'; const hostRules: any = _hostRules; -jest.mock('../../util/got'); jest.mock('../../util/host-rules'); -const got: any = _got; - const pkgListV3 = fs.readFileSync( 'lib/datasource/nuget/__fixtures__/nunitV3.json', 'utf8' @@ -98,6 +95,11 @@ describe('datasource/nuget', () => { beforeEach(() => { jest.resetAllMocks(); hostRules.hosts = jest.fn(() => []); + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); }); it(`can't detect nuget feed version`, async () => { @@ -114,6 +116,7 @@ describe('datasource/nuget', () => { }); it('extracts feed version from registry URL hash', async () => { + httpMock.scope('https://my-registry').get('/').reply(200); const config = { lookupName: 'nunit', registryUrls: ['https://my-registry#protocolVersion=3'], @@ -121,319 +124,375 @@ describe('datasource/nuget', () => { await nuget.getReleases({ ...config, }); - expect(got.mock.calls[0][0]).toEqual('https://my-registry/'); + const trace = httpMock.getTrace(); + expect(trace[0].url).toEqual('https://my-registry/'); + expect(trace).toMatchSnapshot(); }); it(`can't get packages list (v3)`, async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - statusCode: 500, - }); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .reply(200, JSON.parse(nugetIndexV3)); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true') + .reply(500); + const res = await nuget.getReleases({ ...configV3, }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it(`empty packages list (v3)`, async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: JSON.parse('{"totalHits": 0}'), - statusCode: 200, - }); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .reply(200, JSON.parse(nugetIndexV3)); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true') + .reply(200, JSON.parse('{"totalHits": 0}')); + const res = await nuget.getReleases({ ...configV3, }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for empty result (v3v2)', async () => { - got.mockReturnValueOnce({}); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .reply(200, {}); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(200, null); expect( await nuget.getReleases({ ...configV3V2, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for empty result (v2)', async () => { - got.mockReturnValueOnce({}); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(200, {}); expect( await nuget.getReleases({ ...configV2, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for empty result (v3)', async () => { - got.mockReturnValueOnce({}); - expect( - await nuget.getReleases({ - ...configV3, - }) - ).toBeNull(); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .reply(200, {}); + const res = await nuget.getReleases({ + ...configV3, + }); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for non 200 (v3v2)', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 500, - }) - ); + httpMock.scope('https://api.nuget.org').get('/v3/index.json').reply(500); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(500); expect( await nuget.getReleases({ ...configV3V2, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for non 200 (v3)', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 500, - }) - ); + httpMock.scope('https://api.nuget.org').get('/v3/index.json').reply(500); expect( await nuget.getReleases({ ...configV3, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for non 200 (v2)', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 500, - }) - ); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(500); expect( await nuget.getReleases({ ...configV2, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error (v3v2)', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .replyWithError(''); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .replyWithError(''); expect( await nuget.getReleases({ ...configV3V2, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns deduplicated results', async () => { - got - .mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }) - .mockReturnValueOnce({ - body: JSON.parse(pkgListV3), - statusCode: 200, - }) - .mockReturnValueOnce({ - body: pkgInfoV3FromNuget, - statusCode: 200, - }) - .mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }) - .mockReturnValueOnce({ - body: JSON.parse(pkgListV3PrivateFeed), - statusCode: 200, - }) - .mockReturnValueOnce({ - body: pkgInfoV3FromNuget, - statusCode: 200, - }); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .reply(200, JSON.parse(nugetIndexV3)) + .get('/v3-flatcontainer/nunit/3.11.0/nunit.nuspec') + .reply(200, pkgInfoV3FromNuget); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true') + .reply(200, JSON.parse(pkgListV3)) + .get('/query?q=nunit') + .reply(200, JSON.parse(pkgListV3PrivateFeed)); + httpMock + .scope('https://myprivatefeed') + .get('/index.json') + .reply(200, JSON.parse(nugetIndexV3)); + const res = await nuget.getReleases({ ...configV3Multiple, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); expect(res.releases).toHaveLength(30); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error in getReleasesFromV3Feed (v3)', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .replyWithError(''); expect( await nuget.getReleases({ ...configV3, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error in getQueryUrlForV3Feed (v3)', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .reply(200, JSON.parse(nugetIndexV3)); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true') + .replyWithError(''); expect( await nuget.getReleases({ ...configV3, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error (v2)', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .replyWithError(''); expect( await nuget.getReleases({ ...configV2, }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data (v3) feed is a nuget.org', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: JSON.parse(pkgListV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: pkgInfoV3FromNuget, - statusCode: 200, - }); + httpMock + .scope('https://api.nuget.org') + .get('/v3/index.json') + .reply(200, JSON.parse(nugetIndexV3)) + .get('/v3-flatcontainer/nunit/3.11.0/nunit.nuspec') + .reply(200, pkgInfoV3FromNuget); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=PackageId:nunit&semVerLevel=2.0.0&prerelease=true') + .reply(200, JSON.parse(pkgListV3)); const res = await nuget.getReleases({ ...configV3, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); expect(res.sourceUrl).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data (v3) feed is not a nuget.org', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: JSON.parse(pkgListV3), - statusCode: 200, - }); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=nunit') + .reply(200, JSON.parse(pkgListV3)); + httpMock + .scope('https://myprivatefeed') + .get('/index.json') + .reply(200, JSON.parse(nugetIndexV3)); + const res = await nuget.getReleases({ ...configV3NotNugetOrg, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); expect(res.sourceUrl).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data (v3) feed is not a nuget.org with mismatch', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: JSON.parse(pkgListV3), - statusCode: 200, - }); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=nun') + .reply(200, JSON.parse(pkgListV3)); + httpMock + .scope('https://myprivatefeed') + .get('/index.json') + .reply(200, JSON.parse(nugetIndexV3)); const res = await nuget.getReleases({ ...configV3NotNugetOrg, lookupName: 'nun', }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data without project url (v3)', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: JSON.parse(pkgListV3WithoutProkjectUrl), - statusCode: 200, - }); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=nunit') + .reply(200, JSON.parse(pkgListV3WithoutProkjectUrl)); + httpMock + .scope('https://myprivatefeed') + .get('/index.json') + .reply(200, JSON.parse(nugetIndexV3)); const res = await nuget.getReleases({ ...configV3NotNugetOrg, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); expect(res.sourceUrl).not.toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data with no github project url (v3)', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(nugetIndexV3), - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: JSON.parse(pkgListV3NoGitHubProjectUrl), - statusCode: 200, - }); + httpMock + .scope('https://api-v2v3search-0.nuget.org') + .get('/query?q=nunit') + .reply(200, JSON.parse(pkgListV3NoGitHubProjectUrl)); + httpMock + .scope('https://myprivatefeed') + .get('/index.json') + .reply(200, JSON.parse(nugetIndexV3)); const res = await nuget.getReleases({ ...configV3NotNugetOrg, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data (v2)', async () => { - got.mockReturnValueOnce({ - body: pkgListV2, - statusCode: 200, - }); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(200, pkgListV2); const res = await nuget.getReleases({ ...configV2, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); expect(res.sourceUrl).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data no relase (v2)', async () => { - got.mockReturnValueOnce({ - body: pkgListV2NoRelease, - statusCode: 200, - }); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(200, pkgListV2NoRelease); const res = await nuget.getReleases({ ...configV2, }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data without project url (v2)', async () => { - got.mockReturnValueOnce({ - body: pkgListV2WithoutProjectUrl, - statusCode: 200, - }); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(200, pkgListV2WithoutProjectUrl); const res = await nuget.getReleases({ ...configV2, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); expect(res.sourceUrl).not.toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data with no github project url (v2)', async () => { - got.mockReturnValueOnce({ - body: pkgListV2NoGitHubProjectUrl, - statusCode: 200, - }); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(200, pkgListV2NoGitHubProjectUrl); const res = await nuget.getReleases({ ...configV2, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('handles paginated results (v2)', async () => { - got.mockReturnValueOnce({ - body: pkgListV2Page1of2, - statusCode: 200, - }); - got.mockReturnValueOnce({ - body: pkgListV2Page2of2, - statusCode: 200, - }); + httpMock + .scope('https://www.nuget.org') + .get( + '/api/v2//FindPackagesById()?id=%27nunit%27&$select=Version,IsLatestVersion,ProjectUrl' + ) + .reply(200, pkgListV2Page1of2); + httpMock + .scope('https://example.org') + .get('/') + .reply(200, pkgListV2Page2of2); const res = await nuget.getReleases({ ...configV2, }); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/orb/__snapshots__/index.spec.ts.snap b/lib/datasource/orb/__snapshots__/index.spec.ts.snap index 7451fb7e7d0fae..fd44a5442d8638 100644 --- a/lib/datasource/orb/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/orb/__snapshots__/index.spec.ts.snap @@ -50,6 +50,38 @@ Object { } `; +exports[`datasource/orb getReleases processes homeUrl 2`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "orb": Object { + "__args": Object { + "name": "hyper-expanse/library-release-workflows", + }, + "homeUrl": null, + "name": null, + "versions": Object { + "createdAt": null, + "version": null, + }, + }, + }, + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 128, + "content-type": "application/json", + "host": "circleci.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://circleci.com/graphql-unstable", + }, +] +`; + exports[`datasource/orb getReleases processes real data 1`] = ` Object { "homepage": "https://circleci.com/orbs/registry/orb/hyper-expanse/library-release-workflows", @@ -99,3 +131,163 @@ Object { "versions": Object {}, } `; + +exports[`datasource/orb getReleases processes real data 2`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "orb": Object { + "__args": Object { + "name": "hyper-expanse/library-release-workflows", + }, + "homeUrl": null, + "name": null, + "versions": Object { + "createdAt": null, + "version": null, + }, + }, + }, + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 128, + "content-type": "application/json", + "host": "circleci.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://circleci.com/graphql-unstable", + }, +] +`; + +exports[`datasource/orb getReleases returns null for 404 1`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "orb": Object { + "__args": Object { + "name": "hyper-expanse/library-release-workflows", + }, + "homeUrl": null, + "name": null, + "versions": Object { + "createdAt": null, + "version": null, + }, + }, + }, + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 128, + "content-type": "application/json", + "host": "circleci.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://circleci.com/graphql-unstable", + }, +] +`; + +exports[`datasource/orb getReleases returns null for empty result 1`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "orb": Object { + "__args": Object { + "name": "hyper-expanse/library-release-workflows", + }, + "homeUrl": null, + "name": null, + "versions": Object { + "createdAt": null, + "version": null, + }, + }, + }, + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 128, + "content-type": "application/json", + "host": "circleci.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://circleci.com/graphql-unstable", + }, +] +`; + +exports[`datasource/orb getReleases returns null for missing orb 1`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "orb": Object { + "__args": Object { + "name": "hyper-expanse/library-release-wonkflows", + }, + "homeUrl": null, + "name": null, + "versions": Object { + "createdAt": null, + "version": null, + }, + }, + }, + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 128, + "content-type": "application/json", + "host": "circleci.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://circleci.com/graphql-unstable", + }, +] +`; + +exports[`datasource/orb getReleases returns null for unknown error 1`] = ` +Array [ + Object { + "graphql": Object { + "query": Object { + "orb": Object { + "__args": Object { + "name": "hyper-expanse/library-release-workflows", + }, + "homeUrl": null, + "name": null, + "versions": Object { + "createdAt": null, + "version": null, + }, + }, + }, + }, + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "content-length": 128, + "content-type": "application/json", + "host": "circleci.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "POST", + "url": "https://circleci.com/graphql-unstable", + }, +] +`; diff --git a/lib/datasource/orb/index.spec.ts b/lib/datasource/orb/index.spec.ts index c4ff5447da465e..7e173785f1bbb8 100644 --- a/lib/datasource/orb/index.spec.ts +++ b/lib/datasource/orb/index.spec.ts @@ -1,10 +1,6 @@ -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import * as datasource from '.'; -jest.mock('../../util/got'); - -const got: any = _got; - const orbData = { data: { orb: { @@ -26,69 +22,76 @@ const orbData = { }, }; +const baseUrl = 'https://circleci.com'; + describe('datasource/orb', () => { describe('getReleases', () => { beforeEach(() => { jest.clearAllMocks(); + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); }); + it('returns null for empty result', async () => { - got.mockReturnValueOnce({ body: {} }); + httpMock.scope(baseUrl).post('/graphql-unstable').reply(200, {}); expect( await datasource.getReleases({ lookupName: 'hyper-expanse/library-release-workflows', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for missing orb', async () => { - got.mockReturnValueOnce({ body: { data: {} } }); + httpMock + .scope(baseUrl) + .post('/graphql-unstable') + .reply(200, { data: {} }); expect( await datasource.getReleases({ lookupName: 'hyper-expanse/library-release-wonkflows', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock.scope(baseUrl).post('/graphql-unstable').reply(404); expect( await datasource.getReleases({ lookupName: 'hyper-expanse/library-release-workflows', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock.scope(baseUrl).post('/graphql-unstable').replyWithError(''); expect( await datasource.getReleases({ lookupName: 'hyper-expanse/library-release-workflows', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data', async () => { - got.mockReturnValueOnce({ - body: orbData, - }); + httpMock.scope(baseUrl).post('/graphql-unstable').reply(200, orbData); const res = await datasource.getReleases({ lookupName: 'hyper-expanse/library-release-workflows', }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes homeUrl', async () => { orbData.data.orb.homeUrl = 'https://google.com'; - got.mockReturnValueOnce({ - body: orbData, - }); + httpMock.scope(baseUrl).post('/graphql-unstable').reply(200, orbData); const res = await datasource.getReleases({ lookupName: 'hyper-expanse/library-release-workflows', }); expect(res).toMatchSnapshot(); expect(res.homepage).toEqual('https://google.com'); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/packagist/__snapshots__/index.spec.ts.snap b/lib/datasource/packagist/__snapshots__/index.spec.ts.snap index fa9942fe84446c..fd5e7a8af7b5f0 100644 --- a/lib/datasource/packagist/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/packagist/__snapshots__/index.spec.ts.snap @@ -100,6 +100,156 @@ Object { } `; +exports[`datasource/packagist getReleases adds packagist source implicitly 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "packagist.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://packagist.org/p/drewm/mailchimp-api.json", + }, +] +`; + +exports[`datasource/packagist getReleases handles auth rejections 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "packagist.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://packagist.org/p/vendor/package-name.json", + }, +] +`; + +exports[`datasource/packagist getReleases handles not found registries 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "packagist.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://packagist.org/p/drewm/mailchip-api.json", + }, +] +`; + +exports[`datasource/packagist getReleases handles provider-includes miss 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/p/providers-2018-09$14346045d7a7261cb3a12a6b7a1a7c4151982530347b115e5e277d879cad1942.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "packagist.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://packagist.org/p/some/other.json", + }, +] +`; + +exports[`datasource/packagist getReleases handles providers miss 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "packagist.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://packagist.org/p/some/other.json", + }, +] +`; + +exports[`datasource/packagist getReleases handles timeouts 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "packagist.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://packagist.org/p/vendor/package-name2.json", + }, +] +`; + exports[`datasource/packagist getReleases processes real versioned data 1`] = ` Object { "homepage": "https://github.com/drewm/mailchimp-api", @@ -200,6 +350,21 @@ Object { } `; +exports[`datasource/packagist getReleases processes real versioned data 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "packagist.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://packagist.org/p/drewm/mailchimp-api.json", + }, +] +`; + exports[`datasource/packagist getReleases supports includes packages 1`] = ` Object { "homepage": "http://guzzlephp.org/", @@ -345,6 +510,33 @@ Object { } `; +exports[`datasource/packagist getReleases supports includes packages 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic c29tZS11c2VybmFtZTpzb21lLXBhc3N3b3Jk", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "authorization": "Basic c29tZS11c2VybmFtZTpzb21lLXBhc3N3b3Jk", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/include/all$afbf74d51f31c7cbb5ff10304f9290bfb4f4e68b.json", + }, +] +`; + exports[`datasource/packagist getReleases supports plain packages 1`] = ` Object { "homepage": undefined, @@ -374,6 +566,21 @@ Object { } `; +exports[`datasource/packagist getReleases supports plain packages 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, +] +`; + exports[`datasource/packagist getReleases supports provider-includes 1`] = ` Object { "homepage": "https://wordpress.org/plugins/1beyt/", @@ -414,6 +621,41 @@ Object { } `; +exports[`datasource/packagist getReleases supports provider-includes 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/p/providers-2018-09$14346045d7a7261cb3a12a6b7a1a7c4151982530347b115e5e277d879cad1942.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/p/wpackagist-plugin/1beyt$b574a802b5bf20a58c0f027e73aea2a75d23a6f654afc298a8dc467331be316a.json", + }, +] +`; + exports[`datasource/packagist getReleases supports providers 1`] = ` Object { "homepage": "https://wordpress.org/plugins/1beyt/", @@ -453,3 +695,28 @@ Object { "sourceUrl": "https://plugins.svn.wordpress.org/1beyt/", } `; + +exports[`datasource/packagist getReleases supports providers 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/packages.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "composer.renovatebot.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://composer.renovatebot.com/p/wpackagist-plugin/1beyt$b574a802b5bf20a58c0f027e73aea2a75d23a6f654afc298a8dc467331be316a.json", + }, +] +`; diff --git a/lib/datasource/packagist/index.spec.ts b/lib/datasource/packagist/index.spec.ts index 3fedf59cf19253..a1cef7d2c1194f 100644 --- a/lib/datasource/packagist/index.spec.ts +++ b/lib/datasource/packagist/index.spec.ts @@ -1,13 +1,11 @@ import fs from 'fs'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import * as _hostRules from '../../util/host-rules'; import * as composerVersioning from '../../versioning/composer'; import * as packagist from '.'; -jest.mock('../../util/got'); jest.mock('../../util/host-rules'); -const got: any = _got; const hostRules = _hostRules; const includesJson: any = fs.readFileSync( @@ -20,11 +18,14 @@ const mailchimpJson: any = fs.readFileSync( 'lib/datasource/packagist/__fixtures__/mailchimp-api.json' ); +const baseUrl = 'https://packagist.org'; + describe('datasource/packagist', () => { describe('getReleases', () => { let config: any; beforeEach(() => { jest.resetAllMocks(); + httpMock.setup(); hostRules.find = jest.fn((input) => input); hostRules.hosts = jest.fn(() => []); config = { @@ -35,6 +36,11 @@ describe('datasource/packagist', () => { ], }; }); + + afterEach(() => { + httpMock.reset(); + }); + it('supports custom registries', async () => { config = { registryUrls: ['https://composer.renovatebot.com'], @@ -56,51 +62,55 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: packagesOnly, - }); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(200, packagesOnly); const res = await packagist.getReleases({ ...config, lookupName: 'vendor/package-name', }); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('handles timeouts', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - code: 'ETIMEDOUT', - }) - ); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .replyWithError({ code: 'ETIMEDOUT' }); + httpMock.scope(baseUrl).get('/p/vendor/package-name2.json').reply(200); const res = await packagist.getReleases({ ...config, lookupName: 'vendor/package-name2', }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('handles auth rejections', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 403, - }) - ); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(403); + httpMock.scope(baseUrl).get('/p/vendor/package-name.json').reply(200); const res = await packagist.getReleases({ ...config, lookupName: 'vendor/package-name', }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('handles not found registries', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - url: 'https://some.registry/packages.json', - }) - ); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(404); + httpMock.scope(baseUrl).get('/p/drewm/mailchip-api.json').reply(200); const res = await packagist.getReleases({ ...config, lookupName: 'drewm/mailchip-api', }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('supports includes packages', async () => { hostRules.find = jest.fn(() => ({ @@ -115,18 +125,19 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: packagesJson, - }); - got.mockReturnValueOnce({ - body: JSON.parse(includesJson), - }); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(200, packagesJson) + .get('/include/all$afbf74d51f31c7cbb5ff10304f9290bfb4f4e68b.json') + .reply(200, JSON.parse(includesJson)); const res = await packagist.getReleases({ ...config, lookupName: 'guzzlehttp/guzzle', }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('supports provider-includes', async () => { const packagesJson = { @@ -139,9 +150,6 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: packagesJson, - }); const fileJson = { providers: { 'wpackagist-plugin/1337-rss-feed-made-for-sharing': { @@ -154,18 +162,25 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: fileJson, - }); - got.mockReturnValueOnce({ - body: JSON.parse(beytJson), - }); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(200, packagesJson) + .get( + '/p/providers-2018-09$14346045d7a7261cb3a12a6b7a1a7c4151982530347b115e5e277d879cad1942.json' + ) + .reply(200, fileJson) + .get( + '/p/wpackagist-plugin/1beyt$b574a802b5bf20a58c0f027e73aea2a75d23a6f654afc298a8dc467331be316a.json' + ) + .reply(200, JSON.parse(beytJson)); const res = await packagist.getReleases({ ...config, lookupName: 'wpackagist-plugin/1beyt', }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('handles provider-includes miss', async () => { const packagesJson = { @@ -178,9 +193,6 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: packagesJson, - }); const fileJson = { providers: { 'wpackagist-plugin/1337-rss-feed-made-for-sharing': { @@ -193,17 +205,24 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: fileJson, - }); - got.mockReturnValueOnce({ - body: JSON.parse(beytJson), - }); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(200, packagesJson) + .get( + '/p/providers-2018-09$14346045d7a7261cb3a12a6b7a1a7c4151982530347b115e5e277d879cad1942.json' + ) + .reply(200, fileJson); + httpMock + .scope(baseUrl) + .get('/p/some/other.json') + .reply(200, JSON.parse(beytJson)); const res = await packagist.getReleases({ ...config, lookupName: 'some/other', }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('supports providers', async () => { const packagesJson = { @@ -220,18 +239,21 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: packagesJson, - }); - got.mockReturnValueOnce({ - body: JSON.parse(beytJson), - }); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(200, packagesJson) + .get( + '/p/wpackagist-plugin/1beyt$b574a802b5bf20a58c0f027e73aea2a75d23a6f654afc298a8dc467331be316a.json' + ) + .reply(200, JSON.parse(beytJson)); const res = await packagist.getReleases({ ...config, lookupName: 'wpackagist-plugin/1beyt', }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('handles providers miss', async () => { const packagesJson = { @@ -248,22 +270,26 @@ describe('datasource/packagist', () => { }, }, }; - got.mockReturnValueOnce({ - body: packagesJson, - }); - got.mockReturnValueOnce({ - body: JSON.parse(beytJson), - }); + httpMock + .scope('https://composer.renovatebot.com') + .get('/packages.json') + .reply(200, packagesJson); + httpMock + .scope(baseUrl) + .get('/p/some/other.json') + .reply(200, JSON.parse(beytJson)); const res = await packagist.getReleases({ ...config, lookupName: 'some/other', }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real versioned data', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(mailchimpJson), - }); + httpMock + .scope(baseUrl) + .get('/p/drewm/mailchimp-api.json') + .reply(200, JSON.parse(mailchimpJson)); config.registryUrls = ['https://packagist.org']; expect( await packagist.getReleases({ @@ -271,11 +297,13 @@ describe('datasource/packagist', () => { lookupName: 'drewm/mailchimp-api', }) ).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('adds packagist source implicitly', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(mailchimpJson), - }); + httpMock + .scope(baseUrl) + .get('/p/drewm/mailchimp-api.json') + .reply(200, JSON.parse(mailchimpJson)); config.registryUrls = []; expect( await packagist.getReleases({ @@ -283,6 +311,7 @@ describe('datasource/packagist', () => { lookupName: 'drewm/mailchimp-api', }) ).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/ruby-version/__snapshots__/index.spec.ts.snap b/lib/datasource/ruby-version/__snapshots__/index.spec.ts.snap index bb2ef169b30c17..4ee2d66c0cf8e2 100644 --- a/lib/datasource/ruby-version/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/ruby-version/__snapshots__/index.spec.ts.snap @@ -673,3 +673,45 @@ Object { "sourceUrl": "https://github.com/ruby/ruby", } `; + +exports[`datasource/gradle getReleases parses real data 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.ruby-lang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.ruby-lang.org/en/downloads/releases/", + }, +] +`; + +exports[`datasource/gradle getReleases throws for 404 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.ruby-lang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.ruby-lang.org/en/downloads/releases/", + }, +] +`; + +exports[`datasource/gradle getReleases throws for empty result 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate", + "host": "www.ruby-lang.org", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://www.ruby-lang.org/en/downloads/releases/", + }, +] +`; diff --git a/lib/datasource/ruby-version/index.spec.ts b/lib/datasource/ruby-version/index.spec.ts index d4bc65e185010f..5d69dfc9e5cbed 100644 --- a/lib/datasource/ruby-version/index.spec.ts +++ b/lib/datasource/ruby-version/index.spec.ts @@ -1,11 +1,7 @@ import fs from 'fs'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import { getReleases } from '.'; -jest.mock('../../util/got'); - -const got: any = _got; - const rubyReleasesHtml = fs.readFileSync( 'lib/datasource/ruby-version/__fixtures__/releases.html', 'utf8' @@ -13,25 +9,39 @@ const rubyReleasesHtml = fs.readFileSync( describe('datasource/gradle', () => { describe('getReleases', () => { + beforeEach(() => { + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); + }); + it('parses real data', async () => { - got.mockReturnValueOnce({ - body: rubyReleasesHtml, - }); + httpMock + .scope('https://www.ruby-lang.org') + .get('/en/downloads/releases/') + .reply(200, rubyReleasesHtml); const res = await getReleases(); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws for empty result', async () => { - got.mockReturnValueOnce({ body: {} }); + httpMock + .scope('https://www.ruby-lang.org') + .get('/en/downloads/releases/') + .reply(200, {}); await expect(getReleases()).rejects.toThrow(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('throws for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock + .scope('https://www.ruby-lang.org') + .get('/en/downloads/releases/') + .reply(404); await expect(getReleases()).rejects.toThrow(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/rubygems/__snapshots__/index.spec.ts.snap b/lib/datasource/rubygems/__snapshots__/index.spec.ts.snap index 3b5d1d791fe1c0..6a0bf0c46c1744 100644 --- a/lib/datasource/rubygems/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/rubygems/__snapshots__/index.spec.ts.snap @@ -14,6 +14,90 @@ Object { } `; +exports[`datasource/rubygems getReleases returns a dep for rubygems.org package hit 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "identity", + "host": "rubygems.org", + "range": "bytes=0-", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://rubygems.org/versions", + }, +] +`; + +exports[`datasource/rubygems getReleases returns null for missing pkg 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "thirdparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://thirdparty.com/api/v1/gems/rails.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "firstparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://firstparty.com/api/v1/gems/rails.json", + }, +] +`; + +exports[`datasource/rubygems getReleases returns null for rubygems.org package miss 1`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "identity", + "host": "rubygems.org", + "range": "bytes=0-", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://rubygems.org/versions", + }, +] +`; + +exports[`datasource/rubygems getReleases returns null if mismatched name 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "thirdparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://thirdparty.com/api/v1/gems/rails.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "firstparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://firstparty.com/api/v1/gems/rails.json", + }, +] +`; + exports[`datasource/rubygems getReleases uses multiple source urls 1`] = ` Object { "homepage": "http://rubyonrails.org", @@ -2396,6 +2480,44 @@ Object { } `; +exports[`datasource/rubygems getReleases uses multiple source urls 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "thirdparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://thirdparty.com/api/v1/gems/rails.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "firstparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://firstparty.com/api/v1/gems/rails.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "firstparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://firstparty.com/api/v1/versions/rails.json", + }, +] +`; + exports[`datasource/rubygems getReleases uses rubygems.org if no registry urls were provided 1`] = ` Object { "name": "1pass", @@ -2410,6 +2532,21 @@ Object { } `; +exports[`datasource/rubygems getReleases uses rubygems.org if no registry urls were provided 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "identity", + "host": "rubygems.org", + "range": "bytes=0-", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://rubygems.org/versions", + }, +] +`; + exports[`datasource/rubygems getReleases works with real data 1`] = ` Object { "homepage": "http://rubyonrails.org", @@ -4791,3 +4928,30 @@ Object { "sourceUrl": "https://github.com/rails/rails", } `; + +exports[`datasource/rubygems getReleases works with real data 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "thirdparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://thirdparty.com/api/v1/gems/rails.json", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "thirdparty.com", + "hosttype": "rubygems", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://thirdparty.com/api/v1/versions/rails.json", + }, +] +`; diff --git a/lib/datasource/rubygems/get-rubygems-org.ts b/lib/datasource/rubygems/get-rubygems-org.ts index 1ac4f4088d9424..3eb01a4ed97a88 100644 --- a/lib/datasource/rubygems/get-rubygems-org.ts +++ b/lib/datasource/rubygems/get-rubygems-org.ts @@ -9,6 +9,13 @@ let lastSync = new Date('2000-01-01'); let packageReleases: Record = Object.create(null); // Because we might need a "constructor" key let contentLength = 0; +// Note: use only for tests +export function resetCache(): void { + lastSync = new Date('2000-01-01'); + packageReleases = Object.create(null); + contentLength = 0; +} + /* https://bugs.chromium.org/p/v8/issues/detail?id=2869 */ const copystr = (x: string): string => (' ' + x).slice(1); diff --git a/lib/datasource/rubygems/index.spec.ts b/lib/datasource/rubygems/index.spec.ts index 151b3acd10f707..593ac0d4eb90f0 100644 --- a/lib/datasource/rubygems/index.spec.ts +++ b/lib/datasource/rubygems/index.spec.ts @@ -1,12 +1,11 @@ import { getPkgReleases } from '..'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import * as rubyVersioning from '../../versioning/ruby'; import railsInfo from './__fixtures__/rails/info.json'; import railsVersions from './__fixtures__/rails/versions.json'; +import { resetCache } from './get-rubygems-org'; import * as rubygems from '.'; -const got: any = _got; - const rubygemsOrgVersions = `created_at: 2017-03-27T04:38:13+00:00 --- - 1 05d0116933ba44b0b5d0ee19bfd35ccc @@ -26,8 +25,6 @@ const rubygemsOrgVersions = `created_at: 2017-03-27T04:38:13+00:00 1pass -0.1.2 abcdef 21-day-challenge-countdown 0.1.0,0.1.1,0.1.2 57e8873fe713063f4e54e85bbbd709bb`; -jest.mock('../../util/got'); - describe('datasource/rubygems', () => { describe('getReleases', () => { const SKIP_CACHE = process.env.RENOVATE_SKIP_CACHE; @@ -40,24 +37,40 @@ describe('datasource/rubygems', () => { }; beforeEach(() => { + resetCache(); + httpMock.setup(); process.env.RENOVATE_SKIP_CACHE = 'true'; jest.resetAllMocks(); }); afterEach(() => { + httpMock.reset(); process.env.RENOVATE_SKIP_CACHE = SKIP_CACHE; }); it('returns null for missing pkg', async () => { - got.mockReturnValueOnce({}); + httpMock + .scope('https://firstparty.com') + .get('/api/v1/gems/rails.json') + .reply(200, null); + httpMock + .scope('https://thirdparty.com') + .get('/api/v1/gems/rails.json') + .reply(200, null); expect(await getPkgReleases(params)).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for rubygems.org package miss', async () => { const newparams = { ...params }; newparams.registryUrls = []; - got.mockReturnValueOnce({ body: rubygemsOrgVersions }); - expect(await getPkgReleases(newparams)).toBeNull(); + httpMock + .scope('https://rubygems.org') + .get('/versions') + .reply(200, rubygemsOrgVersions); + const res = await getPkgReleases(newparams); + expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns a dep for rubygems.org package hit', async () => { @@ -66,7 +79,10 @@ describe('datasource/rubygems', () => { lookupName: '1pass', registryUrls: [], }; - got.mockReturnValueOnce({ body: rubygemsOrgVersions }); + httpMock + .scope('https://rubygems.org') + .get('/versions') + .reply(200, rubygemsOrgVersions); const res = await getPkgReleases(newparams); expect(res).not.toBeNull(); expect(res.releases).toHaveLength(2); @@ -77,10 +93,14 @@ describe('datasource/rubygems', () => { expect( res.releases.find((release) => release.version === '0.1.2') ).toBeUndefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('uses rubygems.org if no registry urls were provided', async () => { - got.mockReturnValue({ body: rubygemsOrgVersions }); + httpMock + .scope('https://rubygems.org') + .get('/versions') + .reply(200, rubygemsOrgVersions); expect( await getPkgReleases({ @@ -97,36 +117,52 @@ describe('datasource/rubygems', () => { expect(res).not.toBeNull(); expect(res.releases).toHaveLength(2); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('works with real data', async () => { - got - .mockReturnValueOnce({ body: railsInfo }) - .mockReturnValueOnce({ body: railsVersions }); + httpMock + .scope('https://thirdparty.com/') + .get('/api/v1/gems/rails.json') + .reply(200, railsInfo) + .get('/api/v1/versions/rails.json') + .reply(200, railsVersions); const res = await getPkgReleases(params); expect(res.releases).toHaveLength(339); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('uses multiple source urls', async () => { - got - .mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ) - .mockImplementationOnce(() => ({ body: railsInfo })) - .mockImplementationOnce(() => ({ body: railsVersions })); + httpMock + .scope('https://thirdparty.com/') + .get('/api/v1/gems/rails.json') + .reply(401); + httpMock + .scope('https://firstparty.com/') + .get('/api/v1/gems/rails.json') + .reply(200, railsInfo) + .get('/api/v1/versions/rails.json') + .reply(200, railsVersions); const res = await getPkgReleases(params); expect(res.releases).toHaveLength(339); expect(res).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null if mismatched name', async () => { - got.mockReturnValueOnce({ body: { ...railsInfo, name: 'oooops' } }); + httpMock + .scope('https://thirdparty.com/') + .get('/api/v1/gems/rails.json') + .reply(200, { ...railsInfo, name: 'oooops' }); + httpMock + .scope('https://firstparty.com/') + .get('/api/v1/gems/rails.json') + .reply(200, null); expect(await getPkgReleases(params)).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/terraform-module/__snapshots__/index.spec.ts.snap b/lib/datasource/terraform-module/__snapshots__/index.spec.ts.snap index 532181a5425acd..f325481abea80d 100644 --- a/lib/datasource/terraform-module/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/terraform-module/__snapshots__/index.spec.ts.snap @@ -80,6 +80,21 @@ Object { } `; +exports[`datasource/terraform-module getReleases processes real data 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/modules/hashicorp/consul/aws", + }, +] +`; + exports[`datasource/terraform-module getReleases processes with registry in name 1`] = ` Object { "homepage": "https://registry.terraform.io/modules/hashicorp/consul/aws", @@ -159,3 +174,78 @@ Object { "versions": Object {}, } `; + +exports[`datasource/terraform-module getReleases processes with registry in name 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/modules/hashicorp/consul/aws", + }, +] +`; + +exports[`datasource/terraform-module getReleases rejects mismatch 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "terraform.company.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://terraform.company.com/v1/modules/consul/foo", + }, +] +`; + +exports[`datasource/terraform-module getReleases returns null for 404 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/modules/hashicorp/consul/aws", + }, +] +`; + +exports[`datasource/terraform-module getReleases returns null for empty result 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/modules/hashicorp/consul/aws", + }, +] +`; + +exports[`datasource/terraform-module getReleases returns null for unknown error 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/modules/hashicorp/consul/aws", + }, +] +`; diff --git a/lib/datasource/terraform-module/index.spec.ts b/lib/datasource/terraform-module/index.spec.ts index f6c342eb1b2bca..4d9b4db72d9a2a 100644 --- a/lib/datasource/terraform-module/index.spec.ts +++ b/lib/datasource/terraform-module/index.spec.ts @@ -1,79 +1,95 @@ import fs from 'fs'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import * as terraform from '.'; -jest.mock('../../util/got'); - -const got: any = _got; - const consulData: any = fs.readFileSync( 'lib/datasource/terraform-module/__fixtures__/registry-consul.json' ); +const baseUrl = 'https://registry.terraform.io'; + describe('datasource/terraform-module', () => { describe('getReleases', () => { beforeEach(() => { jest.clearAllMocks(); + httpMock.setup(); }); + + afterEach(() => { + httpMock.reset(); + }); + it('returns null for empty result', async () => { - got.mockReturnValueOnce({ body: {} }); + httpMock + .scope(baseUrl) + .get('/v1/modules/hashicorp/consul/aws') + .reply(200, {}); expect( await terraform.getReleases({ lookupName: 'hashicorp/consul/aws', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock + .scope(baseUrl) + .get('/v1/modules/hashicorp/consul/aws') + .reply(404, {}); expect( await terraform.getReleases({ lookupName: 'hashicorp/consul/aws', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock + .scope(baseUrl) + .get('/v1/modules/hashicorp/consul/aws') + .replyWithError(''); expect( await terraform.getReleases({ lookupName: 'hashicorp/consul/aws', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(consulData), - }); + httpMock + .scope(baseUrl) + .get('/v1/modules/hashicorp/consul/aws') + .reply(200, consulData); const res = await terraform.getReleases({ lookupName: 'hashicorp/consul/aws', }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes with registry in name', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(consulData), - }); + httpMock + .scope(baseUrl) + .get('/v1/modules/hashicorp/consul/aws') + .reply(200, consulData); const res = await terraform.getReleases({ lookupName: 'registry.terraform.io/hashicorp/consul/aws', }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('rejects mismatch', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(consulData), - }); + httpMock + .scope('https://terraform.company.com') + .get('/v1/modules/consul/foo') + .reply(200, consulData); const res = await terraform.getReleases({ lookupName: 'consul/foo', registryUrls: ['https://terraform.company.com'], }); expect(res).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap b/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap index c1eed711879019..d52991debb8f1f 100644 --- a/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/terraform-provider/__snapshots__/index.spec.ts.snap @@ -205,3 +205,63 @@ Object { "versions": Object {}, } `; + +exports[`datasource/terraform getReleases processes real data 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/providers/hashicorp/azurerm", + }, +] +`; + +exports[`datasource/terraform getReleases returns null for 404 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/providers/hashicorp/azurerm", + }, +] +`; + +exports[`datasource/terraform getReleases returns null for empty result 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/providers/hashicorp/azurerm", + }, +] +`; + +exports[`datasource/terraform getReleases returns null for unknown error 1`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate", + "host": "registry.terraform.io", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://registry.terraform.io/v1/providers/hashicorp/azurerm", + }, +] +`; diff --git a/lib/datasource/terraform-provider/index.spec.ts b/lib/datasource/terraform-provider/index.spec.ts index 6eb64b723f9162..f730f0de25340b 100644 --- a/lib/datasource/terraform-provider/index.spec.ts +++ b/lib/datasource/terraform-provider/index.spec.ts @@ -1,59 +1,68 @@ import fs from 'fs'; -import _got from '../../util/got'; +import * as httpMock from '../../../test/httpMock'; import * as terraformProvider from '.'; -jest.mock('../../util/got'); - -const got: any = _got; - const consulData: any = fs.readFileSync( 'lib/datasource/terraform-provider/__fixtures__/azurerm-provider.json' ); +const baseUrl = 'https://registry.terraform.io/'; + describe('datasource/terraform', () => { describe('getReleases', () => { beforeEach(() => { jest.clearAllMocks(); + httpMock.setup(); + }); + + afterEach(() => { + httpMock.reset(); }); + it('returns null for empty result', async () => { - got.mockReturnValueOnce({ body: {} }); + httpMock + .scope(baseUrl) + .get('/v1/providers/hashicorp/azurerm') + .reply(200, {}); expect( await terraformProvider.getReleases({ lookupName: 'azurerm', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for 404', async () => { - got.mockImplementationOnce(() => - Promise.reject({ - statusCode: 404, - }) - ); + httpMock.scope(baseUrl).get('/v1/providers/hashicorp/azurerm').reply(404); expect( await terraformProvider.getReleases({ lookupName: 'azurerm', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('returns null for unknown error', async () => { - got.mockImplementationOnce(() => { - throw new Error(); - }); + httpMock + .scope(baseUrl) + .get('/v1/providers/hashicorp/azurerm') + .replyWithError(''); expect( await terraformProvider.getReleases({ lookupName: 'azurerm', }) ).toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); it('processes real data', async () => { - got.mockReturnValueOnce({ - body: JSON.parse(consulData), - }); + httpMock + .scope(baseUrl) + .get('/v1/providers/hashicorp/azurerm') + .reply(200, JSON.parse(consulData)); const res = await terraformProvider.getReleases({ lookupName: 'azurerm', }); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); + expect(httpMock.getTrace()).toMatchSnapshot(); }); }); }); diff --git a/lib/platform/bitbucket-server/index.spec.ts b/lib/platform/bitbucket-server/index.spec.ts index 090ed692ba7e4e..5a824b49d9bd9a 100644 --- a/lib/platform/bitbucket-server/index.spec.ts +++ b/lib/platform/bitbucket-server/index.spec.ts @@ -975,7 +975,6 @@ describe('platform/bitbucket-server', () => { topic: null, content: '!merge', }); - httpMock.getTrace(); expect(res).toBe(true); expect(httpMock.getTrace()).toMatchSnapshot(); }); diff --git a/lib/platform/bitbucket/comments.spec.ts b/lib/platform/bitbucket/comments.spec.ts index 7299f9eb58ba3a..79914fd15a2bcb 100644 --- a/lib/platform/bitbucket/comments.spec.ts +++ b/lib/platform/bitbucket/comments.spec.ts @@ -75,7 +75,6 @@ describe('platform/comments', () => { topic: 'some-subject', content: 'some\ncontent', }); - httpMock.getTrace(); expect(res).toBe(true); expect(httpMock.getTrace()).toMatchSnapshot(); }); diff --git a/lib/util/http/gitea.spec.ts b/lib/util/http/gitea.spec.ts index bb5ecd2d3c5a82..47de55353a5e8f 100644 --- a/lib/util/http/gitea.spec.ts +++ b/lib/util/http/gitea.spec.ts @@ -44,7 +44,6 @@ describe(getName(__filename), () => { const res = await giteaHttp.getJson(`${baseUrl}/pagination-example-1`, { paginate: true, }); - httpMock.getTrace(); expect(res.body).toHaveLength(6); expect(res.body).toEqual(['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr']); diff --git a/lib/workers/pr/changelog/release-notes.spec.ts b/lib/workers/pr/changelog/release-notes.spec.ts index 6221246ebd5837..484773d0c83353 100644 --- a/lib/workers/pr/changelog/release-notes.spec.ts +++ b/lib/workers/pr/changelog/release-notes.spec.ts @@ -298,7 +298,6 @@ describe('workers/pr/release-notes', () => { 'https://gitlab.com/', 'https://api.gitlab.com/' ); - httpMock.getTrace(); expect(res).not.toBeNull(); expect(res).toMatchSnapshot(); expect(httpMock.getTrace()).toMatchSnapshot();