/** * v6 unit tests for the per-publisher namespacing helpers * (loadPublisherSuffix + applyPublisherSuffix). The wiring through * mcplocal/main.ts is exercised at the smoke level; these tests * cover the pure logic so name-mangling regressions are caught fast. */ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { resetConfigCache, applyPublisherSuffix, loadPublisherSuffix } from '../src/http/config.js'; describe('applyPublisherSuffix', () => { it('passes the name through unchanged when the suffix is empty', () => { // Empty suffix is the legacy code path — pre-v6 behavior. expect(applyPublisherSuffix('vllm-local-qwen3', '')).toBe('vllm-local-qwen3'); }); it('appends - to a normal name', () => { expect(applyPublisherSuffix('vllm-local-qwen3', 'alice')).toBe('vllm-local-qwen3-alice'); }); it('throws when the combined length exceeds the 100-char limit', () => { // Name validation on mcpd's side caps at 100; we'd rather error // loud at enqueue time than have the register POST 422 later. const longName = 'a'.repeat(95); expect(() => applyPublisherSuffix(longName, 'alicebob')).toThrow(/100-char limit/); }); it('lets a name + short suffix exactly hit 100', () => { const name = 'a'.repeat(95); expect(applyPublisherSuffix(name, 'four')).toHaveLength(100); }); }); describe('loadPublisherSuffix', () => { beforeEach(() => { resetConfigCache(); vi.unstubAllEnvs(); }); afterEach(() => { vi.unstubAllEnvs(); resetConfigCache(); }); it('honors MCPCTL_PUBLISHER_SUFFIX env var (operations override)', () => { // Env override takes precedence so an operator can flip the suffix // for a one-off run without touching ~/.mcpctl/config.json. expect(loadPublisherSuffix({ MCPCTL_PUBLISHER_SUFFIX: 'BoB.Lap-top' })).toBe('bob-lap-top'); }); it('returns empty string when neither env nor config sets a suffix', () => { expect(loadPublisherSuffix({})).toBe(''); }); it('sanitizes uppercase + special chars + collapses runs', () => { expect(loadPublisherSuffix({ MCPCTL_PUBLISHER_SUFFIX: "Alice's-MacBook.Pro!!" })).toBe('alice-s-macbook-pro'); }); it('strips leading/trailing dashes after sanitization', () => { expect(loadPublisherSuffix({ MCPCTL_PUBLISHER_SUFFIX: '___bob___' })).toBe('bob'); }); });