From 3503a45078fc62efcf1996965764a8088cbffbff Mon Sep 17 00:00:00 2001 From: David Mehren Date: Sun, 3 Apr 2022 17:37:20 +0200 Subject: [PATCH] fix(history-service): user query builder For reasons, the typeorm 0.3 broke the find() method when using relations in the WHERE clause. This replaces the find method with a query builder. Signed-off-by: David Mehren --- src/history/history.service.spec.ts | 96 +++++++++++++++++++++++++---- src/history/history.service.ts | 13 ++-- 2 files changed, 90 insertions(+), 19 deletions(-) diff --git a/src/history/history.service.spec.ts b/src/history/history.service.spec.ts index c1bdc3b29..9169e3866 100644 --- a/src/history/history.service.spec.ts +++ b/src/history/history.service.spec.ts @@ -152,7 +152,19 @@ describe('HistoryService', () => { Note.create(user, alias) as Note, ) as HistoryEntry; it('without an preexisting entry', async () => { - jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined); + const createQueryBuilder = { + where: () => createQueryBuilder, + andWhere: () => createQueryBuilder, + leftJoinAndSelect: () => createQueryBuilder, + getOne: async () => { + return null; + }, + }; + jest + .spyOn(historyRepo, 'createQueryBuilder') + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + .mockImplementation(() => createQueryBuilder); jest .spyOn(historyRepo, 'save') .mockImplementation( @@ -170,7 +182,19 @@ describe('HistoryService', () => { }); it('with an preexisting entry', async () => { - jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(historyEntry); + const createQueryBuilder = { + where: () => createQueryBuilder, + andWhere: () => createQueryBuilder, + leftJoinAndSelect: () => createQueryBuilder, + getOne: async () => { + return historyEntry; + }, + }; + jest + .spyOn(historyRepo, 'createQueryBuilder') + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + .mockImplementation(() => createQueryBuilder); jest .spyOn(historyRepo, 'save') .mockImplementation( @@ -213,7 +237,19 @@ describe('HistoryService', () => { describe('works', () => { it('with an entry', async () => { const historyEntry = HistoryEntry.create(user, note) as HistoryEntry; - jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(historyEntry); + const createQueryBuilder = { + where: () => createQueryBuilder, + andWhere: () => createQueryBuilder, + leftJoinAndSelect: () => createQueryBuilder, + getOne: async () => { + return historyEntry; + }, + }; + jest + .spyOn(historyRepo, 'createQueryBuilder') + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + .mockImplementation(() => createQueryBuilder); jest .spyOn(historyRepo, 'save') .mockImplementation( @@ -234,7 +270,19 @@ describe('HistoryService', () => { }); it('without an entry', async () => { - jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined); + const createQueryBuilder = { + where: () => createQueryBuilder, + andWhere: () => createQueryBuilder, + leftJoinAndSelect: () => createQueryBuilder, + getOne: async () => { + return null; + }, + }; + jest + .spyOn(historyRepo, 'createQueryBuilder') + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + .mockImplementation(() => createQueryBuilder); await expect( service.updateHistoryEntry(note, user, { pinStatus: true, @@ -300,19 +348,31 @@ describe('HistoryService', () => { const alias = 'alias'; const note = Note.create(user, alias) as Note; const historyEntry = HistoryEntry.create(user, note) as HistoryEntry; - jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(historyEntry); - const createQueryBuilder = { - leftJoinAndSelect: () => createQueryBuilder, - where: () => createQueryBuilder, - orWhere: () => createQueryBuilder, - setParameter: () => createQueryBuilder, + const historyQueryBuilder = { + where: () => historyQueryBuilder, + andWhere: () => historyQueryBuilder, + leftJoinAndSelect: () => historyQueryBuilder, + getOne: async () => { + return historyEntry; + }, + }; + jest + .spyOn(historyRepo, 'createQueryBuilder') + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + .mockImplementation(() => historyQueryBuilder); + const noteQueryBuilder = { + leftJoinAndSelect: () => noteQueryBuilder, + where: () => noteQueryBuilder, + orWhere: () => noteQueryBuilder, + setParameter: () => noteQueryBuilder, getOne: () => note, }; jest .spyOn(noteRepo, 'createQueryBuilder') // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - .mockImplementation(() => createQueryBuilder); + .mockImplementation(() => noteQueryBuilder); jest .spyOn(historyRepo, 'remove') .mockImplementation( @@ -341,7 +401,19 @@ describe('HistoryService', () => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore .mockImplementation(() => createQueryBuilder); - jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(undefined); + const historyQueryBuilder = { + where: () => historyQueryBuilder, + andWhere: () => historyQueryBuilder, + leftJoinAndSelect: () => historyQueryBuilder, + getOne: async () => { + return null; + }, + }; + jest + .spyOn(historyRepo, 'createQueryBuilder') + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + .mockImplementation(() => historyQueryBuilder); await expect(service.deleteHistoryEntry(note, user)).rejects.toThrow( NotInDBError, ); diff --git a/src/history/history.service.ts b/src/history/history.service.ts index aaa32c97c..55b965c09 100644 --- a/src/history/history.service.ts +++ b/src/history/history.service.ts @@ -54,13 +54,12 @@ export class HistoryService { * @return {HistoryEntry} the requested history entry */ async getEntryByNote(note: Note, user: User): Promise { - const entry = await this.historyEntryRepository.findOne({ - where: { - note: Equal(note), - user: Equal(user), - }, - relations: ['note', 'note.aliases', 'user'], - }); + const entry = await this.historyEntryRepository + .createQueryBuilder('entry') + .where('entry.note = :note', { note: note.id }) + .andWhere('entry.user = :user', { user: user.id }) + .leftJoinAndSelect('entry.note', 'note') + .getOne(); if (!entry) { throw new NotInDBError( `User '${user.username}' has no HistoryEntry for Note with id '${note.id}'`,