mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2024-11-25 11:16:31 -05:00
refactor(media-upload): lazy-load relations
Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
parent
8aae5cb574
commit
facdc456cd
9 changed files with 39 additions and 30 deletions
|
@ -40,7 +40,9 @@ export class MeController {
|
|||
@Get('media')
|
||||
async getMyMedia(@RequestUser() user: User): Promise<MediaUploadDto[]> {
|
||||
const media = await this.mediaService.listUploadsByUser(user);
|
||||
return media.map((media) => this.mediaService.toMediaUploadDto(media));
|
||||
return await Promise.all(
|
||||
media.map((media) => this.mediaService.toMediaUploadDto(media)),
|
||||
);
|
||||
}
|
||||
|
||||
@Delete()
|
||||
|
|
|
@ -131,7 +131,7 @@ export class MediaController {
|
|||
const mediaUpload = await this.mediaService.findUploadByFilename(
|
||||
filename,
|
||||
);
|
||||
if (mediaUpload.user.username !== username) {
|
||||
if ((await mediaUpload.user).username !== username) {
|
||||
this.logger.warn(
|
||||
`${username} tried to delete '${filename}', but is not the owner`,
|
||||
'deleteMedia',
|
||||
|
|
|
@ -72,7 +72,9 @@ export class NotesController {
|
|||
@UseGuards(PermissionsGuard)
|
||||
async getNotesMedia(@RequestNote() note: Note): Promise<MediaUploadDto[]> {
|
||||
const media = await this.mediaService.listUploadsByNote(note);
|
||||
return media.map((media) => this.mediaService.toMediaUploadDto(media));
|
||||
return await Promise.all(
|
||||
media.map((media) => this.mediaService.toMediaUploadDto(media)),
|
||||
);
|
||||
}
|
||||
|
||||
@Post()
|
||||
|
|
|
@ -188,6 +188,8 @@ export class MeController {
|
|||
@ApiUnauthorizedResponse({ description: unauthorizedDescription })
|
||||
async getMyMedia(@RequestUser() user: User): Promise<MediaUploadDto[]> {
|
||||
const media = await this.mediaService.listUploadsByUser(user);
|
||||
return media.map((media) => this.mediaService.toMediaUploadDto(media));
|
||||
return await Promise.all(
|
||||
media.map((media) => this.mediaService.toMediaUploadDto(media)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ export class MediaController {
|
|||
const mediaUpload = await this.mediaService.findUploadByFilename(
|
||||
filename,
|
||||
);
|
||||
if (mediaUpload.user.username !== username) {
|
||||
if ((await mediaUpload.user).username !== username) {
|
||||
this.logger.warn(
|
||||
`${username} tried to delete '${filename}', but is not the owner`,
|
||||
'deleteMedia',
|
||||
|
|
|
@ -298,6 +298,8 @@ export class NotesController {
|
|||
@RequestNote() note: Note,
|
||||
): Promise<MediaUploadDto[]> {
|
||||
const media = await this.mediaService.listUploadsByNote(note);
|
||||
return media.map((media) => this.mediaService.toMediaUploadDto(media));
|
||||
return await Promise.all(
|
||||
media.map((media) => this.mediaService.toMediaUploadDto(media)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@ export class MediaUpload {
|
|||
@ManyToOne((_) => Note, (note) => note.mediaUploads, {
|
||||
nullable: true,
|
||||
})
|
||||
note: Note | null;
|
||||
note: Promise<Note | null>;
|
||||
|
||||
@ManyToOne((_) => User, (user) => user.mediaUploads, {
|
||||
nullable: false,
|
||||
})
|
||||
user: User;
|
||||
user: Promise<User>;
|
||||
|
||||
@Column({
|
||||
nullable: false,
|
||||
|
@ -72,8 +72,8 @@ export class MediaUpload {
|
|||
): Omit<MediaUpload, 'createdAt'> {
|
||||
const upload = new MediaUpload();
|
||||
upload.id = id;
|
||||
upload.note = note;
|
||||
upload.user = user;
|
||||
upload.note = Promise.resolve(note);
|
||||
upload.user = Promise.resolve(user);
|
||||
upload.backendType = backendType;
|
||||
upload.backendData = null;
|
||||
upload.fileUrl = fileUrl;
|
||||
|
|
|
@ -167,9 +167,9 @@ describe('MediaService', () => {
|
|||
const mockMediaUploadEntry = {
|
||||
id: 'testMediaUpload',
|
||||
backendData: 'testBackendData',
|
||||
user: {
|
||||
user: Promise.resolve({
|
||||
username: 'hardcoded',
|
||||
} as User,
|
||||
} as User),
|
||||
} as MediaUpload;
|
||||
jest
|
||||
.spyOn(service.mediaBackend, 'deleteFile')
|
||||
|
@ -196,15 +196,15 @@ describe('MediaService', () => {
|
|||
const mockMediaUploadEntry = {
|
||||
id: 'testMediaUpload',
|
||||
backendData: backendData,
|
||||
user: {
|
||||
user: Promise.resolve({
|
||||
username: username,
|
||||
} as User,
|
||||
} as User),
|
||||
} as MediaUpload;
|
||||
jest
|
||||
.spyOn(mediaRepo, 'findOne')
|
||||
.mockResolvedValueOnce(mockMediaUploadEntry);
|
||||
const mediaUpload = await service.findUploadByFilename(testFileName);
|
||||
expect(mediaUpload.user.username).toEqual(username);
|
||||
expect((await mediaUpload.user).username).toEqual(username);
|
||||
expect(mediaUpload.backendData).toEqual(backendData);
|
||||
});
|
||||
it("fails: can't find mediaUpload", async () => {
|
||||
|
@ -218,13 +218,14 @@ describe('MediaService', () => {
|
|||
|
||||
describe('listUploadsByUser', () => {
|
||||
describe('works', () => {
|
||||
const username = 'hardcoded';
|
||||
it('with one upload from user', async () => {
|
||||
const mockMediaUploadEntry = {
|
||||
id: 'testMediaUpload',
|
||||
backendData: 'testBackendData',
|
||||
user: {
|
||||
username: 'hardcoded',
|
||||
} as User,
|
||||
user: Promise.resolve({
|
||||
username: username,
|
||||
} as User),
|
||||
} as MediaUpload;
|
||||
jest
|
||||
.spyOn(mediaRepo, 'find')
|
||||
|
@ -237,14 +238,14 @@ describe('MediaService', () => {
|
|||
it('without uploads from user', async () => {
|
||||
jest.spyOn(mediaRepo, 'find').mockResolvedValueOnce([]);
|
||||
const mediaList = await service.listUploadsByUser({
|
||||
username: 'hardcoded',
|
||||
username: username,
|
||||
} as User);
|
||||
expect(mediaList).toEqual([]);
|
||||
});
|
||||
it('with error (undefined as return value of find)', async () => {
|
||||
jest.spyOn(mediaRepo, 'find').mockResolvedValueOnce(undefined);
|
||||
const mediaList = await service.listUploadsByUser({
|
||||
username: 'hardcoded',
|
||||
username: username,
|
||||
} as User);
|
||||
expect(mediaList).toEqual([]);
|
||||
});
|
||||
|
@ -257,9 +258,9 @@ describe('MediaService', () => {
|
|||
const mockMediaUploadEntry = {
|
||||
id: 'testMediaUpload',
|
||||
backendData: 'testBackendData',
|
||||
note: {
|
||||
note: Promise.resolve({
|
||||
id: '123',
|
||||
} as Note,
|
||||
} as Note),
|
||||
} as MediaUpload;
|
||||
jest
|
||||
.spyOn(mediaRepo, 'find')
|
||||
|
@ -294,15 +295,15 @@ describe('MediaService', () => {
|
|||
const mockMediaUploadEntry = {
|
||||
id: 'testMediaUpload',
|
||||
backendData: 'testBackendData',
|
||||
note: mockNote,
|
||||
user: {
|
||||
note: Promise.resolve(mockNote),
|
||||
user: Promise.resolve({
|
||||
username: 'hardcoded',
|
||||
} as User,
|
||||
} as User),
|
||||
} as MediaUpload;
|
||||
jest
|
||||
.spyOn(mediaRepo, 'save')
|
||||
.mockImplementationOnce(async (entry: MediaUpload) => {
|
||||
expect(entry.note).toBeNull();
|
||||
expect(await entry.note).toBeNull();
|
||||
return entry;
|
||||
});
|
||||
await service.removeNoteFromMediaUpload(mockMediaUploadEntry);
|
||||
|
|
|
@ -181,7 +181,7 @@ export class MediaService {
|
|||
'Setting note to null for mediaUpload: ' + mediaUpload.id,
|
||||
'removeNoteFromMediaUpload',
|
||||
);
|
||||
mediaUpload.note = null;
|
||||
mediaUpload.note = Promise.resolve(null);
|
||||
await this.mediaUploadRepository.save(mediaUpload);
|
||||
}
|
||||
|
||||
|
@ -219,12 +219,12 @@ export class MediaService {
|
|||
}
|
||||
}
|
||||
|
||||
toMediaUploadDto(mediaUpload: MediaUpload): MediaUploadDto {
|
||||
async toMediaUploadDto(mediaUpload: MediaUpload): Promise<MediaUploadDto> {
|
||||
return {
|
||||
url: mediaUpload.fileUrl,
|
||||
noteId: mediaUpload.note?.id ?? null,
|
||||
noteId: (await mediaUpload.note)?.id ?? null,
|
||||
createdAt: mediaUpload.createdAt,
|
||||
username: mediaUpload.user.username,
|
||||
username: (await mediaUpload.user).username,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue