Merge pull request #786 from hedgedoc/refactor/dto

This commit is contained in:
David Mehren 2021-02-01 20:19:36 +01:00 committed by GitHub
commit 6bce4c241b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 206 additions and 161 deletions

View file

@ -78,7 +78,10 @@ export class MeController {
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@Get('notes') @Get('notes')
getMyNotes(@Request() req): NoteMetadataDto[] { async getMyNotes(@Request() req): Promise<NoteMetadataDto[]> {
return this.notesService.getUserNotes(req.user.userName); const notes = await this.notesService.getUserNotes(req.user);
return Promise.all(
notes.map((note) => this.notesService.toNoteMetadataDto(note)),
);
} }
} }

View file

@ -29,6 +29,7 @@ import { MediaService } from '../../../media/media.service';
import { MulterFile } from '../../../media/multer-file.interface'; import { MulterFile } from '../../../media/multer-file.interface';
import { TokenAuthGuard } from '../../../auth/token-auth.guard'; import { TokenAuthGuard } from '../../../auth/token-auth.guard';
import { ApiSecurity } from '@nestjs/swagger'; import { ApiSecurity } from '@nestjs/swagger';
import { MediaUploadUrlDto } from '../../../media/media-upload-url.dto';
@ApiSecurity('token') @ApiSecurity('token')
@Controller('media') @Controller('media')
@ -47,7 +48,7 @@ export class MediaController {
@Request() req, @Request() req,
@UploadedFile() file: MulterFile, @UploadedFile() file: MulterFile,
@Headers('HedgeDoc-Note') noteId: string, @Headers('HedgeDoc-Note') noteId: string,
) { ): Promise<MediaUploadUrlDto> {
const username = req.user.userName; const username = req.user.userName;
this.logger.debug( this.logger.debug(
`Recieved filename '${file.originalname}' for note '${noteId}' from user '${username}'`, `Recieved filename '${file.originalname}' for note '${noteId}' from user '${username}'`,
@ -59,9 +60,7 @@ export class MediaController {
username, username,
noteId, noteId,
); );
return { return this.mediaService.toMediaUploadUrlDto(url);
link: url,
};
} catch (e) { } catch (e) {
if (e instanceof ClientError || e instanceof NotInDBError) { if (e instanceof ClientError || e instanceof NotInDBError) {
throw new BadRequestException(e.message); throw new BadRequestException(e.message);
@ -72,7 +71,10 @@ export class MediaController {
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@Delete(':filename') @Delete(':filename')
async deleteMedia(@Request() req, @Param('filename') filename: string) { async deleteMedia(
@Request() req,
@Param('filename') filename: string,
): Promise<void> {
const username = req.user.userName; const username = req.user.userName;
try { try {
await this.mediaService.deleteFile(filename, username); await this.mediaService.deleteFile(filename, username);

View file

@ -8,6 +8,7 @@ import { Controller, Get, UseGuards } from '@nestjs/common';
import { MonitoringService } from '../../../monitoring/monitoring.service'; import { MonitoringService } from '../../../monitoring/monitoring.service';
import { TokenAuthGuard } from '../../../auth/token-auth.guard'; import { TokenAuthGuard } from '../../../auth/token-auth.guard';
import { ApiSecurity } from '@nestjs/swagger'; import { ApiSecurity } from '@nestjs/swagger';
import { ServerStatusDto } from '../../../monitoring/server-status.dto';
@ApiSecurity('token') @ApiSecurity('token')
@Controller('monitoring') @Controller('monitoring')
@ -16,7 +17,8 @@ export class MonitoringController {
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@Get() @Get()
getStatus() { getStatus(): Promise<ServerStatusDto> {
// TODO: toServerStatusDto.
return this.monitoringService.getServerStatus(); return this.monitoringService.getServerStatus();
} }

View file

@ -19,12 +19,19 @@ import {
} from '@nestjs/common'; } from '@nestjs/common';
import { NotInDBError } from '../../../errors/errors'; import { NotInDBError } from '../../../errors/errors';
import { ConsoleLoggerService } from '../../../logger/console-logger.service'; import { ConsoleLoggerService } from '../../../logger/console-logger.service';
import { NotePermissionsUpdateDto } from '../../../notes/note-permissions.dto'; import {
NotePermissionsDto,
NotePermissionsUpdateDto,
} from '../../../notes/note-permissions.dto';
import { NotesService } from '../../../notes/notes.service'; import { NotesService } from '../../../notes/notes.service';
import { RevisionsService } from '../../../revisions/revisions.service'; import { RevisionsService } from '../../../revisions/revisions.service';
import { MarkdownBody } from '../../utils/markdownbody-decorator'; import { MarkdownBody } from '../../utils/markdownbody-decorator';
import { TokenAuthGuard } from '../../../auth/token-auth.guard'; import { TokenAuthGuard } from '../../../auth/token-auth.guard';
import { ApiSecurity } from '@nestjs/swagger'; import { ApiSecurity } from '@nestjs/swagger';
import { NoteDto } from '../../../notes/note.dto';
import { NoteMetadataDto } from '../../../notes/note-metadata.dto';
import { RevisionMetadataDto } from '../../../revisions/revision-metadata.dto';
import { RevisionDto } from '../../../revisions/revision.dto';
@ApiSecurity('token') @ApiSecurity('token')
@Controller('notes') @Controller('notes')
@ -39,18 +46,42 @@ export class NotesController {
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@Post() @Post()
async createNote(@Request() req, @MarkdownBody() text: string) { async createNote(
@Request() req,
@MarkdownBody() text: string,
): Promise<NoteDto> {
// ToDo: provide user for createNoteDto // ToDo: provide user for createNoteDto
this.logger.debug('Got raw markdown:\n' + text); this.logger.debug('Got raw markdown:\n' + text);
return this.noteService.createNoteDto(text); return this.noteService.toNoteDto(
await this.noteService.createNote(text, undefined, req.user),
);
}
@UseGuards(TokenAuthGuard)
@Post(':noteAlias')
async createNamedNote(
@Request() req,
@Param('noteAlias') noteAlias: string,
@MarkdownBody() text: string,
): Promise<NoteDto> {
// ToDo: check if user is allowed to view this note
this.logger.debug('Got raw markdown:\n' + text);
return this.noteService.toNoteDto(
await this.noteService.createNote(text, noteAlias, req.user),
);
} }
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@Get(':noteIdOrAlias') @Get(':noteIdOrAlias')
async getNote(@Request() req, @Param('noteIdOrAlias') noteIdOrAlias: string) { async getNote(
@Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string,
): Promise<NoteDto> {
// ToDo: check if user is allowed to view this note // ToDo: check if user is allowed to view this note
try { try {
return await this.noteService.getNoteDtoByIdOrAlias(noteIdOrAlias); return this.noteService.toNoteDto(
await this.noteService.getNoteByIdOrAlias(noteIdOrAlias),
);
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {
throw new NotFoundException(e.message); throw new NotFoundException(e.message);
@ -59,24 +90,12 @@ export class NotesController {
} }
} }
@UseGuards(TokenAuthGuard)
@Post(':noteAlias')
async createNamedNote(
@Request() req,
@Param('noteAlias') noteAlias: string,
@MarkdownBody() text: string,
) {
// ToDo: check if user is allowed to view this note
this.logger.debug('Got raw markdown:\n' + text);
return this.noteService.createNoteDto(text, noteAlias);
}
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@Delete(':noteIdOrAlias') @Delete(':noteIdOrAlias')
async deleteNote( async deleteNote(
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
) { ): Promise<void> {
// ToDo: check if user is allowed to delete this note // ToDo: check if user is allowed to delete this note
this.logger.debug('Deleting note: ' + noteIdOrAlias); this.logger.debug('Deleting note: ' + noteIdOrAlias);
try { try {
@ -97,11 +116,13 @@ export class NotesController {
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
@MarkdownBody() text: string, @MarkdownBody() text: string,
) { ): Promise<NoteDto> {
// ToDo: check if user is allowed to change this note // ToDo: check if user is allowed to change this note
this.logger.debug('Got raw markdown:\n' + text); this.logger.debug('Got raw markdown:\n' + text);
try { try {
return await this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text); return this.noteService.toNoteDto(
await this.noteService.updateNoteByIdOrAlias(noteIdOrAlias, text),
);
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {
throw new NotFoundException(e.message); throw new NotFoundException(e.message);
@ -116,7 +137,7 @@ export class NotesController {
async getNoteContent( async getNoteContent(
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
) { ): Promise<string> {
// ToDo: check if user is allowed to view this notes content // ToDo: check if user is allowed to view this notes content
try { try {
return await this.noteService.getNoteContent(noteIdOrAlias); return await this.noteService.getNoteContent(noteIdOrAlias);
@ -133,10 +154,12 @@ export class NotesController {
async getNoteMetadata( async getNoteMetadata(
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
) { ): Promise<NoteMetadataDto> {
// ToDo: check if user is allowed to view this notes metadata // ToDo: check if user is allowed to view this notes metadata
try { try {
return await this.noteService.getNoteMetadata(noteIdOrAlias); return this.noteService.toNoteMetadataDto(
await this.noteService.getNoteByIdOrAlias(noteIdOrAlias),
);
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {
throw new NotFoundException(e.message); throw new NotFoundException(e.message);
@ -151,12 +174,11 @@ export class NotesController {
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
@Body() updateDto: NotePermissionsUpdateDto, @Body() updateDto: NotePermissionsUpdateDto,
) { ): Promise<NotePermissionsDto> {
// ToDo: check if user is allowed to view this notes permissions // ToDo: check if user is allowed to view this notes permissions
try { try {
return await this.noteService.updateNotePermissions( return this.noteService.toNotePermissionsDto(
noteIdOrAlias, await this.noteService.updateNotePermissions(noteIdOrAlias, updateDto),
updateDto,
); );
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {
@ -171,12 +193,17 @@ export class NotesController {
async getNoteRevisions( async getNoteRevisions(
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
) { ): Promise<RevisionMetadataDto[]> {
// ToDo: check if user is allowed to view this notes revisions // ToDo: check if user is allowed to view this notes revisions
try { try {
return await this.revisionsService.getNoteRevisionMetadatas( const revisions = await this.revisionsService.getAllRevisions(
noteIdOrAlias, noteIdOrAlias,
); );
return Promise.all(
revisions.map((revision) =>
this.revisionsService.toRevisionMetadataDto(revision),
),
);
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {
throw new NotFoundException(e.message); throw new NotFoundException(e.message);
@ -191,12 +218,11 @@ export class NotesController {
@Request() req, @Request() req,
@Param('noteIdOrAlias') noteIdOrAlias: string, @Param('noteIdOrAlias') noteIdOrAlias: string,
@Param('revisionId') revisionId: number, @Param('revisionId') revisionId: number,
) { ): Promise<RevisionDto> {
// ToDo: check if user is allowed to view this notes revision // ToDo: check if user is allowed to view this notes revision
try { try {
return await this.revisionsService.getNoteRevision( return this.revisionsService.toRevisionDto(
noteIdOrAlias, await this.revisionsService.getRevision(noteIdOrAlias, revisionId),
revisionId,
); );
} catch (e) { } catch (e) {
if (e instanceof NotInDBError) { if (e instanceof NotInDBError) {

View file

@ -5,14 +5,20 @@
*/ */
import { ExecutionContext, Injectable } from '@nestjs/common'; import { ExecutionContext, Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { User } from '../users/user.entity';
@Injectable() @Injectable()
export class MockAuthGuard { export class MockAuthGuard {
canActivate(context: ExecutionContext) { private user: User;
constructor(private usersService: UsersService) {}
async canActivate(context: ExecutionContext) {
const req = context.switchToHttp().getRequest(); const req = context.switchToHttp().getRequest();
req.user = { if (!this.user) {
userName: 'hardcoded', this.user = await this.usersService.createUser('hardcoded', 'Testy');
}; }
req.user = this.user;
return true; return true;
} }
} }

View file

@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { IsString } from 'class-validator';
export class MediaUploadUrlDto {
@IsString()
link: string;
}

View file

@ -18,6 +18,7 @@ import { BackendType } from './backends/backend-type.enum';
import { FilesystemBackend } from './backends/filesystem-backend'; import { FilesystemBackend } from './backends/filesystem-backend';
import { MediaBackend } from './media-backend.interface'; import { MediaBackend } from './media-backend.interface';
import { MediaUpload } from './media-upload.entity'; import { MediaUpload } from './media-upload.entity';
import { MediaUploadUrlDto } from './media-upload-url.dto';
@Injectable() @Injectable()
export class MediaService { export class MediaService {
@ -58,7 +59,11 @@ export class MediaService {
return allowedTypes.includes(mimeType); return allowedTypes.includes(mimeType);
} }
public async saveFile(fileBuffer: Buffer, username: string, noteId: string) { public async saveFile(
fileBuffer: Buffer,
username: string,
noteId: string,
): Promise<string> {
this.logger.debug( this.logger.debug(
`Saving file for note '${noteId}' and user '${username}'`, `Saving file for note '${noteId}' and user '${username}'`,
'saveFile', 'saveFile',
@ -88,7 +93,7 @@ export class MediaService {
return url; return url;
} }
public async deleteFile(filename: string, username: string) { public async deleteFile(filename: string, username: string): Promise<void> {
this.logger.debug( this.logger.debug(
`Deleting '${filename}' for user '${username}'`, `Deleting '${filename}' for user '${username}'`,
'deleteFile', 'deleteFile',
@ -132,4 +137,10 @@ export class MediaService {
return this.moduleRef.get(FilesystemBackend); return this.moduleRef.get(FilesystemBackend);
} }
} }
toMediaUploadUrlDto(url: string): MediaUploadUrlDto {
return {
link: url,
};
}
} }

View file

@ -35,48 +35,26 @@ export class NotesService {
this.logger.setContext(NotesService.name); this.logger.setContext(NotesService.name);
} }
getUserNotes(username: string): NoteMetadataDto[] { getUserNotes(user: User): Note[] {
this.logger.warn('Using hardcoded data!'); this.logger.warn('Using hardcoded data!');
return [ return [
{ {
alias: null,
createTime: new Date(),
description: 'Very descriptive text.',
editedBy: [],
id: 'foobar-barfoo', id: 'foobar-barfoo',
permissions: { alias: null,
owner: { shortid: 'abc',
displayName: 'foo', owner: user,
userName: 'fooUser', description: 'Very descriptive text.',
email: 'foo@example.com', userPermissions: [],
photo: '', groupPermissions: [],
},
sharedToUsers: [],
sharedToGroups: [],
},
tags: [], tags: [],
revisions: Promise.resolve([]),
authorColors: [],
title: 'Title!', title: 'Title!',
updateTime: new Date(), viewcount: 42,
updateUser: {
displayName: 'foo',
userName: 'fooUser',
email: 'foo@example.com',
photo: '',
},
viewCount: 42,
}, },
]; ];
} }
async createNoteDto(
noteContent: string,
alias?: NoteMetadataDto['alias'],
owner?: User,
): Promise<NoteDto> {
const note = await this.createNote(noteContent, alias, owner);
return this.toNoteDto(note);
}
async createNote( async createNote(
noteContent: string, noteContent: string,
alias?: NoteMetadataDto['alias'], alias?: NoteMetadataDto['alias'],
@ -96,7 +74,7 @@ export class NotesService {
return this.noteRepository.save(newNote); return this.noteRepository.save(newNote);
} }
async getCurrentContent(note: Note) { async getCurrentContent(note: Note): Promise<string> {
return (await this.getLatestRevision(note)).content; return (await this.getLatestRevision(note)).content;
} }
@ -108,42 +86,6 @@ export class NotesService {
return this.revisionsService.getFirstRevision(note.id); return this.revisionsService.getFirstRevision(note.id);
} }
async getMetadata(note: Note): Promise<NoteMetadataDto> {
return {
// TODO: Convert DB UUID to base64
id: note.id,
alias: note.alias,
title: note.title,
createTime: (await this.getFirstRevision(note)).createdAt,
description: note.description,
editedBy: note.authorColors.map(
(authorColor) => authorColor.user.userName,
),
// TODO: Extract into method
permissions: {
owner: this.usersService.toUserDto(note.owner),
sharedToUsers: note.userPermissions.map((noteUserPermission) => ({
user: this.usersService.toUserDto(noteUserPermission.user),
canEdit: noteUserPermission.canEdit,
})),
sharedToGroups: note.groupPermissions.map((noteGroupPermission) => ({
group: noteGroupPermission.group,
canEdit: noteGroupPermission.canEdit,
})),
},
tags: note.tags.map((tag) => tag.name),
updateTime: (await this.getLatestRevision(note)).createdAt,
// TODO: Get actual updateUser
updateUser: {
displayName: 'Hardcoded User',
userName: 'hardcoded',
email: 'foo@example.com',
photo: '',
},
viewCount: 42,
};
}
async getNoteByIdOrAlias(noteIdOrAlias: string): Promise<Note> { async getNoteByIdOrAlias(noteIdOrAlias: string): Promise<Note> {
this.logger.debug( this.logger.debug(
`Trying to find note '${noteIdOrAlias}'`, `Trying to find note '${noteIdOrAlias}'`,
@ -178,45 +120,50 @@ export class NotesService {
return note; return note;
} }
async getNoteDtoByIdOrAlias(noteIdOrAlias: string): Promise<NoteDto> {
const note = await this.getNoteByIdOrAlias(noteIdOrAlias);
return this.toNoteDto(note);
}
async deleteNoteByIdOrAlias(noteIdOrAlias: string) { async deleteNoteByIdOrAlias(noteIdOrAlias: string) {
const note = await this.getNoteByIdOrAlias(noteIdOrAlias); const note = await this.getNoteByIdOrAlias(noteIdOrAlias);
return await this.noteRepository.remove(note); return await this.noteRepository.remove(note);
} }
async updateNoteByIdOrAlias(noteIdOrAlias: string, noteContent: string) { async updateNoteByIdOrAlias(
noteIdOrAlias: string,
noteContent: string,
): Promise<Note> {
const note = await this.getNoteByIdOrAlias(noteIdOrAlias); const note = await this.getNoteByIdOrAlias(noteIdOrAlias);
const revisions = await note.revisions; const revisions = await note.revisions;
//TODO: Calculate patch //TODO: Calculate patch
revisions.push(Revision.create(noteContent, noteContent)); revisions.push(Revision.create(noteContent, noteContent));
note.revisions = Promise.resolve(revisions); note.revisions = Promise.resolve(revisions);
await this.noteRepository.save(note); return this.noteRepository.save(note);
return this.toNoteDto(note);
}
async getNoteMetadata(noteIdOrAlias: string): Promise<NoteMetadataDto> {
const note = await this.getNoteByIdOrAlias(noteIdOrAlias);
return this.getMetadata(note);
} }
updateNotePermissions( updateNotePermissions(
noteIdOrAlias: string, noteIdOrAlias: string,
newPermissions: NotePermissionsUpdateDto, newPermissions: NotePermissionsUpdateDto,
): NotePermissionsDto { ): Note {
this.logger.warn('Using hardcoded data!'); this.logger.warn('Using hardcoded data!');
return { return {
id: 'foobar-barfoo',
alias: null,
shortid: 'abc',
owner: { owner: {
displayName: 'foo', authTokens: [],
userName: 'fooUser', createdAt: new Date(),
email: 'foo@example.com', displayName: 'hardcoded',
photo: '', id: '1',
identities: [],
ownedNotes: [],
updatedAt: new Date(),
userName: 'Testy',
}, },
sharedToUsers: [], description: 'Very descriptive text.',
sharedToGroups: [], userPermissions: [],
groupPermissions: [],
tags: [],
revisions: Promise.resolve([]),
authorColors: [],
title: 'Title!',
viewcount: 42,
}; };
} }
@ -225,10 +172,50 @@ export class NotesService {
return this.getCurrentContent(note); return this.getCurrentContent(note);
} }
async toNotePermissionsDto(note: Note): Promise<NotePermissionsDto> {
return {
owner: this.usersService.toUserDto(note.owner),
sharedToUsers: note.userPermissions.map((noteUserPermission) => ({
user: this.usersService.toUserDto(noteUserPermission.user),
canEdit: noteUserPermission.canEdit,
})),
sharedToGroups: note.groupPermissions.map((noteGroupPermission) => ({
group: noteGroupPermission.group,
canEdit: noteGroupPermission.canEdit,
})),
};
}
async toNoteMetadataDto(note: Note): Promise<NoteMetadataDto> {
return {
// TODO: Convert DB UUID to base64
id: note.id,
alias: note.alias,
title: note.title,
createTime: (await this.getFirstRevision(note)).createdAt,
description: note.description,
editedBy: note.authorColors.map(
(authorColor) => authorColor.user.userName,
),
// TODO: Extract into method
permissions: await this.toNotePermissionsDto(note),
tags: note.tags.map((tag) => tag.name),
updateTime: (await this.getLatestRevision(note)).createdAt,
// TODO: Get actual updateUser
updateUser: {
displayName: 'Hardcoded User',
userName: 'hardcoded',
email: 'foo@example.com',
photo: '',
},
viewCount: 42,
};
}
async toNoteDto(note: Note): Promise<NoteDto> { async toNoteDto(note: Note): Promise<NoteDto> {
return { return {
content: await this.getCurrentContent(note), content: await this.getCurrentContent(note),
metadata: await this.getMetadata(note), metadata: await this.toNoteMetadataDto(note),
editedByAtPosition: [], editedByAtPosition: [],
}; };
} }

View file

@ -24,30 +24,26 @@ export class RevisionsService {
this.logger.setContext(RevisionsService.name); this.logger.setContext(RevisionsService.name);
} }
async getNoteRevisionMetadatas( async getAllRevisions(noteIdOrAlias: string): Promise<Revision[]> {
noteIdOrAlias: string,
): Promise<RevisionMetadataDto[]> {
const note = await this.notesService.getNoteByIdOrAlias(noteIdOrAlias); const note = await this.notesService.getNoteByIdOrAlias(noteIdOrAlias);
const revisions = await this.revisionRepository.find({ return await this.revisionRepository.find({
where: { where: {
note: note.id, note: note,
}, },
}); });
return revisions.map((revision) => this.toMetadataDto(revision));
} }
async getNoteRevision( async getRevision(
noteIdOrAlias: string, noteIdOrAlias: string,
revisionId: number, revisionId: number,
): Promise<RevisionDto> { ): Promise<Revision> {
const note = await this.notesService.getNoteByIdOrAlias(noteIdOrAlias); const note = await this.notesService.getNoteByIdOrAlias(noteIdOrAlias);
const revision = await this.revisionRepository.findOne({ return await this.revisionRepository.findOne({
where: { where: {
id: revisionId, id: revisionId,
note: note, note: note,
}, },
}); });
return this.toDto(revision);
} }
getLatestRevision(noteId: string): Promise<Revision> { getLatestRevision(noteId: string): Promise<Revision> {
@ -73,7 +69,7 @@ export class RevisionsService {
}); });
} }
toMetadataDto(revision: Revision): RevisionMetadataDto { toRevisionMetadataDto(revision: Revision): RevisionMetadataDto {
return { return {
id: revision.id, id: revision.id,
length: revision.length, length: revision.length,
@ -81,7 +77,7 @@ export class RevisionsService {
}; };
} }
toDto(revision: Revision): RevisionDto { toRevisionDto(revision: Revision): RevisionDto {
return { return {
id: revision.id, id: revision.id,
content: revision.content, content: revision.content,
@ -90,7 +86,7 @@ export class RevisionsService {
}; };
} }
createRevision(content: string) { createRevision(content: string): Revision {
// TODO: Add previous revision // TODO: Add previous revision
// TODO: Calculate patch // TODO: Calculate patch
// TODO: Save metadata // TODO: Save metadata

View file

@ -20,7 +20,6 @@ import { MediaService } from '../../src/media/media.service';
import { NotesModule } from '../../src/notes/notes.module'; import { NotesModule } from '../../src/notes/notes.module';
import { NotesService } from '../../src/notes/notes.service'; import { NotesService } from '../../src/notes/notes.service';
import { PermissionsModule } from '../../src/permissions/permissions.module'; import { PermissionsModule } from '../../src/permissions/permissions.module';
import { UsersService } from '../../src/users/users.service';
import { AuthModule } from '../../src/auth/auth.module'; import { AuthModule } from '../../src/auth/auth.module';
import { TokenAuthGuard } from '../../src/auth/token-auth.guard'; import { TokenAuthGuard } from '../../src/auth/token-auth.guard';
import { MockAuthGuard } from '../../src/auth/mock-auth.guard'; import { MockAuthGuard } from '../../src/auth/mock-auth.guard';
@ -65,8 +64,6 @@ describe('Notes', () => {
app.useLogger(logger); app.useLogger(logger);
const notesService: NotesService = moduleRef.get('NotesService'); const notesService: NotesService = moduleRef.get('NotesService');
await notesService.createNote('test content', 'test_upload_media'); await notesService.createNote('test content', 'test_upload_media');
const usersService: UsersService = moduleRef.get('UsersService');
await usersService.createUser('hardcoded', 'Hard Coded');
mediaService = moduleRef.get('MediaService'); mediaService = moduleRef.get('MediaService');
}); });

View file

@ -20,7 +20,7 @@ import { PermissionsModule } from '../../src/permissions/permissions.module';
import { AuthModule } from '../../src/auth/auth.module'; import { AuthModule } from '../../src/auth/auth.module';
import { TokenAuthGuard } from '../../src/auth/token-auth.guard'; import { TokenAuthGuard } from '../../src/auth/token-auth.guard';
import { MockAuthGuard } from '../../src/auth/mock-auth.guard'; import { MockAuthGuard } from '../../src/auth/mock-auth.guard';
import { UsersService } from '../../src/users/users.service'; import { UsersModule } from '../../src/users/users.module';
describe('Notes', () => { describe('Notes', () => {
let app: INestApplication; let app: INestApplication;
@ -46,6 +46,7 @@ describe('Notes', () => {
}), }),
LoggerModule, LoggerModule,
AuthModule, AuthModule,
UsersModule,
], ],
}) })
.overrideGuard(TokenAuthGuard) .overrideGuard(TokenAuthGuard)
@ -55,8 +56,6 @@ describe('Notes', () => {
app = moduleRef.createNestApplication(); app = moduleRef.createNestApplication();
await app.init(); await app.init();
notesService = moduleRef.get(NotesService); notesService = moduleRef.get(NotesService);
const usersService: UsersService = moduleRef.get('UsersService');
await usersService.createUser('testy', 'Testy McTestFace');
}); });
it(`POST /notes`, async () => { it(`POST /notes`, async () => {
@ -69,8 +68,9 @@ describe('Notes', () => {
.expect(201); .expect(201);
expect(response.body.metadata?.id).toBeDefined(); expect(response.body.metadata?.id).toBeDefined();
expect( expect(
(await notesService.getNoteDtoByIdOrAlias(response.body.metadata.id)) await notesService.getCurrentContent(
.content, await notesService.getNoteByIdOrAlias(response.body.metadata.id),
),
).toEqual(newNote); ).toEqual(newNote);
}); });
@ -100,8 +100,9 @@ describe('Notes', () => {
.expect(201); .expect(201);
expect(response.body.metadata?.id).toBeDefined(); expect(response.body.metadata?.id).toBeDefined();
return expect( return expect(
(await notesService.getNoteDtoByIdOrAlias(response.body.metadata.id)) await notesService.getCurrentContent(
.content, await notesService.getNoteByIdOrAlias(response.body.metadata?.id),
),
).toEqual(newNote); ).toEqual(newNote);
}); });
@ -125,7 +126,9 @@ describe('Notes', () => {
.send('New note text') .send('New note text')
.expect(200); .expect(200);
await expect( await expect(
(await notesService.getNoteDtoByIdOrAlias('test4')).content, await notesService.getCurrentContent(
await notesService.getNoteByIdOrAlias('test4'),
),
).toEqual('New note text'); ).toEqual('New note text');
expect(response.body.content).toEqual('New note text'); expect(response.body.content).toEqual('New note text');