backend-common: Implement readUrl for gitlab

Signed-off-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
Johan Haals
2021-07-01 13:41:39 +02:00
parent 09d3eb684e
commit 21febfaeb1
2 changed files with 72 additions and 6 deletions
@@ -79,7 +79,7 @@ describe('GitlabUrlReader', () => {
const worker = setupServer();
msw.setupDefaultHandlers(worker);
describe('implementation', () => {
describe('read', () => {
beforeEach(() => {
worker.use(
rest.get('*/api/v4/projects/:name', (_, res, ctx) =>
@@ -180,6 +180,53 @@ describe('GitlabUrlReader', () => {
});
});
describe('readUrl', () => {
const [{ reader }] = GitlabUrlReader.factory({
config: new ConfigReader({}),
logger,
treeResponseFactory,
});
it('should throw NotModified on HTTP 304', async () => {
worker.use(
rest.get('*/api/v4/projects/:name', (_, res, ctx) =>
res(ctx.status(200), ctx.json({ id: 12345 })),
),
rest.get('*', (req, res, ctx) => {
expect(req.headers.get('If-None-Match')).toBe('999');
return res(ctx.status(304));
}),
);
await expect(
reader.readUrl!(
'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml',
{
etag: '999',
},
),
).rejects.toThrow(NotModifiedError);
});
it('should return etag in response', async () => {
worker.use(
rest.get('*/api/v4/projects/:name', (_, res, ctx) =>
res(ctx.status(200), ctx.json({ id: 12345 })),
),
rest.get('*', (req, res, ctx) => {
return res(ctx.status(200), ctx.set('ETag', '999'), ctx.body('foo'));
}),
);
const result = await reader.readUrl!(
'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml',
);
expect(result.etag).toBe('999');
const content = await result.buffer();
expect(content.toString()).toBe('foo');
});
});
describe('readTree', () => {
const archiveBuffer = fs.readFileSync(
path.resolve('src', 'reading', '__fixtures__', 'gitlab-archive.tar.gz'),
@@ -34,6 +34,8 @@ import {
SearchOptions,
SearchResponse,
UrlReader,
ReadUrlResponse,
ReadUrlOptions,
} from './types';
export class GitlabUrlReader implements UrlReader {
@@ -54,20 +56,37 @@ export class GitlabUrlReader implements UrlReader {
) {}
async read(url: string): Promise<Buffer> {
const response = await this.readUrl(url);
return response.buffer();
}
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
const builtUrl = await getGitLabFileFetchUrl(url, this.integration.config);
let response: Response;
try {
response = await fetch(
builtUrl,
getGitLabRequestOptions(this.integration.config),
);
response = await fetch(builtUrl, {
headers: {
...getGitLabRequestOptions(this.integration.config).headers,
...(options?.etag && { 'If-None-Match': options.etag }),
},
});
} catch (e) {
throw new Error(`Unable to read ${url}, ${e}`);
}
if (response.status === 304) {
throw new NotModifiedError();
}
if (response.ok) {
return Buffer.from(await response.text());
const etag = response.headers.get('ETag')
? response.headers.get('ETag')!
: undefined;
return { buffer: async () => Buffer.from(await response.text()), etag };
}
const message = `${url} could not be read as ${builtUrl}, ${response.status} ${response.statusText}`;