Files
renovate/lib/modules/datasource/cdnjs/index.spec.ts
Sebastian Poxhofer 05e1271376 test: use expect().resolves instead of awaiting inside expect (#45672)
Enables the vitest/prefer-expect-resolves oxlint rule and applies its
autofix across the spec suite.
2026-09-04 10:40:46 +00:00

239 lines
6.8 KiB
TypeScript

import { Fixtures } from '~test/fixtures.ts';
import * as httpMock from '~test/http-mock.ts';
import { EXTERNAL_HOST_ERROR } from '../../../constants/error-messages.ts';
import { HttpError } from '../../../util/http/index.ts';
import { getDigest, getPkgReleases } from '../index.ts';
import { CdnjsDatasource } from './index.ts';
const baseUrl = 'https://api.cdnjs.com/';
function pathFor(s: string): string {
return `/libraries/${s.split('/').shift()}?fields=homepage,repository,versions`;
}
function pathForDigest(s: string, version: string): string {
return `/libraries/${s.split('/').shift()}/${version}?fields=sri`;
}
describe('modules/datasource/cdnjs/index', () => {
describe('getReleases', () => {
it('throws for empty result', async () => {
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(200, '}');
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
}),
).rejects.toThrow(EXTERNAL_HOST_ERROR);
});
it('throws for error', async () => {
httpMock.scope(baseUrl).get(pathFor('foo/bar')).replyWithError('error');
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
}),
).rejects.toThrow(EXTERNAL_HOST_ERROR);
});
it('returns null for 404', async () => {
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(404);
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
}),
).resolves.toBeNull();
});
it('returns null for empty 200 OK', async () => {
httpMock
.scope(baseUrl)
.get(pathFor('doesnotexist/doesnotexist'))
.reply(200, {});
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'doesnotexist/doesnotexist',
}),
).resolves.toBeNull();
});
it('throws for 401', async () => {
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(401);
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
}),
).rejects.toThrow(EXTERNAL_HOST_ERROR);
});
it('throws for 429', async () => {
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(429);
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
}),
).rejects.toThrow(EXTERNAL_HOST_ERROR);
});
it('throws for 5xx', async () => {
httpMock.scope(baseUrl).get(pathFor('foo/bar')).reply(502);
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
}),
).rejects.toThrow(EXTERNAL_HOST_ERROR);
});
it('throws for unknown error', async () => {
httpMock.scope(baseUrl).get(pathFor('foo/bar')).replyWithError('error');
await expect(
getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
}),
).rejects.toThrow(EXTERNAL_HOST_ERROR);
});
it('processes real data', async () => {
httpMock
.scope(baseUrl)
.get(pathFor('d3-force/d3-force.js'))
.reply(200, Fixtures.get('d3-force.json'));
const res = await getPkgReleases({
datasource: CdnjsDatasource.id,
packageName: 'd3-force/d3-force.js',
});
expect(res).toMatchObject({
homepage: 'https://d3js.org/d3-force/',
sourceUrl: 'https://github.com/d3/d3-force',
releases: [
{ version: '0.0.1' },
{ version: '0.0.2' },
{ version: '0.0.3' },
{ version: '0.0.4' },
{ version: '0.1.0' },
{ version: '0.2.0' },
{ version: '0.2.1' },
{ version: '0.2.2' },
{ version: '0.3.0' },
{ version: '0.4.0' },
{ version: '0.4.1' },
{ version: '0.5.0' },
{ version: '0.6.0' },
{ version: '0.6.1' },
{ version: '0.6.2' },
{ version: '0.6.3' },
{ version: '0.7.0' },
{ version: '0.7.1' },
{ version: '1.0.0' },
{ version: '1.0.1' },
{ version: '1.0.2' },
{ version: '1.0.3' },
{ version: '1.0.4' },
{ version: '1.0.5' },
{ version: '1.0.6' },
{ version: '1.1.0' },
{ version: '1.1.1' },
{ version: '1.1.2' },
{ version: '1.2.0' },
{ version: '1.2.1' },
{ version: '2.0.0' },
{ version: '2.0.1' },
{ version: '2.1.0' },
{ version: '2.1.0-rc.1' },
{ version: '2.1.0-rc.2' },
{ version: '2.1.1' },
{ version: '3.0.0' },
],
});
});
});
describe('getDigest', () => {
it('returs null for no result', async () => {
httpMock
.scope(baseUrl)
.get(pathForDigest('foo/bar', '1.2.0'))
.reply(200, '{}');
const res = await getDigest(
{
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
},
'1.2.0',
);
expect(res).toBeNull();
});
it('returs null for empty sri object', async () => {
httpMock
.scope(baseUrl)
.get(pathForDigest('foo/bar', '1.2.0'))
.reply(200, JSON.stringify({ sri: {} }));
const res = await getDigest(
{
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
},
'1.2.0',
);
expect(res).toBeNull();
});
it('returs null if file not found', async () => {
httpMock
.scope(baseUrl)
.get(pathForDigest('foo/bar', '1.2.0'))
.reply(200, JSON.stringify({ sri: { string: 'hash' } }));
const res = await getDigest(
{
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
},
'1.2.0',
);
expect(res).toBeNull();
});
it('returns null for 404', async () => {
httpMock.scope(baseUrl).get(pathForDigest('foo/bar', '1.2.0')).reply(404);
await expect(
getDigest(
{
datasource: CdnjsDatasource.id,
packageName: 'foo/bar',
},
'1.2.0',
),
).rejects.toThrow(HttpError);
});
it('returns digest', async () => {
httpMock
.scope(baseUrl)
.get(pathForDigest('bootstrap/js/bootstrap.min.js', '5.2.3'))
.reply(200, Fixtures.get('sri.json'));
const res = await getDigest(
{
datasource: CdnjsDatasource.id,
packageName: 'bootstrap/js/bootstrap.min.js',
},
'5.2.3',
);
expect(res).toBe(
'sha512-1/RvZTcCDEUjY/CypiMz+iqqtaoQfAITmNSJY17Myp4Ms5mdxPS5UV7iOfdZoxcGhzFbOm6sntTKJppjvuhg4g==',
);
});
});
});