-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adds testing framework and signup tests
- Loading branch information
Showing
11 changed files
with
250 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { TestManager } from '../utils/test-manager'; | ||
import { AuthFixtures } from './fixtures'; | ||
|
||
describe('Authentication (e2e)', () => { | ||
let testManager: TestManager<any>; | ||
let fixtures: AuthFixtures; | ||
beforeAll(async () => { | ||
testManager = await TestManager.createTestManager(); | ||
fixtures = new AuthFixtures(testManager); | ||
}); | ||
|
||
afterEach(async () => { | ||
await testManager.clearDatabase(); | ||
}); | ||
|
||
afterAll(async () => { | ||
await testManager.close(); | ||
}); | ||
test(`it should throw validation errors`, async () => { | ||
const response = await fixtures.WhenISignUpANewUserWithWrongPayload({ | ||
email: 'notanemail', | ||
password: '12345', | ||
}); | ||
fixtures.ThenIShouldReceiveValidationErrors(response); | ||
}); | ||
test(`it should throw email already exist error`, async () => { | ||
const user = await fixtures.GivenThereIsUserRegistered(); | ||
const response = await fixtures.WhenISignUpANewUserWithWrongPayload({ | ||
email: user.email, | ||
password: '12345678', | ||
}); | ||
fixtures.ThenIShouldReceiveAEmailAlreadyExistError(response); | ||
}); | ||
test(`it should sign up a new user`, async () => { | ||
const newUser = { | ||
email: '[email protected]', | ||
password: '12345678', | ||
username: 'test', | ||
}; | ||
await fixtures.WhenISignUpANewUser(newUser); | ||
await fixtures.ThenANewUserAShouldBeCreated(newUser); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { TestManager } from '../utils/test-manager'; | ||
import * as request from 'supertest'; | ||
import { SignUpDto } from '@shared/dto/auth/sign-up.dto'; | ||
import { createUser } from '../utils/entity-mocks'; | ||
import { User } from '@shared/dto/users/user.entity'; | ||
|
||
export class AuthFixtures { | ||
testManager: TestManager<any>; | ||
|
||
constructor(testManager: TestManager<any>) { | ||
this.testManager = testManager; | ||
} | ||
|
||
async GivenThereIsUserRegistered(): Promise<User> { | ||
const user = await createUser(this.testManager.getDataSource(), { | ||
email: '[email protected]', | ||
}); | ||
return user; | ||
} | ||
|
||
async WhenISignUpANewUserWithWrongPayload( | ||
signUpDto: SignUpDto, | ||
): Promise<request.Response> { | ||
return request(this.testManager.getApp().getHttpServer()) | ||
.post('/auth/sign-up') | ||
.send(signUpDto); | ||
} | ||
|
||
ThenIShouldReceiveValidationErrors(response: request.Response): void { | ||
expect(response.status).toBe(400); | ||
expect(response.body).toEqual({ | ||
message: [ | ||
'email must be an email', | ||
'password must be longer than or equal to 8 characters', | ||
], | ||
error: 'Bad Request', | ||
statusCode: 400, | ||
}); | ||
} | ||
|
||
ThenIShouldReceiveAEmailAlreadyExistError(response: request.Response) { | ||
expect(response.status).toBe(409); | ||
expect(response.body).toEqual({ | ||
message: 'Email [email protected] already exists', | ||
error: 'Conflict', | ||
statusCode: 409, | ||
}); | ||
} | ||
|
||
async WhenISignUpANewUser(signUpDto: SignUpDto): Promise<request.Response> { | ||
return request(this.testManager.getApp().getHttpServer()) | ||
.post('/auth/sign-up') | ||
.send(signUpDto); | ||
} | ||
|
||
async ThenANewUserAShouldBeCreated(newUser: Partial<User>) { | ||
const user = await this.testManager | ||
.getDataSource() | ||
.getRepository(User) | ||
.findOne({ | ||
where: { email: newUser.email }, | ||
}); | ||
expect(user.id).toBeDefined(); | ||
expect(user.email).toEqual(newUser.email); | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { DataSource, EntityMetadata } from 'typeorm'; | ||
import { difference } from 'lodash'; | ||
|
||
export async function clearTestDataFromDatabase( | ||
dataSource: DataSource, | ||
): Promise<void> { | ||
const queryRunner = dataSource.createQueryRunner(); | ||
await queryRunner.connect(); | ||
await queryRunner.startTransaction(); | ||
try { | ||
const entityTableNames: string[] = dataSource.entityMetadatas | ||
.filter( | ||
(entityMetadata: EntityMetadata) => | ||
entityMetadata.tableType === 'regular' || | ||
entityMetadata.tableType === 'junction', | ||
) | ||
.map((entityMetadata: EntityMetadata) => entityMetadata.tableName); | ||
|
||
await Promise.all( | ||
entityTableNames.map((entityTableName: string) => | ||
queryRunner.query(`TRUNCATE TABLE "${entityTableName}" CASCADE`), | ||
), | ||
); | ||
|
||
entityTableNames.push(dataSource.metadataTableName); | ||
entityTableNames.push( | ||
dataSource.options.migrationsTableName || 'migrations', | ||
); | ||
entityTableNames.push('spatial_ref_sys'); | ||
|
||
const databaseTableNames: string[] = ( | ||
await dataSource.query( | ||
`SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND table_type='BASE TABLE'`, | ||
) | ||
).map((e: Record<string, any>) => e.table_name); | ||
|
||
const tablesToDrop = difference(databaseTableNames, entityTableNames); | ||
|
||
await Promise.all( | ||
tablesToDrop.map((tableToDrop: string) => | ||
queryRunner.dropTable(tableToDrop), | ||
), | ||
); | ||
await queryRunner.commitTransaction(); | ||
} catch (err) { | ||
// rollback changes before throwing error | ||
await queryRunner.rollbackTransaction(); | ||
throw err; | ||
} finally { | ||
// release query runner which is manually created | ||
await queryRunner.release(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { genSalt, hash } from 'bcrypt'; | ||
import { DataSource, DeepPartial, BaseEntity } from 'typeorm'; | ||
import { User } from '@shared/dto/users/user.entity'; | ||
|
||
export const createUser = async ( | ||
dataSource: DataSource, | ||
additionalData: Partial<User>, | ||
) => { | ||
const salt = await genSalt(); | ||
const defaultData: DeepPartial<User> = { | ||
email: '[email protected]', | ||
password: await hash('12345678', salt), | ||
}; | ||
const user = { ...defaultData, ...additionalData }; | ||
return dataSource.getRepository(User).save(user); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { AppModule } from '@api/app.module'; | ||
import { Test } from '@nestjs/testing'; | ||
import { INestApplication, ValidationPipe } from '@nestjs/common'; | ||
import { DataSource } from 'typeorm'; | ||
import { clearTestDataFromDatabase } from './db-helpers'; | ||
|
||
/** | ||
* @description: Abstraction for NestJS testing workflow. For now its a basic implementation to create a test app, but can be extended to encapsulate | ||
* common testing utilities | ||
*/ | ||
|
||
export class TestManager<FixtureType> { | ||
testApp: INestApplication; | ||
dataSource: DataSource; | ||
fixtures?: FixtureType; | ||
constructor( | ||
testApp: INestApplication, | ||
dataSource: DataSource, | ||
options?: { fixtures: FixtureType }, | ||
) { | ||
this.testApp = testApp; | ||
this.dataSource = dataSource; | ||
this.fixtures = options?.fixtures; | ||
} | ||
|
||
static async createTestManager<FixtureType>(options?: { | ||
fixtures: FixtureType; | ||
}) { | ||
const moduleFixture = await Test.createTestingModule({ | ||
imports: [AppModule], | ||
}).compile(); | ||
const dataSource = moduleFixture.get<DataSource>(DataSource); | ||
const testApp = moduleFixture.createNestApplication(); | ||
testApp.useGlobalPipes(new ValidationPipe()); | ||
await testApp.init(); | ||
return new TestManager<FixtureType>(testApp, dataSource); | ||
} | ||
|
||
async clearDatabase() { | ||
await clearTestDataFromDatabase(this.dataSource); | ||
} | ||
|
||
getApp() { | ||
return this.testApp; | ||
} | ||
|
||
getDataSource() { | ||
return this.dataSource; | ||
} | ||
|
||
close() { | ||
return this.testApp.close(); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters