@ -6,10 +6,6 @@ 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' ,
@ -64,6 +60,23 @@ describe('UserService', () => {
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 = {
get : jest . fn ( ) ,
@ -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 ) ;
} ) ;
} ) ;
} ) ;