fix: save created revision on realtime note destroy

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
Tilman Vatteroth 2023-06-21 13:11:30 +02:00
parent b3eb6e4339
commit cf02c35b49
4 changed files with 84 additions and 4 deletions

View file

@ -78,7 +78,7 @@ describe('RealtimeNoteService', () => {
revisionsService = Mock.of<RevisionsService>({ revisionsService = Mock.of<RevisionsService>({
getLatestRevision: jest.fn(), getLatestRevision: jest.fn(),
createRevision: jest.fn(), createAndSaveRevision: jest.fn(),
}); });
consoleLoggerService = Mock.of<ConsoleLoggerService>({ consoleLoggerService = Mock.of<ConsoleLoggerService>({
@ -294,8 +294,8 @@ describe('RealtimeNoteService', () => {
await realtimeNoteService.getOrCreateRealtimeNote(note); await realtimeNoteService.getOrCreateRealtimeNote(note);
const createRevisionSpy = jest const createRevisionSpy = jest
.spyOn(revisionsService, 'createRevision') .spyOn(revisionsService, 'createAndSaveRevision')
.mockImplementation(() => Promise.resolve(Mock.of<Revision>())); .mockResolvedValue();
realtimeNote.emit('beforeDestroy'); realtimeNote.emit('beforeDestroy');
expect(createRevisionSpy).toHaveBeenCalledWith( expect(createRevisionSpy).toHaveBeenCalledWith(

View file

@ -44,7 +44,7 @@ export class RealtimeNoteService implements BeforeApplicationShutdown {
*/ */
public saveRealtimeNote(realtimeNote: RealtimeNote): void { public saveRealtimeNote(realtimeNote: RealtimeNote): void {
this.revisionsService this.revisionsService
.createRevision( .createAndSaveRevision(
realtimeNote.getNote(), realtimeNote.getNote(),
realtimeNote.getRealtimeDoc().getCurrentContent(), realtimeNote.getRealtimeDoc().getCurrentContent(),
realtimeNote.getRealtimeDoc().encodeStateAsUpdate(), realtimeNote.getRealtimeDoc().encodeStateAsUpdate(),

View file

@ -364,4 +364,50 @@ describe('RevisionsService', () => {
expect(saveSpy).not.toHaveBeenCalled(); expect(saveSpy).not.toHaveBeenCalled();
}); });
}); });
describe('createAndSaveRevision', () => {
it('creates and saves a new revision', async () => {
const newRevision = Mock.of<Revision>();
const createRevisionSpy = jest
.spyOn(service, 'createRevision')
.mockResolvedValue(newRevision);
const repoSaveSpy = jest
.spyOn(revisionRepo, 'save')
.mockResolvedValue(newRevision);
const note = Mock.of<Note>({});
const newContent = 'MockContent';
const yjsState = [0, 1, 2, 3, 4, 5];
await service.createAndSaveRevision(note, newContent, yjsState);
expect(createRevisionSpy).toHaveBeenCalledWith(
note,
newContent,
yjsState,
);
expect(repoSaveSpy).toHaveBeenCalledWith(newRevision);
});
it("doesn't save if no revision has been created", async () => {
const createRevisionSpy = jest
.spyOn(service, 'createRevision')
.mockResolvedValue(undefined);
const repoSaveSpy = jest
.spyOn(revisionRepo, 'save')
.mockRejectedValue(new Error("shouldn't have been called"));
const note = Mock.of<Note>({});
const newContent = 'MockContent';
const yjsState = [0, 1, 2, 3, 4, 5];
await service.createAndSaveRevision(note, newContent, yjsState);
expect(createRevisionSpy).toHaveBeenCalledWith(
note,
newContent,
yjsState,
);
expect(repoSaveSpy).not.toHaveBeenCalled();
});
});
}); });

View file

@ -150,6 +150,17 @@ export class RevisionsService {
}; };
} }
/**
* Creates (but does not persist(!)) a new {@link Revision} for the given {@link Note}.
* Useful if the revision is saved together with the note in one action.
*
* @async
* @param note The note for which the revision should be created
* @param newContent The new note content
* @param yjsStateVector The yjs state vector that describes the new content
* @return {Revision} the created revision
* @return {undefined} if the revision couldn't be created because e.g. the content hasn't changed
*/
async createRevision( async createRevision(
note: Note, note: Note,
newContent: string, newContent: string,
@ -185,4 +196,27 @@ export class RevisionsService {
tagEntities, tagEntities,
) as Revision; ) as Revision;
} }
/**
* Creates and saves a new {@link Revision} for the given {@link Note}.
*
* @async
* @param note The note for which the revision should be created
* @param newContent The new note content
* @param yjsStateVector The yjs state vector that describes the new content
*/
async createAndSaveRevision(
note: Note,
newContent: string,
yjsStateVector?: number[],
): Promise<void> {
const revision = await this.createRevision(
note,
newContent,
yjsStateVector,
);
if (revision) {
await this.revisionRepository.save(revision);
}
}
} }