132 lines
4.2 KiB
TypeScript
132 lines
4.2 KiB
TypeScript
|
|
import { tap, expect } from '@git.zone/tstest';
|
||
|
|
import { RegistryStorage } from '../ts/core/classes.registrystorage.js';
|
||
|
|
import { CargoRegistry } from '../ts/cargo/classes.cargoregistry.js';
|
||
|
|
import { AuthManager } from '../ts/core/classes.authmanager.js';
|
||
|
|
|
||
|
|
// Test index path calculation
|
||
|
|
tap.test('should calculate correct index paths for different crate names', async () => {
|
||
|
|
const storage = new RegistryStorage({
|
||
|
|
accessKey: 'test',
|
||
|
|
accessSecret: 'test',
|
||
|
|
endpoint: 's3.test.com',
|
||
|
|
bucketName: 'test-bucket',
|
||
|
|
});
|
||
|
|
|
||
|
|
// Access private method for testing
|
||
|
|
const getPath = (storage as any).getCargoIndexPath.bind(storage);
|
||
|
|
|
||
|
|
// 1-character names
|
||
|
|
expect(getPath('a')).to.equal('cargo/index/1/a');
|
||
|
|
expect(getPath('z')).to.equal('cargo/index/1/z');
|
||
|
|
|
||
|
|
// 2-character names
|
||
|
|
expect(getPath('io')).to.equal('cargo/index/2/io');
|
||
|
|
expect(getPath('ab')).to.equal('cargo/index/2/ab');
|
||
|
|
|
||
|
|
// 3-character names
|
||
|
|
expect(getPath('axo')).to.equal('cargo/index/3/a/axo');
|
||
|
|
expect(getPath('foo')).to.equal('cargo/index/3/f/foo');
|
||
|
|
|
||
|
|
// 4+ character names
|
||
|
|
expect(getPath('serde')).to.equal('cargo/index/se/rd/serde');
|
||
|
|
expect(getPath('tokio')).to.equal('cargo/index/to/ki/tokio');
|
||
|
|
expect(getPath('my-crate')).to.equal('cargo/index/my/--/my-crate');
|
||
|
|
});
|
||
|
|
|
||
|
|
// Test crate file path calculation
|
||
|
|
tap.test('should calculate correct crate file paths', async () => {
|
||
|
|
const storage = new RegistryStorage({
|
||
|
|
accessKey: 'test',
|
||
|
|
accessSecret: 'test',
|
||
|
|
endpoint: 's3.test.com',
|
||
|
|
bucketName: 'test-bucket',
|
||
|
|
});
|
||
|
|
|
||
|
|
// Access private method for testing
|
||
|
|
const getPath = (storage as any).getCargoCratePath.bind(storage);
|
||
|
|
|
||
|
|
expect(getPath('serde', '1.0.0')).to.equal('cargo/crates/serde/serde-1.0.0.crate');
|
||
|
|
expect(getPath('tokio', '1.28.0')).to.equal('cargo/crates/tokio/tokio-1.28.0.crate');
|
||
|
|
expect(getPath('my-crate', '0.1.0')).to.equal('cargo/crates/my-crate/my-crate-0.1.0.crate');
|
||
|
|
});
|
||
|
|
|
||
|
|
// Test crate name validation
|
||
|
|
tap.test('should validate crate names correctly', async () => {
|
||
|
|
const storage = new RegistryStorage({
|
||
|
|
accessKey: 'test',
|
||
|
|
accessSecret: 'test',
|
||
|
|
endpoint: 's3.test.com',
|
||
|
|
bucketName: 'test-bucket',
|
||
|
|
});
|
||
|
|
|
||
|
|
const authManager = new AuthManager({
|
||
|
|
jwtSecret: 'test-secret',
|
||
|
|
tokenStore: 'memory',
|
||
|
|
npmTokens: { enabled: true },
|
||
|
|
ociTokens: { enabled: false, realm: '', service: '' },
|
||
|
|
});
|
||
|
|
|
||
|
|
const registry = new CargoRegistry(storage, authManager, '/cargo', 'http://localhost:5000/cargo');
|
||
|
|
|
||
|
|
// Access private method for testing
|
||
|
|
const validate = (registry as any).validateCrateName.bind(registry);
|
||
|
|
|
||
|
|
// Valid names
|
||
|
|
expect(validate('serde')).to.be.true;
|
||
|
|
expect(validate('tokio')).to.be.true;
|
||
|
|
expect(validate('my-crate')).to.be.true;
|
||
|
|
expect(validate('my_crate')).to.be.true;
|
||
|
|
expect(validate('crate123')).to.be.true;
|
||
|
|
expect(validate('a')).to.be.true;
|
||
|
|
|
||
|
|
// Invalid names (uppercase not allowed)
|
||
|
|
expect(validate('Serde')).to.be.false;
|
||
|
|
expect(validate('MyCreate')).to.be.false;
|
||
|
|
|
||
|
|
// Invalid names (special characters)
|
||
|
|
expect(validate('my.crate')).to.be.false;
|
||
|
|
expect(validate('my@crate')).to.be.false;
|
||
|
|
expect(validate('my crate')).to.be.false;
|
||
|
|
|
||
|
|
// Invalid names (too long)
|
||
|
|
const longName = 'a'.repeat(65);
|
||
|
|
expect(validate(longName)).to.be.false;
|
||
|
|
|
||
|
|
// Invalid names (empty)
|
||
|
|
expect(validate('')).to.be.false;
|
||
|
|
});
|
||
|
|
|
||
|
|
// Test config.json response
|
||
|
|
tap.test('should return valid config.json', async () => {
|
||
|
|
const storage = new RegistryStorage({
|
||
|
|
accessKey: 'test',
|
||
|
|
accessSecret: 'test',
|
||
|
|
endpoint: 's3.test.com',
|
||
|
|
bucketName: 'test-bucket',
|
||
|
|
});
|
||
|
|
|
||
|
|
const authManager = new AuthManager({
|
||
|
|
jwtSecret: 'test-secret',
|
||
|
|
tokenStore: 'memory',
|
||
|
|
npmTokens: { enabled: true },
|
||
|
|
ociTokens: { enabled: false, realm: '', service: '' },
|
||
|
|
});
|
||
|
|
|
||
|
|
const registry = new CargoRegistry(storage, authManager, '/cargo', 'http://localhost:5000/cargo');
|
||
|
|
|
||
|
|
const response = await registry.handleRequest({
|
||
|
|
method: 'GET',
|
||
|
|
path: '/cargo/config.json',
|
||
|
|
headers: {},
|
||
|
|
query: {},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.status).to.equal(200);
|
||
|
|
expect(response.headers['Content-Type']).to.equal('application/json');
|
||
|
|
expect(response.body).to.be.an('object');
|
||
|
|
expect(response.body.dl).to.include('/api/v1/crates/{crate}/{version}/download');
|
||
|
|
expect(response.body.api).to.equal('http://localhost:5000/cargo');
|
||
|
|
});
|
||
|
|
|
||
|
|
export default tap.start();
|