first commit
This commit is contained in:
190
src/cli/tests/registry/types.test.ts
Normal file
190
src/cli/tests/registry/types.test.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
OfficialRegistryResponseSchema,
|
||||
GlamaRegistryResponseSchema,
|
||||
SmitheryRegistryResponseSchema,
|
||||
sanitizeString,
|
||||
} from '../../src/registry/types.js';
|
||||
|
||||
describe('sanitizeString', () => {
|
||||
it('removes ANSI escape codes (\\x1b[)', () => {
|
||||
expect(sanitizeString('\x1b[31mRED\x1b[0m text')).toBe('RED text');
|
||||
});
|
||||
|
||||
it('removes \\033[ style escape codes', () => {
|
||||
expect(sanitizeString('\x1b[1mBOLD\x1b[0m')).toBe('BOLD');
|
||||
});
|
||||
|
||||
it('removes cursor movement codes', () => {
|
||||
expect(sanitizeString('\x1b[2J\x1b[Hscreen cleared')).toBe('screen cleared');
|
||||
});
|
||||
|
||||
it('removes control characters', () => {
|
||||
expect(sanitizeString('hello\x07world')).toBe('helloworld');
|
||||
});
|
||||
|
||||
it('preserves normal text', () => {
|
||||
expect(sanitizeString('A normal MCP server description.')).toBe('A normal MCP server description.');
|
||||
});
|
||||
|
||||
it('preserves unicode characters', () => {
|
||||
expect(sanitizeString('Serveur MCP pour Slack 🚀')).toBe('Serveur MCP pour Slack 🚀');
|
||||
});
|
||||
|
||||
it('handles empty string', () => {
|
||||
expect(sanitizeString('')).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('OfficialRegistryResponseSchema', () => {
|
||||
it('validates a correct response', () => {
|
||||
const valid = {
|
||||
servers: [{
|
||||
server: {
|
||||
name: 'io.github.test/slack-mcp',
|
||||
description: 'Slack integration',
|
||||
packages: [{
|
||||
registryType: 'npm',
|
||||
identifier: '@test/slack-mcp',
|
||||
transport: { type: 'stdio' },
|
||||
environmentVariables: [
|
||||
{ name: 'SLACK_TOKEN', description: 'Bot token', isSecret: true },
|
||||
],
|
||||
}],
|
||||
},
|
||||
}],
|
||||
metadata: { nextCursor: 'abc:1.0.0', count: 1 },
|
||||
};
|
||||
const result = OfficialRegistryResponseSchema.safeParse(valid);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it('validates response with remotes', () => {
|
||||
const valid = {
|
||||
servers: [{
|
||||
server: {
|
||||
name: 'io.github.test/remote-mcp',
|
||||
remotes: [{
|
||||
type: 'sse',
|
||||
url: 'https://example.com/sse',
|
||||
headers: [{ name: 'Authorization', isSecret: true }],
|
||||
}],
|
||||
},
|
||||
}],
|
||||
};
|
||||
const result = OfficialRegistryResponseSchema.safeParse(valid);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects response without servers array', () => {
|
||||
const result = OfficialRegistryResponseSchema.safeParse({ metadata: {} });
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('rejects server without name', () => {
|
||||
const result = OfficialRegistryResponseSchema.safeParse({
|
||||
servers: [{ server: { description: 'no name' } }],
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('defaults missing optional fields', () => {
|
||||
const minimal = {
|
||||
servers: [{ server: { name: 'test/minimal' } }],
|
||||
};
|
||||
const result = OfficialRegistryResponseSchema.parse(minimal);
|
||||
expect(result.servers[0]?.server.packages).toEqual([]);
|
||||
expect(result.servers[0]?.server.remotes).toEqual([]);
|
||||
expect(result.servers[0]?.server.description).toBe('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('GlamaRegistryResponseSchema', () => {
|
||||
it('validates a correct response', () => {
|
||||
const valid = {
|
||||
servers: [{
|
||||
id: 'abc123',
|
||||
name: 'Slack MCP Server',
|
||||
description: 'Slack integration',
|
||||
attributes: ['hosting:local-only'],
|
||||
repository: { url: 'https://github.com/test/slack' },
|
||||
environmentVariablesJsonSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
SLACK_TOKEN: { type: 'string', description: 'Bot token' },
|
||||
},
|
||||
required: ['SLACK_TOKEN'],
|
||||
},
|
||||
}],
|
||||
pageInfo: {
|
||||
endCursor: 'xyz',
|
||||
hasNextPage: true,
|
||||
hasPreviousPage: false,
|
||||
},
|
||||
};
|
||||
const result = GlamaRegistryResponseSchema.safeParse(valid);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects response without pageInfo', () => {
|
||||
const result = GlamaRegistryResponseSchema.safeParse({
|
||||
servers: [{ id: 'a', name: 'test' }],
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('defaults missing env schema properties', () => {
|
||||
const minimal = {
|
||||
servers: [{
|
||||
id: 'a',
|
||||
name: 'test',
|
||||
environmentVariablesJsonSchema: {},
|
||||
}],
|
||||
pageInfo: { hasNextPage: false, hasPreviousPage: false },
|
||||
};
|
||||
const result = GlamaRegistryResponseSchema.parse(minimal);
|
||||
const envSchema = result.servers[0]?.environmentVariablesJsonSchema;
|
||||
expect(envSchema?.properties).toEqual({});
|
||||
expect(envSchema?.required).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('SmitheryRegistryResponseSchema', () => {
|
||||
it('validates a correct response', () => {
|
||||
const valid = {
|
||||
servers: [{
|
||||
qualifiedName: 'slack',
|
||||
displayName: 'Slack',
|
||||
description: 'Slack integration',
|
||||
verified: true,
|
||||
useCount: 14062,
|
||||
remote: true,
|
||||
}],
|
||||
pagination: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
totalPages: 5,
|
||||
totalCount: 50,
|
||||
},
|
||||
};
|
||||
const result = SmitheryRegistryResponseSchema.safeParse(valid);
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects response without pagination', () => {
|
||||
const result = SmitheryRegistryResponseSchema.safeParse({
|
||||
servers: [{ qualifiedName: 'test' }],
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('defaults useCount and verified', () => {
|
||||
const minimal = {
|
||||
servers: [{ qualifiedName: 'test' }],
|
||||
pagination: { currentPage: 1, pageSize: 10, totalPages: 1, totalCount: 1 },
|
||||
};
|
||||
const result = SmitheryRegistryResponseSchema.parse(minimal);
|
||||
expect(result.servers[0]?.useCount).toBe(0);
|
||||
expect(result.servers[0]?.verified).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user