chore: phase 2 and 3 refactors
This commit is contained in:
@@ -142,7 +142,7 @@ describe('Pages shortcut UI', () => {
|
||||
expect(window.electronAPI.posts.filter).not.toHaveBeenCalledWith({ categories: ['page'] });
|
||||
});
|
||||
|
||||
it('uses a flex-height wrapper for active posts/pages sidebar view', async () => {
|
||||
it('conditionally mounts only the active posts/pages sidebar content', async () => {
|
||||
useAppStore.setState({
|
||||
activeView: 'posts',
|
||||
sidebarVisible: true,
|
||||
@@ -153,8 +153,7 @@ describe('Pages shortcut UI', () => {
|
||||
expect(await screen.findByText('POSTS')).toBeInTheDocument();
|
||||
|
||||
const wrappers = container.querySelectorAll('.sidebar > div');
|
||||
expect(wrappers.length).toBeGreaterThanOrEqual(2);
|
||||
expect((wrappers[0] as HTMLElement).style.display).toBe('flex');
|
||||
expect(wrappers.length).toBe(1);
|
||||
});
|
||||
|
||||
it('opens style tab from settings sidebar navigation', async () => {
|
||||
|
||||
@@ -51,4 +51,16 @@ describe('Help menu documentation entry', () => {
|
||||
it('maps Validate Site to a renderer menu event', () => {
|
||||
expect(APP_MENU_ACTION_EVENT_MAP.validateSite).toBe('menu:validateSite');
|
||||
});
|
||||
|
||||
it('includes Edit Preferences action in Edit menu with comma shortcut', () => {
|
||||
const editGroup = APP_MENU_GROUPS.find((group) => group.label === 'Edit');
|
||||
const preferencesItem = editGroup?.items.find((item) => item.action === 'editPreferences');
|
||||
|
||||
expect(preferencesItem).toBeDefined();
|
||||
expect(preferencesItem?.accelerator).toContain(',');
|
||||
});
|
||||
|
||||
it('maps Edit Preferences to a renderer menu event', () => {
|
||||
expect(APP_MENU_ACTION_EVENT_MAP.editPreferences).toBe('menu:editPreferences');
|
||||
});
|
||||
});
|
||||
|
||||
40
tests/renderer/navigation/sectionActivation.test.ts
Normal file
40
tests/renderer/navigation/sectionActivation.test.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { activateSidebarSection } from '../../../src/renderer/navigation/sectionActivation';
|
||||
|
||||
describe('sectionActivation', () => {
|
||||
it('opens editor first and delays section activation when editor is not active', () => {
|
||||
const ensureEditor = vi.fn();
|
||||
const activateSection = vi.fn();
|
||||
const schedule = vi.fn((callback: () => void) => callback());
|
||||
|
||||
activateSidebarSection({
|
||||
isEditorTabActive: false,
|
||||
ensureEditorTabActive: ensureEditor,
|
||||
activateSection,
|
||||
schedule,
|
||||
delayWhenOpeningEditorMs: 100,
|
||||
});
|
||||
|
||||
expect(ensureEditor).toHaveBeenCalledTimes(1);
|
||||
expect(schedule).toHaveBeenCalledTimes(1);
|
||||
expect(schedule).toHaveBeenCalledWith(expect.any(Function), 100);
|
||||
expect(activateSection).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('activates section immediately when editor tab is already active', () => {
|
||||
const ensureEditor = vi.fn();
|
||||
const activateSection = vi.fn();
|
||||
const schedule = vi.fn((callback: () => void) => callback());
|
||||
|
||||
activateSidebarSection({
|
||||
isEditorTabActive: true,
|
||||
ensureEditorTabActive: ensureEditor,
|
||||
activateSection,
|
||||
schedule,
|
||||
});
|
||||
|
||||
expect(ensureEditor).not.toHaveBeenCalled();
|
||||
expect(schedule).toHaveBeenCalledWith(expect.any(Function), 0);
|
||||
expect(activateSection).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
14
tests/renderer/navigation/sidebarUiPersistence.test.ts
Normal file
14
tests/renderer/navigation/sidebarUiPersistence.test.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getPersistedSidebarSection, setPersistedSidebarSection } from '../../../src/renderer/navigation/sidebarUiPersistence';
|
||||
|
||||
describe('sidebarUiPersistence', () => {
|
||||
it('persists and reads section ids by sidebar key', () => {
|
||||
setPersistedSidebarSection('settings', 'project');
|
||||
|
||||
expect(getPersistedSidebarSection('settings')).toBe('project');
|
||||
});
|
||||
|
||||
it('returns null for missing persisted section', () => {
|
||||
expect(getPersistedSidebarSection('tags')).toBeNull();
|
||||
});
|
||||
});
|
||||
30
tests/renderer/navigation/sidebarViewRegistry.test.ts
Normal file
30
tests/renderer/navigation/sidebarViewRegistry.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
DEFAULT_SIDEBAR_VIEW,
|
||||
SIDEBAR_VIEW_REGISTRY,
|
||||
isSidebarView,
|
||||
} from '../../../src/renderer/navigation/sidebarViewRegistry';
|
||||
|
||||
describe('sidebarViewRegistry', () => {
|
||||
it('defines all supported sidebar views in one canonical registry', () => {
|
||||
expect(SIDEBAR_VIEW_REGISTRY).toEqual([
|
||||
'posts',
|
||||
'pages',
|
||||
'media',
|
||||
'settings',
|
||||
'tags',
|
||||
'chat',
|
||||
'import',
|
||||
'git',
|
||||
]);
|
||||
});
|
||||
|
||||
it('uses posts as default sidebar view', () => {
|
||||
expect(DEFAULT_SIDEBAR_VIEW).toBe('posts');
|
||||
});
|
||||
|
||||
it('validates sidebar view values', () => {
|
||||
expect(isSidebarView('tags')).toBe(true);
|
||||
expect(isSidebarView('unknown')).toBe(false);
|
||||
});
|
||||
});
|
||||
27
tests/renderer/navigation/siteValidationPersistence.test.ts
Normal file
27
tests/renderer/navigation/siteValidationPersistence.test.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { SiteValidationReport } from '../../../src/main/shared/electronApi';
|
||||
import {
|
||||
getPersistedSiteValidationReport,
|
||||
persistSiteValidationReport,
|
||||
} from '../../../src/renderer/navigation/siteValidationPersistence';
|
||||
|
||||
const report: SiteValidationReport = {
|
||||
sitemapPath: '/tmp/sitemap.xml',
|
||||
sitemapChanged: false,
|
||||
missingUrlPaths: ['/foo'],
|
||||
extraUrlPaths: ['/bar'],
|
||||
expectedUrlCount: 10,
|
||||
existingHtmlUrlCount: 9,
|
||||
};
|
||||
|
||||
describe('siteValidationPersistence', () => {
|
||||
it('persists and loads site validation report by project', () => {
|
||||
persistSiteValidationReport('project-1', report);
|
||||
|
||||
expect(getPersistedSiteValidationReport('project-1')).toEqual(report);
|
||||
});
|
||||
|
||||
it('returns null when project has no persisted report', () => {
|
||||
expect(getPersistedSiteValidationReport('missing-project')).toBeNull();
|
||||
});
|
||||
});
|
||||
25
tests/renderer/navigation/tabPolicy.test.ts
Normal file
25
tests/renderer/navigation/tabPolicy.test.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getSingletonToolTabSpec, openSingletonToolTab } from '../../../src/renderer/navigation/tabPolicy';
|
||||
|
||||
describe('tabPolicy', () => {
|
||||
it('provides canonical singleton tab specs', () => {
|
||||
expect(getSingletonToolTabSpec('settings')).toEqual({ type: 'settings', id: 'settings', isTransient: false });
|
||||
expect(getSingletonToolTabSpec('tags')).toEqual({ type: 'tags', id: 'tags', isTransient: false });
|
||||
expect(getSingletonToolTabSpec('style')).toEqual({ type: 'style', id: 'style', isTransient: false });
|
||||
expect(getSingletonToolTabSpec('documentation')).toEqual({ type: 'documentation', id: 'documentation', isTransient: false });
|
||||
expect(getSingletonToolTabSpec('metadata-diff')).toEqual({ type: 'metadata-diff', id: 'metadata-diff', isTransient: false });
|
||||
expect(getSingletonToolTabSpec('site-validation')).toEqual({ type: 'site-validation', id: 'site-validation', isTransient: false });
|
||||
});
|
||||
|
||||
it('opens singleton tool tabs using canonical tab spec', () => {
|
||||
const openTab = (tab: { type: string; id: string; isTransient: boolean }) => {
|
||||
captured = tab;
|
||||
};
|
||||
|
||||
let captured: { type: string; id: string; isTransient: boolean } | null = null;
|
||||
|
||||
openSingletonToolTab(openTab, 'site-validation');
|
||||
|
||||
expect(captured).toEqual({ type: 'site-validation', id: 'site-validation', isTransient: false });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user