codex specify

This commit is contained in:
2026-02-25 21:19:48 +03:00
parent b7d1ee2b71
commit 5ec1254336
40 changed files with 3535 additions and 238 deletions

View File

@@ -24,11 +24,27 @@ vi.mock('$lib/i18n', () => ({
fn({
settings: {
title: 'Settings',
migration: 'Migration Sync',
migration_sync: 'Migration Sync',
migration_sync_title: 'Cross-Environment ID Synchronization',
migration_sync_description: 'Sync IDs across environments',
sync_schedule: 'Sync Schedule',
sync_now: 'Sync Now',
syncing: 'Syncing...',
saving: 'Saving...',
environments: 'Environments',
logging: 'Logging',
connections: 'Connections',
llm: 'LLM',
storage: 'Storage',
save_success: 'Settings saved',
save_failed: 'Failed'
save_failed: 'Failed',
env_description: 'Configure environments',
migration_sync_failed: 'Sync failed'
},
common: { refresh: 'Refresh' }
common: { refresh: 'Refresh', save: 'Save' },
tasks: { cron_label: 'Cron Expression', cron_hint: 'Standard cron format' },
nav: { settings_git: 'Git' },
connections: { name: 'Name', user: 'User' }
});
return () => { };
}

View File

@@ -28,11 +28,33 @@ vi.mock('$lib/i18n', () => ({
fn({
settings: {
title: 'Settings',
migration: 'Migration Sync',
migration_sync: 'Migration Sync',
migration_sync_title: 'Cross-Environment ID Synchronization',
migration_sync_description: 'Sync IDs across environments',
sync_schedule: 'Sync Schedule',
sync_now: 'Sync Now',
syncing: 'Syncing...',
saving: 'Saving...',
environments: 'Environments',
logging: 'Logging',
logging_description: 'Configure logging',
log_level: 'Log Level',
task_log_level: 'Task Log Level',
enable_belief_state: 'Enable Belief State',
connections: 'Connections',
llm: 'LLM',
storage: 'Storage',
save_success: 'Settings saved',
save_failed: 'Failed'
save_failed: 'Failed',
save_logging: 'Save Logging Config',
env_description: 'Configure environments',
load_failed: 'Failed to load settings',
migration_sync_failed: 'Sync failed'
},
common: { refresh: 'Refresh', retry: 'Retry' }
common: { refresh: 'Refresh', retry: 'Retry', save: 'Save' },
tasks: { cron_label: 'Cron Expression', cron_hint: 'Standard cron format' },
nav: { settings_git: 'Git' },
connections: { name: 'Name', user: 'User' }
});
return () => { };
}
@@ -74,7 +96,11 @@ describe('SettingsPage UX Contracts', () => {
resolveSettings = resolve;
}));
api.requestApi.mockResolvedValue(mockMigrationSettings);
api.requestApi.mockImplementation((url) => {
if (url === '/migration/settings') return Promise.resolve(mockMigrationSettings);
if (url.includes('/migration/mappings-data')) return Promise.resolve({ items: [], total: 0 });
return Promise.resolve({});
});
render(SettingsPage);
@@ -86,10 +112,11 @@ describe('SettingsPage UX Contracts', () => {
// Resolve the API call
resolveSettings(mockSettings);
// Assert Loaded state
// Assert Loaded state - use getAllByText because 'Environments' may appear
// both as tab text and section heading on the default tab
await waitFor(() => {
expect(screen.getByText('Settings')).toBeTruthy();
expect(screen.getByText('Environments')).toBeTruthy();
expect(screen.getAllByText('Environments').length).toBeGreaterThan(0);
});
});
@@ -115,7 +142,11 @@ describe('SettingsPage UX Contracts', () => {
return mockSettings;
});
api.requestApi.mockResolvedValue(mockMigrationSettings);
api.requestApi.mockImplementation((url) => {
if (url === '/migration/settings') return Promise.resolve(mockMigrationSettings);
if (url.includes('/migration/mappings-data')) return Promise.resolve({ items: [], total: 0 });
return Promise.resolve({});
});
render(SettingsPage);
@@ -128,10 +159,11 @@ describe('SettingsPage UX Contracts', () => {
const retryBtn = screen.getByText('Retry');
await fireEvent.click(retryBtn);
// Verify recovery (Loaded state)
// Verify recovery (Loaded state) - use getAllByText because 'Environments'
// appears both as tab text and section heading
await waitFor(() => {
expect(screen.queryByText('First call failed')).toBeNull();
expect(screen.getByText('Environments')).toBeTruthy();
expect(screen.getAllByText('Environments').length).toBeGreaterThan(0);
});
// We expect it to have been called twice (1. initial mount, 2. retry click)
expect(api.getConsolidatedSettings).toHaveBeenCalledTimes(2);
@@ -147,7 +179,8 @@ describe('SettingsPage UX Contracts', () => {
await waitFor(() => expect(screen.getByText('Settings')).toBeTruthy());
// Navigate to Logging tab where the Save button is
await fireEvent.click(screen.getByText('Logging'));
// 'Logging' appears in both the tab and section heading; use getAllByText
await fireEvent.click(screen.getAllByText('Logging')[0]);
const saveBtn = screen.getByText('Save Logging Config');
await fireEvent.click(saveBtn);
@@ -166,7 +199,8 @@ describe('SettingsPage UX Contracts', () => {
await waitFor(() => expect(screen.getByText('Settings')).toBeTruthy());
// Navigate to Logging tab where the Save button is
await fireEvent.click(screen.getByText('Logging'));
// 'Logging' appears in both the tab and section heading; use getAllByText
await fireEvent.click(screen.getAllByText('Logging')[0]);
const saveBtn = screen.getByText('Save Logging Config');
await fireEvent.click(saveBtn);