mirror of
https://github.com/immich-app/immich.git
synced 2025-01-02 12:48:35 +02:00
Fix user e2e tests (#194)
* WIP fix user e2e tests The e2e tests still don't seem to work due to migrations not running. Changes: - update user.e2e tests to use new `userService.createUser` method - fix server `typeorm` command to use ORM config - update make test-e2e to re-create database volume every time - add User DTO - update auth.service and user.service to use User DTO - update CreateUserDto making optional properties that are optional * Fix migrations - add missing `.ts` extension to migrations path - update user e2e test for the new returned User resource
This commit is contained in:
parent
5b036067ed
commit
b359dc3cb6
2
Makefile
2
Makefile
@ -11,7 +11,7 @@ stage:
|
|||||||
docker-compose -f ./docker/docker-compose.staging.yml up --build -V --remove-orphans
|
docker-compose -f ./docker/docker-compose.staging.yml up --build -V --remove-orphans
|
||||||
|
|
||||||
test-e2e:
|
test-e2e:
|
||||||
docker-compose -f ./docker/docker-compose.test.yml --env-file ./docker/.env.test up --abort-on-container-exit --exit-code-from immich_server_test
|
docker-compose -f ./docker/docker-compose.test.yml --env-file ./docker/.env.test up --renew-anon-volumes --abort-on-container-exit --exit-code-from immich_server_test --remove-orphans
|
||||||
|
|
||||||
prod:
|
prod:
|
||||||
docker-compose -f ./docker/docker-compose.yml up --build -V --remove-orphans
|
docker-compose -f ./docker/docker-compose.yml up --build -V --remove-orphans
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
DB_HOSTNAME=immich_postgres_test
|
|
||||||
# Database
|
# Database
|
||||||
|
DB_HOSTNAME=immich_postgres_test
|
||||||
DB_USERNAME=postgres
|
DB_USERNAME=postgres
|
||||||
DB_PASSWORD=postgres
|
DB_PASSWORD=postgres
|
||||||
DB_DATABASE_NAME=e2e_test
|
DB_DATABASE_NAME=e2e_test
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
REDIS_HOSTNAME=immich_redis_test
|
||||||
|
|
||||||
# Upload File Config
|
# Upload File Config
|
||||||
UPLOAD_LOCATION=./upload
|
UPLOAD_LOCATION=./upload
|
||||||
|
|
||||||
@ -13,4 +16,7 @@ JWT_SECRET=randomstringthatissolongandpowerfulthatnoonecanguess
|
|||||||
# MAPBOX
|
# MAPBOX
|
||||||
## ENABLE_MAPBOX is either true of false -> if true, you have to provide MAPBOX_KEY
|
## ENABLE_MAPBOX is either true of false -> if true, you have to provide MAPBOX_KEY
|
||||||
ENABLE_MAPBOX=false
|
ENABLE_MAPBOX=false
|
||||||
MAPBOX_KEY=
|
|
||||||
|
# WEB
|
||||||
|
MAPBOX_KEY=
|
||||||
|
VITE_SERVER_ENDPOINT=http://localhost:2283
|
@ -40,7 +40,7 @@ services:
|
|||||||
POSTGRES_DB: ${DB_DATABASE_NAME}
|
POSTGRES_DB: ${DB_DATABASE_NAME}
|
||||||
PG_DATA: /var/lib/postgresql/data
|
PG_DATA: /var/lib/postgresql/data
|
||||||
volumes:
|
volumes:
|
||||||
- pgdata-test:/var/lib/postgresql/data
|
- /var/lib/postgresql/data
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
networks:
|
networks:
|
||||||
@ -48,5 +48,3 @@ services:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
immich_network_test:
|
immich_network_test:
|
||||||
volumes:
|
|
||||||
pgdata-test:
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"test:cov": "jest --coverage",
|
"test:cov": "jest --coverage",
|
||||||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||||
"test:e2e": "jest --config ./test/jest-e2e.json",
|
"test:e2e": "jest --config ./test/jest-e2e.json",
|
||||||
"typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js"
|
"typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js --config src/config/database.config.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/mapbox-sdk": "^0.13.3",
|
"@mapbox/mapbox-sdk": "^0.13.3",
|
||||||
|
@ -7,6 +7,7 @@ import { ImmichJwtService } from '../../modules/immich-jwt/immich-jwt.service';
|
|||||||
import { JwtPayloadDto } from './dto/jwt-payload.dto';
|
import { JwtPayloadDto } from './dto/jwt-payload.dto';
|
||||||
import { SignUpDto } from './dto/sign-up.dto';
|
import { SignUpDto } from './dto/sign-up.dto';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
|
import { mapUser, User } from '../user/response-dto/user';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
@ -14,12 +15,24 @@ export class AuthService {
|
|||||||
@InjectRepository(UserEntity)
|
@InjectRepository(UserEntity)
|
||||||
private userRepository: Repository<UserEntity>,
|
private userRepository: Repository<UserEntity>,
|
||||||
private immichJwtService: ImmichJwtService,
|
private immichJwtService: ImmichJwtService,
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
private async validateUser(loginCredential: LoginCredentialDto): Promise<UserEntity> {
|
private async validateUser(loginCredential: LoginCredentialDto): Promise<UserEntity> {
|
||||||
const user = await this.userRepository.findOne(
|
const user = await this.userRepository.findOne(
|
||||||
{ email: loginCredential.email },
|
{ email: loginCredential.email },
|
||||||
{ select: ['id', 'email', 'password', 'salt', 'firstName', 'lastName', 'isAdmin', 'profileImagePath', 'isFirstLoggedIn'] },
|
{
|
||||||
|
select: [
|
||||||
|
'id',
|
||||||
|
'email',
|
||||||
|
'password',
|
||||||
|
'salt',
|
||||||
|
'firstName',
|
||||||
|
'lastName',
|
||||||
|
'isAdmin',
|
||||||
|
'profileImagePath',
|
||||||
|
'isFirstLoggedIn',
|
||||||
|
],
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const isAuthenticated = await this.validatePassword(user.password, loginCredential.password, user.salt);
|
const isAuthenticated = await this.validatePassword(user.password, loginCredential.password, user.salt);
|
||||||
@ -48,38 +61,29 @@ export class AuthService {
|
|||||||
lastName: validatedUser.lastName,
|
lastName: validatedUser.lastName,
|
||||||
isAdmin: validatedUser.isAdmin,
|
isAdmin: validatedUser.isAdmin,
|
||||||
profileImagePath: validatedUser.profileImagePath,
|
profileImagePath: validatedUser.profileImagePath,
|
||||||
isFirstLogin: validatedUser.isFirstLoggedIn
|
isFirstLogin: validatedUser.isFirstLoggedIn,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async adminSignUp(signUpCredential: SignUpDto): Promise<User> {
|
||||||
public async adminSignUp(signUpCrendential: SignUpDto) {
|
|
||||||
const adminUser = await this.userRepository.findOne({ where: { isAdmin: true } });
|
const adminUser = await this.userRepository.findOne({ where: { isAdmin: true } });
|
||||||
|
|
||||||
if (adminUser) {
|
if (adminUser) {
|
||||||
throw new BadRequestException('The server already has an admin')
|
throw new BadRequestException('The server already has an admin');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const newAdminUser = new UserEntity();
|
const newAdminUser = new UserEntity();
|
||||||
newAdminUser.email = signUpCrendential.email;
|
newAdminUser.email = signUpCredential.email;
|
||||||
newAdminUser.salt = await bcrypt.genSalt();
|
newAdminUser.salt = await bcrypt.genSalt();
|
||||||
newAdminUser.password = await this.hashPassword(signUpCrendential.password, newAdminUser.salt);
|
newAdminUser.password = await this.hashPassword(signUpCredential.password, newAdminUser.salt);
|
||||||
newAdminUser.firstName = signUpCrendential.firstName;
|
newAdminUser.firstName = signUpCredential.firstName;
|
||||||
newAdminUser.lastName = signUpCrendential.lastName;
|
newAdminUser.lastName = signUpCredential.lastName;
|
||||||
newAdminUser.isAdmin = true;
|
newAdminUser.isAdmin = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const savedNewAdminUserUser = await this.userRepository.save(newAdminUser);
|
const savedNewAdminUserUser = await this.userRepository.save(newAdminUser);
|
||||||
|
|
||||||
return {
|
return mapUser(savedNewAdminUserUser);
|
||||||
id: savedNewAdminUserUser.id,
|
|
||||||
email: savedNewAdminUserUser.email,
|
|
||||||
firstName: savedNewAdminUserUser.firstName,
|
|
||||||
lastName: savedNewAdminUserUser.lastName,
|
|
||||||
createdAt: savedNewAdminUserUser.createdAt,
|
|
||||||
};
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error('e', 'signUp');
|
Logger.error('e', 'signUp');
|
||||||
throw new InternalServerErrorException('Failed to register new admin user');
|
throw new InternalServerErrorException('Failed to register new admin user');
|
||||||
|
@ -14,14 +14,14 @@ export class CreateUserDto {
|
|||||||
lastName: string;
|
lastName: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
profileImagePath: string;
|
profileImagePath?: string;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
isAdmin: boolean;
|
isAdmin?: boolean;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
isFirstLoggedIn: boolean;
|
isFirstLoggedIn?: boolean;
|
||||||
|
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
id: string;
|
id?: string;
|
||||||
}
|
}
|
||||||
|
19
server/src/api-v1/user/response-dto/user.ts
Normal file
19
server/src/api-v1/user/response-dto/user.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { UserEntity } from '../entities/user.entity';
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
createdAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapUser(entity: UserEntity): User {
|
||||||
|
return {
|
||||||
|
id: entity.id,
|
||||||
|
email: entity.email,
|
||||||
|
firstName: entity.firstName,
|
||||||
|
lastName: entity.lastName,
|
||||||
|
createdAt: entity.createdAt,
|
||||||
|
};
|
||||||
|
}
|
@ -6,19 +6,18 @@ import { CreateUserDto } from './dto/create-user.dto';
|
|||||||
import { UpdateUserDto } from './dto/update-user.dto';
|
import { UpdateUserDto } from './dto/update-user.dto';
|
||||||
import { UserEntity } from './entities/user.entity';
|
import { UserEntity } from './entities/user.entity';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import sharp from 'sharp';
|
import { createReadStream } from 'fs';
|
||||||
import { createReadStream, unlink, unlinkSync } from 'fs';
|
|
||||||
import { Response as Res } from 'express';
|
import { Response as Res } from 'express';
|
||||||
|
import { mapUser, User } from './response-dto/user';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(UserEntity)
|
@InjectRepository(UserEntity)
|
||||||
private userRepository: Repository<UserEntity>,
|
private userRepository: Repository<UserEntity>,
|
||||||
) { }
|
) {}
|
||||||
|
|
||||||
async getAllUsers(authUser: AuthUserDto, isAll: boolean) {
|
async getAllUsers(authUser: AuthUserDto, isAll: boolean) {
|
||||||
|
|
||||||
if (isAll) {
|
if (isAll) {
|
||||||
return await this.userRepository.find();
|
return await this.userRepository.find();
|
||||||
}
|
}
|
||||||
@ -26,8 +25,8 @@ export class UserService {
|
|||||||
return await this.userRepository.find({
|
return await this.userRepository.find({
|
||||||
where: { id: Not(authUser.id) },
|
where: { id: Not(authUser.id) },
|
||||||
order: {
|
order: {
|
||||||
createdAt: 'DESC'
|
createdAt: 'DESC',
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,14 +39,12 @@ export class UserService {
|
|||||||
users = await this.userRepository.find();
|
users = await this.userRepository.find();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userCount: users.length
|
userCount: users.length,
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createUser(createUserDto: CreateUserDto) {
|
async createUser(createUserDto: CreateUserDto): Promise<User> {
|
||||||
const user = await this.userRepository.findOne({ where: { email: createUserDto.email } });
|
const user = await this.userRepository.findOne({ where: { email: createUserDto.email } });
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
@ -62,18 +59,10 @@ export class UserService {
|
|||||||
newUser.lastName = createUserDto.lastName;
|
newUser.lastName = createUserDto.lastName;
|
||||||
newUser.isAdmin = false;
|
newUser.isAdmin = false;
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const savedUser = await this.userRepository.save(newUser);
|
const savedUser = await this.userRepository.save(newUser);
|
||||||
|
|
||||||
return {
|
return mapUser(savedUser);
|
||||||
id: savedUser.id,
|
|
||||||
email: savedUser.email,
|
|
||||||
firstName: savedUser.firstName,
|
|
||||||
lastName: savedUser.lastName,
|
|
||||||
createdAt: savedUser.createdAt,
|
|
||||||
};
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(e, 'Create new user');
|
Logger.error(e, 'Create new user');
|
||||||
throw new InternalServerErrorException('Failed to register new user');
|
throw new InternalServerErrorException('Failed to register new user');
|
||||||
@ -84,7 +73,6 @@ export class UserService {
|
|||||||
return bcrypt.hash(password, salt);
|
return bcrypt.hash(password, salt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async updateUser(updateUserDto: UpdateUserDto) {
|
async updateUser(updateUserDto: UpdateUserDto) {
|
||||||
const user = await this.userRepository.findOne(updateUserDto.id);
|
const user = await this.userRepository.findOne(updateUserDto.id);
|
||||||
|
|
||||||
@ -100,10 +88,10 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (updateUserDto.isAdmin) {
|
if (updateUserDto.isAdmin) {
|
||||||
const adminUser = await this.userRepository.findOne({ where: { isAdmin: true } })
|
const adminUser = await this.userRepository.findOne({ where: { isAdmin: true } });
|
||||||
|
|
||||||
if (adminUser) {
|
if (adminUser) {
|
||||||
throw new BadRequestException("Admin user exists")
|
throw new BadRequestException('Admin user exists');
|
||||||
}
|
}
|
||||||
|
|
||||||
user.isAdmin = true;
|
user.isAdmin = true;
|
||||||
@ -120,7 +108,6 @@ export class UserService {
|
|||||||
isAdmin: updatedUser.isAdmin,
|
isAdmin: updatedUser.isAdmin,
|
||||||
profileImagePath: updatedUser.profileImagePath,
|
profileImagePath: updatedUser.profileImagePath,
|
||||||
};
|
};
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(e, 'Create new user');
|
Logger.error(e, 'Create new user');
|
||||||
throw new InternalServerErrorException('Failed to register new user');
|
throw new InternalServerErrorException('Failed to register new user');
|
||||||
@ -130,13 +117,12 @@ export class UserService {
|
|||||||
async createProfileImage(authUser: AuthUserDto, fileInfo: Express.Multer.File) {
|
async createProfileImage(authUser: AuthUserDto, fileInfo: Express.Multer.File) {
|
||||||
try {
|
try {
|
||||||
await this.userRepository.update(authUser.id, {
|
await this.userRepository.update(authUser.id, {
|
||||||
profileImagePath: fileInfo.path
|
profileImagePath: fileInfo.path,
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userId: authUser.id,
|
userId: authUser.id,
|
||||||
profileImagePath: fileInfo.path
|
profileImagePath: fileInfo.path,
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Logger.error(e, 'Create User Profile Image');
|
Logger.error(e, 'Create User Profile Image');
|
||||||
@ -146,7 +132,7 @@ export class UserService {
|
|||||||
|
|
||||||
async getUserProfileImage(userId: string, res: Res) {
|
async getUserProfileImage(userId: string, res: Res) {
|
||||||
try {
|
try {
|
||||||
const user = await this.userRepository.findOne({ id: userId })
|
const user = await this.userRepository.findOne({ id: userId });
|
||||||
|
|
||||||
if (!user.profileImagePath) {
|
if (!user.profileImagePath) {
|
||||||
// throw new BadRequestException('User does not have a profile image');
|
// throw new BadRequestException('User does not have a profile image');
|
||||||
@ -157,11 +143,10 @@ export class UserService {
|
|||||||
res.set({
|
res.set({
|
||||||
'Content-Type': 'image/jpeg',
|
'Content-Type': 'image/jpeg',
|
||||||
});
|
});
|
||||||
const fileStream = createReadStream(user.profileImagePath)
|
const fileStream = createReadStream(user.profileImagePath);
|
||||||
return new StreamableFile(fileStream);
|
return new StreamableFile(fileStream);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("error getting user profile")
|
console.log('error getting user profile');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,11 @@ export const databaseConfig: TypeOrmModuleOptions = {
|
|||||||
database: process.env.DB_DATABASE_NAME,
|
database: process.env.DB_DATABASE_NAME,
|
||||||
entities: [__dirname + '/../**/*.entity.{js,ts}'],
|
entities: [__dirname + '/../**/*.entity.{js,ts}'],
|
||||||
synchronize: false,
|
synchronize: false,
|
||||||
migrations: [__dirname + '/../migration/*.js'],
|
migrations: [__dirname + '/../migration/*.{js,ts}'],
|
||||||
cli: {
|
cli: {
|
||||||
migrationsDir: __dirname + '/../migration',
|
migrationsDir: __dirname + '/../migration',
|
||||||
},
|
},
|
||||||
migrationsRun: true,
|
migrationsRun: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default databaseConfig;
|
||||||
|
@ -5,14 +5,13 @@ import request from 'supertest';
|
|||||||
import { clearDb, authCustom } from './test-utils';
|
import { clearDb, authCustom } from './test-utils';
|
||||||
import { databaseConfig } from '../src/config/database.config';
|
import { databaseConfig } from '../src/config/database.config';
|
||||||
import { UserModule } from '../src/api-v1/user/user.module';
|
import { UserModule } from '../src/api-v1/user/user.module';
|
||||||
import { AuthModule } from '../src/api-v1/auth/auth.module';
|
|
||||||
import { AuthService } from '../src/api-v1/auth/auth.service';
|
|
||||||
import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module';
|
import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module';
|
||||||
import { SignUpDto } from '../src/api-v1/auth/dto/sign-up.dto';
|
import { UserService } from '../src/api-v1/user/user.service';
|
||||||
import { AuthUserDto } from '../src/decorators/auth-user.decorator';
|
import { CreateUserDto } from '../src/api-v1/user/dto/create-user.dto';
|
||||||
|
import { User } from '../src/api-v1/user/response-dto/user';
|
||||||
|
|
||||||
function _createUser(authService: AuthService, data: SignUpDto) {
|
function _createUser(userService: UserService, data: CreateUserDto) {
|
||||||
return authService.signUp(data);
|
return userService.createUser(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('User', () => {
|
describe('User', () => {
|
||||||
@ -44,17 +43,17 @@ describe('User', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('with auth', () => {
|
describe('with auth', () => {
|
||||||
let authService: AuthService;
|
let userService: UserService;
|
||||||
let authUser: AuthUserDto;
|
let authUser: User;
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const builder = Test.createTestingModule({
|
const builder = Test.createTestingModule({
|
||||||
imports: [UserModule, AuthModule, TypeOrmModule.forRoot(databaseConfig)],
|
imports: [UserModule, TypeOrmModule.forRoot(databaseConfig)],
|
||||||
});
|
});
|
||||||
const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile();
|
const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile();
|
||||||
|
|
||||||
app = moduleFixture.createNestApplication();
|
app = moduleFixture.createNestApplication();
|
||||||
authService = app.get(AuthService);
|
userService = app.get(UserService);
|
||||||
await app.init();
|
await app.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,9 +64,24 @@ describe('User', () => {
|
|||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await Promise.allSettled([
|
await Promise.allSettled([
|
||||||
_createUser(authService, { email: authUserEmail, password: '1234' }).then((user) => (authUser = user)),
|
_createUser(userService, {
|
||||||
_createUser(authService, { email: userOneEmail, password: '1234' }),
|
firstName: 'auth-user',
|
||||||
_createUser(authService, { email: userTwoEmail, password: '1234' }),
|
lastName: 'test',
|
||||||
|
email: authUserEmail,
|
||||||
|
password: '1234',
|
||||||
|
}).then((user) => (authUser = user)),
|
||||||
|
_createUser(userService, {
|
||||||
|
firstName: 'one',
|
||||||
|
lastName: 'test',
|
||||||
|
email: userOneEmail,
|
||||||
|
password: '1234',
|
||||||
|
}),
|
||||||
|
_createUser(userService, {
|
||||||
|
firstName: 'two',
|
||||||
|
lastName: 'test',
|
||||||
|
email: userTwoEmail,
|
||||||
|
password: '1234',
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -79,13 +93,23 @@ describe('User', () => {
|
|||||||
expect.arrayContaining([
|
expect.arrayContaining([
|
||||||
{
|
{
|
||||||
email: userOneEmail,
|
email: userOneEmail,
|
||||||
|
firstName: 'one',
|
||||||
|
lastName: 'test',
|
||||||
id: expect.anything(),
|
id: expect.anything(),
|
||||||
createdAt: expect.anything(),
|
createdAt: expect.anything(),
|
||||||
|
isAdmin: false,
|
||||||
|
isFirstLoggedIn: true,
|
||||||
|
profileImagePath: '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
email: userTwoEmail,
|
email: userTwoEmail,
|
||||||
|
firstName: 'two',
|
||||||
|
lastName: 'test',
|
||||||
id: expect.anything(),
|
id: expect.anything(),
|
||||||
createdAt: expect.anything(),
|
createdAt: expect.anything(),
|
||||||
|
isAdmin: false,
|
||||||
|
isFirstLoggedIn: true,
|
||||||
|
profileImagePath: '',
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user