import AutoStatusPlugin, { AutoStatusSettingTab } from '../src/main'; import { App } from 'obsidian'; // Mock the Setting class jest.mock('obsidian', () => { const originalModule = jest.requireActual('./mock_obsidian'); return { ...originalModule, PluginSettingTab: jest.fn().mockImplementation((app, plugin) => ({ app, plugin, containerEl: { empty: jest.fn(), createEl: jest.fn().mockReturnValue({ createEl: jest.fn(), }), }, display: jest.fn(), })), Setting: jest.fn().mockImplementation(() => ({ setName: jest.fn().mockReturnThis(), setDesc: jest.fn().mockReturnThis(), addText: jest.fn().mockReturnThis(), addToggle: jest.fn().mockReturnThis(), addTextArea: jest.fn().mockReturnThis(), addButton: jest.fn().mockReturnThis(), })), }; }); describe('Settings UI', () => { let plugin: AutoStatusPlugin; let mockApp: App; beforeEach(() => { mockApp = new App(); plugin = new AutoStatusPlugin(mockApp, {} as any); plugin.settings = { propertyName: 'Pending tasks', enableAutoProcessing: true, excludeFolders: [], includeFolders: [], debounceDelay: 500, enableTaskCounts: false, pendingTasksCountProperty: 'Pending tasks count', totalTasksCountProperty: 'Total tasks count', countRootTasksOnly: false, }; jest.clearAllMocks(); }); test('should create settings tab correctly', () => { if (AutoStatusSettingTab) { const settingTab = new AutoStatusSettingTab(mockApp as any, plugin as any); expect(settingTab.app).toBe(mockApp); expect(settingTab.plugin).toBe(plugin); } }); test('should initialize settings UI elements', () => { // Test that settings are properly structured for UI expect(plugin.settings).toHaveProperty('propertyName'); expect(plugin.settings).toHaveProperty('enableAutoProcessing'); expect(plugin.settings).toHaveProperty('excludeFolders'); expect(plugin.settings).toHaveProperty('includeFolders'); expect(plugin.settings).toHaveProperty('debounceDelay'); expect(Array.isArray(plugin.settings.excludeFolders)).toBe(true); expect(Array.isArray(plugin.settings.includeFolders)).toBe(true); expect(typeof plugin.settings.propertyName).toBe('string'); expect(typeof plugin.settings.enableAutoProcessing).toBe('boolean'); expect(typeof plugin.settings.debounceDelay).toBe('number'); }); test('should handle folder array conversion correctly', () => { // Test folder string to array conversion logic const testFolderString = 'Daily Notes, Projects, Work'; const expectedArray = ['Daily Notes', 'Projects', 'Work']; const result = testFolderString .split(',') .map(s => s.trim()) .filter(s => s.length > 0); expect(result).toEqual(expectedArray); }); test('should handle empty folder string correctly', () => { const testFolderString = ''; const result = testFolderString .split(',') .map(s => s.trim()) .filter(s => s.length > 0); expect(result).toEqual([]); }); test('should handle folder string with extra whitespace', () => { const testFolderString = ' Daily Notes , Projects , Work '; const expectedArray = ['Daily Notes', 'Projects', 'Work']; const result = testFolderString .split(',') .map(s => s.trim()) .filter(s => s.length > 0); expect(result).toEqual(expectedArray); }); test('should convert array to display string correctly', () => { const testArray = ['Daily Notes', 'Projects', 'Work']; const expectedString = 'Daily Notes, Projects, Work'; const result = testArray.join(', '); expect(result).toBe(expectedString); }); test('should handle empty array conversion', () => { const testArray: string[] = []; const expectedString = ''; const result = testArray.join(', '); expect(result).toBe(expectedString); }); test('should validate debounce delay input', () => { // Test debounce delay validation logic const validValues = ['500', '1000', '100', '0']; const invalidValues = ['abc', '-100']; validValues.forEach(value => { const numValue = parseInt(value); expect(!isNaN(numValue) && numValue >= 0).toBe(true); }); invalidValues.forEach(value => { const numValue = parseInt(value); expect(!isNaN(numValue) && numValue >= 0).toBe(false); }); // Special case: empty string returns NaN from parseInt const emptyValue = ''; const emptyNumValue = parseInt(emptyValue); expect(isNaN(emptyNumValue)).toBe(true); }); });