diff --git a/test/private-api/alias.e2e-spec.ts b/test/private-api/alias.e2e-spec.ts index fae3293e3..541c2180f 100644 --- a/test/private-api/alias.e2e-spec.ts +++ b/test/private-api/alias.e2e-spec.ts @@ -9,7 +9,7 @@ import request from 'supertest'; import { AliasCreateDto } from '../../src/notes/alias-create.dto'; import { AliasUpdateDto } from '../../src/notes/alias-update.dto'; import { User } from '../../src/users/user.entity'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Alias', () => { let testSetup: TestSetup; @@ -22,7 +22,7 @@ describe('Alias', () => { let agent2: request.SuperAgentTest; beforeAll(async () => { - testSetup = await (await TestSetup.create()).withUsers(); + testSetup = await TestSetupBuilder.create().withUsers().build(); await testSetup.app.init(); forbiddenNoteId = diff --git a/test/private-api/auth.e2e-spec.ts b/test/private-api/auth.e2e-spec.ts index 8a14b281c..a213888e7 100644 --- a/test/private-api/auth.e2e-spec.ts +++ b/test/private-api/auth.e2e-spec.ts @@ -17,7 +17,7 @@ import { UpdatePasswordDto } from '../../src/identity/local/update-password.dto' import { UserRelationEnum } from '../../src/users/user-relation.enum'; import { checkPassword } from '../../src/utils/password'; import { setupSessionMiddleware } from '../../src/utils/session'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Auth', () => { let testSetup: TestSetup; @@ -27,7 +27,7 @@ describe('Auth', () => { let password: string; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().build(); const authConfig = testSetup.configService.get('authConfig') as AuthConfig; setupSessionMiddleware(testSetup.app, authConfig); diff --git a/test/private-api/history.e2e-spec.ts b/test/private-api/history.e2e-spec.ts index f8735bd77..ce62f422e 100644 --- a/test/private-api/history.e2e-spec.ts +++ b/test/private-api/history.e2e-spec.ts @@ -16,7 +16,7 @@ import { NotesService } from '../../src/notes/notes.service'; import { User } from '../../src/users/user.entity'; import { UsersService } from '../../src/users/users.service'; import { setupSessionMiddleware } from '../../src/utils/session'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('History', () => { let testSetup: TestSetup; @@ -30,7 +30,7 @@ describe('History', () => { let agent: request.SuperAgentTest; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().build(); forbiddenNoteId = testSetup.configService.get('appConfig').forbiddenNoteIds[0]; diff --git a/test/private-api/me.e2e-spec.ts b/test/private-api/me.e2e-spec.ts index 97071d73d..f044310f9 100644 --- a/test/private-api/me.e2e-spec.ts +++ b/test/private-api/me.e2e-spec.ts @@ -12,7 +12,7 @@ import { Note } from '../../src/notes/note.entity'; import { UserInfoDto } from '../../src/users/user-info.dto'; import { User } from '../../src/users/user.entity'; import { setupSessionMiddleware } from '../../src/utils/session'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Me', () => { let testSetup: TestSetup; @@ -26,7 +26,7 @@ describe('Me', () => { let agent: request.SuperAgentTest; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().build(); uploadPath = testSetup.configService.get('mediaConfig').backend.filesystem.uploadPath; diff --git a/test/private-api/media.e2e-spec.ts b/test/private-api/media.e2e-spec.ts index 448b1ecef..4ae3327df 100644 --- a/test/private-api/media.e2e-spec.ts +++ b/test/private-api/media.e2e-spec.ts @@ -11,7 +11,7 @@ import request from 'supertest'; import { AuthConfig } from '../../src/config/auth.config'; import { ConsoleLoggerService } from '../../src/logger/console-logger.service'; import { setupSessionMiddleware } from '../../src/utils/session'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; import { ensureDeleted } from '../utils'; describe('Media', () => { @@ -22,7 +22,7 @@ describe('Media', () => { let user: User; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().build(); uploadPath = testSetup.configService.get('mediaConfig').backend.filesystem.uploadPath; diff --git a/test/private-api/notes.e2e-spec.ts b/test/private-api/notes.e2e-spec.ts index efa5f5eb3..6c99599dd 100644 --- a/test/private-api/notes.e2e-spec.ts +++ b/test/private-api/notes.e2e-spec.ts @@ -11,7 +11,7 @@ import { AuthConfig } from '../../src/config/auth.config'; import { NotInDBError } from '../../src/errors/errors'; import { User } from '../../src/users/user.entity'; import { setupSessionMiddleware } from '../../src/utils/session'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Notes', () => { let testSetup: TestSetup; @@ -25,7 +25,7 @@ describe('Notes', () => { let agent: request.SuperAgentTest; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().build(); forbiddenNoteId = testSetup.configService.get('appConfig').forbiddenNoteIds[0]; diff --git a/test/private-api/register-and-login.e2e-spec.ts b/test/private-api/register-and-login.e2e-spec.ts index 82e75c675..4f49ccb0f 100644 --- a/test/private-api/register-and-login.e2e-spec.ts +++ b/test/private-api/register-and-login.e2e-spec.ts @@ -7,7 +7,7 @@ import request from 'supertest'; import { LoginDto } from '../../src/identity/local/login.dto'; import { RegisterDto } from '../../src/identity/local/register.dto'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Register and Login', () => { let testSetup: TestSetup; @@ -17,7 +17,7 @@ describe('Register and Login', () => { const PASSWORD = 'secure'; beforeEach(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().build(); await testSetup.app.init(); }); diff --git a/test/private-api/tokens.e2e-spec.ts b/test/private-api/tokens.e2e-spec.ts index d73aeb5ff..f74b84808 100644 --- a/test/private-api/tokens.e2e-spec.ts +++ b/test/private-api/tokens.e2e-spec.ts @@ -8,7 +8,7 @@ import request from 'supertest'; import { AuthConfig } from '../../src/config/auth.config'; import { User } from '../../src/users/user.entity'; import { setupSessionMiddleware } from '../../src/utils/session'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Tokens', () => { let testSetup: TestSetup; @@ -18,7 +18,7 @@ describe('Tokens', () => { let keyId: string; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().build(); user = await testSetup.userService.createUser('hardcoded', 'Testy'); await testSetup.identityService.createLocalIdentity(user, 'test'); diff --git a/test/public-api/alias.e2e-spec.ts b/test/public-api/alias.e2e-spec.ts index e527a3537..cfc5ea2e1 100644 --- a/test/public-api/alias.e2e-spec.ts +++ b/test/public-api/alias.e2e-spec.ts @@ -7,8 +7,7 @@ import request from 'supertest'; import { AliasCreateDto } from '../../src/notes/alias-create.dto'; import { AliasUpdateDto } from '../../src/notes/alias-update.dto'; -import { User } from '../../src/users/user.entity'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Alias', () => { let testSetup: TestSetup; @@ -17,7 +16,7 @@ describe('Alias', () => { let forbiddenNoteId: string; beforeAll(async () => { - testSetup = await (await TestSetup.create(false)).withUsers(); + testSetup = await TestSetupBuilder.create().withUsers().withNotes().build(); forbiddenNoteId = testSetup.configService.get('appConfig').forbiddenNoteIds[0]; diff --git a/test/public-api/me.e2e-spec.ts b/test/public-api/me.e2e-spec.ts index 6549191ac..814a6b257 100644 --- a/test/public-api/me.e2e-spec.ts +++ b/test/public-api/me.e2e-spec.ts @@ -11,7 +11,7 @@ import { HistoryEntryUpdateDto } from '../../src/history/history-entry-update.dt import { HistoryEntryDto } from '../../src/history/history-entry.dto'; import { NoteMetadataDto } from '../../src/notes/note-metadata.dto'; import { User } from '../../src/users/user.entity'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; // TODO Tests have to be reworked using UserService functions @@ -22,7 +22,7 @@ describe('Me', () => { let user: User; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().withMockAuth().build(); uploadPath = testSetup.configService.get('mediaConfig').backend.filesystem.uploadPath; diff --git a/test/public-api/media.e2e-spec.ts b/test/public-api/media.e2e-spec.ts index 913b498df..70e806d22 100644 --- a/test/public-api/media.e2e-spec.ts +++ b/test/public-api/media.e2e-spec.ts @@ -10,7 +10,7 @@ import request from 'supertest'; import { ConsoleLoggerService } from '../../src/logger/console-logger.service'; import { Note } from '../../src/notes/note.entity'; import { User } from '../../src/users/user.entity'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; import { ensureDeleted } from '../utils'; describe('Media', () => { @@ -20,7 +20,7 @@ describe('Media', () => { let user: User; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().withMockAuth().build(); uploadPath = testSetup.configService.get('mediaConfig').backend.filesystem.uploadPath; diff --git a/test/public-api/notes.e2e-spec.ts b/test/public-api/notes.e2e-spec.ts index 15e09af4c..42274cf76 100644 --- a/test/public-api/notes.e2e-spec.ts +++ b/test/public-api/notes.e2e-spec.ts @@ -10,7 +10,7 @@ import request from 'supertest'; import { NotInDBError } from '../../src/errors/errors'; import { NotePermissionsUpdateDto } from '../../src/notes/note-permissions.dto'; import { User } from '../../src/users/user.entity'; -import { TestSetup } from '../test-setup'; +import { TestSetup, TestSetupBuilder } from '../test-setup'; describe('Notes', () => { let testSetup: TestSetup; @@ -23,7 +23,7 @@ describe('Notes', () => { let testImage: Buffer; beforeAll(async () => { - testSetup = await TestSetup.create(); + testSetup = await TestSetupBuilder.create().withMockAuth().build(); forbiddenNoteId = testSetup.configService.get('appConfig').forbiddenNoteIds[0]; diff --git a/test/test-setup.ts b/test/test-setup.ts index bc96ce709..f79027520 100644 --- a/test/test-setup.ts +++ b/test/test-setup.ts @@ -5,7 +5,7 @@ */ import { ConfigModule, ConfigService } from '@nestjs/config'; import { NestExpressApplication } from '@nestjs/platform-express'; -import { Test, TestingModule } from '@nestjs/testing'; +import { Test, TestingModule, TestingModuleBuilder } from '@nestjs/testing'; import { TypeOrmModule } from '@nestjs/typeorm'; import { RouterModule, Routes } from 'nest-router'; @@ -34,6 +34,7 @@ import { MediaModule } from '../src/media/media.module'; import { MediaService } from '../src/media/media.service'; import { MonitoringModule } from '../src/monitoring/monitoring.module'; import { AliasService } from '../src/notes/alias.service'; +import { Note } from '../src/notes/note.entity'; import { NotesModule } from '../src/notes/notes.module'; import { NotesService } from '../src/notes/notes.service'; import { PermissionsModule } from '../src/permissions/permissions.module'; @@ -58,9 +59,27 @@ export class TestSetup { users: User[] = []; authTokens: AuthTokenWithSecretDto[] = []; + notes: Note[] = []; +} - public static async create(withMockAuth = true): Promise { - const testSetup = new TestSetup(); +/** + * Builder class for TestSetup + * Should be instantiated with the create() method + * The useable TestSetup is genereated using build() + */ +export class TestSetupBuilder { + // list of functions that should be executed before or after builing the TestingModule + private setupPreCompile: (() => Promise)[] = []; + private setupPostCompile: (() => Promise)[] = []; + + private testingModuleBuilder: TestingModuleBuilder; + private testSetup = new TestSetup(); + + /** + * Creates a new instance of TestSetupBuilder + */ + public static create(): TestSetupBuilder { + const testSetupBuilder = new TestSetupBuilder(); const routes: Routes = [ { path: '/api/v2', @@ -71,8 +90,7 @@ export class TestSetup { module: PrivateApiModule, }, ]; - - const testingModule = Test.createTestingModule({ + testSetupBuilder.testingModuleBuilder = Test.createTestingModule({ imports: [ RouterModule.forRoutes(routes), TypeOrmModule.forRoot({ @@ -109,66 +127,121 @@ export class TestSetup { IdentityModule, ], }); - - if (withMockAuth) { - testingModule.overrideGuard(TokenAuthGuard).useClass(MockAuthGuard); - } - - testSetup.moduleRef = await testingModule.compile(); - - testSetup.userService = testSetup.moduleRef.get(UsersService); - testSetup.configService = - testSetup.moduleRef.get(ConfigService); - testSetup.identityService = - testSetup.moduleRef.get(IdentityService); - testSetup.notesService = - testSetup.moduleRef.get(NotesService); - testSetup.mediaService = - testSetup.moduleRef.get(MediaService); - testSetup.historyService = - testSetup.moduleRef.get(HistoryService); - testSetup.aliasService = - testSetup.moduleRef.get(AliasService); - testSetup.authService = testSetup.moduleRef.get(AuthService); - - testSetup.app = testSetup.moduleRef.createNestApplication(); - - setupSessionMiddleware( - testSetup.app, - testSetup.configService.get('authConfig'), - ); - - return testSetup; + return testSetupBuilder; } - public async withUsers(): Promise { - // Create users - this.users.push( - await this.userService.createUser('testuser1', 'Test User 1'), - ); - this.users.push( - await this.userService.createUser('testuser2', 'Test User 2'), - ); - this.users.push( - await this.userService.createUser('testuser3', 'Test User 3'), + /** + * Builds the final TestSetup from the configured builder + */ + public async build(): Promise { + for (const setupFunction of this.setupPreCompile) { + await setupFunction(); + } + + this.testSetup.moduleRef = await this.testingModuleBuilder.compile(); + + this.testSetup.userService = + this.testSetup.moduleRef.get(UsersService); + this.testSetup.configService = + this.testSetup.moduleRef.get(ConfigService); + this.testSetup.identityService = + this.testSetup.moduleRef.get(IdentityService); + this.testSetup.notesService = + this.testSetup.moduleRef.get(NotesService); + this.testSetup.mediaService = + this.testSetup.moduleRef.get(MediaService); + this.testSetup.historyService = + this.testSetup.moduleRef.get(HistoryService); + this.testSetup.aliasService = + this.testSetup.moduleRef.get(AliasService); + this.testSetup.authService = + this.testSetup.moduleRef.get(AuthService); + + this.testSetup.app = this.testSetup.moduleRef.createNestApplication(); + + setupSessionMiddleware( + this.testSetup.app, + this.testSetup.configService.get('authConfig'), ); - // Create identities for login - await this.identityService.createLocalIdentity(this.users[0], 'testuser1'); - await this.identityService.createLocalIdentity(this.users[1], 'testuser2'); - await this.identityService.createLocalIdentity(this.users[2], 'testuser3'); + for (const setupFunction of this.setupPostCompile) { + await setupFunction(); + } + return this.testSetup; + } - // create auth tokens - this.authTokens = await Promise.all( - this.users.map(async (user) => { - return await this.authService.createTokenForUser( - user, - 'test', - new Date().getTime() + 60 * 60 * 1000, - ); - }), - ); + /** + * Enable mock authentication for the public API + */ + public withMockAuth() { + this.setupPreCompile.push(async () => { + this.testingModuleBuilder + .overrideGuard(TokenAuthGuard) + .useClass(MockAuthGuard); + return await Promise.resolve(); + }); + return this; + } + /** + * Generate a few users, identities and auth tokens for testing + */ + public withUsers() { + this.setupPostCompile.push(async () => { + // Create users + this.testSetup.users.push( + await this.testSetup.userService.createUser('testuser1', 'Test User 1'), + ); + this.testSetup.users.push( + await this.testSetup.userService.createUser('testuser2', 'Test User 2'), + ); + this.testSetup.users.push( + await this.testSetup.userService.createUser('testuser3', 'Test User 3'), + ); + + // Create identities for login + await this.testSetup.identityService.createLocalIdentity( + this.testSetup.users[0], + 'testuser1', + ); + await this.testSetup.identityService.createLocalIdentity( + this.testSetup.users[1], + 'testuser2', + ); + await this.testSetup.identityService.createLocalIdentity( + this.testSetup.users[2], + 'testuser3', + ); + + // create auth tokens + this.testSetup.authTokens = await Promise.all( + this.testSetup.users.map(async (user) => { + return await this.testSetup.authService.createTokenForUser( + user, + 'test', + new Date().getTime() + 60 * 60 * 1000, + ); + }), + ); + }); + return this; + } + + /** + * Generate a few notes for testing + */ + public withNotes(): TestSetupBuilder { + this.setupPostCompile.push(async () => { + this.testSetup.notes.push( + await this.testSetup.notesService.createNote('Test Note 1', null), + ); + this.testSetup.notes.push( + await this.testSetup.notesService.createNote('Test Note 2', null), + ); + this.testSetup.notes.push( + await this.testSetup.notesService.createNote('Test Note 3', null), + ); + }); return this; } }