229 lines
6.5 KiB
TypeScript
229 lines
6.5 KiB
TypeScript
import React from 'react';
|
|
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
import { act, render, screen } from '@testing-library/react';
|
|
import { TabBar } from '../../../src/renderer/components/TabBar/TabBar';
|
|
import { useAppStore } from '../../../src/renderer/store';
|
|
|
|
describe('TabBar', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
|
|
(window as any).addEventListener = vi.fn();
|
|
(window as any).removeEventListener = vi.fn();
|
|
|
|
if (!(globalThis as any).ResizeObserver) {
|
|
(globalThis as any).ResizeObserver = class {
|
|
observe() {}
|
|
disconnect() {}
|
|
};
|
|
}
|
|
|
|
useAppStore.setState({
|
|
activeProject: {
|
|
id: 'project-1',
|
|
name: 'Test Project',
|
|
slug: 'test-project',
|
|
isActive: true,
|
|
dataPath: '/repo/path',
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
},
|
|
tabs: [
|
|
{ type: 'git-diff', id: 'git-diff:commit:abc123def456', isTransient: false },
|
|
],
|
|
activeTabId: 'git-diff:commit:abc123def456',
|
|
media: [],
|
|
dirtyPosts: new Set<string>(),
|
|
sidebarVisible: true,
|
|
});
|
|
|
|
(window as any).electronAPI = {
|
|
...(window as any).electronAPI,
|
|
git: {
|
|
...(window as any).electronAPI?.git,
|
|
getHistory: vi.fn().mockResolvedValue([
|
|
{
|
|
hash: 'abc123def456',
|
|
shortHash: 'abc123d',
|
|
date: '2026-02-16T10:00:00.000Z',
|
|
subject: 'feat: improve commit diff tabs',
|
|
author: 'Dev One',
|
|
},
|
|
]),
|
|
},
|
|
app: {
|
|
...(window as any).electronAPI?.app,
|
|
getDefaultProjectPath: vi.fn().mockResolvedValue('/repo/path'),
|
|
},
|
|
posts: {
|
|
...(window as any).electronAPI?.posts,
|
|
get: vi.fn(),
|
|
},
|
|
chat: {
|
|
...(window as any).electronAPI?.chat,
|
|
getConversation: vi.fn(),
|
|
onTitleUpdated: vi.fn(() => () => {}),
|
|
},
|
|
importDefinitions: {
|
|
...(window as any).electronAPI?.importDefinitions,
|
|
get: vi.fn(),
|
|
onNameUpdated: vi.fn(() => () => {}),
|
|
},
|
|
scripts: {
|
|
...(window as any).electronAPI?.scripts,
|
|
get: vi.fn(),
|
|
},
|
|
templates: {
|
|
...(window as any).electronAPI?.templates,
|
|
get: vi.fn(),
|
|
},
|
|
};
|
|
});
|
|
|
|
it('renders commit subject in git-diff commit tab titles when available', async () => {
|
|
render(<TabBar />);
|
|
|
|
expect(await screen.findByText('abc123d feat: improve commit diff tabs')).toBeInTheDocument();
|
|
expect((window as any).electronAPI.git.getHistory).toHaveBeenCalledWith('/repo/path', 200);
|
|
});
|
|
|
|
it('does not render the tab bar when there are no open tabs', () => {
|
|
useAppStore.setState({ tabs: [], activeTabId: null });
|
|
|
|
const { container } = render(<TabBar />);
|
|
|
|
expect(container.querySelector('.tab-bar')).toBeNull();
|
|
});
|
|
|
|
it('renders style tab label', async () => {
|
|
useAppStore.setState({
|
|
tabs: [{ type: 'style', id: 'style', isTransient: false }],
|
|
activeTabId: 'style',
|
|
});
|
|
|
|
render(<TabBar />);
|
|
|
|
expect(await screen.findByText('Style')).toBeInTheDocument();
|
|
});
|
|
|
|
it('updates post tab title when post title changes in store', async () => {
|
|
useAppStore.setState({
|
|
tabs: [{ type: 'post', id: 'post-1', isTransient: false }],
|
|
activeTabId: 'post-1',
|
|
posts: [{
|
|
id: 'post-1',
|
|
title: '',
|
|
slug: 'post-1',
|
|
content: '',
|
|
excerpt: null,
|
|
author: null,
|
|
status: 'draft',
|
|
publishedAt: null,
|
|
scheduledAt: null,
|
|
tags: [],
|
|
categories: [],
|
|
metadata: {},
|
|
projectId: 'project-1',
|
|
createdAt: new Date().toISOString(),
|
|
updatedAt: new Date().toISOString(),
|
|
}],
|
|
});
|
|
|
|
(window as any).electronAPI.posts.get = vi.fn().mockResolvedValue({
|
|
id: 'post-1',
|
|
title: '',
|
|
});
|
|
|
|
render(<TabBar />);
|
|
|
|
expect(await screen.findByText('Untitled')).toBeInTheDocument();
|
|
|
|
act(() => {
|
|
useAppStore.getState().updatePost('post-1', { title: 'Updated Title' });
|
|
});
|
|
|
|
expect(await screen.findByText('Updated Title')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders script title for script tab', async () => {
|
|
useAppStore.setState({
|
|
tabs: [{ type: 'scripts', id: 'script-1', isTransient: false }],
|
|
activeTabId: 'script-1',
|
|
posts: [],
|
|
media: [],
|
|
dirtyPosts: new Set<string>(),
|
|
});
|
|
|
|
(window as any).electronAPI.scripts.get = vi.fn().mockResolvedValue({
|
|
id: 'script-1',
|
|
title: 'Publish Macro',
|
|
});
|
|
|
|
render(<TabBar />);
|
|
|
|
expect(await screen.findByText('Publish Macro')).toBeInTheDocument();
|
|
expect((window as any).electronAPI.scripts.get).toHaveBeenCalledWith('script-1');
|
|
});
|
|
|
|
it('renders template title for template tab', async () => {
|
|
useAppStore.setState({
|
|
tabs: [{ type: 'templates', id: 'template-1', isTransient: false }],
|
|
activeTabId: 'template-1',
|
|
posts: [],
|
|
media: [],
|
|
dirtyPosts: new Set<string>(),
|
|
});
|
|
|
|
(window as any).electronAPI.templates.get = vi.fn().mockResolvedValue({
|
|
id: 'template-1',
|
|
title: 'Blog Post Layout',
|
|
});
|
|
|
|
render(<TabBar />);
|
|
|
|
expect(await screen.findByText('Blog Post Layout')).toBeInTheDocument();
|
|
expect((window as any).electronAPI.templates.get).toHaveBeenCalledWith('template-1');
|
|
});
|
|
|
|
it('updates template tab title when template changes', async () => {
|
|
useAppStore.setState({
|
|
tabs: [{ type: 'templates', id: 'template-1', isTransient: false }],
|
|
activeTabId: 'template-1',
|
|
posts: [],
|
|
media: [],
|
|
dirtyPosts: new Set<string>(),
|
|
});
|
|
|
|
(window as any).electronAPI.templates.get = vi.fn().mockResolvedValue({
|
|
id: 'template-1',
|
|
title: 'Old Title',
|
|
});
|
|
|
|
// Capture the bds:templates-changed listener
|
|
let templatesChangedHandler: (() => void) | null = null;
|
|
(window as any).addEventListener = vi.fn((event: string, handler: () => void) => {
|
|
if (event === 'bds:templates-changed') {
|
|
templatesChangedHandler = handler;
|
|
}
|
|
});
|
|
(window as any).removeEventListener = vi.fn();
|
|
|
|
render(<TabBar />);
|
|
|
|
expect(await screen.findByText('Old Title')).toBeInTheDocument();
|
|
|
|
// Now simulate the template being updated
|
|
(window as any).electronAPI.templates.get = vi.fn().mockResolvedValue({
|
|
id: 'template-1',
|
|
title: 'New Title',
|
|
});
|
|
|
|
// Trigger the templates-changed event
|
|
await act(async () => {
|
|
templatesChangedHandler?.();
|
|
});
|
|
|
|
expect(await screen.findByText('New Title')).toBeInTheDocument();
|
|
});
|
|
});
|