diff --git a/lib/datasource/nuget/__fixtures__/nunitV3_privateFeed.json b/lib/datasource/nuget/__fixtures__/nunitV3_privateFeed.json new file mode 100644 index 0000000000000000000000000000000000000000..2b772054a7f1737dd2b779af978a4538e5554505 --- /dev/null +++ b/lib/datasource/nuget/__fixtures__/nunitV3_privateFeed.json @@ -0,0 +1,51 @@ +{ + "@context": { + "@vocab": "http://schema.nuget.org/schema#", + "@base": "https://api.nuget.org/v3/registration3/" + }, + "totalHits": 1, + "lastReopen": "2019-02-04T10:47:54.6449537Z", + "index": "v3-lucene2-v2v3-20171018", + "data": [ + { + "@id": "https://api.nuget.org/v3/registration3/nunit/index.json", + "@type": "Package", + "registration": "https://api.nuget.org/v3/registration3/nunit/index.json", + "id": "NUnit", + "version": "3.11.0", + "description": "NUnit features a fluent assert syntax, parameterized, generic and theory tests and is user-extensible.\n\nThis package includes the NUnit 3 framework assembly, which is referenced by your tests. You will need to install version 3 of the nunit3-console program or a third-party runner that supports NUnit 3 in order to execute tests. Runners intended for use with NUnit 2.x will not run NUnit 3 tests correctly.\n\nSupported platforms:\n- .NET Framework 2.0+\n- .NET Standard 1.4+\n- .NET Core", + "summary": "NUnit is a unit-testing framework for all .NET languages with a strong TDD focus.", + "title": "NUnit", + "iconUrl": "https://cdn.rawgit.com/nunit/resources/master/images/icon/nunit_256.png", + "licenseUrl": "https://raw.githubusercontent.com/nunit/nunit/master/LICENSE.txt", + "projectUrl": "https://github.com/nunit/nunit", + "tags": [ + "nunit", + "test", + "testing", + "tdd", + "framework", + "fluent", + "assert", + "theory", + "plugin", + "addin" + ], + "authors": ["Charlie Poole, Rob Prouse"], + "totalDownloads": 34513003, + "verified": true, + "versions": [ + { + "version": "3.11.0", + "downloads": 3857714, + "@id": "https://myprivatefeed/registration3/nunit/3.10.1.json" + }, + { + "version": "3.12.0", + "downloads": 1284682, + "@id": "https://myprivatefeed/registration3/nunit/3.11.0.json" + } + ] + } + ] +} diff --git a/lib/datasource/nuget/__snapshots__/index.spec.ts.snap b/lib/datasource/nuget/__snapshots__/index.spec.ts.snap index 1b704b89b246ff359ea5074bf7cf72281449dc86..ff43c28a2fddd7fb6f1f533303078b7d36640dd5 100644 --- a/lib/datasource/nuget/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/nuget/__snapshots__/index.spec.ts.snap @@ -599,3 +599,102 @@ Object { ], } `; + +exports[`datasource/nuget getReleases returns deduplicated results 1`] = ` +Object { + "pkgName": "nunit", + "releases": Array [ + Object { + "version": "2.5.7.10213", + }, + Object { + "version": "2.5.9.10348", + }, + Object { + "version": "2.5.10.11092", + }, + Object { + "version": "2.6.0.12054", + }, + Object { + "version": "2.6.1", + }, + Object { + "version": "2.6.2", + }, + Object { + "version": "2.6.3", + }, + Object { + "version": "2.6.4", + }, + Object { + "version": "2.6.5", + }, + Object { + "version": "2.6.6", + }, + Object { + "version": "2.6.7", + }, + Object { + "version": "2.7.0", + }, + Object { + "version": "3.0.0", + }, + Object { + "version": "3.0.1", + }, + Object { + "version": "3.2.0", + }, + Object { + "version": "3.2.1", + }, + Object { + "version": "3.4.0", + }, + Object { + "version": "3.4.1", + }, + Object { + "version": "3.5.0", + }, + Object { + "version": "3.6.0", + }, + Object { + "version": "3.6.1", + }, + Object { + "version": "3.7.0", + }, + Object { + "version": "3.7.1", + }, + Object { + "version": "3.8.0", + }, + Object { + "version": "3.8.1", + }, + Object { + "version": "3.9.0", + }, + Object { + "version": "3.10.0", + }, + Object { + "version": "3.10.1", + }, + Object { + "version": "3.11.0", + }, + Object { + "version": "3.12.0", + }, + ], + "sourceUrl": "https://github.com/nunit/nunit", +} +`; diff --git a/lib/datasource/nuget/index.spec.ts b/lib/datasource/nuget/index.spec.ts index 811f49e3642d70dd4b02259a12ebd83de734449a..99846bb60e24c0db11d5d1bb76a74c31c475a469 100644 --- a/lib/datasource/nuget/index.spec.ts +++ b/lib/datasource/nuget/index.spec.ts @@ -24,6 +24,10 @@ const pkgListV3NoGitHubProjectUrl = fs.readFileSync( 'lib/datasource/nuget/__fixtures__/nunitV3_noGitHubProjectUrl.json', 'utf8' ); +const pkgListV3PrivateFeed = fs.readFileSync( + 'lib/datasource/nuget/__fixtures__/nunitV3_privateFeed.json', + 'utf8' +); const pkgInfoV3FromNuget = fs.readFileSync( 'lib/datasource/nuget/__fixtures__/nunitv3_nuget-org.xml', 'utf8' @@ -83,6 +87,14 @@ const configV3NotNugetOrg = { registryUrls: ['https://myprivatefeed/index.json'], }; +const configV3Multiple = { + lookupName: 'nunit', + registryUrls: [ + 'https://api.nuget.org/v3/index.json', + 'https://myprivatefeed/index.json', + ], +}; + describe('datasource/nuget', () => { beforeEach(() => { runCache.clear(); @@ -220,6 +232,39 @@ describe('datasource/nuget', () => { }) ).toBeNull(); }); + 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, + }); + const res = await nuget.getReleases({ + ...configV3Multiple, + }); + expect(res).not.toBeNull(); + expect(res).toMatchSnapshot(); + expect(res.releases).toHaveLength(30); + }); it('returns null for unknown error in getReleasesFromV3Feed (v3)', async () => { got.mockImplementationOnce(() => { throw new Error(); diff --git a/lib/datasource/nuget/index.ts b/lib/datasource/nuget/index.ts index eff8c665a1c27a53015ab175d1c2a2e11b0eb413..32638925752d99f146b1779a7d58ea7febcc646f 100644 --- a/lib/datasource/nuget/index.ts +++ b/lib/datasource/nuget/index.ts @@ -1,4 +1,5 @@ import urlApi from 'url'; +import uniqBy from 'lodash/uniqBy'; import { logger } from '../../logger'; import { GetReleasesConfig, ReleaseResult } from '../common'; import * as v2 from './v2'; @@ -37,16 +38,21 @@ export async function getReleases({ let dep: ReleaseResult = null; for (const feed of registryUrls) { const { feedUrl, protocolVersion } = parseRegistryUrl(feed); + let res: ReleaseResult = null; if (protocolVersion === 2) { - dep = await v2.getReleases(feedUrl, lookupName); + res = await v2.getReleases(feedUrl, lookupName); } else if (protocolVersion === 3) { const queryUrl = await v3.getQueryUrl(feedUrl); if (queryUrl !== null) { - dep = await v3.getReleases(feedUrl, queryUrl, lookupName); + res = await v3.getReleases(feedUrl, queryUrl, lookupName); } } - if (dep != null) { - break; + if (res !== null) { + if (dep !== null) { + dep.releases = uniqBy(dep.releases.concat(res.releases), 'version'); + } else { + dep = res; + } } } if (dep === null) {