1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00
joplin/packages/app-desktop/gui/NoteEditor/utils/useFormNote.test.ts
2024-11-10 14:04:46 +00:00

184 lines
4.9 KiB
TypeScript

import Note from '@joplin/lib/models/Note';
import { setupDatabaseAndSynchronizer, supportDir, switchClient } from '@joplin/lib/testing/test-utils';
import { act, renderHook } from '@testing-library/react-hooks';
import useFormNote, { HookDependencies } from './useFormNote';
import shim from '@joplin/lib/shim';
import Resource from '@joplin/lib/models/Resource';
import { join } from 'path';
import { formNoteToNote } from '.';
const defaultFormNoteProps: HookDependencies = {
noteId: '',
isProvisional: false,
titleInputRef: null,
editorRef: null,
onBeforeLoad: () => { },
onAfterLoad: () => { },
editorId: 'editor',
builtInEditorVisible: false,
};
describe('useFormNote', () => {
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
});
it('should update note when decryption completes', async () => {
const testNote = await Note.save({ title: 'Test Note!' });
const makeFormNoteProps = (): HookDependencies => {
return {
...defaultFormNoteProps,
noteId: testNote.id,
};
};
const formNote = renderHook(props => useFormNote(props), {
initialProps: makeFormNoteProps(),
});
await formNote.waitFor(() => {
// id is falsy until after the first load of the form note.
expect(formNote.result.current.formNote.id).not.toBeFalsy();
});
expect(formNote.result.current.formNote).toMatchObject({
encryption_applied: 0,
title: testNote.title,
});
await act(async () => {
await Note.save({
id: testNote.id,
encryption_cipher_text: 'cipher_text',
encryption_applied: 1,
});
});
// Changing encryption_applied should cause a re-render
await act(async () => {
await formNote.waitFor(() => {
expect(formNote.result.current.formNote).toMatchObject({
encryption_applied: 1,
});
});
});
await act(async () => {
await Note.save({
id: testNote.id,
encryption_applied: 0,
title: 'Test Note!',
});
});
// Ending decryption should also cause a re-render
await formNote.waitFor(() => {
expect(formNote.result.current.formNote).toMatchObject({
encryption_applied: 0,
});
// A larger-than-default timeout is needed to prevent CI failures:
}, { timeout: 5_000 });
formNote.unmount();
});
// Lacking is_conflict has previously caused UI issues. See https://github.com/laurent22/joplin/pull/10913
// for details.
it('should preserve value of is_conflict on save', async () => {
const testNote = await Note.save({ title: 'Test Note!', is_conflict: 1 });
const makeFormNoteProps = (): HookDependencies => {
return {
...defaultFormNoteProps,
noteId: testNote.id,
};
};
const formNote = renderHook(props => useFormNote(props), {
initialProps: makeFormNoteProps(),
});
await formNote.waitFor(() => {
expect(formNote.result.current.formNote).toMatchObject({
is_conflict: 1,
title: testNote.title,
});
});
// Should preserve is_conflict after save.
expect(await formNoteToNote(formNote.result.current.formNote)).toMatchObject({
is_conflict: 1,
deleted_time: 0,
title: testNote.title,
});
formNote.unmount();
});
it('should reload the note when it is changed outside of the editor', async () => {
const note = await Note.save({ title: 'Test Note!', body: '...' });
const props = {
...defaultFormNoteProps,
noteId: note.id,
};
const formNote = renderHook(props => useFormNote(props), {
initialProps: props,
});
await formNote.waitFor(() => {
expect(formNote.result.current.formNote.title).toBe('Test Note!');
});
// Simulate the note being modified outside the editor
await act(async () => {
await Note.save({ id: note.id, title: 'Modified' });
});
await formNote.waitFor(() => {
expect(formNote.result.current.formNote.title).toBe('Modified');
});
formNote.unmount();
});
test('should refresh resource infos when changed outside the editor', async () => {
let note = await Note.save({});
note = await shim.attachFileToNote(note, join(supportDir, 'sample.txt'));
const resourceIds = Note.linkedItemIds(note.body);
const resource = await Resource.load(resourceIds[0]);
const makeFormNoteProps = (): HookDependencies => {
return {
...defaultFormNoteProps,
noteId: note.id,
};
};
const formNote = renderHook(props => useFormNote(props), {
initialProps: makeFormNoteProps(),
});
await formNote.waitFor(() => {
return Object.values(formNote.result.current.resourceInfos).length > 0;
});
const initialResourceInfos = formNote.result.current.resourceInfos;
expect(initialResourceInfos).toMatchObject({
[resource.id]: { item: { id: resource.id } },
});
await act(async () => {
await Resource.save({ ...resource, filename: 'test.txt' });
});
await formNote.waitFor(() => {
const resourceInfo = formNote.result.current.resourceInfos[resource.id];
expect(resourceInfo.item).toMatchObject({
id: resource.id, filename: 'test.txt',
});
});
formNote.unmount();
});
});