import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { DataSyncScheduler } from '@/services/ble/DataSyncScheduler'; const storage = new Map(); vi.mock('@tarojs/taro', () => ({ default: { getStorageSync: vi.fn((key: string) => storage.get(key) || ''), setStorageSync: vi.fn((key: string, value: string) => { storage.set(key, value); }), removeStorageSync: vi.fn((key: string) => { storage.delete(key); }), }, })); describe('DataSyncScheduler', () => { let scheduler: DataSyncScheduler; let syncFn: ReturnType; beforeEach(() => { storage.clear(); syncFn = vi.fn().mockResolvedValue({ success: true, uploadedCount: 5 }); scheduler = new DataSyncScheduler({ intervalMs: 60 * 60 * 1000, storageKey: 'last_ble_sync', }); }); afterEach(() => { scheduler.destroy(); }); it('首次同步:无记录时立即需要同步', () => { expect(scheduler.needsSync()).toBe(true); }); it('同步后记录时间戳', async () => { await scheduler.recordSync(syncFn); expect(storage.has('last_ble_sync')).toBe(true); expect(syncFn).toHaveBeenCalled(); }); it('同步后不需要再次同步', async () => { await scheduler.recordSync(syncFn); expect(scheduler.needsSync()).toBe(false); }); it('超过间隔后需要再次同步', async () => { const twoHoursAgo = Date.now() - 2 * 60 * 60 * 1000; storage.set('last_ble_sync', JSON.stringify({ lastSyncAt: twoHoursAgo })); scheduler = new DataSyncScheduler({ intervalMs: 60 * 60 * 1000, storageKey: 'last_ble_sync' }); expect(scheduler.needsSync()).toBe(true); }); it('同步失败不更新时间戳', async () => { const failFn = vi.fn().mockRejectedValue(new Error('network error')); const oneHourAgo = Date.now() - 60 * 60 * 1000; storage.set('last_ble_sync', JSON.stringify({ lastSyncAt: oneHourAgo })); await scheduler.recordSync(failFn); const stored = JSON.parse(storage.get('last_ble_sync') || '{}'); expect(stored.lastSyncAt).toBe(oneHourAgo); }); it('tryAutoSync 首次时触发同步', async () => { const result = await scheduler.tryAutoSync(syncFn); expect(result).toBe(true); expect(syncFn).toHaveBeenCalledTimes(1); }); it('tryAutoSync 未超时不触发', async () => { await scheduler.recordSync(syncFn); syncFn.mockClear(); const result = await scheduler.tryAutoSync(syncFn); expect(result).toBe(false); expect(syncFn).not.toHaveBeenCalled(); }); it('destroy 清理定时器', () => { const clearIntervalSpy = vi.spyOn(global, 'clearInterval'); scheduler.startPeriodicCheck(syncFn, 30000); scheduler.destroy(); expect(clearIntervalSpy).toHaveBeenCalled(); clearIntervalSpy.mockRestore(); }); it('getLastSyncAt 返回上次同步时间', async () => { await scheduler.recordSync(syncFn); const lastSync = scheduler.getLastSyncAt(); expect(lastSync).toBeTruthy(); expect(typeof lastSync).toBe('number'); }); });