Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
},
"devDependencies": {
"@eslint/compat": "^1.1.1",
"@faker-js/faker": "^9.0.3",
"@jest/test-sequencer": "^29.7.0",
"@types/bcryptjs": "^2.4.6",
"@types/body-parser": "^1.19.5",
Expand Down
17 changes: 13 additions & 4 deletions src/core/base/Factory.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import IFactory from "@src/core/interfaces/IFactory";
import { faker } from "@faker-js/faker";
import { ICtor } from "@src/core/interfaces/ICtor";
import IFactory from "@src/core/interfaces/IFactory";

import { IModel } from "../interfaces/IModel";
import IModelAttributes from "../interfaces/IModelData";

/**
* Abstract base class for factories that create instances of a specific model.
*
* @template Model The type of model to create.
* @template Data The type of data to pass to the model constructor.
*/
export default abstract class Factory<Model, Data> implements IFactory {
export default abstract class Factory<Model extends IModel = IModel> implements IFactory {

/**
* The faker instance to use.
*/
protected faker = faker;

/**
* The constructor of the model to create.
Expand All @@ -29,8 +38,8 @@ export default abstract class Factory<Model, Data> implements IFactory {
* @param data The data to pass to the model constructor.
* @returns A new instance of the model.
*/
create(data: Data): Model {
createWithData<Data extends IModelAttributes = IModelAttributes>(data: Data | null = null): Model {
return new this.modelCtor(data)
}

}
2 changes: 1 addition & 1 deletion src/core/domains/auth/actions/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default async (req: Request, res: Response): Promise<void> => {
}

// Create a new user
const user = new UserFactory().create({
const user = new UserFactory().createWithData({
email,
password,
hashedPassword: hashPassword(password ?? ''),
Expand Down
9 changes: 3 additions & 6 deletions src/core/domains/auth/factory/apiTokenFactory.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import ApiToken from '@src/app/models/auth/ApiToken'
import Factory from '@src/core/base/Factory'
import IApiTokenModel, { IApiTokenData } from '@src/core/domains/auth/interfaces/IApitokenModel'
import IApiTokenModel from '@src/core/domains/auth/interfaces/IApitokenModel'
import IUserModel from '@src/core/domains/auth/interfaces/IUserModel'
import tokenFactory from '@src/core/domains/auth/utils/generateToken'

/**
* Factory for creating ApiToken models.
*
* @class ApiTokenFactory
* @extends {Factory<IApiTokenModel, IApiTokenData>}
*/
class ApiTokenFactory extends Factory<IApiTokenModel, IApiTokenData> {
class ApiTokenFactory extends Factory<IApiTokenModel> {

constructor() {
super(ApiToken)
Expand All @@ -23,7 +20,7 @@ class ApiTokenFactory extends Factory<IApiTokenModel, IApiTokenData> {
* @returns {IApiTokenModel}
*/
createFromUser(user: IUserModel, scopes: string[] = []): IApiTokenModel {
return new this.modelCtor({
return this.createWithData({
userId: user.attributes?.id,
token: tokenFactory(),
scopes: scopes,
Expand Down
2 changes: 1 addition & 1 deletion src/core/domains/auth/factory/userFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Factory from '@src/core/base/Factory';
* @class UserFactory
* @extends {Factory<User, IUserData>}
*/
export default class UserFactory extends Factory<User, IUserData> {
export default class UserFactory extends Factory<User> {

/**
* Constructor
Expand Down
3 changes: 2 additions & 1 deletion src/core/interfaces/IFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

export default interface IFactory {
// eslint-disable-next-line no-unused-vars
create(...args: any[]): any;
createWithData(...args: any[]): any;
}
2 changes: 1 addition & 1 deletion src/tests/auth/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('attempt to run app with normal appConfig', () => {
/**
* Create a test user
*/
testUser = new UserFactory().create({
testUser = new UserFactory().createWithData({
email,
hashedPassword,
roles: [],
Expand Down
23 changes: 23 additions & 0 deletions src/tests/factory/TestMovieFaker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Factory from "@src/core/base/Factory";

import { TestMovieModel } from "../models/models/TestMovie";

class TestMovieFactory extends Factory<TestMovieModel> {

constructor() {
super(TestMovieModel)
}

createFakeMovie(): TestMovieModel {
return this.createWithData({
authorId: this.faker.number.int({ min: 1, max: 100 }).toString(),
name: this.faker.person.fullName(),
yearReleased: this.faker.number.int({ min: 1900, max: 2000 }),
createdAt: this.faker.date.past(),
updatedAt: this.faker.date.recent()
})
}

}

export default TestMovieFactory
36 changes: 36 additions & 0 deletions src/tests/factory/factory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable no-undef */
import { describe } from '@jest/globals';
import Kernel from '@src/core/Kernel';
import testAppConfig from '@src/tests/config/testConfig';

import TestDatabaseProvider from '../providers/TestDatabaseProvider';
import TestMovieFactory from './TestMovieFaker';

describe('test migrations', () => {


beforeAll(async () => {
await Kernel.boot({
...testAppConfig,
providers: [
...testAppConfig.providers,
new TestDatabaseProvider()
]
}, {})


});


test('test factory', async () => {
const factory = new TestMovieFactory();
const movie = factory.createFakeMovie();

expect(movie).toBeTruthy();
expect(typeof movie.getAttribute('authorId') === 'string').toEqual(true);
expect(typeof movie.getAttribute('name') === 'string').toEqual(true);
expect(typeof movie.getAttribute('yearReleased') === 'number').toEqual(true);
expect(movie.getAttribute('createdAt') instanceof Date).toEqual(true);
expect(movie.getAttribute('updatedAt') instanceof Date).toEqual(true);
});
});
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,11 @@
dependencies:
levn "^0.4.1"

"@faker-js/faker@^9.0.3":
version "9.0.3"
resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-9.0.3.tgz#be817db896b07d1716bc65d9aad1ba587b499826"
integrity sha512-lWrrK4QNlFSU+13PL9jMbMKLJYXDFu3tQfayBsMXX7KL/GiQeqfB1CzHkqD5UHBUtPAuPo6XwGbMFNdVMZObRA==

"@gar/promisify@^1.0.1":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
Expand Down