Refactor workspace settings handling in tests and components to use currentWorkspace directly

This commit is contained in:
2025-07-06 00:41:30 +02:00
parent 7368797a11
commit cf554fbb6e
9 changed files with 25 additions and 73 deletions

View File

@@ -70,7 +70,6 @@ describe('ContentView', () => {
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: mockCurrentWorkspace, currentWorkspace: mockCurrentWorkspace,
workspaces: [], workspaces: [],
settings: mockCurrentWorkspace,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',
@@ -88,7 +87,6 @@ describe('ContentView', () => {
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: null,
workspaces: [], workspaces: [],
settings: mockCurrentWorkspace,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',

View File

@@ -9,7 +9,7 @@ import React from 'react';
import { MantineProvider } from '@mantine/core'; import { MantineProvider } from '@mantine/core';
import MarkdownPreview from './MarkdownPreview'; import MarkdownPreview from './MarkdownPreview';
import { notifications } from '@mantine/notifications'; import { notifications } from '@mantine/notifications';
import { Theme, DEFAULT_WORKSPACE_SETTINGS } from '../../types/models'; import { Theme } from '../../types/models';
// Mock notifications // Mock notifications
vi.mock('@mantine/notifications', () => ({ vi.mock('@mantine/notifications', () => ({
@@ -70,7 +70,6 @@ describe('MarkdownPreview', () => {
lastOpenedFilePath: '', lastOpenedFilePath: '',
}, },
workspaces: [], workspaces: [],
settings: DEFAULT_WORKSPACE_SETTINGS,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',
@@ -213,7 +212,6 @@ describe('MarkdownPreview', () => {
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: null,
workspaces: [], workspaces: [],
settings: DEFAULT_WORKSPACE_SETTINGS,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',

View File

@@ -23,7 +23,10 @@ describe('FileActions', () => {
const mockSetDeleteFileModalVisible = vi.fn(); const mockSetDeleteFileModalVisible = vi.fn();
const mockSetCommitMessageModalVisible = vi.fn(); const mockSetCommitMessageModalVisible = vi.fn();
const mockSettings = { const mockCurrentWorkspace = {
id: 1,
name: 'Test Workspace',
createdAt: '2024-01-01T00:00:00Z',
gitEnabled: true, gitEnabled: true,
gitAutoCommit: false, gitAutoCommit: false,
theme: Theme.Light, theme: Theme.Light,
@@ -61,9 +64,8 @@ describe('FileActions', () => {
const { useWorkspace } = await import('../../hooks/useWorkspace'); const { useWorkspace } = await import('../../hooks/useWorkspace');
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: mockCurrentWorkspace,
workspaces: [], workspaces: [],
settings: mockSettings,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',
@@ -140,9 +142,8 @@ describe('FileActions', () => {
it('disables git buttons when git is not enabled', async () => { it('disables git buttons when git is not enabled', async () => {
const { useWorkspace } = await import('../../hooks/useWorkspace'); const { useWorkspace } = await import('../../hooks/useWorkspace');
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: { ...mockCurrentWorkspace, gitEnabled: false },
workspaces: [], workspaces: [],
settings: { ...mockSettings, gitEnabled: false },
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',
@@ -186,9 +187,8 @@ describe('FileActions', () => {
it('disables commit button when auto-commit is enabled', async () => { it('disables commit button when auto-commit is enabled', async () => {
const { useWorkspace } = await import('../../hooks/useWorkspace'); const { useWorkspace } = await import('../../hooks/useWorkspace');
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: { ...mockCurrentWorkspace, gitAutoCommit: true },
workspaces: [], workspaces: [],
settings: { ...mockSettings, gitAutoCommit: true },
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',

View File

@@ -18,7 +18,7 @@ const FileActions: React.FC<FileActionsProps> = ({
handlePullChanges, handlePullChanges,
selectedFile, selectedFile,
}) => { }) => {
const { settings } = useWorkspace(); const { currentWorkspace } = useWorkspace();
const { const {
setNewFileModalVisible, setNewFileModalVisible,
setDeleteFileModalVisible, setDeleteFileModalVisible,
@@ -61,7 +61,7 @@ const FileActions: React.FC<FileActionsProps> = ({
<Tooltip <Tooltip
label={ label={
settings.gitEnabled currentWorkspace?.gitEnabled
? 'Pull changes from remote' ? 'Pull changes from remote'
: 'Git is not enabled' : 'Git is not enabled'
} }
@@ -74,7 +74,7 @@ const FileActions: React.FC<FileActionsProps> = ({
console.error('Error pulling changes:', error); console.error('Error pulling changes:', error);
}); });
}} }}
disabled={!settings.gitEnabled} disabled={!currentWorkspace?.gitEnabled}
aria-label="Pull changes from remote" aria-label="Pull changes from remote"
data-testid="pull-changes-button" data-testid="pull-changes-button"
> >
@@ -84,9 +84,9 @@ const FileActions: React.FC<FileActionsProps> = ({
<Tooltip <Tooltip
label={ label={
!settings.gitEnabled !currentWorkspace?.gitEnabled
? 'Git is not enabled' ? 'Git is not enabled'
: settings.gitAutoCommit : currentWorkspace.gitAutoCommit
? 'Auto-commit is enabled' ? 'Auto-commit is enabled'
: 'Commit and push changes' : 'Commit and push changes'
} }
@@ -95,7 +95,9 @@ const FileActions: React.FC<FileActionsProps> = ({
variant="default" variant="default"
size="md" size="md"
onClick={handleCommitAndPush} onClick={handleCommitAndPush}
disabled={!settings.gitEnabled || settings.gitAutoCommit} disabled={
!currentWorkspace?.gitEnabled || currentWorkspace.gitAutoCommit
}
aria-label="Commit and push changes" aria-label="Commit and push changes"
data-testid="commit-push-button" data-testid="commit-push-button"
> >

View File

@@ -72,7 +72,6 @@ describe('Layout', () => {
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: mockCurrentWorkspace, currentWorkspace: mockCurrentWorkspace,
workspaces: [], workspaces: [],
settings: mockCurrentWorkspace,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',
@@ -112,7 +111,6 @@ describe('Layout', () => {
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: mockCurrentWorkspace, currentWorkspace: mockCurrentWorkspace,
workspaces: [], workspaces: [],
settings: mockCurrentWorkspace,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: true, loading: true,
colorScheme: 'light', colorScheme: 'light',
@@ -137,7 +135,6 @@ describe('Layout', () => {
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: null,
workspaces: [], workspaces: [],
settings: mockCurrentWorkspace,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',

View File

@@ -58,7 +58,10 @@ describe('Sidebar', () => {
}, },
]; ];
const mockSettings = { const mockCurrentWorkspace = {
id: 1,
name: 'test-workspace',
createdAt: '2024-01-01T00:00:00Z',
gitEnabled: true, gitEnabled: true,
gitAutoCommit: false, gitAutoCommit: false,
theme: Theme.Light, theme: Theme.Light,
@@ -88,7 +91,6 @@ describe('Sidebar', () => {
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: null,
workspaces: [], workspaces: [],
settings: mockSettings,
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',
@@ -122,9 +124,8 @@ describe('Sidebar', () => {
it('passes showHiddenFiles setting to file tree', async () => { it('passes showHiddenFiles setting to file tree', async () => {
const { useWorkspace } = await import('../../hooks/useWorkspace'); const { useWorkspace } = await import('../../hooks/useWorkspace');
vi.mocked(useWorkspace).mockReturnValue({ vi.mocked(useWorkspace).mockReturnValue({
currentWorkspace: null, currentWorkspace: { ...mockCurrentWorkspace, showHiddenFiles: true },
workspaces: [], workspaces: [],
settings: { ...mockSettings, showHiddenFiles: true },
updateSettings: vi.fn(), updateSettings: vi.fn(),
loading: false, loading: false,
colorScheme: 'light', colorScheme: 'light',

View File

@@ -19,7 +19,7 @@ const Sidebar: React.FC<SidebarProps> = ({
files, files,
loadFileList, loadFileList,
}) => { }) => {
const { settings } = useWorkspace(); const { currentWorkspace } = useWorkspace();
const { handlePull } = useGitOperations(); const { handlePull } = useGitOperations();
useEffect(() => { useEffect(() => {
@@ -41,7 +41,7 @@ const Sidebar: React.FC<SidebarProps> = ({
<FileTree <FileTree
files={files} files={files}
handleFileSelect={handleFileSelect} handleFileSelect={handleFileSelect}
showHiddenFiles={settings.showHiddenFiles || false} showHiddenFiles={currentWorkspace?.showHiddenFiles || false}
/> />
</Box> </Box>
); );

View File

@@ -85,7 +85,6 @@ describe('useWorkspace', () => {
// Reset mock data to defaults // Reset mock data to defaults
mockWorkspaceData.currentWorkspace = null; mockWorkspaceData.currentWorkspace = null;
mockWorkspaceData.workspaces = []; mockWorkspaceData.workspaces = [];
mockWorkspaceData.settings = DEFAULT_WORKSPACE_SETTINGS;
mockWorkspaceData.loading = false; mockWorkspaceData.loading = false;
mockTheme.colorScheme = 'light'; mockTheme.colorScheme = 'light';
}); });
@@ -100,7 +99,6 @@ describe('useWorkspace', () => {
expect(result.current.currentWorkspace).toBeNull(); expect(result.current.currentWorkspace).toBeNull();
expect(result.current.workspaces).toEqual([]); expect(result.current.workspaces).toEqual([]);
expect(result.current.settings).toEqual(DEFAULT_WORKSPACE_SETTINGS);
expect(result.current.loading).toBe(false); expect(result.current.loading).toBe(false);
expect(result.current.colorScheme).toBe('light'); expect(result.current.colorScheme).toBe('light');
}); });
@@ -119,13 +117,11 @@ describe('useWorkspace', () => {
it('returns current workspace data', () => { it('returns current workspace data', () => {
mockWorkspaceData.currentWorkspace = mockWorkspace; mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.workspaces = mockWorkspaces; mockWorkspaceData.workspaces = mockWorkspaces;
mockWorkspaceData.settings = mockWorkspace;
const { result } = renderHook(() => useWorkspace()); const { result } = renderHook(() => useWorkspace());
expect(result.current.currentWorkspace).toEqual(mockWorkspace); expect(result.current.currentWorkspace).toEqual(mockWorkspace);
expect(result.current.workspaces).toEqual(mockWorkspaces); expect(result.current.workspaces).toEqual(mockWorkspaces);
expect(result.current.settings).toEqual(mockWorkspace);
}); });
it('returns loading state from workspace data', () => { it('returns loading state from workspace data', () => {
@@ -135,24 +131,6 @@ describe('useWorkspace', () => {
expect(result.current.loading).toBe(true); expect(result.current.loading).toBe(true);
}); });
it('uses default settings when no current workspace', () => {
mockWorkspaceData.currentWorkspace = null;
mockWorkspaceData.settings = DEFAULT_WORKSPACE_SETTINGS;
const { result } = renderHook(() => useWorkspace());
expect(result.current.settings).toEqual(DEFAULT_WORKSPACE_SETTINGS);
});
it('uses current workspace as settings when available', () => {
mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.settings = mockWorkspace;
const { result } = renderHook(() => useWorkspace());
expect(result.current.settings).toEqual(mockWorkspace);
});
}); });
describe('theme integration', () => { describe('theme integration', () => {
@@ -203,7 +181,6 @@ describe('useWorkspace', () => {
it('returns consistent data across multiple renders', () => { it('returns consistent data across multiple renders', () => {
mockWorkspaceData.currentWorkspace = mockWorkspace; mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.workspaces = mockWorkspaces; mockWorkspaceData.workspaces = mockWorkspaces;
mockWorkspaceData.settings = mockWorkspace;
mockTheme.colorScheme = 'dark'; mockTheme.colorScheme = 'dark';
const { result, rerender } = renderHook(() => useWorkspace()); const { result, rerender } = renderHook(() => useWorkspace());
@@ -216,7 +193,6 @@ describe('useWorkspace', () => {
firstResult.currentWorkspace firstResult.currentWorkspace
); );
expect(result.current.workspaces).toEqual(firstResult.workspaces); expect(result.current.workspaces).toEqual(firstResult.workspaces);
expect(result.current.settings).toEqual(firstResult.settings);
expect(result.current.colorScheme).toEqual(firstResult.colorScheme); expect(result.current.colorScheme).toEqual(firstResult.colorScheme);
}); });
@@ -230,13 +206,11 @@ describe('useWorkspace', () => {
// Add workspace data // Add workspace data
mockWorkspaceData.currentWorkspace = mockWorkspace; mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.workspaces = mockWorkspaces; mockWorkspaceData.workspaces = mockWorkspaces;
mockWorkspaceData.settings = mockWorkspace;
rerender(); rerender();
expect(result.current.currentWorkspace).toEqual(mockWorkspace); expect(result.current.currentWorkspace).toEqual(mockWorkspace);
expect(result.current.workspaces).toEqual(mockWorkspaces); expect(result.current.workspaces).toEqual(mockWorkspaces);
expect(result.current.settings).toEqual(mockWorkspace);
}); });
it('reflects theme changes', () => { it('reflects theme changes', () => {
@@ -334,7 +308,6 @@ describe('useWorkspace', () => {
const expectedKeys = [ const expectedKeys = [
'currentWorkspace', 'currentWorkspace',
'workspaces', 'workspaces',
'settings',
'updateSettings', 'updateSettings',
'loading', 'loading',
'colorScheme', 'colorScheme',
@@ -356,7 +329,6 @@ describe('useWorkspace', () => {
typeof result.current.currentWorkspace === 'object' typeof result.current.currentWorkspace === 'object'
).toBe(true); ).toBe(true);
expect(Array.isArray(result.current.workspaces)).toBe(true); expect(Array.isArray(result.current.workspaces)).toBe(true);
expect(typeof result.current.settings === 'object').toBe(true);
expect(typeof result.current.updateSettings === 'function').toBe(true); expect(typeof result.current.updateSettings === 'function').toBe(true);
expect(typeof result.current.loading === 'boolean').toBe(true); expect(typeof result.current.loading === 'boolean').toBe(true);
expect(typeof result.current.colorScheme === 'string').toBe(true); expect(typeof result.current.colorScheme === 'string').toBe(true);
@@ -373,13 +345,11 @@ describe('useWorkspace', () => {
// Simulate undefined data that might occur during loading // Simulate undefined data that might occur during loading
mockWorkspaceData.currentWorkspace = null; mockWorkspaceData.currentWorkspace = null;
mockWorkspaceData.workspaces = []; mockWorkspaceData.workspaces = [];
mockWorkspaceData.settings = DEFAULT_WORKSPACE_SETTINGS;
const { result } = renderHook(() => useWorkspace()); const { result } = renderHook(() => useWorkspace());
expect(result.current.currentWorkspace).toBeNull(); expect(result.current.currentWorkspace).toBeNull();
expect(result.current.workspaces).toEqual([]); expect(result.current.workspaces).toEqual([]);
expect(result.current.settings).toEqual(DEFAULT_WORKSPACE_SETTINGS);
expect(typeof result.current.updateSettings).toBe('function'); expect(typeof result.current.updateSettings).toBe('function');
}); });
@@ -395,7 +365,6 @@ describe('useWorkspace', () => {
const singleWorkspace = [mockWorkspace]; const singleWorkspace = [mockWorkspace];
mockWorkspaceData.workspaces = singleWorkspace; mockWorkspaceData.workspaces = singleWorkspace;
mockWorkspaceData.currentWorkspace = mockWorkspace; mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.settings = mockWorkspace;
const { result } = renderHook(() => useWorkspace()); const { result } = renderHook(() => useWorkspace());
@@ -411,12 +380,10 @@ describe('useWorkspace', () => {
}; };
mockWorkspaceData.currentWorkspace = minimalWorkspace; mockWorkspaceData.currentWorkspace = minimalWorkspace;
mockWorkspaceData.settings = minimalWorkspace;
const { result } = renderHook(() => useWorkspace()); const { result } = renderHook(() => useWorkspace());
expect(result.current.currentWorkspace).toEqual(minimalWorkspace); expect(result.current.currentWorkspace).toEqual(minimalWorkspace);
expect(result.current.settings).toEqual(minimalWorkspace);
}); });
}); });
@@ -424,7 +391,6 @@ describe('useWorkspace', () => {
it('provides complete workspace management interface', () => { it('provides complete workspace management interface', () => {
mockWorkspaceData.currentWorkspace = mockWorkspace; mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.workspaces = mockWorkspaces; mockWorkspaceData.workspaces = mockWorkspaces;
mockWorkspaceData.settings = mockWorkspace;
mockTheme.colorScheme = 'light'; mockTheme.colorScheme = 'light';
const { result } = renderHook(() => useWorkspace()); const { result } = renderHook(() => useWorkspace());
@@ -432,7 +398,6 @@ describe('useWorkspace', () => {
// Should have all data // Should have all data
expect(result.current.currentWorkspace).toEqual(mockWorkspace); expect(result.current.currentWorkspace).toEqual(mockWorkspace);
expect(result.current.workspaces).toEqual(mockWorkspaces); expect(result.current.workspaces).toEqual(mockWorkspaces);
expect(result.current.settings).toEqual(mockWorkspace);
expect(result.current.colorScheme).toBe('light'); expect(result.current.colorScheme).toBe('light');
// Should have all operations // Should have all operations
@@ -457,13 +422,9 @@ describe('useWorkspace', () => {
it('supports settings management workflow', () => { it('supports settings management workflow', () => {
mockWorkspaceData.currentWorkspace = mockWorkspace; mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.settings = mockWorkspace;
const { result } = renderHook(() => useWorkspace()); const { result } = renderHook(() => useWorkspace());
// Should have current settings
expect(result.current.settings).toEqual(mockWorkspace);
// Should provide update function // Should provide update function
expect(typeof result.current.updateSettings).toBe('function'); expect(typeof result.current.updateSettings).toBe('function');
expect(result.current.updateSettings).toBe( expect(result.current.updateSettings).toBe(
@@ -491,7 +452,6 @@ describe('useWorkspace', () => {
it('correctly integrates with WorkspaceDataContext mock', () => { it('correctly integrates with WorkspaceDataContext mock', () => {
mockWorkspaceData.currentWorkspace = mockWorkspace; mockWorkspaceData.currentWorkspace = mockWorkspace;
mockWorkspaceData.workspaces = mockWorkspaces; mockWorkspaceData.workspaces = mockWorkspaces;
mockWorkspaceData.settings = mockWorkspace;
mockWorkspaceData.loading = true; mockWorkspaceData.loading = true;
const { result } = renderHook(() => useWorkspace()); const { result } = renderHook(() => useWorkspace());
@@ -500,7 +460,6 @@ describe('useWorkspace', () => {
mockWorkspaceData.currentWorkspace mockWorkspaceData.currentWorkspace
); );
expect(result.current.workspaces).toBe(mockWorkspaceData.workspaces); expect(result.current.workspaces).toBe(mockWorkspaceData.workspaces);
expect(result.current.settings).toBe(mockWorkspaceData.settings);
expect(result.current.loading).toBe(mockWorkspaceData.loading); expect(result.current.loading).toBe(mockWorkspaceData.loading);
}); });

View File

@@ -1,13 +1,12 @@
import { useWorkspaceData } from '../contexts/WorkspaceDataContext'; import { useWorkspaceData } from '../contexts/WorkspaceDataContext';
import { useTheme } from '../contexts/ThemeContext'; import { useTheme } from '../contexts/ThemeContext';
import { useWorkspaceOperations } from './useWorkspaceOperations'; import { useWorkspaceOperations } from './useWorkspaceOperations';
import type { Workspace, DEFAULT_WORKSPACE_SETTINGS } from '@/types/models'; import type { Workspace } from '@/types/models';
import type { MantineColorScheme } from '@mantine/core'; import type { MantineColorScheme } from '@mantine/core';
interface UseWorkspaceResult { interface UseWorkspaceResult {
currentWorkspace: Workspace | null; currentWorkspace: Workspace | null;
workspaces: Workspace[]; workspaces: Workspace[];
settings: Workspace | typeof DEFAULT_WORKSPACE_SETTINGS;
updateSettings: (newSettings: Partial<Workspace>) => Promise<void>; updateSettings: (newSettings: Partial<Workspace>) => Promise<void>;
loading: boolean; loading: boolean;
colorScheme: MantineColorScheme; colorScheme: MantineColorScheme;
@@ -17,8 +16,7 @@ interface UseWorkspaceResult {
} }
export const useWorkspace = (): UseWorkspaceResult => { export const useWorkspace = (): UseWorkspaceResult => {
const { currentWorkspace, workspaces, settings, loading } = const { currentWorkspace, workspaces, loading } = useWorkspaceData();
useWorkspaceData();
const { colorScheme, updateColorScheme } = useTheme(); const { colorScheme, updateColorScheme } = useTheme();
const { switchWorkspace, deleteCurrentWorkspace, updateSettings } = const { switchWorkspace, deleteCurrentWorkspace, updateSettings } =
useWorkspaceOperations(); useWorkspaceOperations();
@@ -26,7 +24,6 @@ export const useWorkspace = (): UseWorkspaceResult => {
return { return {
currentWorkspace, currentWorkspace,
workspaces, workspaces,
settings,
updateSettings, updateSettings,
loading, loading,
colorScheme, colorScheme,