mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-15 09:06:25 +00:00
347 lines
10 KiB
TypeScript
347 lines
10 KiB
TypeScript
import { getPkgReleases } from '..';
|
|
import * as httpMock from '../../../test/http-mock';
|
|
import { loadFixture } from '../../../test/util';
|
|
import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
|
|
import { id as versioning } from '../../versioning/loose';
|
|
import type { RepologyPackage } from './types';
|
|
import { id as datasource } from '.';
|
|
|
|
const repologyHost = 'https://repology.org/';
|
|
|
|
type ResponseMock = { status?: number; body?: string; code?: string };
|
|
|
|
const mockApiCall = (name: string, response: ResponseMock) => {
|
|
const interceptor = httpMock
|
|
.scope(repologyHost)
|
|
.get(`/api/v1/project/${name}`);
|
|
if (response.status) {
|
|
interceptor.reply(response.status, response.body);
|
|
} else {
|
|
interceptor.replyWithError({ code: response.code });
|
|
}
|
|
};
|
|
|
|
const mockResolverCall = (
|
|
repo: string,
|
|
name: string,
|
|
name_type: string,
|
|
response: ResponseMock
|
|
) => {
|
|
const query = {
|
|
repo,
|
|
name_type,
|
|
target_page: 'api_v1_project',
|
|
noautoresolve: 'on',
|
|
name,
|
|
};
|
|
|
|
const interceptor = httpMock
|
|
.scope(repologyHost)
|
|
.get('/tools/project-by')
|
|
.query(query);
|
|
if (response.status) {
|
|
interceptor.reply(response.status, response.body);
|
|
} else {
|
|
interceptor.replyWithError({ code: response.code });
|
|
}
|
|
};
|
|
|
|
const fixtureNginx = loadFixture(`nginx.json`);
|
|
const fixtureGccDefaults = loadFixture(`gcc-defaults.json`);
|
|
const fixtureGcc = loadFixture(`gcc.json`);
|
|
const fixturePulseaudio = loadFixture(`pulseaudio.json`);
|
|
const fixtureJdk = loadFixture(`openjdk.json`);
|
|
|
|
describe('datasource/repology/index', () => {
|
|
describe('getReleases', () => {
|
|
it('returns null for empty result', async () => {
|
|
mockResolverCall('debian_stable', 'nginx', 'binname', {
|
|
status: 200,
|
|
body: '[]',
|
|
});
|
|
mockResolverCall('debian_stable', 'nginx', 'srcname', {
|
|
status: 200,
|
|
body: '[]',
|
|
});
|
|
|
|
expect(
|
|
await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/nginx',
|
|
})
|
|
).toBeNull();
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns null for missing repository or package', async () => {
|
|
mockResolverCall('this_should', 'never-exist', 'binname', {
|
|
status: 404,
|
|
});
|
|
mockResolverCall('this_should', 'never-exist', 'srcname', {
|
|
status: 404,
|
|
});
|
|
|
|
expect(
|
|
await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'this_should/never-exist',
|
|
})
|
|
).toBeNull();
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('throws error on unexpected API response', async () => {
|
|
mockResolverCall('debian_stable', 'nginx', 'binname', {
|
|
status: 200,
|
|
body: '[]',
|
|
});
|
|
mockResolverCall('debian_stable', 'nginx', 'srcname', {
|
|
status: 403,
|
|
});
|
|
mockApiCall('nginx', { status: 500 });
|
|
|
|
await expect(
|
|
getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/nginx',
|
|
})
|
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('throws error on unexpected Resolver response with binary package', async () => {
|
|
mockResolverCall('debian_stable', 'nginx', 'binname', {
|
|
status: 500,
|
|
});
|
|
|
|
await expect(
|
|
getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/nginx',
|
|
})
|
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('throws error on unexpected Resolver response with source package', async () => {
|
|
mockResolverCall('debian_stable', 'nginx', 'binname', {
|
|
status: 200,
|
|
body: '[]',
|
|
});
|
|
mockResolverCall('debian_stable', 'nginx', 'srcname', {
|
|
status: 500,
|
|
});
|
|
|
|
await expect(
|
|
getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/nginx',
|
|
})
|
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('throws error on API request timeout', async () => {
|
|
mockResolverCall('debian_stable', 'nginx', 'binname', {
|
|
status: 200,
|
|
body: '[]',
|
|
});
|
|
mockResolverCall('debian_stable', 'nginx', 'srcname', {
|
|
status: 403,
|
|
});
|
|
mockApiCall('nginx', { code: 'ETIMEDOUT' });
|
|
|
|
await expect(
|
|
getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/nginx',
|
|
})
|
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('throws error on Resolver request timeout', async () => {
|
|
mockResolverCall('debian_stable', 'nginx', 'binname', {
|
|
code: 'ETIMEDOUT',
|
|
});
|
|
|
|
await expect(
|
|
getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/nginx',
|
|
})
|
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns null on Resolver ambiguous binary package', async () => {
|
|
mockResolverCall('ubuntu_20_04', 'git', 'binname', {
|
|
status: 300,
|
|
body: '[]',
|
|
});
|
|
|
|
expect(
|
|
await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'ubuntu_20_04/git',
|
|
})
|
|
).toBeNull();
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('throws without repository and package name', async () => {
|
|
await expect(
|
|
getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'invalid-lookup-name',
|
|
})
|
|
).rejects.toThrow(EXTERNAL_HOST_ERROR);
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns correct version for binary package', async () => {
|
|
mockResolverCall('debian_stable', 'nginx', 'binname', {
|
|
status: 200,
|
|
body: fixtureNginx,
|
|
});
|
|
|
|
const res = await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/nginx',
|
|
});
|
|
expect(res).toMatchSnapshot();
|
|
expect(res.releases).toHaveLength(1);
|
|
expect(res.releases[0].version).toBe('1.14.2-2+deb10u1');
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns correct version for source package', async () => {
|
|
mockResolverCall('debian_stable', 'gcc-defaults', 'binname', {
|
|
status: 404,
|
|
});
|
|
mockResolverCall('debian_stable', 'gcc-defaults', 'srcname', {
|
|
status: 200,
|
|
body: fixtureGccDefaults,
|
|
});
|
|
|
|
const res = await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/gcc-defaults',
|
|
});
|
|
expect(res).toMatchSnapshot();
|
|
expect(res.releases).toHaveLength(1);
|
|
expect(res.releases[0].version).toBe('1.181');
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns correct version for api package', async () => {
|
|
mockResolverCall('debian_stable', 'gcc-defaults', 'binname', {
|
|
status: 403,
|
|
});
|
|
mockApiCall('gcc-defaults', { status: 200, body: fixtureGccDefaults });
|
|
|
|
const res = await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/gcc-defaults',
|
|
});
|
|
expect(res).toMatchSnapshot();
|
|
expect(res.releases).toHaveLength(1);
|
|
expect(res.releases[0].version).toBe('1.181');
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns correct version for multi-package project with same name', async () => {
|
|
mockResolverCall('alpine_3_12', 'gcc', 'binname', {
|
|
status: 200,
|
|
body: fixtureGcc,
|
|
});
|
|
|
|
const res = await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'alpine_3_12/gcc',
|
|
});
|
|
expect(res).toMatchSnapshot();
|
|
expect(res.releases).toHaveLength(1);
|
|
expect(res.releases[0].version).toBe('9.3.0-r2');
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns correct version for multi-package project with different name', async () => {
|
|
mockResolverCall('debian_stable', 'pulseaudio-utils', 'binname', {
|
|
status: 200,
|
|
body: fixturePulseaudio,
|
|
});
|
|
|
|
const res = await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'debian_stable/pulseaudio-utils',
|
|
});
|
|
expect(res).toMatchSnapshot();
|
|
expect(res.releases).toHaveLength(1);
|
|
expect(res.releases[0].version).toBe('12.2-4+deb10u1');
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns multiple versions if they are present in repository', async () => {
|
|
mockResolverCall('centos_8', 'java-11-openjdk', 'binname', {
|
|
status: 404,
|
|
});
|
|
mockResolverCall('centos_8', 'java-11-openjdk', 'srcname', {
|
|
status: 200,
|
|
body: fixtureJdk,
|
|
});
|
|
|
|
const res = await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'centos_8/java-11-openjdk',
|
|
});
|
|
expect(res).toMatchSnapshot();
|
|
expect(res.releases).toHaveLength(6);
|
|
expect(res.releases[0].version).toBe('1:11.0.7.10-1.el8_1');
|
|
expect(res.releases[5].version).toBe('1:11.0.9.11-3.el8_3');
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
|
|
it('returns null for scenario when repo is not in package results', async () => {
|
|
const pkgs: RepologyPackage[] = [
|
|
{ repo: 'not-dummy', version: '1.0.0', visiblename: 'example' },
|
|
{ repo: 'not-dummy', version: '2.0.0', visiblename: 'example' },
|
|
];
|
|
const pkgsJSON = JSON.stringify(pkgs);
|
|
|
|
mockResolverCall('dummy', 'example', 'binname', {
|
|
status: 200,
|
|
body: pkgsJSON,
|
|
});
|
|
|
|
mockResolverCall('dummy', 'example', 'srcname', {
|
|
status: 200,
|
|
body: pkgsJSON,
|
|
});
|
|
|
|
const release = await getPkgReleases({
|
|
datasource,
|
|
versioning,
|
|
depName: 'dummy/example',
|
|
});
|
|
|
|
expect(release).toBeNull();
|
|
expect(httpMock.getTrace()).toMatchSnapshot();
|
|
});
|
|
});
|
|
});
|