Skip to main content
Glama
links.test.ts9.12 kB
/** * TUI Link Components Tests * * @package WP_Navigator_Pro * @since 1.1.0 */ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { WPNAV_URLS, supportsHyperlinks, link, wpnavLink, demoLink, helpLink, docsLink, troubleshootLink, cliDocsLink, resourceLinks, getErrorHelpLink, errorWithHelp, } from './links.js'; describe('TUI Links', () => { // Save original env const originalEnv = { ...process.env }; beforeEach(() => { // Reset env for each test process.env = { ...originalEnv }; // Clear hyperlink-related env vars delete process.env.FORCE_HYPERLINK; delete process.env.TERM_PROGRAM; delete process.env.TERM_PROGRAM_VERSION; delete process.env.WT_SESSION; delete process.env.VTE_VERSION; delete process.env.ALACRITTY_LOG; delete process.env.KITTY_WINDOW_ID; delete process.env.WEZTERM_EXECUTABLE; delete process.env.NO_COLOR; delete process.env.FORCE_COLOR; }); afterEach(() => { process.env = originalEnv; }); describe('WPNAV_URLS', () => { it('should have all required URLs', () => { expect(WPNAV_URLS.demo).toBe('https://wpnav.ai/start/demo'); expect(WPNAV_URLS.help).toBe('https://wpnav.ai/help'); expect(WPNAV_URLS.docs).toBe('https://wpnav.ai/docs'); expect(WPNAV_URLS.troubleshoot).toBe('https://wpnav.ai/troubleshoot'); expect(WPNAV_URLS.cliDocs).toBe('https://wpnav.ai/docs/cli'); expect(WPNAV_URLS.download).toBe('https://wpnav.ai/download'); expect(WPNAV_URLS.start).toBe('https://wpnav.ai/start'); }); it('should have immutable URLs (readonly)', () => { // TypeScript ensures this at compile time, but we can verify the values const urls = WPNAV_URLS; expect(Object.keys(urls)).toContain('demo'); expect(Object.keys(urls)).toContain('help'); expect(Object.keys(urls)).toContain('docs'); }); }); describe('supportsHyperlinks()', () => { it('should return true when FORCE_HYPERLINK=1', () => { process.env.FORCE_HYPERLINK = '1'; expect(supportsHyperlinks()).toBe(true); }); it('should return false when FORCE_HYPERLINK=0', () => { process.env.FORCE_HYPERLINK = '0'; expect(supportsHyperlinks()).toBe(false); }); // Note: Tests that require modifying process.stdout.isTTY are skipped // because the property cannot be redefined in Node.js test environment. // The FORCE_HYPERLINK env var tests cover the override behavior. }); describe('link()', () => { beforeEach(() => { // Force no hyperlinks, no colors for predictable output process.env.FORCE_HYPERLINK = '0'; process.env.NO_COLOR = '1'; }); it('should return URL as-is when no text provided', () => { const result = link('https://example.com'); expect(result).toBe('https://example.com'); }); it('should return custom text when provided', () => { const result = link('https://example.com', { text: 'Example' }); expect(result).toBe('Example'); }); it('should show URL in parentheses with showUrl option', () => { const result = link('https://example.com', { text: 'Example', showUrl: true }); expect(result).toBe('Example (https://example.com)'); }); it('should not show parentheses when text not provided', () => { const result = link('https://example.com', { showUrl: true }); // When no text, showUrl is ignored - URL is already shown expect(result).toBe('https://example.com'); }); }); describe('link() with hyperlinks enabled', () => { beforeEach(() => { process.env.FORCE_HYPERLINK = '1'; process.env.NO_COLOR = '1'; }); it('should include OSC 8 escape sequences', () => { const result = link('https://example.com', { text: 'Example' }); // OSC 8 format: \x1b]8;;URL\x1b\\text\x1b]8;;\x1b\\ expect(result).toContain('\x1b]8;;https://example.com\x1b\\'); expect(result).toContain('Example'); expect(result).toContain('\x1b]8;;\x1b\\'); }); }); describe('wpnavLink()', () => { beforeEach(() => { process.env.FORCE_HYPERLINK = '0'; process.env.NO_COLOR = '1'; }); it('should return correct URL for demo', () => { const result = wpnavLink('demo'); expect(result).toBe('https://wpnav.ai/start/demo'); }); it('should return correct URL for help', () => { const result = wpnavLink('help'); expect(result).toBe('https://wpnav.ai/help'); }); it('should return correct URL for docs', () => { const result = wpnavLink('docs'); expect(result).toBe('https://wpnav.ai/docs'); }); it('should use custom text when provided', () => { const result = wpnavLink('help', { text: 'Get Help' }); expect(result).toBe('Get Help'); }); }); describe('contextual link helpers', () => { beforeEach(() => { process.env.FORCE_HYPERLINK = '0'; process.env.NO_COLOR = '1'; }); it('demoLink() should include demo URL', () => { const result = demoLink(); expect(result).toContain('https://wpnav.ai/start/demo'); expect(result).toContain('Watch demo'); }); it('helpLink() should include help URL', () => { const result = helpLink(); expect(result).toContain('https://wpnav.ai/help'); expect(result).toContain('Need help?'); }); it('docsLink() should include docs URL', () => { const result = docsLink(); expect(result).toContain('https://wpnav.ai/docs'); expect(result).toContain('Documentation'); }); it('troubleshootLink() should include troubleshoot URL', () => { const result = troubleshootLink(); expect(result).toContain('https://wpnav.ai/troubleshoot'); expect(result).toContain('Troubleshooting'); }); it('cliDocsLink() should include CLI docs URL', () => { const result = cliDocsLink(); expect(result).toContain('https://wpnav.ai/docs/cli'); expect(result).toContain('CLI docs'); }); }); describe('resourceLinks()', () => { beforeEach(() => { process.env.FORCE_HYPERLINK = '0'; process.env.NO_COLOR = '1'; }); it('should return default links (demo, help, docs)', () => { const result = resourceLinks(); expect(result).toHaveLength(3); expect(result[0]).toContain('demo'); expect(result[1]).toContain('help'); expect(result[2]).toContain('docs'); }); it('should return specified links', () => { const result = resourceLinks(['troubleshoot', 'cliDocs']); expect(result).toHaveLength(2); expect(result[0]).toContain('troubleshoot'); expect(result[1]).toContain('docs/cli'); }); it('should not duplicate URLs', () => { // If same key is passed twice, should only appear once const result = resourceLinks(['help', 'help']); expect(result).toHaveLength(1); }); }); describe('getErrorHelpLink()', () => { it('should return troubleshoot URL for connection errors', () => { expect(getErrorHelpLink('connection')).toBe(WPNAV_URLS.troubleshoot); expect(getErrorHelpLink('network')).toBe(WPNAV_URLS.troubleshoot); expect(getErrorHelpLink('timeout')).toBe(WPNAV_URLS.troubleshoot); expect(getErrorHelpLink('auth')).toBe(WPNAV_URLS.troubleshoot); expect(getErrorHelpLink('authentication')).toBe(WPNAV_URLS.troubleshoot); }); it('should return docs URL for config/validation errors', () => { expect(getErrorHelpLink('config')).toBe(WPNAV_URLS.docs); expect(getErrorHelpLink('validation')).toBe(WPNAV_URLS.docs); expect(getErrorHelpLink('manifest')).toBe(WPNAV_URLS.docs); }); it('should return help URL for unknown error types', () => { expect(getErrorHelpLink()).toBe(WPNAV_URLS.help); expect(getErrorHelpLink('unknown')).toBe(WPNAV_URLS.help); expect(getErrorHelpLink('')).toBe(WPNAV_URLS.help); }); it('should be case-insensitive', () => { expect(getErrorHelpLink('CONNECTION')).toBe(WPNAV_URLS.troubleshoot); expect(getErrorHelpLink('Config')).toBe(WPNAV_URLS.docs); }); }); describe('errorWithHelp()', () => { beforeEach(() => { process.env.FORCE_HYPERLINK = '0'; process.env.NO_COLOR = '1'; }); it('should append help link to error message', () => { const result = errorWithHelp('Something went wrong'); expect(result).toContain('Something went wrong'); expect(result).toContain('Get help'); // When NO_COLOR is set and no hyperlinks, link() returns just the text }); it('should use contextual help URL for connection errors', () => { // Verify the function uses the right URL internally const helpUrl = getErrorHelpLink('connection'); expect(helpUrl).toBe(WPNAV_URLS.troubleshoot); }); it('should format message with newline before help', () => { const result = errorWithHelp('Error message', 'config'); expect(result).toContain('\n'); expect(result).toContain('Error message'); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/littlebearapps/wp-navigator-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server