feat(note-metadata): replace primaryAlias with primaryAddress

The primary address is never null.
If no alias is set, the id is returned.

To still easily get the primary alias, the complete Alias DTOs
are now included in the metadata.

Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
David Mehren 2022-02-14 15:26:29 +01:00
parent 64b16c831e
commit 342efcd7b7
9 changed files with 50 additions and 21 deletions

View file

@ -33,6 +33,7 @@ import { UsersModule } from '../users/users.module';
import { Alias } from './alias.entity'; import { Alias } from './alias.entity';
import { AliasService } from './alias.service'; import { AliasService } from './alias.service';
import { Note } from './note.entity'; import { Note } from './note.entity';
import { NotesModule } from './notes.module';
import { NotesService } from './notes.service'; import { NotesService } from './notes.service';
import { Tag } from './tag.entity'; import { Tag } from './tag.entity';
@ -72,6 +73,7 @@ describe('AliasService', () => {
UsersModule, UsersModule,
GroupsModule, GroupsModule,
RevisionsModule, RevisionsModule,
NotesModule,
], ],
}) })
.overrideProvider(getRepositoryToken(Note)) .overrideProvider(getRepositoryToken(Note))

View file

@ -3,7 +3,7 @@
* *
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { Inject, Injectable } from '@nestjs/common'; import { forwardRef, Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
@ -25,7 +25,7 @@ export class AliasService {
private readonly logger: ConsoleLoggerService, private readonly logger: ConsoleLoggerService,
@InjectRepository(Note) private noteRepository: Repository<Note>, @InjectRepository(Note) private noteRepository: Repository<Note>,
@InjectRepository(Alias) private aliasRepository: Repository<Alias>, @InjectRepository(Alias) private aliasRepository: Repository<Alias>,
@Inject(NotesService) private notesService: NotesService, @Inject(forwardRef(() => NotesService)) private notesService: NotesService,
) { ) {
this.logger.setContext(AliasService.name); this.logger.setContext(AliasService.name);
} }

View file

@ -15,6 +15,7 @@ import {
} from 'class-validator'; } from 'class-validator';
import { BaseDto } from '../utils/base.dto.'; import { BaseDto } from '../utils/base.dto.';
import { AliasDto } from './alias.dto';
import { NotePermissionsDto } from './note-permissions.dto'; import { NotePermissionsDto } from './note-permissions.dto';
export class NoteMetadataDto extends BaseDto { export class NoteMetadataDto extends BaseDto {
@ -29,16 +30,18 @@ export class NoteMetadataDto extends BaseDto {
* All aliases of the note (including the primaryAlias) * All aliases of the note (including the primaryAlias)
*/ */
@IsArray() @IsArray()
@IsString({ each: true }) @ValidateNested()
@ApiProperty() @ApiProperty()
aliases: string[]; aliases: AliasDto[];
/** /**
* The primary alias of the note * The primary adress of the note
* If at least one alias is set, this is the primary alias
* If no alias is set, this is the note's ID
*/ */
@IsString() @IsString()
@ApiProperty() @ApiProperty()
primaryAlias: string | null; primaryAddress: string;
/** /**
* Title of the note * Title of the note

View file

@ -31,6 +31,7 @@ import { Session } from '../users/session.entity';
import { User } from '../users/user.entity'; import { User } from '../users/user.entity';
import { UsersModule } from '../users/users.module'; import { UsersModule } from '../users/users.module';
import { Alias } from './alias.entity'; import { Alias } from './alias.entity';
import { AliasService } from './alias.service';
import { import {
NoteGroupPermissionUpdateDto, NoteGroupPermissionUpdateDto,
NoteUserPermissionUpdateDto, NoteUserPermissionUpdateDto,
@ -57,6 +58,7 @@ describe('NotesService', () => {
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
providers: [ providers: [
NotesService, NotesService,
AliasService,
{ {
provide: getRepositoryToken(Note), provide: getRepositoryToken(Note),
useClass: Repository, useClass: Repository,
@ -771,7 +773,7 @@ describe('NotesService', () => {
const metadataDto = await service.toNoteMetadataDto(note); const metadataDto = await service.toNoteMetadataDto(note);
expect(metadataDto.id).toEqual(note.publicId); expect(metadataDto.id).toEqual(note.publicId);
expect(metadataDto.aliases).toHaveLength(1); expect(metadataDto.aliases).toHaveLength(1);
expect(metadataDto.aliases[0]).toEqual((await note.aliases)[0].name); expect(metadataDto.aliases[0].name).toEqual((await note.aliases)[0].name);
expect(metadataDto.title).toEqual(note.title); expect(metadataDto.title).toEqual(note.title);
expect(metadataDto.createdAt).toEqual(revisions[0].createdAt); expect(metadataDto.createdAt).toEqual(revisions[0].createdAt);
expect(metadataDto.description).toEqual(note.description); expect(metadataDto.description).toEqual(note.description);
@ -873,7 +875,9 @@ describe('NotesService', () => {
const noteDto = await service.toNoteDto(note); const noteDto = await service.toNoteDto(note);
expect(noteDto.metadata.id).toEqual(note.publicId); expect(noteDto.metadata.id).toEqual(note.publicId);
expect(noteDto.metadata.aliases).toHaveLength(1); expect(noteDto.metadata.aliases).toHaveLength(1);
expect(noteDto.metadata.aliases[0]).toEqual((await note.aliases)[0].name); expect(noteDto.metadata.aliases[0].name).toEqual(
(await note.aliases)[0].name,
);
expect(noteDto.metadata.title).toEqual(note.title); expect(noteDto.metadata.title).toEqual(note.title);
expect(noteDto.metadata.createdAt).toEqual(revisions[0].createdAt); expect(noteDto.metadata.createdAt).toEqual(revisions[0].createdAt);
expect(noteDto.metadata.description).toEqual(note.description); expect(noteDto.metadata.description).toEqual(note.description);

View file

@ -25,6 +25,7 @@ import { User } from '../users/user.entity';
import { UsersService } from '../users/users.service'; import { UsersService } from '../users/users.service';
import { checkArrayForDuplicates } from '../utils/arrayDuplicatCheck'; import { checkArrayForDuplicates } from '../utils/arrayDuplicatCheck';
import { Alias } from './alias.entity'; import { Alias } from './alias.entity';
import { AliasService } from './alias.service';
import { NoteMetadataDto } from './note-metadata.dto'; import { NoteMetadataDto } from './note-metadata.dto';
import { import {
NotePermissionsDto, NotePermissionsDto,
@ -49,6 +50,7 @@ export class NotesService {
private revisionsService: RevisionsService, private revisionsService: RevisionsService,
@Inject(noteConfiguration.KEY) @Inject(noteConfiguration.KEY)
private noteConfig: NoteConfig, private noteConfig: NoteConfig,
@Inject(forwardRef(() => AliasService)) private aliasService: AliasService,
) { ) {
this.logger.setContext(NotesService.name); this.logger.setContext(NotesService.name);
} }
@ -397,9 +399,11 @@ export class NotesService {
return { return {
id: note.publicId, id: note.publicId,
aliases: await Promise.all( aliases: await Promise.all(
(await note.aliases).map((alias) => alias.name), (
await note.aliases
).map((alias) => this.aliasService.toAliasDto(alias, note)),
), ),
primaryAlias: (await getPrimaryAlias(note)) ?? null, primaryAddress: (await getPrimaryAlias(note)) ?? note.id,
title: note.title ?? '', title: note.title ?? '',
createdAt: (await this.getFirstRevision(note)).createdAt, createdAt: (await this.getFirstRevision(note)).createdAt,
description: note.description ?? '', description: note.description ?? '',

View file

@ -75,8 +75,12 @@ describe('Alias', () => {
const note = await agent1 const note = await agent1
.get(`/api/private/notes/${newAlias}`) .get(`/api/private/notes/${newAlias}`)
.expect(200); .expect(200);
expect(note.body.metadata.aliases).toContain(newAlias); expect(note.body.metadata.aliases).toContainEqual({
expect(note.body.metadata.primaryAlias).toBeTruthy(); name: 'normalAlias',
primaryAlias: false,
noteId: publicId,
});
expect(note.body.metadata.primaryAddress).toEqual(testAlias);
expect(note.body.metadata.id).toEqual(publicId); expect(note.body.metadata.id).toEqual(publicId);
}); });
@ -142,8 +146,12 @@ describe('Alias', () => {
const note = await agent1 const note = await agent1
.get(`/api/private/notes/${newAlias}`) .get(`/api/private/notes/${newAlias}`)
.expect(200); .expect(200);
expect(note.body.metadata.aliases).toContain(newAlias); expect(note.body.metadata.aliases).toContainEqual({
expect(note.body.metadata.primaryAlias).toBeTruthy(); name: newAlias,
primaryAlias: true,
noteId: publicId,
});
expect(note.body.metadata.primaryAddress).toEqual(newAlias);
expect(note.body.metadata.id).toEqual(publicId); expect(note.body.metadata.id).toEqual(publicId);
}); });

View file

@ -52,8 +52,12 @@ describe('Alias', () => {
.set('Authorization', `Bearer ${testSetup.authTokens[0].secret}`) .set('Authorization', `Bearer ${testSetup.authTokens[0].secret}`)
.expect(200); .expect(200);
expect(note.body.metadata.aliases).toContain('normalAlias'); expect(note.body.metadata.aliases).toContainEqual({
expect(note.body.metadata.primaryAlias).toBeTruthy(); name: 'normalAlias',
primaryAlias: false,
noteId: publicId,
});
expect(note.body.metadata.primaryAddress).toEqual(testAlias);
expect(note.body.metadata.id).toEqual(publicId); expect(note.body.metadata.id).toEqual(publicId);
}); });
@ -127,8 +131,12 @@ describe('Alias', () => {
.set('Authorization', `Bearer ${testSetup.authTokens[0].secret}`) .set('Authorization', `Bearer ${testSetup.authTokens[0].secret}`)
.expect(200); .expect(200);
expect(note.body.metadata.aliases).toContain(testAlias); expect(note.body.metadata.aliases).toContainEqual({
expect(note.body.metadata.primaryAlias).toBeTruthy(); name: testAlias,
primaryAlias: true,
noteId: publicId,
});
expect(note.body.metadata.primaryAddress).toEqual(testAlias);
expect(note.body.metadata.id).toEqual(publicId); expect(note.body.metadata.id).toEqual(publicId);
}); });

View file

@ -179,7 +179,7 @@ describe('Me', () => {
.expect(200); .expect(200);
const noteMetaDtos = response.body as NoteMetadataDto[]; const noteMetaDtos = response.body as NoteMetadataDto[];
expect(noteMetaDtos).toHaveLength(1); expect(noteMetaDtos).toHaveLength(1);
expect(noteMetaDtos[0].primaryAlias).toEqual(noteName); expect(noteMetaDtos[0].primaryAddress).toEqual(noteName);
expect(noteMetaDtos[0].updateUsername).toEqual(user.username); expect(noteMetaDtos[0].updateUsername).toEqual(user.username);
}); });

View file

@ -276,8 +276,8 @@ describe('Notes', () => {
.get('/api/v2/notes/test5/metadata') .get('/api/v2/notes/test5/metadata')
.expect(200); .expect(200);
expect(typeof metadata.body.id).toEqual('string'); expect(typeof metadata.body.id).toEqual('string');
expect(metadata.body.aliases).toEqual(['test5']); expect(metadata.body.aliases[0].name).toEqual('test5');
expect(metadata.body.primaryAlias).toEqual('test5'); expect(metadata.body.primaryAddress).toEqual('test5');
expect(metadata.body.title).toEqual(''); expect(metadata.body.title).toEqual('');
expect(metadata.body.description).toEqual(''); expect(metadata.body.description).toEqual('');
expect(typeof metadata.body.createdAt).toEqual('string'); expect(typeof metadata.body.createdAt).toEqual('string');