feat(core,storage,oci,registry-config): add streaming response support and configurable registry URLs across protocols
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import { SmartRegistry } from '../ts/index.js';
|
||||
import { streamToBuffer, streamToJson } from '../ts/core/helpers.stream.js';
|
||||
import {
|
||||
createTestRegistry,
|
||||
createTestTokens,
|
||||
@@ -101,9 +102,10 @@ tap.test('PyPI: should retrieve Simple API root index HTML (GET /simple/)', asyn
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.headers['Content-Type']).toStartWith('text/html');
|
||||
expect(response.body).toBeTypeOf('string');
|
||||
const body = await streamToBuffer(response.body);
|
||||
const html = body.toString('utf-8');
|
||||
expect(html).toBeTypeOf('string');
|
||||
|
||||
const html = response.body as string;
|
||||
expect(html).toContain('<!DOCTYPE html>');
|
||||
expect(html).toContain('<title>Simple Index</title>');
|
||||
expect(html).toContain(normalizedPackageName);
|
||||
@@ -121,9 +123,9 @@ tap.test('PyPI: should retrieve Simple API root index JSON (GET /simple/ with Ac
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.headers['Content-Type']).toEqual('application/vnd.pypi.simple.v1+json');
|
||||
expect(response.body).toBeTypeOf('object');
|
||||
const json = await streamToJson(response.body);
|
||||
expect(json).toBeTypeOf('object');
|
||||
|
||||
const json = response.body as any;
|
||||
expect(json).toHaveProperty('meta');
|
||||
expect(json).toHaveProperty('projects');
|
||||
expect(json.projects).toBeInstanceOf(Array);
|
||||
@@ -144,9 +146,10 @@ tap.test('PyPI: should retrieve Simple API package HTML (GET /simple/{package}/)
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.headers['Content-Type']).toStartWith('text/html');
|
||||
expect(response.body).toBeTypeOf('string');
|
||||
const body = await streamToBuffer(response.body);
|
||||
const html = body.toString('utf-8');
|
||||
expect(html).toBeTypeOf('string');
|
||||
|
||||
const html = response.body as string;
|
||||
expect(html).toContain('<!DOCTYPE html>');
|
||||
expect(html).toContain(`<title>Links for ${normalizedPackageName}</title>`);
|
||||
expect(html).toContain('.whl');
|
||||
@@ -165,9 +168,9 @@ tap.test('PyPI: should retrieve Simple API package JSON (GET /simple/{package}/
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.headers['Content-Type']).toEqual('application/vnd.pypi.simple.v1+json');
|
||||
expect(response.body).toBeTypeOf('object');
|
||||
const json = await streamToJson(response.body);
|
||||
expect(json).toBeTypeOf('object');
|
||||
|
||||
const json = response.body as any;
|
||||
expect(json).toHaveProperty('meta');
|
||||
expect(json).toHaveProperty('name');
|
||||
expect(json.name).toEqual(normalizedPackageName);
|
||||
@@ -187,8 +190,9 @@ tap.test('PyPI: should download wheel file (GET /pypi/packages/{package}/{filena
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toBeInstanceOf(Buffer);
|
||||
expect((response.body as Buffer).length).toEqual(testWheelData.length);
|
||||
const body = await streamToBuffer(response.body);
|
||||
expect(body).toBeInstanceOf(Buffer);
|
||||
expect(body.length).toEqual(testWheelData.length);
|
||||
expect(response.headers['Content-Type']).toEqual('application/octet-stream');
|
||||
});
|
||||
|
||||
@@ -234,7 +238,7 @@ tap.test('PyPI: should list both wheel and sdist in Simple API', async () => {
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
const json = response.body as any;
|
||||
const json = await streamToJson(response.body);
|
||||
// PEP 691: files is an array of file objects
|
||||
expect(json.files.length).toEqual(2);
|
||||
|
||||
@@ -289,7 +293,7 @@ tap.test('PyPI: should list multiple versions in Simple API', async () => {
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
const json = response.body as any;
|
||||
const json = await streamToJson(response.body);
|
||||
// PEP 691: files is an array of file objects
|
||||
expect(json.files.length).toBeGreaterThan(2);
|
||||
|
||||
@@ -323,7 +327,8 @@ tap.test('PyPI: should return 404 for non-existent package', async () => {
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(404);
|
||||
expect(response.body).toHaveProperty('error');
|
||||
const body = await streamToJson(response.body);
|
||||
expect(body).toHaveProperty('error');
|
||||
});
|
||||
|
||||
tap.test('PyPI: should return 401 for unauthorized upload', async () => {
|
||||
@@ -353,7 +358,8 @@ tap.test('PyPI: should return 401 for unauthorized upload', async () => {
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(401);
|
||||
expect(response.body).toHaveProperty('error');
|
||||
const body = await streamToJson(response.body);
|
||||
expect(body).toHaveProperty('error');
|
||||
});
|
||||
|
||||
tap.test('PyPI: should reject upload with mismatched hash', async () => {
|
||||
@@ -382,7 +388,8 @@ tap.test('PyPI: should reject upload with mismatched hash', async () => {
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(400);
|
||||
expect(response.body).toHaveProperty('error');
|
||||
const body = await streamToJson(response.body);
|
||||
expect(body).toHaveProperty('error');
|
||||
});
|
||||
|
||||
tap.test('PyPI: should handle package with requires-python metadata', async () => {
|
||||
@@ -425,7 +432,8 @@ tap.test('PyPI: should handle package with requires-python metadata', async () =
|
||||
query: {},
|
||||
});
|
||||
|
||||
const html = getResponse.body as string;
|
||||
const getBody = await streamToBuffer(getResponse.body);
|
||||
const html = getBody.toString('utf-8');
|
||||
expect(html).toContain('data-requires-python');
|
||||
// Note: >= gets HTML-escaped to >= in attribute values
|
||||
expect(html).toContain('>=3.8');
|
||||
@@ -441,9 +449,9 @@ tap.test('PyPI: should support JSON API for package metadata', async () => {
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.headers['Content-Type']).toEqual('application/json');
|
||||
expect(response.body).toBeTypeOf('object');
|
||||
const json = await streamToJson(response.body);
|
||||
expect(json).toBeTypeOf('object');
|
||||
|
||||
const json = response.body as any;
|
||||
expect(json).toHaveProperty('info');
|
||||
expect(json.info).toHaveProperty('name');
|
||||
expect(json.info.name).toEqual(normalizedPackageName);
|
||||
@@ -460,9 +468,9 @@ tap.test('PyPI: should support JSON API for specific version', async () => {
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.headers['Content-Type']).toEqual('application/json');
|
||||
expect(response.body).toBeTypeOf('object');
|
||||
const json = await streamToJson(response.body);
|
||||
expect(json).toBeTypeOf('object');
|
||||
|
||||
const json = response.body as any;
|
||||
expect(json).toHaveProperty('info');
|
||||
expect(json.info.version).toEqual(testVersion);
|
||||
expect(json).toHaveProperty('urls');
|
||||
|
||||
Reference in New Issue
Block a user