Files
renovate/lib/modules/datasource/maven/s3.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

211 lines
6.0 KiB
TypeScript

import { Readable } from 'node:stream';
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { mockClient } from 'aws-sdk-client-mock';
import { Fixtures } from '~test/fixtures.ts';
import { logger } from '../../../logger/index.ts';
import * as hostRules from '../../../util/host-rules.ts';
import { id as versioning } from '../../versioning/maven/index.ts';
import type { ReleaseResult } from '../index.ts';
import { getPkgReleases } from '../index.ts';
import { MavenDatasource } from './index.ts';
const datasource = MavenDatasource.id;
const baseUrlS3 = 's3://repobucket';
function get(
packageName = 'org.example:package',
...registryUrls: string[]
): Promise<ReleaseResult | null> {
const conf = { versioning, datasource, packageName };
return getPkgReleases(registryUrls ? { ...conf, registryUrls } : conf);
}
const meta = Readable.from(Fixtures.getBinary('metadata-s3.xml'));
describe('modules/datasource/maven/s3', () => {
const s3mock = mockClient(S3Client);
beforeEach(() => {
hostRules.add({
hostType: datasource,
matchHost: 'custom.registry.renovatebot.com',
token: '123test',
});
});
afterEach(() => {
s3mock.reset();
hostRules.clear();
});
describe('S3', () => {
it('returns releases', async () => {
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.resolvesOnce({
Body: meta as never,
LastModified: new Date('2020-01-01T00:00Z'),
});
const res = await get('org.example:package', baseUrlS3);
expect(res).toEqual({
display: 'org.example:package',
group: 'org.example',
name: 'package',
registryUrl: 's3://repobucket',
releases: [
{ version: '0.0.1' },
{ version: '1.0.0' },
{ version: '1.0.1' },
{ version: '1.0.2' },
{ version: '1.0.3' },
],
respectLatest: false,
tags: {
latest: '1.0.2',
release: '1.0.2',
},
isPrivate: true,
});
});
describe('errors', () => {
it('returns null on auth error', async () => {
class CredentialsProviderError extends Error {
constructor() {
super();
this.name = 'CredentialsProviderError';
}
}
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.rejectsOnce(new CredentialsProviderError());
const res = await get('org.example:package', baseUrlS3);
expect(res).toBeNull();
expect(logger.debug).toHaveBeenCalledWith(
{
failedUrl: 's3://repobucket/org/example/package/maven-metadata.xml',
},
'Maven S3 lookup error: credentials provider error, check "AWS_ACCESS_KEY_ID" and "AWS_SECRET_ACCESS_KEY" variables',
);
});
it('returns null for incorrect region', async () => {
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.rejectsOnce('Region is missing');
const res = await get('org.example:package', baseUrlS3);
expect(res).toBeNull();
expect(logger.debug).toHaveBeenCalledWith(
{
failedUrl: 's3://repobucket/org/example/package/maven-metadata.xml',
},
'Maven S3 lookup error: missing region, check "AWS_REGION" variable',
);
});
it('returns null for NoSuchKey error', async () => {
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.rejectsOnce('NoSuchKey');
const res = await get('org.example:package', baseUrlS3);
expect(res).toBeNull();
expect(logger.trace).toHaveBeenCalledWith(
{
failedUrl: 's3://repobucket/org/example/package/maven-metadata.xml',
},
'Maven S3 lookup error: object not found',
);
});
it('returns null for NotFound error', async () => {
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.rejectsOnce('NotFound');
const res = await get('org.example:package', baseUrlS3);
expect(res).toBeNull();
expect(logger.trace).toHaveBeenCalledWith(
{
failedUrl: 's3://repobucket/org/example/package/maven-metadata.xml',
},
'Maven S3 lookup error: object not found',
);
});
it('returns null for Deleted marker', async () => {
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.resolvesOnce({ DeleteMarker: true });
const res = await get('org.example:package', baseUrlS3);
expect(res).toBeNull();
});
it('returns null for unknown error', async () => {
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.rejectsOnce('Unknown error');
const res = await get('org.example:package', baseUrlS3);
expect(res).toBeNull();
expect(logger.debug).toHaveBeenCalledWith(
{
err: expect.objectContaining({ message: 'Unknown error' }),
failedUrl: 's3://repobucket/org/example/package/maven-metadata.xml',
},
'Maven S3 lookup error: unknown error',
);
});
it('returns null for unexpected response type', async () => {
s3mock
.on(GetObjectCommand, {
Bucket: 'repobucket',
Key: 'org/example/package/maven-metadata.xml',
})
.resolvesOnce({});
await expect(get('org.example:package', baseUrlS3)).resolves.toBeNull();
});
});
});
});