diff --git a/apps/server/src/modules/user/service/user.service.spec.ts b/apps/server/src/modules/user/service/user.service.spec.ts index ea29891cee7..a24704014f5 100644 --- a/apps/server/src/modules/user/service/user.service.spec.ts +++ b/apps/server/src/modules/user/service/user.service.spec.ts @@ -2,7 +2,7 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { EntityManager } from '@mikro-orm/core'; import { ConfigService } from '@nestjs/config'; import { Test, TestingModule } from '@nestjs/testing'; -import { IFindOptions, LanguageType, Permission, Role, RoleName, SortOrder, User } from '@shared/domain'; +import { EntityId, IFindOptions, LanguageType, Permission, Role, RoleName, SortOrder, User } from '@shared/domain'; import { UserDO } from '@shared/domain/domainobject/user.do'; import { UserRepo } from '@shared/repo'; import { UserDORepo } from '@shared/repo/user/user-do.repo'; @@ -329,4 +329,50 @@ describe('UserService', () => { expect(userDORepo.saveAll).toHaveBeenCalledWith(users); }); }); + + describe('deleteUser', () => { + describe('when user is missing', () => { + const setup = () => { + const user: UserDO = userDoFactory.build({ id: undefined }); + const userId: EntityId = user.id as EntityId; + + userRepo.deleteUser.mockResolvedValue(0); + + return { + userId, + }; + }; + + it('should return 0', async () => { + const { userId } = setup(); + + const result = await service.deleteUser(userId); + + expect(result).toEqual(0); + }); + }); + + describe('when deleting by userId', () => { + const setup = () => { + const user1: User = userFactory.asStudent().buildWithId(); + userFactory.asStudent().buildWithId(); + + userRepo.findById.mockResolvedValue(user1); + userRepo.deleteUser.mockResolvedValue(1); + + return { + user1, + }; + }; + + it('should delete user by userId', async () => { + const { user1 } = setup(); + + const result = await service.deleteUser(user1.id); + + expect(userRepo.deleteUser).toHaveBeenCalledWith(user1.id); + expect(result).toEqual(1); + }); + }); + }); }); diff --git a/apps/server/src/modules/user/service/user.service.ts b/apps/server/src/modules/user/service/user.service.ts index 8f7bf0beeba..60f62e5ee28 100644 --- a/apps/server/src/modules/user/service/user.service.ts +++ b/apps/server/src/modules/user/service/user.service.ts @@ -1,4 +1,3 @@ -import { BadRequestException, Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { EntityId, IFindOptions, LanguageType, User } from '@shared/domain'; import { RoleReference } from '@shared/domain/domainobject'; @@ -12,6 +11,7 @@ import { ICurrentUser } from '@src/modules/authentication'; import { CurrentUserMapper } from '@src/modules/authentication/mapper'; import { RoleDto } from '@src/modules/role/service/dto/role.dto'; import { RoleService } from '@src/modules/role/service/role.service'; +import { BadRequestException, Injectable } from '@nestjs/common'; import { IUserConfig } from '../interfaces'; import { UserMapper } from '../mapper/user.mapper'; import { UserDto } from '../uc/dto/user.dto'; @@ -107,4 +107,10 @@ export class UserService { throw new BadRequestException('Language is not activated.'); } } + + async deleteUser(userId: EntityId): Promise { + const deletedUserNumber: Promise = this.userRepo.deleteUser(userId); + + return deletedUserNumber; + } } diff --git a/apps/server/src/shared/repo/user/user.repo.integration.spec.ts b/apps/server/src/shared/repo/user/user.repo.integration.spec.ts index 04e19284040..d469b59c14b 100644 --- a/apps/server/src/shared/repo/user/user.repo.integration.spec.ts +++ b/apps/server/src/shared/repo/user/user.repo.integration.spec.ts @@ -399,4 +399,45 @@ describe('user repo', () => { expect(user.id).not.toBeNull(); }); }); + + describe('delete', () => { + const setup = async () => { + const user1: User = userFactory.buildWithId(); + const user2: User = userFactory.buildWithId(); + const user3: User = userFactory.buildWithId(); + await em.persistAndFlush([user1, user2, user3]); + + return { + user1, + user2, + user3, + }; + }; + it('should delete user', async () => { + const { user1, user2, user3 } = await setup(); + const deleteResult = await repo.deleteUser(user1.id); + expect(deleteResult).toEqual(1); + + const result1 = await em.find(User, { id: user1.id }); + expect(result1).toHaveLength(0); + + const result2 = await repo.findById(user2.id); + expect(result2).toMatchObject({ + firstName: user2.firstName, + lastName: user2.lastName, + email: user2.email, + roles: user2.roles, + school: user2.school, + }); + + const result3 = await repo.findById(user3.id); + expect(result3).toMatchObject({ + firstName: user3.firstName, + lastName: user3.lastName, + email: user3.email, + roles: user3.roles, + school: user3.school, + }); + }); + }); }); diff --git a/apps/server/src/shared/repo/user/user.repo.ts b/apps/server/src/shared/repo/user/user.repo.ts index 32aa38578a0..a067953faba 100644 --- a/apps/server/src/shared/repo/user/user.repo.ts +++ b/apps/server/src/shared/repo/user/user.repo.ts @@ -163,6 +163,13 @@ export class UserRepo extends BaseRepo { return promise; } + async deleteUser(userId: EntityId): Promise { + const deletedUserNumber: Promise = this._em.nativeDelete(User, { + id: userId, + }); + return deletedUserNumber; + } + private async populateRoles(roles: Role[]): Promise { for (let i = 0; i < roles.length; i += 1) { const role = roles[i];