@ -6,63 +6,76 @@ import { when } from 'jest-when';
import { UserService } from './user.service' ;
import { UpdateUserDto } from './dto/update-user.dto' ;
describe ( 'UserService' , ( ) = > {
let sut : UserService ;
let userRepositoryMock : jest.Mocked < IUserRepository > ;
const adminUserAuth : AuthUserDto = Object . freeze ( {
id : 'admin_id' ,
email : 'admin@test.com' ,
isAdmin : true ,
} ) ;
const adminUserAuth : AuthUserDto = Object . freeze ( {
id : 'admin _id',
email : 'admin @test.com',
isAdmin : tru e,
} ) ;
const immich UserAuth: AuthUserDto = Object . freeze ( {
id : 'immich _id',
email : 'immich @test.com',
isAdmin : fals e,
} ) ;
const immichUserAuth : AuthUserDto = Object . freeze ( {
id : 'immich_id' ,
email : 'immich@test.com' ,
isAdmin : false ,
} ) ;
const adminUser : UserEntity = Object . freeze ( {
id : adminUserAuth.id ,
email : 'admin@test.com' ,
password : 'admin_password' ,
firstName : 'admin_first_name' ,
lastName : 'admin_last_name' ,
isAdmin : true ,
oauthId : '' ,
shouldChangePassword : false ,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
tags : [ ] ,
} ) ;
const adminUser : UserEntity = Object . freeze ( {
id : adminUserAuth.id ,
email : 'admin@test.com' ,
password : 'admin_password' ,
firstName : 'admin_first_name' ,
lastName : 'admin_last_name' ,
isAdmin : true ,
oauthId : '' ,
shouldChangePassword : false ,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
tags : [ ] ,
} ) ;
const immich User: UserEntity = Object . freeze ( {
id : immich UserAuth.id,
email : 'immich @test.com',
password : 'immich _password',
firstName : 'immich _first_name',
lastName : 'immich _last_name',
isAdmin : fals e,
oauthId : '' ,
shouldChangePassword : false ,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
tags : [ ] ,
} ) ;
const i mmichUser: UserEntity = Object . freeze ( {
id : immichUserAuth.id ,
email : 'immich@test.com' ,
password : 'immich_password' ,
firstName : ' immich_first_name',
lastName : ' immich_last_name',
isAdmin : false ,
oauthId : '' ,
shouldChangePassword : fals e,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
tags : [ ] ,
} ) ;
const updatedI mmichUser: UserEntity = Object . freeze ( {
id : immichUserAuth.id ,
email : 'immich@test.com' ,
password : 'immich_password' ,
firstName : ' updated_ immich_first_name',
lastName : ' updated_ immich_last_name',
isAdmin : false ,
oauthId : '' ,
shouldChangePassword : tru e,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
tags : [ ] ,
} ) ;
const updatedImmichUser : UserEntity = Object . freeze ( {
id : immichUserAuth.id ,
email : 'immich@test.com' ,
password : 'immich_password' ,
firstName : 'updated_immich_first_name' ,
lastName : 'updated_immich_last_name' ,
isAdmin : false ,
oauthId : '' ,
shouldChangePassword : true ,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
tags : [ ] ,
} ) ;
const adminUserResponse = Object . freeze ( {
id : adminUserAuth.id ,
email : 'admin@test.com' ,
deletedAt : undefined ,
firstName : 'admin_first_name' ,
lastName : 'admin_last_name' ,
isAdmin : true ,
oauthId : '' ,
shouldChangePassword : false ,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
} ) ;
describe ( 'UserService' , ( ) = > {
let sut : UserService ;
let userRepositoryMock : jest.Mocked < IUserRepository > ;
beforeEach ( ( ) = > {
userRepositoryMock = {
@ -78,12 +91,86 @@ describe('UserService', () => {
} ;
when ( userRepositoryMock . get ) . calledWith ( adminUser . id ) . mockResolvedValue ( adminUser ) ;
when ( userRepositoryMock . get ) . calledWith ( adminUser . id , undefined ) . mockResolvedValue ( adminUser ) ;
when ( userRepositoryMock . get ) . calledWith ( immichUser . id ) . mockResolvedValue ( immichUser ) ;
when ( userRepositoryMock . get ) . calledWith ( immichUser . id , undefined ) . mockResolvedValue ( immichUser ) ;
sut = new UserService ( userRepositoryMock ) ;
} ) ;
describe ( 'Update user' , ( ) = > {
describe ( 'getAllUsers' , ( ) = > {
it ( 'should get all users' , async ( ) = > {
userRepositoryMock . getList . mockResolvedValue ( [ adminUser ] ) ;
const response = await sut . getAllUsers ( adminUserAuth , false ) ;
expect ( userRepositoryMock . getList ) . toHaveBeenCalledWith ( { excludeId : adminUser.id } ) ;
expect ( response ) . toEqual ( [
{
id : adminUserAuth.id ,
email : 'admin@test.com' ,
deletedAt : undefined ,
firstName : 'admin_first_name' ,
lastName : 'admin_last_name' ,
isAdmin : true ,
oauthId : '' ,
shouldChangePassword : false ,
profileImagePath : '' ,
createdAt : '2021-01-01' ,
} ,
] ) ;
} ) ;
} ) ;
describe ( 'getUserById' , ( ) = > {
it ( 'should get a user by id' , async ( ) = > {
userRepositoryMock . get . mockResolvedValue ( adminUser ) ;
const response = await sut . getUserById ( adminUser . id ) ;
expect ( userRepositoryMock . get ) . toHaveBeenCalledWith ( adminUser . id , false ) ;
expect ( response ) . toEqual ( adminUserResponse ) ;
} ) ;
it ( 'should throw an error if a user is not found' , async ( ) = > {
userRepositoryMock . get . mockResolvedValue ( null ) ;
await expect ( sut . getUserById ( adminUser . id ) ) . rejects . toBeInstanceOf ( NotFoundException ) ;
expect ( userRepositoryMock . get ) . toHaveBeenCalledWith ( adminUser . id , false ) ;
} ) ;
} ) ;
describe ( 'getUserInfo' , ( ) = > {
it ( "should get the auth user's info" , async ( ) = > {
userRepositoryMock . get . mockResolvedValue ( adminUser ) ;
const response = await sut . getUserInfo ( adminUser ) ;
expect ( userRepositoryMock . get ) . toHaveBeenCalledWith ( adminUser . id , undefined ) ;
expect ( response ) . toEqual ( adminUserResponse ) ;
} ) ;
it ( 'should throw an error if a user is not found' , async ( ) = > {
userRepositoryMock . get . mockResolvedValue ( null ) ;
await expect ( sut . getUserInfo ( adminUser ) ) . rejects . toBeInstanceOf ( BadRequestException ) ;
expect ( userRepositoryMock . get ) . toHaveBeenCalledWith ( adminUser . id , undefined ) ;
} ) ;
} ) ;
describe ( 'getUserCount' , ( ) = > {
it ( 'should get the user count' , async ( ) = > {
userRepositoryMock . getList . mockResolvedValue ( [ adminUser ] ) ;
const response = await sut . getUserCount ( { } ) ;
expect ( userRepositoryMock . getList ) . toHaveBeenCalled ( ) ;
expect ( response ) . toEqual ( { userCount : 1 } ) ;
} ) ;
} ) ;
describe ( 'update' , ( ) = > {
it ( 'should update user' , async ( ) = > {
const update : UpdateUserDto = {
id : immichUser.id ,
@ -161,17 +248,7 @@ describe('UserService', () => {
await expect ( result ) . rejects . toBeInstanceOf ( NotFoundException ) ;
} ) ;
} ) ;
describe ( 'Delete user' , ( ) = > {
it ( 'cannot delete admin user' , async ( ) = > {
const result = sut . deleteUser ( adminUserAuth , adminUserAuth . id ) ;
await expect ( result ) . rejects . toBeInstanceOf ( ForbiddenException ) ;
} ) ;
} ) ;
describe ( 'Create user' , ( ) = > {
it ( 'should let the admin update himself' , async ( ) = > {
const dto = { id : adminUser.id , shouldChangePassword : true , isAdmin : true } ;
@ -190,7 +267,37 @@ describe('UserService', () => {
await expect ( sut . updateUser ( adminUser , dto ) ) . rejects . toBeInstanceOf ( BadRequestException ) ;
} ) ;
} ) ;
describe ( 'restoreUser' , ( ) = > {
it ( 'should require an admin' , async ( ) = > {
when ( userRepositoryMock . get ) . calledWith ( adminUser . id , true ) . mockResolvedValue ( adminUser ) ;
await expect ( sut . restoreUser ( immichUserAuth , adminUser . id ) ) . rejects . toBeInstanceOf ( ForbiddenException ) ;
expect ( userRepositoryMock . get ) . toHaveBeenCalledWith ( adminUser . id , true ) ;
} ) ;
it ( 'should require the auth user be an admin' , async ( ) = > {
await expect ( sut . deleteUser ( immichUserAuth , adminUserAuth . id ) ) . rejects . toBeInstanceOf ( ForbiddenException ) ;
expect ( userRepositoryMock . delete ) . not . toHaveBeenCalled ( ) ;
} ) ;
} ) ;
describe ( 'deleteUser' , ( ) = > {
it ( 'cannot delete admin user' , async ( ) = > {
const result = sut . deleteUser ( adminUserAuth , adminUserAuth . id ) ;
await expect ( result ) . rejects . toBeInstanceOf ( ForbiddenException ) ;
} ) ;
it ( 'should require the auth user be an admin' , async ( ) = > {
await expect ( sut . deleteUser ( immichUserAuth , adminUserAuth . id ) ) . rejects . toBeInstanceOf ( ForbiddenException ) ;
expect ( userRepositoryMock . delete ) . not . toHaveBeenCalled ( ) ;
} ) ;
} ) ;
describe ( 'update' , ( ) = > {
it ( 'should not create a user if there is no local admin account' , async ( ) = > {
when ( userRepositoryMock . getAdmin ) . calledWith ( ) . mockResolvedValueOnce ( null ) ;
@ -204,4 +311,33 @@ describe('UserService', () => {
) . rejects . toBeInstanceOf ( BadRequestException ) ;
} ) ;
} ) ;
describe ( 'createProfileImage' , ( ) = > {
it ( 'should throw an error if the user does not exist' , async ( ) = > {
const file = { path : '/profile/path' } as Express . Multer . File ;
userRepositoryMock . update . mockResolvedValue ( { . . . adminUser , profileImagePath : file.path } ) ;
await sut . createProfileImage ( adminUserAuth , file ) ;
expect ( userRepositoryMock . update ) . toHaveBeenCalledWith ( adminUserAuth . id , { profileImagePath : file.path } ) ;
} ) ;
} ) ;
describe ( 'getUserProfileImage' , ( ) = > {
it ( 'should throw an error if the user does not exist' , async ( ) = > {
userRepositoryMock . get . mockResolvedValue ( null ) ;
await expect ( sut . getUserProfileImage ( adminUserAuth . id ) ) . rejects . toBeInstanceOf ( NotFoundException ) ;
expect ( userRepositoryMock . get ) . toHaveBeenCalledWith ( adminUserAuth . id , undefined ) ;
} ) ;
it ( 'should throw an error if the user does not have a picture' , async ( ) = > {
userRepositoryMock . get . mockResolvedValue ( adminUser ) ;
await expect ( sut . getUserProfileImage ( adminUserAuth . id ) ) . rejects . toBeInstanceOf ( NotFoundException ) ;
expect ( userRepositoryMock . get ) . toHaveBeenCalledWith ( adminUserAuth . id , undefined ) ;
} ) ;
} ) ;
} ) ;