2026-02-22 13:42:20 +01:00
|
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
2026-02-23 19:57:59 +01:00
|
|
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
|
2026-02-22 13:42:20 +01:00
|
|
|
import { SettingsPanel } from './SettingsPanel'
|
|
|
|
|
import type { Settings } from '../types'
|
|
|
|
|
|
2026-02-23 19:57:59 +01:00
|
|
|
// Mock the tauri/mock-tauri calls used by GitHubSection
|
|
|
|
|
const mockInvokeFn = vi.fn()
|
2026-02-28 13:06:43 +01:00
|
|
|
const mockOpenExternalUrl = vi.fn().mockResolvedValue(undefined)
|
2026-02-23 19:57:59 +01:00
|
|
|
vi.mock('@tauri-apps/api/core', () => ({
|
|
|
|
|
invoke: (...args: unknown[]) => mockInvokeFn(...args),
|
|
|
|
|
}))
|
|
|
|
|
vi.mock('../mock-tauri', () => ({
|
|
|
|
|
isTauri: () => false,
|
|
|
|
|
mockInvoke: (...args: unknown[]) => mockInvokeFn(...args),
|
|
|
|
|
}))
|
2026-02-28 13:06:43 +01:00
|
|
|
vi.mock('../utils/url', () => ({
|
|
|
|
|
openExternalUrl: (...args: unknown[]) => mockOpenExternalUrl(...args),
|
|
|
|
|
}))
|
2026-02-23 19:57:59 +01:00
|
|
|
|
2026-02-22 13:42:20 +01:00
|
|
|
const emptySettings: Settings = {
|
2026-02-22 17:46:31 +01:00
|
|
|
github_token: null,
|
2026-02-23 19:56:30 +01:00
|
|
|
github_username: null,
|
feat: auto-pull vault changes from Git (background sync + conflict handling) (#79)
* feat: add auto-pull vault sync with conflict handling
- Add git_pull, has_remote, get_conflict_files to Rust backend
- Add GitPullResult type and auto_pull_interval_minutes to Settings
- Create useAutoSync hook (pull on launch, focus, periodic interval)
- Update StatusBar with real sync status indicator
- Add pull interval setting to SettingsPanel
- Add mock handler for git_pull
- Update existing tests for new Settings field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add tests for git pull, settings, and useAutoSync hook
- Add Rust tests: has_remote, git_pull (no_remote, up_to_date, updated),
get_conflict_files, parse_updated_files, GitPullResult serialization
- Add frontend tests: useAutoSync (mount pull, focus pull, conflict,
error, manual trigger, concurrent prevention, no_remote)
- Fix existing settings tests for new auto_pull_interval_minutes field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* design: add auto-pull-vault wireframes
Frames showing: sync idle, syncing, conflict indicator,
settings sync section, and conflict toast notification.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add auto_pull_interval_minutes to all Settings literals
Fix build error and test fixtures missing the new field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: cargo fmt
* ci: re-trigger CI after flaky test
* ci: retrigger after disk space cleanup
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 01:55:16 +01:00
|
|
|
auto_pull_interval_minutes: null,
|
2026-03-25 16:05:13 +01:00
|
|
|
telemetry_consent: null,
|
|
|
|
|
crash_reporting_enabled: null,
|
|
|
|
|
analytics_enabled: null,
|
|
|
|
|
anonymous_id: null,
|
2026-04-04 12:11:26 +02:00
|
|
|
release_channel: null,
|
2026-02-22 13:42:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
describe('SettingsPanel', () => {
|
|
|
|
|
const onSave = vi.fn()
|
|
|
|
|
const onClose = vi.fn()
|
|
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
vi.clearAllMocks()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('renders nothing when not open', () => {
|
|
|
|
|
const { container } = render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={false} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
expect(container.innerHTML).toBe('')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('renders modal when open', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
expect(screen.getByText('Settings')).toBeInTheDocument()
|
2026-04-05 01:34:30 +02:00
|
|
|
expect(screen.getByText('GitHub')).toBeInTheDocument()
|
2026-02-22 13:42:20 +01:00
|
|
|
})
|
|
|
|
|
|
2026-04-05 01:34:30 +02:00
|
|
|
it('does not show AI Provider Keys section', () => {
|
2026-02-22 13:42:20 +01:00
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
2026-04-05 01:34:30 +02:00
|
|
|
expect(screen.queryByText('AI Provider Keys')).not.toBeInTheDocument()
|
|
|
|
|
expect(screen.queryByText('OpenAI')).not.toBeInTheDocument()
|
|
|
|
|
expect(screen.queryByText('Google AI')).not.toBeInTheDocument()
|
2026-02-22 13:42:20 +01:00
|
|
|
})
|
|
|
|
|
|
2026-04-05 01:34:30 +02:00
|
|
|
it('calls onSave with settings on save', () => {
|
2026-02-22 13:42:20 +01:00
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByTestId('settings-save'))
|
|
|
|
|
|
2026-03-25 16:05:13 +01:00
|
|
|
expect(onSave).toHaveBeenCalledWith(expect.objectContaining({
|
2026-02-22 17:46:31 +01:00
|
|
|
github_token: null,
|
2026-02-23 19:56:30 +01:00
|
|
|
github_username: null,
|
feat: auto-pull vault changes from Git (background sync + conflict handling) (#79)
* feat: add auto-pull vault sync with conflict handling
- Add git_pull, has_remote, get_conflict_files to Rust backend
- Add GitPullResult type and auto_pull_interval_minutes to Settings
- Create useAutoSync hook (pull on launch, focus, periodic interval)
- Update StatusBar with real sync status indicator
- Add pull interval setting to SettingsPanel
- Add mock handler for git_pull
- Update existing tests for new Settings field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add tests for git pull, settings, and useAutoSync hook
- Add Rust tests: has_remote, git_pull (no_remote, up_to_date, updated),
get_conflict_files, parse_updated_files, GitPullResult serialization
- Add frontend tests: useAutoSync (mount pull, focus pull, conflict,
error, manual trigger, concurrent prevention, no_remote)
- Fix existing settings tests for new auto_pull_interval_minutes field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* design: add auto-pull-vault wireframes
Frames showing: sync idle, syncing, conflict indicator,
settings sync section, and conflict toast notification.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add auto_pull_interval_minutes to all Settings literals
Fix build error and test fixtures missing the new field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: cargo fmt
* ci: re-trigger CI after flaky test
* ci: retrigger after disk space cleanup
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 01:55:16 +01:00
|
|
|
auto_pull_interval_minutes: 5,
|
2026-03-25 16:05:13 +01:00
|
|
|
}))
|
2026-02-22 13:42:20 +01:00
|
|
|
expect(onClose).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('calls onClose when Cancel is clicked', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
fireEvent.click(screen.getByText('Cancel'))
|
|
|
|
|
expect(onClose).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('calls onClose when close button is clicked', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
fireEvent.click(screen.getByTitle('Close settings'))
|
|
|
|
|
expect(onClose).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('calls onClose on Escape key', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
fireEvent.keyDown(screen.getByTestId('settings-panel'), { key: 'Escape' })
|
|
|
|
|
expect(onClose).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('saves on Cmd+Enter', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
fireEvent.keyDown(screen.getByTestId('settings-panel'), { key: 'Enter', metaKey: true })
|
|
|
|
|
|
2026-03-25 16:05:13 +01:00
|
|
|
expect(onSave).toHaveBeenCalledWith(expect.objectContaining({
|
2026-02-22 17:46:31 +01:00
|
|
|
github_token: null,
|
2026-02-23 19:56:30 +01:00
|
|
|
github_username: null,
|
feat: auto-pull vault changes from Git (background sync + conflict handling) (#79)
* feat: add auto-pull vault sync with conflict handling
- Add git_pull, has_remote, get_conflict_files to Rust backend
- Add GitPullResult type and auto_pull_interval_minutes to Settings
- Create useAutoSync hook (pull on launch, focus, periodic interval)
- Update StatusBar with real sync status indicator
- Add pull interval setting to SettingsPanel
- Add mock handler for git_pull
- Update existing tests for new Settings field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add tests for git pull, settings, and useAutoSync hook
- Add Rust tests: has_remote, git_pull (no_remote, up_to_date, updated),
get_conflict_files, parse_updated_files, GitPullResult serialization
- Add frontend tests: useAutoSync (mount pull, focus pull, conflict,
error, manual trigger, concurrent prevention, no_remote)
- Fix existing settings tests for new auto_pull_interval_minutes field
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* design: add auto-pull-vault wireframes
Frames showing: sync idle, syncing, conflict indicator,
settings sync section, and conflict toast notification.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add auto_pull_interval_minutes to all Settings literals
Fix build error and test fixtures missing the new field.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: cargo fmt
* ci: re-trigger CI after flaky test
* ci: retrigger after disk space cleanup
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 01:55:16 +01:00
|
|
|
auto_pull_interval_minutes: 5,
|
2026-03-25 16:05:13 +01:00
|
|
|
}))
|
2026-02-22 13:42:20 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('calls onClose when clicking backdrop', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
fireEvent.click(screen.getByTestId('settings-panel'))
|
|
|
|
|
expect(onClose).toHaveBeenCalled()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('shows keyboard shortcut hint in footer', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-22 13:42:20 +01:00
|
|
|
)
|
|
|
|
|
expect(screen.getByText(/to open settings/)).toBeInTheDocument()
|
|
|
|
|
})
|
|
|
|
|
|
2026-02-23 19:57:59 +01:00
|
|
|
|
|
|
|
|
describe('GitHub OAuth section', () => {
|
|
|
|
|
it('shows Login with GitHub button when not connected', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-23 19:57:59 +01:00
|
|
|
)
|
|
|
|
|
expect(screen.getByTestId('github-login')).toBeInTheDocument()
|
|
|
|
|
expect(screen.getByText('Login with GitHub')).toBeInTheDocument()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('does not show GitHub token input field', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-23 19:57:59 +01:00
|
|
|
)
|
|
|
|
|
expect(screen.queryByTestId('settings-key-github-token')).not.toBeInTheDocument()
|
|
|
|
|
expect(screen.queryByPlaceholderText('ghp_... or gho_...')).not.toBeInTheDocument()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('shows connected state with username when GitHub is connected', () => {
|
|
|
|
|
const connectedSettings: Settings = {
|
|
|
|
|
...emptySettings,
|
|
|
|
|
github_token: 'gho_test_token',
|
|
|
|
|
github_username: 'lucaong',
|
|
|
|
|
}
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={connectedSettings} onSave={onSave} onClose={onClose} />
|
2026-02-23 19:57:59 +01:00
|
|
|
)
|
|
|
|
|
expect(screen.getByTestId('github-connected')).toBeInTheDocument()
|
|
|
|
|
expect(screen.getByText('lucaong')).toBeInTheDocument()
|
|
|
|
|
expect(screen.getByText('Connected')).toBeInTheDocument()
|
|
|
|
|
expect(screen.getByTestId('github-disconnect')).toBeInTheDocument()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('clears GitHub connection on disconnect', () => {
|
|
|
|
|
const connectedSettings: Settings = {
|
|
|
|
|
...emptySettings,
|
|
|
|
|
github_token: 'gho_test_token',
|
|
|
|
|
github_username: 'lucaong',
|
|
|
|
|
}
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={connectedSettings} onSave={onSave} onClose={onClose} />
|
2026-02-23 19:57:59 +01:00
|
|
|
)
|
|
|
|
|
fireEvent.click(screen.getByTestId('github-disconnect'))
|
|
|
|
|
|
|
|
|
|
// onSave should be called with cleared GitHub fields
|
|
|
|
|
expect(onSave).toHaveBeenCalledWith(expect.objectContaining({
|
|
|
|
|
github_token: null,
|
|
|
|
|
github_username: null,
|
|
|
|
|
}))
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('shows waiting state with user code during OAuth flow', async () => {
|
|
|
|
|
mockInvokeFn.mockImplementation(async (cmd: string) => {
|
|
|
|
|
if (cmd === 'github_device_flow_start') {
|
|
|
|
|
return {
|
|
|
|
|
device_code: 'test_device_code',
|
|
|
|
|
user_code: 'TEST-1234',
|
|
|
|
|
verification_uri: 'https://github.com/login/device',
|
|
|
|
|
expires_in: 900,
|
|
|
|
|
interval: 5,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (cmd === 'github_device_flow_poll') {
|
|
|
|
|
return { status: 'pending', access_token: null, error: 'authorization_pending' }
|
|
|
|
|
}
|
|
|
|
|
return null
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-23 19:57:59 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByTestId('github-login'))
|
|
|
|
|
|
|
|
|
|
await waitFor(() => {
|
|
|
|
|
expect(screen.getByTestId('github-waiting')).toBeInTheDocument()
|
|
|
|
|
expect(screen.getByTestId('github-user-code')).toHaveTextContent('TEST-1234')
|
|
|
|
|
})
|
|
|
|
|
|
2026-02-28 13:06:43 +01:00
|
|
|
expect(mockOpenExternalUrl).toHaveBeenCalledWith('https://github.com/login/device')
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('shows verification URL as clickable link in waiting state', async () => {
|
|
|
|
|
mockInvokeFn.mockImplementation(async (cmd: string) => {
|
|
|
|
|
if (cmd === 'github_device_flow_start') {
|
|
|
|
|
return {
|
|
|
|
|
device_code: 'test_device_code',
|
|
|
|
|
user_code: 'TEST-1234',
|
|
|
|
|
verification_uri: 'https://github.com/login/device',
|
|
|
|
|
expires_in: 900,
|
|
|
|
|
interval: 5,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (cmd === 'github_device_flow_poll') {
|
|
|
|
|
return { status: 'pending', access_token: null, error: 'authorization_pending' }
|
|
|
|
|
}
|
|
|
|
|
return null
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-28 13:06:43 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByTestId('github-login'))
|
|
|
|
|
|
|
|
|
|
await waitFor(() => {
|
|
|
|
|
const urlButton = screen.getByTestId('github-open-url')
|
|
|
|
|
expect(urlButton).toBeInTheDocument()
|
|
|
|
|
expect(urlButton).toHaveTextContent('https://github.com/login/device')
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('shows retry button when OAuth flow errors', async () => {
|
|
|
|
|
mockInvokeFn.mockImplementation(async (cmd: string) => {
|
|
|
|
|
if (cmd === 'github_device_flow_start') {
|
|
|
|
|
throw 'Network error'
|
|
|
|
|
}
|
|
|
|
|
return null
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-28 13:06:43 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByTestId('github-login'))
|
|
|
|
|
|
|
|
|
|
await waitFor(() => {
|
|
|
|
|
expect(screen.getByTestId('github-error')).toHaveTextContent('Network error')
|
|
|
|
|
expect(screen.getByTestId('github-retry')).toBeInTheDocument()
|
|
|
|
|
})
|
2026-02-23 19:57:59 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('shows GitHub section description about connecting', () => {
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-23 19:57:59 +01:00
|
|
|
)
|
|
|
|
|
expect(screen.getByText(/Connect your GitHub account/)).toBeInTheDocument()
|
|
|
|
|
})
|
2026-02-24 10:30:53 +01:00
|
|
|
|
|
|
|
|
it('displays the actual backend error string when device flow start fails', async () => {
|
|
|
|
|
mockInvokeFn.mockImplementation(async (cmd: string) => {
|
|
|
|
|
if (cmd === 'github_device_flow_start') {
|
|
|
|
|
// Tauri invoke rejects with a plain string, not an Error instance
|
|
|
|
|
throw 'GitHub device flow not available. Ensure a GitHub App is registered.'
|
|
|
|
|
}
|
|
|
|
|
return null
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-24 10:30:53 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
fireEvent.click(screen.getByTestId('github-login'))
|
|
|
|
|
|
|
|
|
|
await waitFor(() => {
|
|
|
|
|
expect(screen.getByTestId('github-error')).toHaveTextContent(
|
|
|
|
|
'GitHub device flow not available. Ensure a GitHub App is registered.'
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('prevents double-click by disabling button during login flow', async () => {
|
|
|
|
|
let resolveStart: ((v: unknown) => void) | null = null
|
|
|
|
|
mockInvokeFn.mockImplementation(async (cmd: string) => {
|
|
|
|
|
if (cmd === 'github_device_flow_start') {
|
|
|
|
|
return new Promise(r => { resolveStart = r })
|
|
|
|
|
}
|
|
|
|
|
return null
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
render(
|
refactor: remove theming system entirely
Remove all theme switching, creation, and management functionality
from the app — backend (Rust theme module, Tauri commands, menu items,
startup tasks, vault seeding), frontend (useThemeManager, ThemePropertyEditor,
themeSchema, command palette Appearance group, settings panel appearance
section, isDarkTheme prop chain), mock data, and all related tests.
Editor styling via theme.json/EditorTheme.css is preserved (not user theming).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:57:58 +01:00
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
2026-02-24 10:30:53 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const loginBtn = screen.getByTestId('github-login') as HTMLButtonElement
|
|
|
|
|
fireEvent.click(loginBtn)
|
|
|
|
|
|
|
|
|
|
// Button should be disabled while waiting
|
|
|
|
|
await waitFor(() => {
|
|
|
|
|
expect(loginBtn.disabled).toBe(true)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Clean up
|
|
|
|
|
resolveStart?.({
|
|
|
|
|
device_code: 'dc', user_code: 'UC-1234',
|
|
|
|
|
verification_uri: 'https://github.com/login/device',
|
|
|
|
|
expires_in: 900, interval: 5,
|
|
|
|
|
})
|
|
|
|
|
})
|
2026-02-23 19:57:59 +01:00
|
|
|
})
|
2026-03-25 16:10:39 +01:00
|
|
|
|
|
|
|
|
describe('Privacy & Telemetry section', () => {
|
|
|
|
|
it('renders crash reporting and analytics toggles', () => {
|
|
|
|
|
render(
|
|
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
|
|
|
|
)
|
|
|
|
|
expect(screen.getByTestId('settings-crash-reporting')).toBeInTheDocument()
|
|
|
|
|
expect(screen.getByTestId('settings-analytics')).toBeInTheDocument()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('toggles reflect initial settings state', () => {
|
|
|
|
|
const withTelemetry: Settings = {
|
|
|
|
|
...emptySettings,
|
|
|
|
|
telemetry_consent: true,
|
|
|
|
|
crash_reporting_enabled: true,
|
|
|
|
|
analytics_enabled: false,
|
|
|
|
|
anonymous_id: 'test-uuid',
|
|
|
|
|
}
|
|
|
|
|
render(
|
|
|
|
|
<SettingsPanel open={true} settings={withTelemetry} onSave={onSave} onClose={onClose} />
|
|
|
|
|
)
|
|
|
|
|
const crashCheckbox = screen.getByTestId('settings-crash-reporting').querySelector('input') as HTMLInputElement
|
|
|
|
|
const analyticsCheckbox = screen.getByTestId('settings-analytics').querySelector('input') as HTMLInputElement
|
|
|
|
|
expect(crashCheckbox.checked).toBe(true)
|
|
|
|
|
expect(analyticsCheckbox.checked).toBe(false)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
it('saves telemetry settings when toggled and saved', () => {
|
|
|
|
|
render(
|
|
|
|
|
<SettingsPanel open={true} settings={emptySettings} onSave={onSave} onClose={onClose} />
|
|
|
|
|
)
|
|
|
|
|
const crashCheckbox = screen.getByTestId('settings-crash-reporting').querySelector('input')!
|
|
|
|
|
fireEvent.click(crashCheckbox)
|
|
|
|
|
fireEvent.click(screen.getByTestId('settings-save'))
|
|
|
|
|
|
|
|
|
|
expect(onSave).toHaveBeenCalledWith(expect.objectContaining({
|
|
|
|
|
crash_reporting_enabled: true,
|
|
|
|
|
analytics_enabled: false,
|
|
|
|
|
}))
|
|
|
|
|
})
|
|
|
|
|
})
|
2026-02-22 13:42:20 +01:00
|
|
|
})
|