import shim from '@joplin/lib/shim'; import * as exportDeletionLog from './exportDeletionLog'; import Setting from '@joplin/lib/models/Setting'; import { AppState, createAppDefaultState } from '../app.reducer'; jest.mock('../services/bridge', () => ({ __esModule: true, default: () => ({ openItem: jest.fn, }), })); const logContentWithDeleteAction = ` 2024-09-17 18:34:28: Running migration: 20 2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 1 2024-09-17 18:34:28: Running migration: 27 2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 2 2024-09-17 18:34:28: Running migration: 33 2024-09-17 18:34:28: SearchEngine: Updating FTS table... 2024-09-17 18:34:28: Updating items_normalized from {"updated_time":0,"id":""} 2024-09-17 18:34:28: SearchEngine: Updated FTS table in 1ms. Inserted: 0. Deleted: 0 2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 3 2024-09-17 18:34:29: Running migration: 35 2024-09-17 18:34:29: SearchEngine: Updating FTS table... 2024-09-17 18:34:29: Updating items_normalized from {"updated_time":0,"id":""} 2024-09-17 18:34:29: SearchEngine: Updated FTS table in 1ms. Inserted: 0. Deleted: 0 2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4 2024-09-17 18:34:29: Running migration: 42 2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5 2024-09-17 18:34:29: App: "syncInfoCache" was changed - setting up encryption related code `; const createFakeLogFile = async (filename: string, content: string) => { await shim.fsDriver().writeFile(`${Setting.value('profileDir')}/${filename}`, content, 'utf8'); }; describe('exportDeletionLog', () => { let state: AppState = undefined; beforeAll(() => { state = createAppDefaultState({}, {}); jest.useFakeTimers(); jest.setSystemTime(new Date('2024-09-18T12:00:00Z').getTime()); }); it('should get all deletion lines from the log file', async () => { await createFakeLogFile('log.txt', logContentWithDeleteAction); await exportDeletionLog.runtime().execute({ state, dispatch: () => {} }); const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8'); expect(result).toBe( `2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 1 2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 2 2024-09-17 18:34:28: DeleteAction: MigrationService: ; Item IDs: 3 2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4 2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5 `); }); it('should return a empty file if there is not deletion lines', async () => { await createFakeLogFile('log.txt', ''); await exportDeletionLog.runtime().execute({ state, dispatch: () => {} }); const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8'); expect(result).toBe(''); }); it('should ignore logs from log files that are not recent', async () => { const before = new Date('2024-09-16').getTime(); const after = new Date('2024-09-17').getTime(); await createFakeLogFile(`log-${before}.txt`, logContentWithDeleteAction); await createFakeLogFile(`log-${after}.txt`, ''); await createFakeLogFile('log.txt', ''); await exportDeletionLog.runtime().execute({ state, dispatch: () => {} }); const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8'); expect(result).toBe(''); }); it('should contain the content from the recent log files', async () => { const rotateLog = new Date('2024-09-17').getTime(); await createFakeLogFile(`log-${rotateLog}.txt`, '2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4'); await createFakeLogFile('log.txt', '2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5'); await exportDeletionLog.runtime().execute({ state, dispatch: () => {} }); const result = await shim.fsDriver().readFile(`${Setting.value('profileDir')}/deletion_log_20240918.txt`, 'utf-8'); expect(result).toBe( `2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 4 2024-09-17 18:34:29: DeleteAction: MigrationService: ; Item IDs: 5 `); }); it('should contain the date in the filename', async () => { await shim.fsDriver().remove(`${Setting.value('profileDir')}/deletion_log_20230111.txt`); jest.setSystemTime(new Date('2023-01-11T12:00:00Z').getTime()); await createFakeLogFile('log.txt', ''); await exportDeletionLog.runtime().execute({ state, dispatch: () => {} }); const exists = await shim.fsDriver().exists(`${Setting.value('profileDir')}/deletion_log_20230111.txt`); expect(exists).toBe(true); }); });