Browse Source

Fix e2e tests (#1321)

* Fix e2e tests

* Enable e2e tests in CI

* Remove unnecessary TypeOrmModule from e2e tests
Jaime Baez 2 years ago
parent
commit
036d0556a4

+ 8 - 8
.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

+ 0 - 1
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),

+ 32 - 26
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);

+ 15 - 9
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',

+ 0 - 2
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"],