文件
mynode/packages/lib/services/noteLock/noteLockPrompts.test.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

94 行
3.7 KiB
TypeScript

import Setting from '../../models/Setting';
import shim from '../../shim';
import { encryptionService, setupDatabaseAndSynchronizer, switchClient } from '../../testing/test-utils';
import EncryptionService from '../e2ee/EncryptionService';
import NoteLockKey from './NoteLockKey';
import NoteLockService from './NoteLockService';
import NoteLockSession from './NoteLockSession';
import { promptForImportedNoteLockKey } from './noteLockPrompts';
import { ErrorCode } from '../../errors';
const makePrompts = (passwords: (string|null)[]) => ({
promptPassword: jest.fn(async () => passwords.shift() ?? null),
goToNoteLockSetup: jest.fn(),
});
describe('noteLockPrompts', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
NoteLockService.destroyInstance();
NoteLockSession.destroyInstance();
NoteLockKey.destroyInstance();
EncryptionService.instance_ = encryptionService();
Setting.setValue('featureFlag.noteLock', true);
shim.showErrorDialog = jest.fn(async () => {});
});
const otherBackupKey = async () => ({ ...await encryptionService().generateMasterKey('backup'), id: 'backup' });
// Answers the dialogs in order: the "update them?" question (0 Yes, 1 No, 2 Cancel), then the setup question (0 Yes, 1 No).
const answer = (...responses: number[]) => {
shim.showMessageBox = jest.fn(async () => responses.shift());
};
it('should import a backup of this profile as it is, without any prompt', async () => {
const key = await NoteLockKey.instance().create('local');
answer(0);
const prompts = makePrompts([]);
expect(await promptForImportedNoteLockKey(key, prompts)).toBeNull();
expect(shim.showMessageBox).not.toHaveBeenCalled();
expect(prompts.promptPassword).not.toHaveBeenCalled();
});
it('should unlock the session, then decrypt the key of a backup from another profile', async () => {
const backupKey = await otherBackupKey();
await NoteLockKey.instance().create('local');
answer(0);
const prompts = makePrompts(['local', 'wrong', 'backup']);
expect((await promptForImportedNoteLockKey(backupKey, prompts)).id).toBe(backupKey.id);
expect(NoteLockSession.instance().isUnlocked()).toBe(true);
expect(prompts.promptPassword).toHaveBeenNthCalledWith(1, 'Enter your current note lock password');
expect(shim.showErrorDialog).toHaveBeenCalledTimes(1);
});
it('should import unchanged when the user does not want to update the notes', async () => {
const backupKey = await otherBackupKey();
await NoteLockKey.instance().create('local');
answer(1);
const prompts = makePrompts([]);
expect(await promptForImportedNoteLockKey(backupKey, prompts)).toBeNull();
expect(prompts.promptPassword).not.toHaveBeenCalled();
});
it.each([
['the question', []],
['the current password', [null]],
['the backup password', ['local', null]],
])('should cancel the import when %s is cancelled', async (_step, passwords: (string|null)[]) => {
const backupKey = await otherBackupKey();
await NoteLockKey.instance().create('local');
answer(passwords.length ? 0 : 2);
await expect(promptForImportedNoteLockKey(backupKey, makePrompts(passwords))).rejects.toMatchObject({ code: ErrorCode.Cancelled });
});
it.each([
['opens the note lock setup', true],
['does not', false],
])('should cancel the import when no note lock key is set up and the user %s', async (_label, opensSetup) => {
const backupKey = await otherBackupKey();
answer(0, opensSetup ? 0 : 1);
const prompts = makePrompts([]);
await expect(promptForImportedNoteLockKey(backupKey, prompts)).rejects.toMatchObject({ code: ErrorCode.Cancelled });
expect(prompts.goToNoteLockSetup).toHaveBeenCalledTimes(opensSetup ? 1 : 0);
expect(prompts.promptPassword).not.toHaveBeenCalled();
});
});