From 036d0556a45cd95cfe746e96916fcf642e506713 Mon Sep 17 00:00:00 2001 From: Jaime Baez Date: Sun, 15 Jan 2023 20:08:24 +0100 Subject: [PATCH] Fix e2e tests (#1321) * Fix e2e tests * Enable e2e tests in CI * Remove unnecessary TypeOrmModule from e2e tests --- .github/workflows/test.yml | 16 ++--- .../immich/src/api-v1/asset/asset.module.ts | 1 - server/apps/immich/test/album.e2e-spec.ts | 58 ++++++++++--------- server/apps/immich/test/user.e2e-spec.ts | 24 +++++--- server/tsconfig.json | 2 - 5 files changed, 55 insertions(+), 46 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 729c48e225..db79ec0677 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,17 +6,17 @@ on: branches: [main] jobs: - # e2e-tests: - # name: Run end-to-end test suites + e2e-tests: + name: Run end-to-end test suites - # runs-on: ubuntu-latest + runs-on: ubuntu-latest - # steps: - # - name: Checkout code - # uses: actions/checkout@v3 + steps: + - name: Checkout code + uses: actions/checkout@v3 - # - name: Run Immich Server E2E Test - # run: docker-compose -f ./docker/docker-compose.test.yml --env-file ./docker/.env.test up --abort-on-container-exit --exit-code-from immich-server-test + - name: Run Immich Server E2E Test + run: docker-compose -f ./docker/docker-compose.test.yml --env-file ./docker/.env.test up --abort-on-container-exit --exit-code-from immich-server-test server-unit-tests: name: Run server unit test suites and checks diff --git a/server/apps/immich/src/api-v1/asset/asset.module.ts b/server/apps/immich/src/api-v1/asset/asset.module.ts index 79f7e28f90..12fe50e588 100644 --- a/server/apps/immich/src/api-v1/asset/asset.module.ts +++ b/server/apps/immich/src/api-v1/asset/asset.module.ts @@ -26,7 +26,6 @@ const ASSET_REPOSITORY_PROVIDER = { CommunicationModule, BackgroundTaskModule, DownloadModule, - AlbumModule, TagModule, StorageModule, forwardRef(() => AlbumModule), diff --git a/server/apps/immich/test/album.e2e-spec.ts b/server/apps/immich/test/album.e2e-spec.ts index f9436dda73..0bc660eaa7 100644 --- a/server/apps/immich/test/album.e2e-spec.ts +++ b/server/apps/immich/test/album.e2e-spec.ts @@ -1,15 +1,16 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; import request from 'supertest'; import { clearDb, getAuthUser, authCustom } from './test-utils'; -import { databaseConfig } from '@app/infra'; +import { InfraModule } from '@app/infra'; import { AlbumModule } from '../src/api-v1/album/album.module'; import { CreateAlbumDto } from '../src/api-v1/album/dto/create-album.dto'; import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module'; import { AuthUserDto } from '../src/decorators/auth-user.decorator'; -import { UserService } from '@app/domain'; +import { DomainModule, UserService } from '@app/domain'; import { DataSource } from 'typeorm'; +import { AuthService } from '../src/api-v1/auth/auth.service'; +import { AuthModule } from '../src/api-v1/auth/auth.module'; function _createAlbum(app: INestApplication, data: CreateAlbumDto) { return request(app.getHttpServer()).post('/album').send(data); @@ -19,15 +20,10 @@ describe('Album', () => { let app: INestApplication; let database: DataSource; - afterAll(async () => { - await clearDb(database); - await app.close(); - }); - describe('without auth', () => { beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AlbumModule, ImmichJwtModule, TypeOrmModule.forRoot(databaseConfig)], + imports: [DomainModule.register({ imports: [InfraModule] }), AlbumModule, ImmichJwtModule], }).compile(); app = moduleFixture.createNestApplication(); @@ -36,6 +32,7 @@ describe('Album', () => { }); afterAll(async () => { + await clearDb(database); await app.close(); }); @@ -48,21 +45,27 @@ describe('Album', () => { describe('with auth', () => { let authUser: AuthUserDto; let userService: UserService; + let authService: AuthService; beforeAll(async () => { const builder = Test.createTestingModule({ - imports: [AlbumModule, TypeOrmModule.forRoot(databaseConfig)], + imports: [DomainModule.register({ imports: [InfraModule] }), AuthModule, AlbumModule], }); authUser = getAuthUser(); // set default auth user const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile(); app = moduleFixture.createNestApplication(); userService = app.get(UserService); + authService = app.get(AuthService); database = app.get(DataSource); await app.init(); }); + afterAll(async () => { + await app.close(); + }); + describe('with empty DB', () => { afterEach(async () => { await clearDb(database); @@ -93,22 +96,21 @@ describe('Album', () => { beforeAll(async () => { // setup users - const result = await Promise.all([ - userService.createUser({ - email: 'one@test.com', - password: '1234', - firstName: 'one', - lastName: 'test', - }), - userService.createUser({ - email: 'two@test.com', - password: '1234', - firstName: 'two', - lastName: 'test', - }), - ]); - userOne = result[0]; - userTwo = result[1]; + const adminSignUpDto = await authService.adminSignUp({ + email: 'one@test.com', + password: '1234', + firstName: 'one', + lastName: 'test', + }); + userOne = { ...adminSignUpDto, isAdmin: true }; // TODO: find out why adminSignUp doesn't have isAdmin (maybe can just return UserResponseDto) + + userTwo = await userService.createUser({ + email: 'two@test.com', + password: '1234', + firstName: 'two', + lastName: 'test', + }); + // add user one albums authUser = userOne; await Promise.all([ @@ -125,6 +127,10 @@ describe('Album', () => { authUser = userOne; }); + afterAll(async () => { + await clearDb(database); + }); + it('returns the album collection including owned and shared', async () => { const { status, body } = await request(app.getHttpServer()).get('/album'); expect(status).toEqual(200); diff --git a/server/apps/immich/test/user.e2e-spec.ts b/server/apps/immich/test/user.e2e-spec.ts index 5d67689c47..9061bf8d89 100644 --- a/server/apps/immich/test/user.e2e-spec.ts +++ b/server/apps/immich/test/user.e2e-spec.ts @@ -1,14 +1,16 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; -import { TypeOrmModule } from '@nestjs/typeorm'; import request from 'supertest'; import { clearDb, authCustom } from './test-utils'; -import { databaseConfig } from '@app/infra'; +import { InfraModule } from '@app/infra'; import { ImmichJwtModule } from '../src/modules/immich-jwt/immich-jwt.module'; -import { CreateAdminDto, CreateUserDto, UserResponseDto, UserService } from '@app/domain'; +import { DomainModule, CreateUserDto, UserService, AuthUserDto } from '@app/domain'; import { DataSource } from 'typeorm'; +import { UserController } from '../src/controllers'; +import { AuthModule } from '../src/api-v1/auth/auth.module'; +import { AuthService } from '../src/api-v1/auth/auth.service'; -function _createUser(userService: UserService, data: CreateUserDto | CreateAdminDto) { +function _createUser(userService: UserService, data: CreateUserDto) { return userService.createUser(data); } @@ -24,7 +26,8 @@ describe('User', () => { describe('without auth', () => { beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [ImmichJwtModule, TypeOrmModule.forRoot(databaseConfig)], + imports: [DomainModule.register({ imports: [InfraModule] }), ImmichJwtModule], + controllers: [UserController], }).compile(); app = moduleFixture.createNestApplication(); @@ -44,16 +47,19 @@ describe('User', () => { describe('with auth', () => { let userService: UserService; - let authUser: UserResponseDto; + let authService: AuthService; + let authUser: AuthUserDto; beforeAll(async () => { const builder = Test.createTestingModule({ - imports: [TypeOrmModule.forRoot(databaseConfig)], + imports: [DomainModule.register({ imports: [InfraModule] }), AuthModule], + controllers: [UserController], }); const moduleFixture: TestingModule = await authCustom(builder, () => authUser).compile(); app = moduleFixture.createNestApplication(); userService = app.get(UserService); + authService = app.get(AuthService); database = app.get(DataSource); await app.init(); }); @@ -65,13 +71,13 @@ describe('User', () => { beforeAll(async () => { // first user must be admin - authUser = await _createUser(userService, { + const adminSignupResponseDto = await authService.adminSignUp({ firstName: 'auth-user', lastName: 'test', email: authUserEmail, password: '1234', - isAdmin: true, }); + authUser = { ...adminSignupResponseDto, isAdmin: true }; // TODO: find out why adminSignUp doesn't have isAdmin (maybe can just return UserResponseDto) await Promise.allSettled([ _createUser(userService, { firstName: 'one', diff --git a/server/tsconfig.json b/server/tsconfig.json index 3df0b52c7e..39ecfcb2a8 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -18,8 +18,6 @@ "paths": { "@app/common": ["libs/common/src"], "@app/common/*": ["libs/common/src/*"], - "@app/infra": ["libs/database/src"], - "@app/infra/*": ["libs/database/src/*"], "@app/job": ["libs/job/src"], "@app/job/*": ["libs/job/src/*"], "@app/immich-config": ["libs/immich-config/src"],