update
This commit is contained in:
361
test/test.npm.ts
361
test/test.npm.ts
@@ -0,0 +1,361 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import { SmartRegistry } from '../ts/index.js';
|
||||
import { createTestRegistry, createTestTokens, createTestPackument } from './helpers/registry.js';
|
||||
|
||||
let registry: SmartRegistry;
|
||||
let npmToken: string;
|
||||
let userId: string;
|
||||
|
||||
// Test data
|
||||
const testPackageName = 'test-package';
|
||||
const testVersion = '1.0.0';
|
||||
const testTarballData = Buffer.from('fake tarball content', 'utf-8');
|
||||
|
||||
tap.test('NPM: should create registry instance', async () => {
|
||||
registry = await createTestRegistry();
|
||||
const tokens = await createTestTokens(registry);
|
||||
npmToken = tokens.npmToken;
|
||||
userId = tokens.userId;
|
||||
|
||||
expect(registry).toBeInstanceOf(SmartRegistry);
|
||||
expect(npmToken).toBeTypeOf('string');
|
||||
});
|
||||
|
||||
tap.test('NPM: should handle user authentication (PUT /-/user/org.couchdb.user:{user})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'PUT',
|
||||
path: '/npm/-/user/org.couchdb.user:testuser',
|
||||
headers: {},
|
||||
query: {},
|
||||
body: {
|
||||
name: 'testuser',
|
||||
password: 'testpass',
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(201);
|
||||
expect(response.body).toHaveProperty('token');
|
||||
expect((response.body as any).token).toBeTypeOf('string');
|
||||
});
|
||||
|
||||
tap.test('NPM: should publish a package (PUT /{package})', async () => {
|
||||
const packument = createTestPackument(testPackageName, testVersion, testTarballData);
|
||||
|
||||
const response = await registry.handleRequest({
|
||||
method: 'PUT',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
query: {},
|
||||
body: packument,
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(201);
|
||||
expect(response.body).toHaveProperty('ok');
|
||||
expect((response.body as any).ok).toEqual(true);
|
||||
});
|
||||
|
||||
tap.test('NPM: should retrieve package metadata (GET /{package})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toHaveProperty('name');
|
||||
expect((response.body as any).name).toEqual(testPackageName);
|
||||
expect((response.body as any).versions).toHaveProperty(testVersion);
|
||||
expect((response.body as any)['dist-tags'].latest).toEqual(testVersion);
|
||||
});
|
||||
|
||||
tap.test('NPM: should retrieve specific version metadata (GET /{package}/{version})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}/${testVersion}`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toHaveProperty('version');
|
||||
expect((response.body as any).version).toEqual(testVersion);
|
||||
expect((response.body as any).name).toEqual(testPackageName);
|
||||
});
|
||||
|
||||
tap.test('NPM: should download tarball (GET /{package}/-/{tarball})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}/-/${testPackageName}-${testVersion}.tgz`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toBeInstanceOf(Buffer);
|
||||
expect((response.body as Buffer).toString('utf-8')).toEqual('fake tarball content');
|
||||
expect(response.headers['Content-Type']).toEqual('application/octet-stream');
|
||||
});
|
||||
|
||||
tap.test('NPM: should publish a new version of the package', async () => {
|
||||
const newVersion = '1.1.0';
|
||||
const newTarballData = Buffer.from('new version tarball', 'utf-8');
|
||||
const packument = createTestPackument(testPackageName, newVersion, newTarballData);
|
||||
|
||||
const response = await registry.handleRequest({
|
||||
method: 'PUT',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
query: {},
|
||||
body: packument,
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(201);
|
||||
|
||||
// Verify the new version is available
|
||||
const getResponse = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(getResponse.status).toEqual(200);
|
||||
expect((getResponse.body as any).versions).toHaveProperty(newVersion);
|
||||
});
|
||||
|
||||
tap.test('NPM: should get dist-tags (GET /-/package/{pkg}/dist-tags)', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/-/package/${testPackageName}/dist-tags`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toHaveProperty('latest');
|
||||
expect((response.body as any).latest).toBeTypeOf('string');
|
||||
});
|
||||
|
||||
tap.test('NPM: should update dist-tag (PUT /-/package/{pkg}/dist-tags/{tag})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'PUT',
|
||||
path: `/npm/-/package/${testPackageName}/dist-tags/beta`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
query: {},
|
||||
body: '1.1.0',
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
// Verify the tag was updated
|
||||
const getResponse = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect((getResponse.body as any)['dist-tags'].beta).toEqual('1.1.0');
|
||||
});
|
||||
|
||||
tap.test('NPM: should delete dist-tag (DELETE /-/package/{pkg}/dist-tags/{tag})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'DELETE',
|
||||
path: `/npm/-/package/${testPackageName}/dist-tags/beta`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
// Verify the tag was deleted
|
||||
const getResponse = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect((getResponse.body as any)['dist-tags']).not.toHaveProperty('beta');
|
||||
});
|
||||
|
||||
tap.test('NPM: should create a new token (POST /-/npm/v1/tokens)', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'POST',
|
||||
path: '/npm/-/npm/v1/tokens',
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
query: {},
|
||||
body: {
|
||||
password: 'testpass',
|
||||
readonly: true,
|
||||
cidr_whitelist: [],
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toHaveProperty('token');
|
||||
expect((response.body as any).readonly).toEqual(true);
|
||||
});
|
||||
|
||||
tap.test('NPM: should list tokens (GET /-/npm/v1/tokens)', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: '/npm/-/npm/v1/tokens',
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toHaveProperty('objects');
|
||||
expect((response.body as any).objects).toBeInstanceOf(Array);
|
||||
expect((response.body as any).objects.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
tap.test('NPM: should search packages (GET /-/v1/search)', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: '/npm/-/v1/search',
|
||||
headers: {},
|
||||
query: {
|
||||
text: 'test',
|
||||
size: '20',
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toHaveProperty('objects');
|
||||
expect((response.body as any).objects).toBeInstanceOf(Array);
|
||||
expect((response.body as any).total).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
tap.test('NPM: should search packages with specific query', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: '/npm/-/v1/search',
|
||||
headers: {},
|
||||
query: {
|
||||
text: testPackageName,
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
const results = (response.body as any).objects;
|
||||
expect(results.length).toBeGreaterThan(0);
|
||||
expect(results[0].package.name).toEqual(testPackageName);
|
||||
});
|
||||
|
||||
tap.test('NPM: should unpublish a specific version (DELETE /{package}/-/{version})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'DELETE',
|
||||
path: `/npm/${testPackageName}/-/${testVersion}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
// Verify the version was removed
|
||||
const getResponse = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect((getResponse.body as any).versions).not.toHaveProperty(testVersion);
|
||||
});
|
||||
|
||||
tap.test('NPM: should unpublish entire package (DELETE /{package}/-rev/{rev})', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'DELETE',
|
||||
path: `/npm/${testPackageName}/-rev/1`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${npmToken}`,
|
||||
},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
// Verify the package was removed
|
||||
const getResponse = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: `/npm/${testPackageName}`,
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(getResponse.status).toEqual(404);
|
||||
});
|
||||
|
||||
tap.test('NPM: should return 404 for non-existent package', async () => {
|
||||
const response = await registry.handleRequest({
|
||||
method: 'GET',
|
||||
path: '/npm/non-existent-package',
|
||||
headers: {},
|
||||
query: {},
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(404);
|
||||
expect(response.body).toHaveProperty('error');
|
||||
});
|
||||
|
||||
tap.test('NPM: should return 401 for unauthorized publish', async () => {
|
||||
const packument = createTestPackument('unauthorized-package', '1.0.0', testTarballData);
|
||||
|
||||
const response = await registry.handleRequest({
|
||||
method: 'PUT',
|
||||
path: '/npm/unauthorized-package',
|
||||
headers: {
|
||||
// No authorization header
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
query: {},
|
||||
body: packument,
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(401);
|
||||
expect(response.body).toHaveProperty('error');
|
||||
});
|
||||
|
||||
tap.test('NPM: should reject readonly token for write operations', async () => {
|
||||
// Create a readonly token
|
||||
const authManager = registry.getAuthManager();
|
||||
const readonlyToken = await authManager.createNpmToken(userId, true);
|
||||
|
||||
const packument = createTestPackument('readonly-test', '1.0.0', testTarballData);
|
||||
|
||||
const response = await registry.handleRequest({
|
||||
method: 'PUT',
|
||||
path: '/npm/readonly-test',
|
||||
headers: {
|
||||
Authorization: `Bearer ${readonlyToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
query: {},
|
||||
body: packument,
|
||||
});
|
||||
|
||||
expect(response.status).toEqual(401);
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
|
||||
Reference in New Issue
Block a user