diff --git a/src/quiz/quiz.persistence.ts b/src/quiz/quiz.persistence.ts index 945ca3f..56c378a 100644 --- a/src/quiz/quiz.persistence.ts +++ b/src/quiz/quiz.persistence.ts @@ -233,4 +233,21 @@ export class QuizPersistence { }, }); } + + getRecentQuizUploads({ limit }: { limit: number }) { + return this.#prisma.client().quiz.findMany({ + take: limit, + orderBy: { + uploadedAt: 'desc', + }, + include: { + uploadedByUser: { + select: { + email: true, + name: true, + }, + }, + }, + }); + } } diff --git a/src/quiz/quiz.service.test.ts b/src/quiz/quiz.service.test.ts index 111c0d2..8dd3cec 100644 --- a/src/quiz/quiz.service.test.ts +++ b/src/quiz/quiz.service.test.ts @@ -16,6 +16,7 @@ const mockPersistence = { getQuizzesWithUserResults: jest.fn(), getQuizByIdWithResults: jest.fn(), getRecentQuizCompletions: jest.fn(), + getRecentQuizUploads: jest.fn(), }; const mockFileService = { createKey: jest.fn(), @@ -353,5 +354,39 @@ describe('quiz', () => { ]); }); }); + describe('getRecentQuizUploads', () => { + it('must call getRecentQuizUploads on persistence with correct arguments and transform the result', async () => { + mockPersistence.getRecentQuizUploads.mockResolvedValueOnce([ + { + id: 'fake-quiz-id', + type: 'SHARK', + date: new Date('2022-12-12'), + uploadedAt: new Date('2023-01-01'), + uploadedByUser: { + email: 'master@quizlord.net', + name: 'Quiz Master', + }, + }, + ]); + + const actual = await sut.getRecentQuizUploads(); + + expect(mockPersistence.getRecentQuizUploads).toHaveBeenCalledTimes(1); + expect(mockPersistence.getRecentQuizUploads).toHaveBeenCalledWith({ limit: 20 }); + + expect(actual).toEqual([ + { + id: 'fake-quiz-id', + type: 'SHARK', + date: new Date('2022-12-12'), + uploadedAt: new Date('2023-01-01'), + uploadedBy: { + email: 'master@quizlord.net', + name: 'Quiz Master', + }, + }, + ]); + }); + }); }); }); diff --git a/src/quiz/quiz.service.ts b/src/quiz/quiz.service.ts index 7195c8c..5e84cf7 100644 --- a/src/quiz/quiz.service.ts +++ b/src/quiz/quiz.service.ts @@ -233,6 +233,25 @@ export class QuizService { })); } + /** + * Get the most recent `first` quiz uploads. + * @param first The number of quizzes to get. Defaults to 20. + * @returns The most recent `first` quiz uploads. + */ + async getRecentQuizUploads(first = 20) { + const recent = await this.#persistence.getRecentQuizUploads({ limit: first }); + return recent.map((quiz) => ({ + id: quiz.id, + type: quiz.type, + date: quiz.date, + uploadedAt: quiz.uploadedAt, + uploadedBy: { + name: quiz.uploadedByUser.name, + email: quiz.uploadedByUser.email, + }, + })); + } + async #populateFileWithUploadLink(file: { fileName: string; type: QuizImageType; imageKey: string }) { const uploadLink = await this.#fileService.generateSignedUploadUrl(file.imageKey); return {