Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

244 lines
10 KiB
JavaScript

/**
* JavaScript tests for URL configuration
* Run with: npm test tests/infrastructure_tests/test_urls.test.js
*/
// Mock the window object for testing
global.window = {};
// Load the URLs configuration
const urlsModule = require('../../src/local_deep_research/web/static/js/config/urls.js');
// Get the exported values from window (for browser environment tests)
const { URLS, URLBuilder } = global.window;
describe('URLs Configuration', () => {
describe('URL Structure', () => {
test('URLS object should have required sections', () => {
expect(URLS).toBeDefined();
expect(URLS.API).toBeDefined();
expect(URLS.PAGES).toBeDefined();
expect(URLS.HISTORY_API).toBeDefined();
expect(URLS.SETTINGS_API).toBeDefined();
expect(URLS.METRICS_API).toBeDefined();
});
test('Critical API endpoints should be defined', () => {
const criticalAPIs = [
'START_RESEARCH',
'RESEARCH_STATUS',
'RESEARCH_DETAILS',
'RESEARCH_LOGS',
'RESEARCH_REPORT',
'TERMINATE_RESEARCH',
'DELETE_RESEARCH',
'HISTORY'
];
criticalAPIs.forEach(api => {
expect(URLS.API[api]).toBeDefined();
expect(typeof URLS.API[api]).toBe('string');
});
});
test('Page routes should be defined', () => {
const pages = ['HOME', 'PROGRESS', 'RESULTS', 'DETAILS', 'HISTORY', 'SETTINGS', 'METRICS',
'NEWS', 'NEWS_SUBSCRIPTIONS', 'BENCHMARK', 'BENCHMARK_RESULTS', 'EMBEDDING_SETTINGS'];
pages.forEach(page => {
expect(URLS.PAGES[page]).toBeDefined();
expect(typeof URLS.PAGES[page]).toBe('string');
});
});
});
describe('URLBuilder Functionality', () => {
test('build() should replace {id} placeholders', () => {
const template = '/api/research/{id}/status';
const result = URLBuilder.build(template, 123);
expect(result).toBe('/api/research/123/status');
});
test('buildWithReplacements() should handle multiple placeholders', () => {
const template = '/api/{type}/{id}/action';
const result = URLBuilder.buildWithReplacements(template, {
type: 'research',
id: 456
});
expect(result).toBe('/api/research/456/action');
});
test('Convenience methods should return correct URLs', () => {
expect(URLBuilder.progressPage(123)).toBe('/progress/123');
expect(URLBuilder.resultsPage(456)).toBe('/results/456');
expect(URLBuilder.detailsPage(789)).toBe('/details/789');
expect(URLBuilder.researchStatus(111)).toBe('/api/research/111/status');
expect(URLBuilder.researchDetails(222)).toBe('/api/research/222');
expect(URLBuilder.researchLogs(333)).toBe('/api/research/333/logs');
expect(URLBuilder.researchReport(444)).toBe('/api/report/444');
expect(URLBuilder.terminateResearch(555)).toBe('/api/terminate/555');
expect(URLBuilder.deleteResearch(666)).toBe('/api/delete/666');
});
test('History API convenience methods should work', () => {
expect(URLBuilder.historyStatus(123)).toBe('/history/status/123');
expect(URLBuilder.historyDetails(456)).toBe('/history/details/456');
expect(URLBuilder.historyLogs(789)).toBe('/history/logs/789');
expect(URLBuilder.historyReport(111)).toBe('/history/report/111');
expect(URLBuilder.markdownExport(222)).toBe('/api/markdown/222');
});
test('Settings API convenience methods should work', () => {
expect(URLBuilder.getSetting('llm.model')).toBe('/settings/api/llm.model');
expect(URLBuilder.updateSetting('search.tool')).toBe('/settings/api/search.tool');
expect(URLBuilder.deleteSetting('custom.key')).toBe('/settings/api/custom.key');
});
test('Metrics API convenience methods should work', () => {
expect(URLBuilder.researchMetrics(123)).toBe('/metrics/api/metrics/research/123');
expect(URLBuilder.researchTimelineMetrics(456)).toBe('/metrics/api/metrics/research/456/timeline');
expect(URLBuilder.researchSearchMetrics(789)).toBe('/metrics/api/metrics/research/789/search');
expect(URLBuilder.getRating(111)).toBe('/metrics/api/ratings/111');
expect(URLBuilder.saveRating(222)).toBe('/metrics/api/ratings/222');
expect(URLBuilder.researchCosts(333)).toBe('/metrics/api/research-costs/333');
});
});
describe('URL Pattern Extraction', () => {
beforeEach(() => {
// Mock window.location for testing
delete global.window.location;
global.window.location = { pathname: '/' };
});
test('extractResearchId() should extract ID from various patterns', () => {
const testCases = [
{ path: '/results/123', expected: '123' },
{ path: '/details/456', expected: '456' },
{ path: '/progress/789', expected: '789' },
{ path: '/home', expected: null },
{ path: '/settings/', expected: null }
];
testCases.forEach(({ path, expected }) => {
global.window.location.pathname = path;
expect(URLBuilder.extractResearchId()).toBe(expected);
});
});
test('extractResearchIdFromPattern() should work for specific patterns', () => {
global.window.location.pathname = '/results/999';
expect(URLBuilder.extractResearchIdFromPattern('results')).toBe('999');
global.window.location.pathname = '/details/888';
expect(URLBuilder.extractResearchIdFromPattern('details')).toBe('888');
expect(URLBuilder.extractResearchIdFromPattern('results')).toBe(null);
});
test('getCurrentPageType() should identify page types', () => {
const testCases = [
{ path: '/', expected: 'home' },
{ path: '/index', expected: 'home' },
{ path: '/results/123', expected: 'results' },
{ path: '/details/456', expected: 'details' },
{ path: '/progress/789', expected: 'progress' },
{ path: '/history', expected: 'history' },
{ path: '/history/', expected: 'history' },
{ path: '/settings', expected: 'settings' },
{ path: '/settings/advanced', expected: 'settings' },
{ path: '/metrics', expected: 'metrics' },
{ path: '/metrics/costs', expected: 'metrics' },
{ path: '/unknown/path', expected: 'unknown' }
];
testCases.forEach(({ path, expected }) => {
global.window.location.pathname = path;
expect(URLBuilder.getCurrentPageType()).toBe(expected);
});
});
});
describe('URL Consistency Checks', () => {
test('All URLs should start with /', () => {
const checkUrls = (obj, path = '') => {
Object.entries(obj).forEach(([key, value]) => {
if (typeof value === 'string') {
expect(value).toMatch(/^\//);
} else if (typeof value === 'object' && value !== null) {
checkUrls(value, `${path}.${key}`);
}
});
};
checkUrls(URLS);
});
test('URLs with parameters should use consistent placeholder format', () => {
const checkPlaceholders = (obj) => {
Object.entries(obj).forEach(([_key, value]) => {
if (typeof value === 'string') {
// Check that placeholders use {name} format
const placeholders = value.match(/\{[^}]+\}/g) || [];
placeholders.forEach(placeholder => {
expect(placeholder).toMatch(/^\{[a-z_]+\}$/i);
});
} else if (typeof value === 'object' && value !== null) {
checkPlaceholders(value);
}
});
};
checkPlaceholders(URLS);
});
test('API URLs should follow RESTful conventions', () => {
// URLs ending with ID should be for single resource operations
const singleResourcePatterns = [
'RESEARCH_STATUS',
'RESEARCH_DETAILS',
'RESEARCH_LOGS',
'RESEARCH_REPORT',
'TERMINATE_RESEARCH',
'DELETE_RESEARCH'
];
singleResourcePatterns.forEach(pattern => {
expect(URLS.API[pattern]).toMatch(/\{id\}/);
});
// Collection URLs should not have ID
expect(URLS.API.HISTORY).not.toMatch(/\{id\}/);
expect(URLS.API.CLEAR_HISTORY).not.toMatch(/\{id\}/);
});
test('Settings API URLs should be consistent', () => {
Object.entries(URLS.SETTINGS_API).forEach(([key, url]) => {
if (key !== 'BASE') {
expect(url).toMatch(/^\/settings\//);
}
});
});
test('Metrics API URLs should be consistent', () => {
Object.entries(URLS.METRICS_API).forEach(([key, url]) => {
if (key !== 'BASE') {
expect(url).toMatch(/^\/metrics\//);
}
});
});
});
describe('Export Validation', () => {
test('Module should export correctly for different environments', () => {
// Browser environment (already tested via global.window)
expect(global.window.URLS).toBeDefined();
expect(global.window.URLBuilder).toBeDefined();
// Node.js environment - check the imported module
expect(urlsModule).toBeDefined();
expect(urlsModule.URLS).toBeDefined();
expect(urlsModule.URLBuilder).toBeDefined();
});
});
});