Skip to content

Commit a79fcaa

Browse files
authored
fix: replace file running twice (#2396)
1 parent 0ee9fa0 commit a79fcaa

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

packages/super-editor/src/core/Editor.replace-file.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
22
import { Doc as YDoc } from 'yjs';
3+
4+
const { seedPartsFromEditorSpy } = vi.hoisted(() => ({
5+
seedPartsFromEditorSpy: vi.fn(),
6+
}));
7+
8+
vi.mock('@extensions/collaboration/part-sync/seed-parts.js', async (importOriginal) => {
9+
const actual = await importOriginal<typeof import('@extensions/collaboration/part-sync/seed-parts.js')>();
10+
11+
return {
12+
...actual,
13+
seedPartsFromEditor: vi.fn((...args: Parameters<typeof actual.seedPartsFromEditor>) => {
14+
seedPartsFromEditorSpy(...args);
15+
return actual.seedPartsFromEditor(...args);
16+
}),
17+
};
18+
});
19+
320
import { Editor } from './Editor.js';
421
import { getStarterExtensions } from '@extensions/index.js';
522
import { getTestDataAsFileBuffer, loadTestDataForEditorTests } from '@tests/helpers/helpers.js';
@@ -55,6 +72,7 @@ describe('Editor.replaceFile', () => {
5572

5673
afterEach(() => {
5774
vi.useRealTimers();
75+
vi.clearAllMocks();
5876
});
5977

6078
it('applies replacement when provider emits sync(true) without synced event', async () => {
@@ -186,6 +204,48 @@ describe('Editor.replaceFile', () => {
186204
}
187205
});
188206

207+
it('runs collaborative replace side effects once when the provider is already synced', async () => {
208+
const provider = createProviderStub();
209+
provider.synced = true;
210+
provider.isSynced = true;
211+
212+
const ydoc = new YDoc();
213+
const editor = createTestEditor({
214+
ydoc,
215+
collaborationProvider: provider,
216+
});
217+
const expectedEditor = createTestEditor();
218+
219+
try {
220+
await editor.open(undefined, {
221+
mode: 'docx',
222+
content: blankDocData.docx as any,
223+
mediaFiles: blankDocData.mediaFiles as any,
224+
fonts: blankDocData.fonts as any,
225+
});
226+
await expectedEditor.open(replacementBuffer, { mode: 'docx' });
227+
228+
const seedCallsBeforeReplace = seedPartsFromEditorSpy.mock.calls.length;
229+
230+
await editor.replaceFile(replacementBuffer);
231+
232+
const seedCallsDuringReplace = seedPartsFromEditorSpy.mock.calls.length - seedCallsBeforeReplace;
233+
234+
expect(editor.state.doc.textContent).toBe(expectedEditor.state.doc.textContent);
235+
expect(seedCallsDuringReplace).toBe(1);
236+
expect(seedPartsFromEditorSpy).toHaveBeenLastCalledWith(editor, ydoc, { replaceExisting: true });
237+
} finally {
238+
if (editor.lifecycleState === 'ready') {
239+
editor.close();
240+
}
241+
if (expectedEditor.lifecycleState === 'ready') {
242+
expectedEditor.close();
243+
}
244+
editor.destroy();
245+
expectedEditor.destroy();
246+
}
247+
});
248+
189249
it('seeds collaborative bodySectPr metadata when replacing a file with a final section', async () => {
190250
const provider = createProviderStub();
191251
const ydoc = new YDoc();

packages/super-editor/src/core/Editor.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3318,7 +3318,6 @@ export class Editor extends EventEmitter<EditorEventMap> {
33183318
}, SYNC_TIMEOUT_MS);
33193319
}
33203320
});
3321-
doReplaceFileSync();
33223321
} else {
33233322
this.#insertNewFileData();
33243323
}

0 commit comments

Comments
 (0)