NotesService: Implement getAuthorUsers

This reimplements logic to get all Users that ever edited a note
and fixes the empty `editedBy` property of `toNoteMetadataDto`
introduced in 81cc092e.

Signed-off-by: David Mehren <git@herrmehren.de>
This commit is contained in:
David Mehren 2021-05-24 21:58:44 +02:00
parent 5f9f134eb0
commit 4d0205a61f
No known key found for this signature in database
GPG key ID: 185982BA4C42B7C3
3 changed files with 51 additions and 2 deletions

View file

@ -12,6 +12,7 @@ import { LoggerModule } from '../logger/logger.module';
import { NoteGroupPermission } from '../permissions/note-group-permission.entity';
import { NoteUserPermission } from '../permissions/note-user-permission.entity';
import { RevisionsModule } from '../revisions/revisions.module';
import { User } from '../users/user.entity';
import { UsersModule } from '../users/users.module';
import { Note } from './note.entity';
import { NotesService } from './notes.service';
@ -24,6 +25,7 @@ import { Tag } from './tag.entity';
Tag,
NoteGroupPermission,
NoteUserPermission,
User,
]),
forwardRef(() => RevisionsModule),
UsersModule,

View file

@ -46,6 +46,12 @@ describe('NotesService', () => {
let forbiddenNoteId: string;
beforeEach(async () => {
/**
* We need to have *one* userRepo for both the providers array and
* the overrideProvider call, as otherwise we have two instances
* and the mock of createQueryBuilder replaces the wrong one
* **/
userRepo = new Repository<User>();
const module: TestingModule = await Test.createTestingModule({
providers: [
NotesService,
@ -57,6 +63,10 @@ describe('NotesService', () => {
provide: getRepositoryToken(Tag),
useClass: Repository,
},
{
provide: getRepositoryToken(User),
useValue: userRepo,
},
],
imports: [
ConfigModule.forRoot({
@ -74,7 +84,7 @@ describe('NotesService', () => {
.overrideProvider(getRepositoryToken(Tag))
.useClass(Repository)
.overrideProvider(getRepositoryToken(User))
.useClass(Repository)
.useValue(userRepo)
.overrideProvider(getRepositoryToken(AuthToken))
.useValue({})
.overrideProvider(getRepositoryToken(Identity))
@ -688,6 +698,16 @@ describe('NotesService', () => {
];
revisions[0].createdAt = new Date(1549312452000);
jest.spyOn(revisionRepo, 'findOne').mockResolvedValue(revisions[0]);
const createQueryBuilder = {
innerJoin: () => createQueryBuilder,
where: () => createQueryBuilder,
getMany: () => [user],
};
jest
.spyOn(userRepo, 'createQueryBuilder')
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
.mockImplementation(() => createQueryBuilder);
note.publicId = 'testId';
note.alias = 'testAlias';
note.title = 'testTitle';
@ -777,6 +797,16 @@ describe('NotesService', () => {
.spyOn(revisionRepo, 'findOne')
.mockResolvedValue(revisions[0])
.mockResolvedValue(revisions[0]);
const createQueryBuilder = {
innerJoin: () => createQueryBuilder,
where: () => createQueryBuilder,
getMany: () => [user],
};
jest
.spyOn(userRepo, 'createQueryBuilder')
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
.mockImplementation(() => createQueryBuilder);
note.publicId = 'testId';
note.alias = 'testAlias';
note.title = 'testTitle';

View file

@ -41,6 +41,7 @@ export class NotesService {
private readonly logger: ConsoleLoggerService,
@InjectRepository(Note) private noteRepository: Repository<Note>,
@InjectRepository(Tag) private tagRepository: Repository<Tag>,
@InjectRepository(User) private userRepository: Repository<User>,
@Inject(UsersService) private usersService: UsersService,
@Inject(GroupsService) private groupsService: GroupsService,
@Inject(forwardRef(() => RevisionsService))
@ -188,6 +189,22 @@ export class NotesService {
return note;
}
/**
* @async
* Get all users that ever appeared as an author for the given note
* @param note The note to search authors for
*/
async getAuthorUsers(note: Note): Promise<User[]> {
return await this.userRepository
.createQueryBuilder('user')
.innerJoin('user.authors', 'author')
.innerJoin('author.authorships', 'authorship')
.innerJoin('authorship.revisions', 'revision')
.innerJoin('revision.note', 'note')
.where('note.id = :id', { id: note.id })
.getMany();
}
/**
* Check if the provided note id or alias is not forbidden
* @param noteIdOrAlias - the alias or id in question
@ -358,7 +375,7 @@ export class NotesService {
title: note.title ?? '',
createTime: (await this.getFirstRevision(note)).createdAt,
description: note.description ?? '',
editedBy: [], // TODO temporary placeholder,
editedBy: (await this.getAuthorUsers(note)).map((user) => user.userName),
permissions: this.toNotePermissionsDto(note),
tags: this.toTagList(note),
updateTime: (await this.getLatestRevision(note)).createdAt,