1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-11-23 22:36:32 +02:00

Chore: Sync fuzzer: Add actions for publishing and unpublishing notes (#13062)

This commit is contained in:
Henry Heino
2025-09-08 04:02:53 -07:00
committed by GitHub
parent 1f0a98999f
commit 88f687ba6a
4 changed files with 82 additions and 1 deletions

View File

@@ -434,6 +434,35 @@ class ActionTracker {
this.checkRep_(); this.checkRep_();
return Promise.resolve(); return Promise.resolve();
}, },
publishNote: (id) => {
const oldItem = this.idToItem_.get(id);
assert.ok(oldItem, 'should exist');
assert.ok(!isFolder(oldItem), 'folders cannot be published');
assert.ok(!oldItem.published, 'should not be published');
this.idToItem_.set(id, {
...oldItem,
published: true,
});
this.checkRep_();
return Promise.resolve();
},
unpublishNote: (id) => {
const oldItem = this.idToItem_.get(id);
assert.ok(oldItem, 'should exist');
assert.ok(!isFolder(oldItem), 'folders cannot be unpublished');
assert.ok(oldItem.published, 'should be published');
this.idToItem_.set(id, {
...oldItem,
published: false,
});
this.checkRep_();
return Promise.resolve();
},
sync: () => Promise.resolve(), sync: () => Promise.resolve(),
listNotes: () => { listNotes: () => {
const notes = mapItems(item => { const notes = mapItems(item => {

View File

@@ -580,6 +580,31 @@ class Client implements ActionableClient {
await this.execCliCommand_('share', 'delete', '-f', id); await this.execCliCommand_('share', 'delete', '-f', id);
} }
public async publishNote(id: ItemId) {
await this.tracker_.publishNote(id);
logger.info('Publish note', id, 'in', this.label);
const publishOutput = await this.execCliCommand_('publish', '-f', id);
const publishUrl = publishOutput.stdout.match(/http[s]?:\/\/\S+/);
assert.notEqual(publishUrl, null, 'should log the publication URL');
logger.info('Testing publication URL: ', publishUrl[0]);
const fetchResult = await fetch(publishUrl[0]);
if (!fetchResult.ok) {
logger.warn('Fetch failed', fetchResult.statusText);
}
assert.equal(fetchResult.status, 200, `should be able to fetch the published note (status: ${fetchResult.statusText}).`);
}
public async unpublishNote(id: ItemId) {
await this.tracker_.publishNote(id);
logger.info('Unpublish note', id, 'in', this.label);
await this.execCliCommand_('unpublish', id);
}
public async moveItem(itemId: ItemId, newParentId: ItemId) { public async moveItem(itemId: ItemId, newParentId: ItemId) {
logger.info('Move', itemId, 'to', newParentId); logger.info('Move', itemId, 'to', newParentId);
await this.tracker_.moveItem(itemId, newParentId); await this.tracker_.moveItem(itemId, newParentId);
@@ -589,7 +614,7 @@ class Client implements ActionableClient {
public async listNotes() { public async listNotes() {
const params = { const params = {
fields: 'id,parent_id,body,title,is_conflict,conflict_original_id,share_id', fields: 'id,parent_id,body,title,is_conflict,conflict_original_id,share_id,is_shared',
include_deleted: '1', include_deleted: '1',
include_conflicts: '1', include_conflicts: '1',
}; };
@@ -605,6 +630,7 @@ class Client implements ActionableClient {
title: getStringProperty(item, 'title'), title: getStringProperty(item, 'title'),
body: getStringProperty(item, 'body'), body: getStringProperty(item, 'body'),
isShared: getStringProperty(item, 'share_id') !== '', isShared: getStringProperty(item, 'share_id') !== '',
published: getNumberProperty(item, 'is_shared') === 1,
}), }),
); );
} }

View File

@@ -59,12 +59,17 @@ const doRandomAction = async (context: FuzzContext, client: Client, clientPool:
return parentId; return parentId;
}; };
const defaultNoteProperties = {
published: false,
};
const selectOrCreateWriteableNote = async () => { const selectOrCreateWriteableNote = async () => {
const options = { includeReadOnly: false }; const options = { includeReadOnly: false };
let note = await client.randomNote(options); let note = await client.randomNote(options);
if (!note) { if (!note) {
await client.createNote({ await client.createNote({
...defaultNoteProperties,
parentId: await selectOrCreateParentFolder(), parentId: await selectOrCreateParentFolder(),
id: uuid.create(), id: uuid.create(),
title: 'Test note', title: 'Test note',
@@ -104,6 +109,7 @@ const doRandomAction = async (context: FuzzContext, client: Client, clientPool:
newNote: async () => { newNote: async () => {
const parentId = await selectOrCreateParentFolder(); const parentId = await selectOrCreateParentFolder();
await client.createNote({ await client.createNote({
...defaultNoteProperties,
parentId: parentId, parentId: parentId,
title: `Test (x${context.randInt(0, 1000)})`, title: `Test (x${context.randInt(0, 1000)})`,
body: 'Testing...', body: 'Testing...',
@@ -247,6 +253,7 @@ const doRandomAction = async (context: FuzzContext, client: Client, clientPool:
for (let i = 0; i < welcomeNoteCount; i++) { for (let i = 0; i < welcomeNoteCount; i++) {
await client.createNote({ await client.createNote({
...defaultNoteProperties,
parentId: testNotesFolderId, parentId: testNotesFolderId,
id: uuid.create(), id: uuid.create(),
title: `Test note ${i}/${welcomeNoteCount}`, title: `Test note ${i}/${welcomeNoteCount}`,
@@ -287,6 +294,22 @@ const doRandomAction = async (context: FuzzContext, client: Client, clientPool:
} }
return true; return true;
}, },
publishNote: async () => {
const note = await client.randomNote({
includeReadOnly: true,
});
if (!note || note.published) return false;
await client.publishNote(note.id);
return true;
},
unpublishNote: async () => {
const note = await client.randomNote({ includeReadOnly: true });
if (!note || !note.published) return false;
await client.unpublishNote(note.id);
return true;
},
}; };
const actionKeys = [...Object.keys(actions)] as (keyof typeof actions)[]; const actionKeys = [...Object.keys(actions)] as (keyof typeof actions)[];

View File

@@ -11,6 +11,7 @@ export interface NoteData {
id: ItemId; id: ItemId;
title: string; title: string;
body: string; body: string;
published: boolean;
} }
export interface DetailedNoteData extends NoteData { export interface DetailedNoteData extends NoteData {
isShared: boolean; isShared: boolean;
@@ -73,6 +74,8 @@ export interface ActionableClient {
createNote(data: NoteData): Promise<void>; createNote(data: NoteData): Promise<void>;
updateNote(data: NoteData): Promise<void>; updateNote(data: NoteData): Promise<void>;
moveItem(itemId: ItemId, newParentId: ItemId): Promise<void>; moveItem(itemId: ItemId, newParentId: ItemId): Promise<void>;
publishNote(id: ItemId): Promise<void>;
unpublishNote(id: ItemId): Promise<void>;
sync(): Promise<void>; sync(): Promise<void>;
listNotes(): Promise<NoteData[]>; listNotes(): Promise<NoteData[]>;