Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] Jest Test e2e #402

Merged
merged 22 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a405362
chore(deps): bump jest from ^27.1.1 to ^29.7.0
rahul-rocket Apr 19, 2024
249b95b
fix: updated gitignore file
rahul-rocket Apr 19, 2024
34431dd
fix: typeorm nested relations query syntax
rahul-rocket Apr 19, 2024
ba62f0c
chore(deps): bump prettier from ^2.4.0 to ^3.2.5
rahul-rocket Apr 20, 2024
3155f79
fix: run prettier for formatting
rahul-rocket Apr 20, 2024
37c71f2
fix: run prettier for formatting
rahul-rocket Apr 20, 2024
0c47d0d
fix: typeorm nested relations query syntax
rahul-rocket Apr 20, 2024
977d9af
fix: get data source connection for e2e testing
rahul-rocket Apr 20, 2024
b09e9b2
fix: run prettier for formatting
rahul-rocket Apr 20, 2024
589b3f2
fix: run prettier for formatting
rahul-rocket Apr 20, 2024
0601077
fix: increased jest testTimeout
rahul-rocket Apr 20, 2024
c0baafb
fix: removed maxWorker for jest
rahul-rocket Apr 20, 2024
a8e3b4d
Merge branch 'develop' into fix/jest-e2e-test
rahul-rocket Jun 24, 2024
3ae84c0
update yarn.lock
rahul-rocket Jun 24, 2024
320fb89
Merge branch 'develop' into fix/jest-e2e-test
rahul-rocket Oct 18, 2024
9d2f066
chore: update yarn.lock
rahul-rocket Oct 18, 2024
4068acb
fix: coderabbitai suggestion
rahul-rocket Oct 18, 2024
16f3500
fix: coderabbitai suggestion
rahul-rocket Oct 18, 2024
182792b
chore: update yarn.lock
rahul-rocket Oct 18, 2024
9d03935
fix: removed console
rahul-rocket Oct 18, 2024
8eb3d11
style: fix code style issues using Prettier
rahul-rocket Oct 18, 2024
e5b950a
fix: updated connection datasource
rahul-rocket Oct 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions api/src/connection/datasource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { DataSource, DataSourceOptions, DefaultNamingStrategy } from 'typeorm';
import * as process from 'process';
import { SnakeNamingStrategy } from '../utils/snake-naming-strategy';

const env = process.env;

/**
* Retrieves the connection options for TypeORM DataSource or TypeORMModule.
*
* @returns The connection options for TypeORM DataSource or TypeORMModule.
*/
export const dataSourceOptions = (): DataSourceOptions => {
// Safely cast the database type or default to 'mysql'
const dbType = (env.TR_DB_TYPE as any) || 'mysql';

// Parse the port safely with fallback to 3306 if parsing fails
const port = isNaN(parseInt(env.TR_DB_PORT, 10)) ? 3306 : parseInt(env.TR_DB_PORT, 10);
rahul-rocket marked this conversation as resolved.
Show resolved Hide resolved

// Base options object using the more generic DataSourceOptions
const options: DataSourceOptions = {
type: dbType,
host: env.TR_DB_HOST || 'localhost',
port,
username: env.TR_DB_USER || 'root',
password: env.TR_DB_PASSWORD || 'root',
database: env.TR_DB_DATABASE || 'tr_dev',
charset: 'utf8mb4',
synchronize: false,
logging: false,
entities: [__dirname + '/../entity/*.entity.{js,ts}'],
migrations: [__dirname + '/../migrations/*.{js,ts}'],
namingStrategy: dbType === 'postgres' ? new SnakeNamingStrategy() : new DefaultNamingStrategy(),
};

return options;
};

/**
* Creates and initializes a TypeORM DataSource instance with the provided configuration options.
*
* @returns Initialized TypeORM DataSource instance.
*/
let dataSource: DataSource;
export const getDataSourceConnection = async (): Promise<DataSource> => {
if (!dataSource) {
dataSource = new DataSource(dataSourceOptions());
}

try {
if (!dataSource.isInitialized) {
await dataSource.initialize();
}
} catch (error) {
console.error(`Error initializing database connection: ${error?.message}`);
}

return dataSource;
};
8 changes: 6 additions & 2 deletions api/src/controllers/exports.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ export class ExportsController {
// Ensure locale is requested project locale
const projectLocale = await this.projectLocaleRepo.findOne({
where: {
project: membership.project,
project: {
id: membership.project.id,
},
rahul-rocket marked this conversation as resolved.
Show resolved Hide resolved
locale: {
code: query.locale,
},
Expand Down Expand Up @@ -98,7 +100,9 @@ export class ExportsController {
if (query.fallbackLocale) {
const fallbackProjectLocale = await this.projectLocaleRepo.findOne({
where: {
project: membership.project,
project: {
id: membership.project.id,
},
locale: {
code: query.fallbackLocale,
},
Expand Down
4 changes: 3 additions & 1 deletion api/src/controllers/import.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ export class ImportController {
// Extract into service for creating project locales
projectLocale = this.projectLocaleRepo.create({
locale: locale,
project: membership.project,
project: {
id: membership.project.id,
},
});
projectLocale = await entityManager.save(ProjectLocale, projectLocale);
await entityManager.increment(Project, { id: membership.project.id }, 'localesCount', 1);
Expand Down
24 changes: 13 additions & 11 deletions api/src/controllers/project-label.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export default class ProjectLabelController {
async delete(@Req() req, @Param('projectId') projectId: string, @Param('labelId') labelId: string) {
const user = this.auth.getRequestUserOrClient(req);
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.DeleteLabel);
const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: membership.project } });
const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: { id: membership.project.id } } });
await this.labelRepo.remove(label);
}

Expand All @@ -122,8 +122,8 @@ export default class ProjectLabelController {
const user = this.auth.getRequestUserOrClient(req);
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.EditLabel);

const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: membership.project } });
const term = await this.termsRepo.findOneOrFail({ where: { id: termId, project: membership.project }, relations: ['labels'] });
const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: { id: membership.project.id } } });
const term = await this.termsRepo.findOneOrFail({ where: { id: termId, project: { id: membership.project.id } }, relations: ['labels'] });

term.labels.push(label);

Expand All @@ -149,8 +149,8 @@ export default class ProjectLabelController {
const user = this.auth.getRequestUserOrClient(req);
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.EditLabel);

const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: membership.project } });
const term = await this.termsRepo.findOneOrFail({ where: { id: termId, project: membership.project }, relations: ['labels'] });
const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: { id: membership.project.id } } });
const term = await this.termsRepo.findOneOrFail({ where: { id: termId, project: { id: membership.project.id } }, relations: ['labels'] });

term.labels = term.labels.filter(t => t.id !== label.id);

Expand All @@ -174,19 +174,21 @@ export default class ProjectLabelController {
const user = this.auth.getRequestUserOrClient(req);
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.EditLabel);

const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: membership.project } });
const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: { id: membership.project.id } } });

const projectLocale = await this.projectLocaleRepo.findOneOrFail({
where: {
project: membership.project,
project: {
id: membership.project.id,
},
locale: {
code: localeCode,
},
},
});

const translation = await this.translationsRepo.findOneOrFail({
where: { termId: termId, projectLocale: projectLocale },
where: { termId: termId, projectLocale: { id: projectLocale.id } },
relations: ['labels'],
});

Expand All @@ -212,19 +214,19 @@ export default class ProjectLabelController {
const user = this.auth.getRequestUserOrClient(req);
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.EditLabel);

const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: membership.project } });
const label = await this.labelRepo.findOneOrFail({ where: { id: labelId, project: { id: membership.project.id } } });

const projectLocale = await this.projectLocaleRepo.findOneOrFail({
where: {
project: membership.project,
project: { id: membership.project.id },
locale: {
code: localeCode,
},
},
});

const translation = await this.translationsRepo.findOneOrFail({
where: { termId: termId, projectLocale: projectLocale },
where: { termId: termId, projectLocale: { id: projectLocale.id } },
relations: ['labels'],
});

Expand Down
2 changes: 1 addition & 1 deletion api/src/controllers/project-stats.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class ProjectStatsController {
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.ViewTranslation);
const locales = await this.projectLocaleRepo.find({
where: {
project: membership.project,
project: { id: membership.project.id },
},
relations: ['locale'],
});
Expand Down
5 changes: 4 additions & 1 deletion api/src/controllers/project-user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import AuthorizationService from '../services/authorization.service';
@ApiOAuth2([])
@ApiTags('Project Users')
export default class ProjectUserController {
constructor(private auth: AuthorizationService, @InjectRepository(ProjectUser) private projectUserRepo: Repository<ProjectUser>) {}
constructor(
private auth: AuthorizationService,
@InjectRepository(ProjectUser) private projectUserRepo: Repository<ProjectUser>,
) {}

@Get(':projectId/users')
@ApiOperation({ summary: 'List all users with access to a project' })
Expand Down
6 changes: 4 additions & 2 deletions api/src/controllers/term.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ export default class TermController {

const projectLocales = await this.projectLocaleRepo.find({
where: {
project: membership.project,
project: {
id: membership.project.id,
},
},
});

Expand Down Expand Up @@ -143,7 +145,7 @@ export default class TermController {
const user = this.auth.getRequestUserOrClient(req);
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.DeleteTerm);
await this.termRepo.manager.transaction(async entityManager => {
const term = await entityManager.findOneOrFail(Term, { where: { id: termId, project: membership.project } });
const term = await entityManager.findOneOrFail(Term, { where: { id: termId, project: { id: membership.project.id } } });
await entityManager.remove(term);
await entityManager.decrement(Project, { id: membership.project.id }, 'termsCount', 1);
});
Expand Down
20 changes: 13 additions & 7 deletions api/src/controllers/translation.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class TranslationController {
const membership = await this.auth.authorizeProjectAction(user, projectId, ProjectAction.ViewTranslation);
const locales = await this.projectLocaleRepo.find({
where: {
project: membership.project,
project: { id: membership.project.id },
},
relations: ['locale'],
});
Expand Down Expand Up @@ -95,8 +95,10 @@ export default class TranslationController {
});

const result = await this.projectLocaleRepo.findOneByOrFail({
locale,
project: membership.project,
locale: {
code: locale.code,
},
project: { id: membership.project.id },
});

return {
Expand Down Expand Up @@ -126,7 +128,7 @@ export default class TranslationController {
// Ensure locale is requested project locale
const projectLocale = await this.projectLocaleRepo.findOneOrFail({
where: {
project: membership.project,
project: { id: membership.project.id },
locale: {
code: localeCode,
},
Expand All @@ -135,7 +137,9 @@ export default class TranslationController {
try {
const translations = await this.translationRepo.find({
where: {
projectLocale,
projectLocale: {
id: projectLocale.id,
},
},
relations: ['term', 'labels'],
});
Expand Down Expand Up @@ -186,7 +190,9 @@ export default class TranslationController {
let translation = await this.translationRepo.findOne({
where: {
termId: term.id,
projectLocale: projectLocale,
projectLocale: {
id: projectLocale.id,
},
},
relations: ['labels'],
});
Expand Down Expand Up @@ -231,7 +237,7 @@ export default class TranslationController {
await this.projectLocaleRepo.manager.transaction(async entityManager => {
const projectLocale = await entityManager.findOneOrFail(ProjectLocale, {
where: {
project: membership.project,
project: { id: membership.project.id },
locale: {
code: localeCode,
},
Expand Down
5 changes: 4 additions & 1 deletion api/src/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import { UserService } from '../services/user.service';
@ApiOAuth2([])
@ApiTags('Users')
export default class UserController {
constructor(private auth: AuthorizationService, private userService: UserService) {}
constructor(
private auth: AuthorizationService,
private userService: UserService,
) {}

@Get('me')
@ApiOperation({ summary: `Get the current user's profile` })
Expand Down
10 changes: 7 additions & 3 deletions api/test/jest-e2e.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": ".",
"testEnvironment": "node",
"testTimeout": 60000,
"testTimeout": 120000,
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}
}
14 changes: 8 additions & 6 deletions api/test/user.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Connection } from 'typeorm';
import { DataSource } from 'typeorm';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { getRepository } from 'typeorm';
import { getDataSourceConnection } from '../src/connection/datasource';
import { ProjectLocale } from '../src/entity/project-locale.entity';
import { Project } from '../src/entity/project.entity';
import { Term } from '../src/entity/term.entity';
Expand All @@ -10,6 +10,7 @@ import { createAndMigrateApp, createTestProject, signupTestUser, TestingProject,

describe('UserController (e2e)', () => {
let app: INestApplication;
let connection: DataSource;
rahul-rocket marked this conversation as resolved.
Show resolved Hide resolved
let testingUser: TestingUser;
let testingUser2: TestingUser;
let testingUser3: TestingUser;
Expand All @@ -18,6 +19,7 @@ describe('UserController (e2e)', () => {

beforeEach(async () => {
app = await createAndMigrateApp();
connection = await getDataSourceConnection();
testingUser = await signupTestUser(app);
testingUser2 = await signupTestUser(app, 'e2e-user2@test.com');
testingUser3 = await signupTestUser(app, 'e2e-user3@test.com');
Expand Down Expand Up @@ -224,15 +226,15 @@ describe('UserController (e2e)', () => {

await request(app.getHttpServer()).get('/api/v1/projects').set('Authorization', `Bearer ${testingUser3.accessToken}`).expect(401);

const project = await getRepository(Project).findOneBy({ id: testProject.id });
const project = await connection.getRepository(Project).findOneBy({ id: testProject.id });
expect(project).toBeDefined();
expect(project.id).toEqual(testProject.id);

const term = await getRepository(Term).findOneBy({ id: termId });
const term = await connection.getRepository(Term).findOneBy({ id: termId });
expect(term).toBeDefined();
expect(term.id).toEqual(termId);

const projectLocales = await getRepository(ProjectLocale).find({
const projectLocales = await connection.getRepository(ProjectLocale).find({
where: { project: { id: testProject.id } },
relations: ['locale'],
});
Expand All @@ -242,7 +244,7 @@ describe('UserController (e2e)', () => {
});

afterEach(async () => {
await app.get(Connection).close();
await connection.destroy();
await app.close();
});
});
Loading