mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 12:15:57 +00:00
- Fix "Remote" → "Local" in sync-dialog.tsx and CLI help text - Add resetWatcherState() export for test cleanup - Add unit tests for profile-mapper, local-config-sync, auto-sync-watcher - Remove unused ModelAlias and AliasesResponse types from hooks
124 lines
3.6 KiB
TypeScript
124 lines
3.6 KiB
TypeScript
/**
|
|
* Tests for Auto-Sync Watcher
|
|
* Verifies debounce behavior, watcher lifecycle, and state management.
|
|
*/
|
|
|
|
import * as assert from 'assert';
|
|
|
|
describe('Auto-Sync Watcher', () => {
|
|
const autoSyncWatcher = require('../../../dist/cliproxy/sync/auto-sync-watcher');
|
|
|
|
beforeEach(async () => {
|
|
// Ensure clean state before each test
|
|
await autoSyncWatcher.resetWatcherState();
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Clean up after each test
|
|
await autoSyncWatcher.stopAutoSyncWatcher();
|
|
});
|
|
|
|
describe('isAutoSyncEnabled', () => {
|
|
it('returns a boolean', () => {
|
|
const result = autoSyncWatcher.isAutoSyncEnabled();
|
|
assert.ok(typeof result === 'boolean');
|
|
});
|
|
});
|
|
|
|
describe('getAutoSyncStatus', () => {
|
|
it('returns status object with required fields', () => {
|
|
const status = autoSyncWatcher.getAutoSyncStatus();
|
|
|
|
assert.ok(typeof status === 'object');
|
|
assert.ok(typeof status.enabled === 'boolean');
|
|
assert.ok(typeof status.watching === 'boolean');
|
|
assert.ok(typeof status.syncing === 'boolean');
|
|
});
|
|
|
|
it('reports not watching when watcher not started', () => {
|
|
const status = autoSyncWatcher.getAutoSyncStatus();
|
|
assert.strictEqual(status.watching, false);
|
|
});
|
|
|
|
it('reports not syncing initially', () => {
|
|
const status = autoSyncWatcher.getAutoSyncStatus();
|
|
assert.strictEqual(status.syncing, false);
|
|
});
|
|
});
|
|
|
|
describe('startAutoSyncWatcher', () => {
|
|
it('does not throw when called', () => {
|
|
assert.doesNotThrow(() => {
|
|
autoSyncWatcher.startAutoSyncWatcher();
|
|
});
|
|
});
|
|
|
|
it('is idempotent (can be called multiple times)', () => {
|
|
assert.doesNotThrow(() => {
|
|
autoSyncWatcher.startAutoSyncWatcher();
|
|
autoSyncWatcher.startAutoSyncWatcher();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('stopAutoSyncWatcher', () => {
|
|
it('resolves without error', async () => {
|
|
await assert.doesNotReject(async () => {
|
|
await autoSyncWatcher.stopAutoSyncWatcher();
|
|
});
|
|
});
|
|
|
|
it('can stop when not started', async () => {
|
|
await assert.doesNotReject(async () => {
|
|
await autoSyncWatcher.stopAutoSyncWatcher();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('restartAutoSyncWatcher', () => {
|
|
it('resolves without error', async () => {
|
|
await assert.doesNotReject(async () => {
|
|
await autoSyncWatcher.restartAutoSyncWatcher();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('resetWatcherState', () => {
|
|
it('clears all state', async () => {
|
|
// Start watcher to set state
|
|
autoSyncWatcher.startAutoSyncWatcher();
|
|
|
|
// Reset state
|
|
await autoSyncWatcher.resetWatcherState();
|
|
|
|
// Verify state is cleared
|
|
const status = autoSyncWatcher.getAutoSyncStatus();
|
|
assert.strictEqual(status.watching, false);
|
|
assert.strictEqual(status.syncing, false);
|
|
});
|
|
|
|
it('is safe to call multiple times', async () => {
|
|
await assert.doesNotReject(async () => {
|
|
await autoSyncWatcher.resetWatcherState();
|
|
await autoSyncWatcher.resetWatcherState();
|
|
await autoSyncWatcher.resetWatcherState();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('Debounce Behavior', () => {
|
|
/**
|
|
* Debounce is set to 3000ms (DEBOUNCE_MS constant).
|
|
* This prevents sync storms during rapid edits.
|
|
*
|
|
* Testing actual debounce requires file system manipulation
|
|
* and timing-based assertions, which are flaky in unit tests.
|
|
* Integration tests should cover this behavior.
|
|
*/
|
|
it('debounce constant is documented', () => {
|
|
// DEBOUNCE_MS = 3000 (3 seconds)
|
|
assert.ok(true, 'Debounce documented in code comments');
|
|
});
|
|
});
|
|
});
|