mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-14 07:04:45 -04:00
refactor: extract "extract note from request" logic into separate function
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
65fb110a1e
commit
ab5aebc9c4
3 changed files with 125 additions and 10 deletions
87
backend/src/api/utils/extract-note-from-request.spec.ts
Normal file
87
backend/src/api/utils/extract-note-from-request.spec.ts
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { Mock } from 'ts-mockery';
|
||||||
|
|
||||||
|
import { Note } from '../../notes/note.entity';
|
||||||
|
import { NotesService } from '../../notes/notes.service';
|
||||||
|
import { extractNoteFromRequest } from './extract-note-from-request';
|
||||||
|
import { CompleteRequest } from './request.type';
|
||||||
|
|
||||||
|
describe('extract note from request', () => {
|
||||||
|
const mockNoteIdOrAlias1 = 'mockNoteIdOrAlias1';
|
||||||
|
const mockNoteIdOrAlias2 = 'mockNoteIdOrAlias2';
|
||||||
|
|
||||||
|
const mockNote1 = Mock.of<Note>({ id: 1 });
|
||||||
|
const mockNote2 = Mock.of<Note>({ id: 2 });
|
||||||
|
|
||||||
|
let notesService: NotesService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
notesService = Mock.of<NotesService>({
|
||||||
|
getNoteByIdOrAlias: async (id) => {
|
||||||
|
if (id === mockNoteIdOrAlias1) {
|
||||||
|
return mockNote1;
|
||||||
|
} else if (id === mockNoteIdOrAlias2) {
|
||||||
|
return mockNote2;
|
||||||
|
} else {
|
||||||
|
throw new Error('unknown note id');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function createRequest(
|
||||||
|
parameterValue: string | undefined,
|
||||||
|
headerValue: string | string[] | undefined,
|
||||||
|
): CompleteRequest {
|
||||||
|
return Mock.of<CompleteRequest>({
|
||||||
|
params: parameterValue
|
||||||
|
? {
|
||||||
|
noteIdOrAlias: parameterValue,
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
headers: headerValue
|
||||||
|
? {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
|
'hedgedoc-note': headerValue,
|
||||||
|
}
|
||||||
|
: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it('will return undefined if no id is present', async () => {
|
||||||
|
const request = createRequest(undefined, undefined);
|
||||||
|
expect(await extractNoteFromRequest(request, notesService)).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can extract an id from parameters', async () => {
|
||||||
|
const request = createRequest(mockNoteIdOrAlias1, undefined);
|
||||||
|
expect(await extractNoteFromRequest(request, notesService)).toBe(mockNote1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can extract an id from headers if no parameter is given', async () => {
|
||||||
|
const request = createRequest(undefined, mockNoteIdOrAlias1);
|
||||||
|
expect(await extractNoteFromRequest(request, notesService)).toBe(mockNote1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can extract the first id from multiple id headers', async () => {
|
||||||
|
const request = createRequest(undefined, [
|
||||||
|
mockNoteIdOrAlias1,
|
||||||
|
mockNoteIdOrAlias2,
|
||||||
|
]);
|
||||||
|
expect(await extractNoteFromRequest(request, notesService)).toBe(mockNote1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will return undefined if no parameter and empty id header array', async () => {
|
||||||
|
const request = createRequest(undefined, []);
|
||||||
|
expect(await extractNoteFromRequest(request, notesService)).toBe(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will prefer the parameter over the header', async () => {
|
||||||
|
const request = createRequest(mockNoteIdOrAlias1, mockNoteIdOrAlias2);
|
||||||
|
expect(await extractNoteFromRequest(request, notesService)).toBe(mockNote1);
|
||||||
|
});
|
||||||
|
});
|
33
backend/src/api/utils/extract-note-from-request.ts
Normal file
33
backend/src/api/utils/extract-note-from-request.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
import { isArray } from 'class-validator';
|
||||||
|
|
||||||
|
import { Note } from '../../notes/note.entity';
|
||||||
|
import { NotesService } from '../../notes/notes.service';
|
||||||
|
import { CompleteRequest } from './request.type';
|
||||||
|
|
||||||
|
export async function extractNoteFromRequest(
|
||||||
|
request: CompleteRequest,
|
||||||
|
noteService: NotesService,
|
||||||
|
): Promise<Note | undefined> {
|
||||||
|
const noteIdOrAlias = extractNoteIdOrAlias(request);
|
||||||
|
if (noteIdOrAlias === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return await noteService.getNoteByIdOrAlias(noteIdOrAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractNoteIdOrAlias(request: CompleteRequest): string | undefined {
|
||||||
|
const noteIdOrAlias =
|
||||||
|
request.params['noteIdOrAlias'] || request.headers['hedgedoc-note'];
|
||||||
|
if (noteIdOrAlias === undefined) {
|
||||||
|
return undefined;
|
||||||
|
} else if (isArray(noteIdOrAlias)) {
|
||||||
|
return noteIdOrAlias[0];
|
||||||
|
} else {
|
||||||
|
return noteIdOrAlias;
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,8 +11,8 @@ import {
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
import { Note } from '../../notes/note.entity';
|
|
||||||
import { NotesService } from '../../notes/notes.service';
|
import { NotesService } from '../../notes/notes.service';
|
||||||
|
import { extractNoteFromRequest } from './extract-note-from-request';
|
||||||
import { CompleteRequest } from './request.type';
|
import { CompleteRequest } from './request.type';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,15 +28,10 @@ export class GetNoteInterceptor implements NestInterceptor {
|
||||||
next: CallHandler,
|
next: CallHandler,
|
||||||
): Promise<Observable<T>> {
|
): Promise<Observable<T>> {
|
||||||
const request: CompleteRequest = context.switchToHttp().getRequest();
|
const request: CompleteRequest = context.switchToHttp().getRequest();
|
||||||
const noteIdOrAlias = request.params['noteIdOrAlias'];
|
const note = await extractNoteFromRequest(request, this.noteService);
|
||||||
request.note = await getNote(this.noteService, noteIdOrAlias);
|
if (note !== undefined) {
|
||||||
|
request.note = note;
|
||||||
|
}
|
||||||
return next.handle();
|
return next.handle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNote(
|
|
||||||
noteService: NotesService,
|
|
||||||
noteIdOrAlias: string,
|
|
||||||
): Promise<Note> {
|
|
||||||
return await noteService.getNoteByIdOrAlias(noteIdOrAlias);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue