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 <git@herrmehren.de>
This commit is contained in:
David Mehren 2022-04-03 17:37:20 +02:00
parent 366aead689
commit 3503a45078
2 changed files with 90 additions and 19 deletions

View file

@ -152,7 +152,19 @@ describe('HistoryService', () => {
Note.create(user, alias) as Note, Note.create(user, alias) as Note,
) as HistoryEntry; ) as HistoryEntry;
it('without an preexisting entry', async () => { 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 jest
.spyOn(historyRepo, 'save') .spyOn(historyRepo, 'save')
.mockImplementation( .mockImplementation(
@ -170,7 +182,19 @@ describe('HistoryService', () => {
}); });
it('with an preexisting entry', async () => { 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 jest
.spyOn(historyRepo, 'save') .spyOn(historyRepo, 'save')
.mockImplementation( .mockImplementation(
@ -213,7 +237,19 @@ describe('HistoryService', () => {
describe('works', () => { describe('works', () => {
it('with an entry', async () => { it('with an entry', async () => {
const historyEntry = HistoryEntry.create(user, note) as HistoryEntry; 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 jest
.spyOn(historyRepo, 'save') .spyOn(historyRepo, 'save')
.mockImplementation( .mockImplementation(
@ -234,7 +270,19 @@ describe('HistoryService', () => {
}); });
it('without an entry', async () => { 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( await expect(
service.updateHistoryEntry(note, user, { service.updateHistoryEntry(note, user, {
pinStatus: true, pinStatus: true,
@ -300,19 +348,31 @@ describe('HistoryService', () => {
const alias = 'alias'; const alias = 'alias';
const note = Note.create(user, alias) as Note; const note = Note.create(user, alias) as Note;
const historyEntry = HistoryEntry.create(user, note) as HistoryEntry; const historyEntry = HistoryEntry.create(user, note) as HistoryEntry;
jest.spyOn(historyRepo, 'findOne').mockResolvedValueOnce(historyEntry); const historyQueryBuilder = {
const createQueryBuilder = { where: () => historyQueryBuilder,
leftJoinAndSelect: () => createQueryBuilder, andWhere: () => historyQueryBuilder,
where: () => createQueryBuilder, leftJoinAndSelect: () => historyQueryBuilder,
orWhere: () => createQueryBuilder, getOne: async () => {
setParameter: () => createQueryBuilder, 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, getOne: () => note,
}; };
jest jest
.spyOn(noteRepo, 'createQueryBuilder') .spyOn(noteRepo, 'createQueryBuilder')
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
.mockImplementation(() => createQueryBuilder); .mockImplementation(() => noteQueryBuilder);
jest jest
.spyOn(historyRepo, 'remove') .spyOn(historyRepo, 'remove')
.mockImplementation( .mockImplementation(
@ -341,7 +401,19 @@ describe('HistoryService', () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
.mockImplementation(() => createQueryBuilder); .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( await expect(service.deleteHistoryEntry(note, user)).rejects.toThrow(
NotInDBError, NotInDBError,
); );

View file

@ -54,13 +54,12 @@ export class HistoryService {
* @return {HistoryEntry} the requested history entry * @return {HistoryEntry} the requested history entry
*/ */
async getEntryByNote(note: Note, user: User): Promise<HistoryEntry> { async getEntryByNote(note: Note, user: User): Promise<HistoryEntry> {
const entry = await this.historyEntryRepository.findOne({ const entry = await this.historyEntryRepository
where: { .createQueryBuilder('entry')
note: Equal(note), .where('entry.note = :note', { note: note.id })
user: Equal(user), .andWhere('entry.user = :user', { user: user.id })
}, .leftJoinAndSelect('entry.note', 'note')
relations: ['note', 'note.aliases', 'user'], .getOne();
});
if (!entry) { if (!entry) {
throw new NotInDBError( throw new NotInDBError(
`User '${user.username}' has no HistoryEntry for Note with id '${note.id}'`, `User '${user.username}' has no HistoryEntry for Note with id '${note.id}'`,