mirror of
https://github.com/firstsun-dev/git-files-sync.git
synced 2026-07-22 06:54:27 +00:00
- Conflict modal (#42): resize to min(1100px,92vw) x min(85vh,800px) flex layout, remove the 280px content height cap, and add a Diff/Local/Remote tab switcher on narrow screens (defaults to Diff). - Settings connection status (#41): show a persistent Connected/Not connected/Checking badge in the settings tab, auto-tested on open and after an 800ms debounce on token/branch/URL/owner/repo edits, updated in place (no full re-render, so typing focus is preserved). - Local ignore patterns (#40): new "Ignore patterns" setting (.gitignore- style, multi-line) applied in GitignoreManager.isIgnored() in addition to the repo's own .gitignore, covering push/pull/refresh uniformly. Closes #42, #41, #40. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YYCTyZw7gUmJ7oh1VTmAqh
57 lines
2.3 KiB
TypeScript
57 lines
2.3 KiB
TypeScript
import { beforeAll, describe, it, expect, vi } from 'vitest';
|
|
import { App } from 'obsidian';
|
|
import { applyDestructiveStyle, SyncConflictModal } from '../../src/ui/SyncConflictModal';
|
|
import { createContainer, setupObsidianDOM } from './setup-dom';
|
|
|
|
// Guards the backward-compatibility fix that lets the plugin run on Obsidian
|
|
// down to minAppVersion 1.11.0. ButtonComponent.setDestructive() only exists on
|
|
// Obsidian >= 1.13; calling it unconditionally would throw on older versions.
|
|
describe('applyDestructiveStyle (Obsidian version compatibility)', () => {
|
|
it('applies the destructive style on Obsidian >= 1.13 (method present)', () => {
|
|
const setDestructive = vi.fn();
|
|
const btn = { setDestructive };
|
|
|
|
expect(applyDestructiveStyle(btn)).toBe(btn);
|
|
expect(setDestructive).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it('degrades gracefully on Obsidian < 1.13 (method absent) without throwing', () => {
|
|
const btn = {}; // an older ButtonComponent has no setDestructive()
|
|
|
|
expect(() => applyDestructiveStyle(btn)).not.toThrow();
|
|
expect(applyDestructiveStyle(btn)).toBe(btn);
|
|
});
|
|
|
|
it('ignores a non-function setDestructive rather than crashing', () => {
|
|
const btn = { setDestructive: 'nope' as unknown as () => unknown };
|
|
|
|
expect(() => applyDestructiveStyle(btn)).not.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('SyncConflictModal', () => {
|
|
beforeAll(() => { setupObsidianDOM(); });
|
|
|
|
it('defaults to the diff panel and switches panels via tabs', () => {
|
|
const modal = new SyncConflictModal(new App(), 'note.md', 'local', 'remote', vi.fn());
|
|
modal.contentEl = createContainer();
|
|
|
|
modal.onOpen();
|
|
|
|
const contentEl = modal.contentEl;
|
|
const tabs = Array.from(contentEl.querySelectorAll<HTMLElement>('.conflict-tab'));
|
|
const panels = Array.from(contentEl.querySelectorAll<HTMLElement>('.conflict-panel'));
|
|
|
|
const activePanel = () => panels.find(panel => panel.classList.contains('is-active'));
|
|
const activeTab = () => tabs.find(tab => tab.classList.contains('is-active'));
|
|
|
|
expect(activeTab()?.textContent).toBe('Diff');
|
|
expect(activePanel()?.classList.contains('conflict-diff-section')).toBe(true);
|
|
|
|
const localTab = tabs.find(tab => tab.textContent === 'Local');
|
|
localTab?.dispatchEvent(new Event('click'));
|
|
|
|
expect(activeTab()?.textContent).toBe('Local');
|
|
expect(activePanel()?.classList.contains('conflict-section')).toBe(true);
|
|
});
|
|
});
|