一些检查失败了
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
78 行
3.0 KiB
TypeScript
78 行
3.0 KiB
TypeScript
import Api, { RequestMethod } from '../Api';
|
|
import Note from '../../../models/Note';
|
|
import Revision from '../../../models/Revision';
|
|
import Setting from '../../../models/Setting';
|
|
import BaseModel from '../../../BaseModel';
|
|
import { setupDatabaseAndSynchronizer, switchClient, noteLockCipherTextStandIn } from '../../../testing/test-utils';
|
|
import { RevisionEntity } from '../../database/types';
|
|
|
|
const createNoteAndRevision = async (isLocked: number) => {
|
|
// A JLD-prefixed body passes the save path untouched, standing in for real ciphertext.
|
|
const note = await Note.save({ title: 'note', body: isLocked ? noteLockCipherTextStandIn('body') : 'body', is_locked: isLocked });
|
|
const revision = await Revision.save({
|
|
item_type: BaseModel.TYPE_NOTE,
|
|
item_id: note.id,
|
|
item_updated_time: note.updated_time,
|
|
parent_id: '',
|
|
title_diff: '[]',
|
|
body_diff: '[]',
|
|
metadata_diff: '{"new":{},"deleted":[]}',
|
|
is_locked: isLocked,
|
|
});
|
|
return { note, revision };
|
|
};
|
|
|
|
describe('routes/revisions', () => {
|
|
|
|
beforeEach(async () => {
|
|
await setupDatabaseAndSynchronizer(1);
|
|
await switchClient(1);
|
|
});
|
|
|
|
test('should block load and save of a locked revision', async () => {
|
|
Setting.setValue('featureFlag.noteLock', true);
|
|
const api = new Api();
|
|
const { revision } = await createNoteAndRevision(1);
|
|
|
|
await expect(api.route(RequestMethod.GET, `revisions/${revision.id}`)).rejects.toThrow('locked revision');
|
|
await expect(api.route(RequestMethod.PUT, `revisions/${revision.id}`, null, JSON.stringify({ title_diff: '[]' }))).rejects.toThrow('locked revision');
|
|
|
|
expect(await Revision.load(revision.id)).toBeTruthy();
|
|
});
|
|
|
|
test('should still allow deleting the revisions of a locked note', async () => {
|
|
Setting.setValue('featureFlag.noteLock', true);
|
|
const api = new Api();
|
|
const { revision } = await createNoteAndRevision(1);
|
|
|
|
await api.route(RequestMethod.DELETE, `revisions/${revision.id}`);
|
|
expect(await Revision.load(revision.id)).toBeFalsy();
|
|
});
|
|
|
|
test('should exclude the revisions of locked notes from the collection response', async () => {
|
|
Setting.setValue('featureFlag.noteLock', true);
|
|
const api = new Api();
|
|
await createNoteAndRevision(1);
|
|
const { revision: plainRevision } = await createNoteAndRevision(0);
|
|
|
|
const response = await api.route(RequestMethod.GET, 'revisions');
|
|
expect(response.items.map((r: RevisionEntity) => r.id)).toEqual([plainRevision.id]);
|
|
|
|
Setting.setValue('featureFlag.noteLock', false);
|
|
expect((await api.route(RequestMethod.GET, 'revisions')).items.length).toBe(2);
|
|
});
|
|
|
|
test.each([
|
|
{ label: 'the note is not locked', flagEnabled: true, isLocked: 0 },
|
|
{ label: 'note lock is disabled', flagEnabled: false, isLocked: 1 },
|
|
])('should allow revision access when $label', async ({ flagEnabled, isLocked }) => {
|
|
Setting.setValue('featureFlag.noteLock', flagEnabled);
|
|
const api = new Api();
|
|
const { revision } = await createNoteAndRevision(isLocked);
|
|
|
|
const response = await api.route(RequestMethod.GET, `revisions/${revision.id}`);
|
|
expect(response.id).toBe(revision.id);
|
|
});
|
|
|
|
});
|