diff --git a/src/__tests__/box/data/box/BoxBuilder.ts b/src/__tests__/box/data/box/BoxBuilder.ts new file mode 100644 index 00000000..87d743a6 --- /dev/null +++ b/src/__tests__/box/data/box/BoxBuilder.ts @@ -0,0 +1,110 @@ +import {SessionStage} from "../../../../box/enum/SessionStage.enum"; +import {Box} from "../../../../box/schemas/box.schema"; +import {ObjectId} from "mongodb"; +import {Tester} from "../../../../box/schemas/tester.schema"; +import {DailyTask} from "../../../../dailyTasks/dailyTasks.schema"; + +export default class BoxBuilder { + private readonly base: Partial = { + adminPassword: 'defaultAdminPassword', + sessionStage: SessionStage.PREPARING, + testersSharedPassword: null, + boxRemovalTime: Date.now() + 1000000, + sessionResetTime: Date.now() + 500000, + adminProfile_id: null, + adminPlayer_id: null, + clan_ids: [], + soulHome_ids: [], + room_ids: [], + stock_ids: [], + chat_id: null, + testers: [], + accountClaimersIds: [], + dailyTasks: [], + _id: null + }; + + build(): Box { + return { ...this.base } as Box; + } + + setAdminPassword(password: string) { + this.base.adminPassword = password; + return this; + } + + setSessionStage(stage: SessionStage) { + this.base.sessionStage = stage; + return this; + } + + setTestersSharedPassword(password: string | null) { + this.base.testersSharedPassword = password; + return this; + } + + setBoxRemovalTime(time: number) { + this.base.boxRemovalTime = time; + return this; + } + + setSessionResetTime(time: number) { + this.base.sessionResetTime = time; + return this; + } + + setAdminProfileId(profileId: ObjectId) { + this.base.adminProfile_id = profileId; + return this; + } + + setAdminPlayerId(playerId: ObjectId) { + this.base.adminPlayer_id = playerId; + return this; + } + + setClanIds(clanIds: ObjectId[]) { + this.base.clan_ids = clanIds; + return this; + } + + setSoulHomeIds(soulHomeIds: ObjectId[]) { + this.base.soulHome_ids = soulHomeIds; + return this; + } + + setRoomIds(roomIds: ObjectId[]) { + this.base.room_ids = roomIds; + return this; + } + + setStockIds(stockIds: ObjectId[]) { + this.base.stock_ids = stockIds; + return this; + } + + setChatId(chatId: ObjectId) { + this.base.chat_id = chatId; + return this; + } + + setTesters(testers: Tester[]) { + this.base.testers = testers; + return this; + } + + setAccountClaimersIds(accountClaimersIds: string[]) { + this.base.accountClaimersIds = accountClaimersIds; + return this; + } + + setDailyTasks(dailyTasks: DailyTask[]) { + this.base.dailyTasks = dailyTasks; + return this; + } + + setId(id: ObjectId) { + this.base._id = id; + return this; + } +} diff --git a/src/__tests__/box/data/box/CreateBoxDtoBuilder.ts b/src/__tests__/box/data/box/CreateBoxDtoBuilder.ts new file mode 100644 index 00000000..4583a82f --- /dev/null +++ b/src/__tests__/box/data/box/CreateBoxDtoBuilder.ts @@ -0,0 +1,105 @@ +import {SessionStage} from "../../../../box/enum/SessionStage.enum"; +import {ObjectId} from "mongodb"; +import {Tester} from "../../../../box/schemas/tester.schema"; +import {DailyTask} from "../../../../dailyTasks/dailyTasks.schema"; +import {CreateBoxDto} from "../../../../box/dto/createBox.dto"; + + +export default class CreateBoxDtoBuilder { + private readonly base: Partial = { + adminPassword: 'defaultAdminPassword', + sessionStage: SessionStage.PREPARING, + testersSharedPassword: null, + boxRemovalTime: Date.now() + 1000000, + sessionResetTime: Date.now() + 500000, + adminProfile_id: null, + adminPlayer_id: null, + clan_ids: [], + soulHome_ids: [], + room_ids: [], + stock_ids: [], + chat_id: null, + testers: [], + accountClaimersIds: [], + dailyTasks: [], + }; + + build(): CreateBoxDto { + return { ...this.base } as CreateBoxDto; + } + + setAdminPassword(password: string) { + this.base.adminPassword = password; + return this; + } + + setSessionStage(stage: SessionStage) { + this.base.sessionStage = stage; + return this; + } + + setTestersSharedPassword(password: string | null) { + this.base.testersSharedPassword = password; + return this; + } + + setBoxRemovalTime(time: number) { + this.base.boxRemovalTime = time; + return this; + } + + setSessionResetTime(time: number) { + this.base.sessionResetTime = time; + return this; + } + + setAdminProfileId(profileId: ObjectId) { + this.base.adminProfile_id = profileId; + return this; + } + + setAdminPlayerId(playerId: ObjectId) { + this.base.adminPlayer_id = playerId; + return this; + } + + setClanIds(clanIds: ObjectId[]) { + this.base.clan_ids = clanIds; + return this; + } + + setSoulHomeIds(soulHomeIds: ObjectId[]) { + this.base.soulHome_ids = soulHomeIds; + return this; + } + + setRoomIds(roomIds: ObjectId[]) { + this.base.room_ids = roomIds; + return this; + } + + setStockIds(stockIds: ObjectId[]) { + this.base.stock_ids = stockIds; + return this; + } + + setChatId(chatId: ObjectId) { + this.base.chat_id = chatId; + return this; + } + + setTesters(testers: Tester[]) { + this.base.testers = testers; + return this; + } + + setAccountClaimersIds(accountClaimersIds: string[]) { + this.base.accountClaimersIds = accountClaimersIds; + return this; + } + + setDailyTasks(dailyTasks: DailyTask[]) { + this.base.dailyTasks = dailyTasks; + return this; + } +} diff --git a/src/__tests__/box/data/box/GroupAdminBuilder.ts b/src/__tests__/box/data/box/GroupAdminBuilder.ts new file mode 100644 index 00000000..90f39ec9 --- /dev/null +++ b/src/__tests__/box/data/box/GroupAdminBuilder.ts @@ -0,0 +1,23 @@ +import {ObjectId} from "mongodb"; +import {GroupAdmin} from "../../../../box/schemas/groupAdmin.schema"; + +export default class GroupAdminBuilder { + private readonly base: Partial = { + password: 'defaultPassword', + _id: null, + }; + + build(): GroupAdmin { + return { ...this.base } as GroupAdmin; + } + + setPassword(password: string) { + this.base.password = password; + return this; + } + + setId(id: ObjectId) { + this.base._id = id; + return this; + } +} diff --git a/src/__tests__/box/data/box/UpdateBoxDtoBuilder.ts b/src/__tests__/box/data/box/UpdateBoxDtoBuilder.ts new file mode 100644 index 00000000..7ab56474 --- /dev/null +++ b/src/__tests__/box/data/box/UpdateBoxDtoBuilder.ts @@ -0,0 +1,111 @@ +import {UpdateBoxDto} from "../../../../box/dto/updateBox.dto"; +import {SessionStage} from "../../../../box/enum/SessionStage.enum"; +import {ObjectId} from "mongodb"; +import {Tester} from "../../../../box/schemas/tester.schema"; +import {DailyTask} from "../../../../dailyTasks/dailyTasks.schema"; + + +export default class UpdateBoxDtoBuilder { + private readonly base: Partial = { + _id: null, + adminPassword: null, + sessionStage: null, + testersSharedPassword: null, + boxRemovalTime: null, + sessionResetTime: null, + adminProfile_id: null, + adminPlayer_id: null, + clan_ids: null, + soulHome_ids: null, + room_ids: null, + stock_ids: null, + chat_id: null, + testers: null, + accountClaimersIds: null, + dailyTasks: null, + }; + + build(): UpdateBoxDto { + return { ...this.base } as UpdateBoxDto; + } + + setId(id: string) { + this.base._id = id; + return this; + } + + setAdminPassword(password: string) { + this.base.adminPassword = password; + return this; + } + + setSessionStage(stage: SessionStage) { + this.base.sessionStage = stage; + return this; + } + + setTestersSharedPassword(password: string | null) { + this.base.testersSharedPassword = password; + return this; + } + + setBoxRemovalTime(time: number) { + this.base.boxRemovalTime = time; + return this; + } + + setSessionResetTime(time: number) { + this.base.sessionResetTime = time; + return this; + } + + setAdminProfileId(profileId: ObjectId) { + this.base.adminProfile_id = profileId; + return this; + } + + setAdminPlayerId(playerId: ObjectId) { + this.base.adminPlayer_id = playerId; + return this; + } + + setClanIds(clanIds: ObjectId[]) { + this.base.clan_ids = clanIds; + return this; + } + + setSoulHomeIds(soulHomeIds: ObjectId[]) { + this.base.soulHome_ids = soulHomeIds; + return this; + } + + setRoomIds(roomIds: ObjectId[]) { + this.base.room_ids = roomIds; + return this; + } + + setStockIds(stockIds: ObjectId[]) { + this.base.stock_ids = stockIds; + return this; + } + + setChatId(chatId: ObjectId) { + this.base.chat_id = chatId; + return this; + } + + setTesters(testers: Tester[]) { + this.base.testers = testers; + return this; + } + + setAccountClaimersIds(accountClaimersIds: string[]) { + this.base.accountClaimersIds = accountClaimersIds; + return this; + } + + setDailyTasks(dailyTasks: DailyTask[]) { + this.base.dailyTasks = dailyTasks; + return this; + } +} diff --git a/src/__tests__/box/data/boxBuilderFactory.ts b/src/__tests__/box/data/boxBuilderFactory.ts new file mode 100644 index 00000000..e5592a66 --- /dev/null +++ b/src/__tests__/box/data/boxBuilderFactory.ts @@ -0,0 +1,31 @@ +import BoxBuilder from "./box/BoxBuilder"; +import CreateBoxDtoBuilder from "./box/CreateBoxDtoBuilder"; +import UpdateBoxDtoBuilder from "./box/UpdateBoxDtoBuilder"; +import GroupAdminBuilder from "./box/GroupAdminBuilder"; + + +type BuilderName = 'Box' | 'CreateBoxDto' | 'UpdateBoxDto' | 'GroupAdmin'; + +type BuilderMap = { + Box: BoxBuilder, + CreateBoxDto: CreateBoxDtoBuilder, + UpdateBoxDto: UpdateBoxDtoBuilder, + GroupAdmin: GroupAdminBuilder +}; + +export default class BoxBuilderFactory { + static getBuilder(builderName: T): BuilderMap[T] { + switch (builderName) { + case 'Box': + return new BoxBuilder() as BuilderMap[T]; + case 'CreateBoxDto': + return new CreateBoxDtoBuilder() as BuilderMap[T]; + case 'UpdateBoxDto': + return new UpdateBoxDtoBuilder() as BuilderMap[T]; + case 'GroupAdmin': + return new GroupAdminBuilder() as BuilderMap[T]; + default: + throw new Error(`Unknown builder name: ${builderName}`); + } + } +} \ No newline at end of file diff --git a/src/__tests__/box/modules/box.module.ts b/src/__tests__/box/modules/box.module.ts new file mode 100644 index 00000000..d875c3e0 --- /dev/null +++ b/src/__tests__/box/modules/box.module.ts @@ -0,0 +1,23 @@ +import mongoose from "mongoose"; +import BoxCommonModule from "./boxCommon"; +import { ModelName } from "../../../common/enum/modelName.enum"; +import {BoxService} from "../../../box/box.service"; +import {BoxSchema} from "../../../box/schemas/box.schema"; +import {GroupAdminSchema} from "../../../box/schemas/groupAdmin.schema"; + +export default class BoxModule { + private constructor() {} + + static async getBoxService(){ + const module = await BoxCommonModule.getModule(); + return module.resolve(BoxService); + } + + static getBoxModel(){ + return mongoose.model(ModelName.BOX, BoxSchema); + } + + static getGroupAdminModel(){ + return mongoose.model(ModelName.GROUP_ADMIN, GroupAdminSchema); + } +} diff --git a/src/__tests__/box/modules/boxCommon.ts b/src/__tests__/box/modules/boxCommon.ts new file mode 100644 index 00000000..6415f39e --- /dev/null +++ b/src/__tests__/box/modules/boxCommon.ts @@ -0,0 +1,34 @@ +import {Test, TestingModule} from '@nestjs/testing'; +import {MongooseModule} from '@nestjs/mongoose'; +import {ModelName} from '../../../common/enum/modelName.enum'; +import {mongooseOptions, mongoString} from '../../test_utils/const/db'; +import {BoxSchema} from "../../../box/schemas/box.schema"; +import {GroupAdminSchema} from "../../../box/schemas/groupAdmin.schema"; +import {BoxService} from "../../../box/box.service"; + + +export default class BoxCommonModule { + private constructor() { + } + + private static module: TestingModule; + + static async getModule() { + if (!BoxCommonModule.module) + BoxCommonModule.module = await Test.createTestingModule({ + imports: [ + MongooseModule.forRoot(mongoString, mongooseOptions), + MongooseModule.forFeature([ + { name: ModelName.BOX, schema: BoxSchema }, + { name: ModelName.GROUP_ADMIN, schema: GroupAdminSchema } + ]), + + ], + providers: [ + BoxService + ] + }).compile(); + + return BoxCommonModule.module; + } +} \ No newline at end of file diff --git a/src/__tests__/box/util/isTestingSession.test.ts b/src/__tests__/box/util/isTestingSession.test.ts new file mode 100644 index 00000000..a0323b3a --- /dev/null +++ b/src/__tests__/box/util/isTestingSession.test.ts @@ -0,0 +1,14 @@ +import {envVars} from "../../../common/service/envHandler/envVars"; +import isTestingSession from "../../../box/util/isTestingSession"; + +describe('isTestingSession() test suite', () => { + it('Should return true when environment variable is set to TESTING_SESSION', () => { + envVars.ENVIRONMENT = 'TESTING_SESSION'; + expect(isTestingSession()).toBeTruthy(); + }); + + it('Should return false when environment variable is not set to TESTING_SESSION', () => { + envVars.ENVIRONMENT = 'OTHER_ENVIRONMENT'; + expect(isTestingSession()).toBeFalsy(); + }); +}); \ No newline at end of file diff --git a/src/box/dto/box.dto.ts b/src/box/dto/box.dto.ts index 7cdd5936..bfba1921 100644 --- a/src/box/dto/box.dto.ts +++ b/src/box/dto/box.dto.ts @@ -1,7 +1,7 @@ import {Expose, Type} from "class-transformer"; import {ExtractField} from "../../common/decorator/response/ExtractField"; import {SessionStage} from "../enum/SessionStage.enum"; -import {ObjectId} from "mongoose"; +import {ObjectId} from "mongodb"; import {Tester} from "../schemas/tester.schema"; import {DailyTask} from "../../dailyTasks/dailyTasks.schema"; diff --git a/src/box/dto/createBox.dto.ts b/src/box/dto/createBox.dto.ts index 0c788903..dd10aac1 100644 --- a/src/box/dto/createBox.dto.ts +++ b/src/box/dto/createBox.dto.ts @@ -7,7 +7,7 @@ import { ValidateNested } from "class-validator"; import {SessionStage} from "../enum/SessionStage.enum"; -import { ObjectId } from "mongoose"; +import { ObjectId } from "mongodb"; import { Tester } from "../schemas/tester.schema"; import {Type} from "class-transformer"; import {DailyTask} from "../../dailyTasks/dailyTasks.schema"; diff --git a/src/box/dto/updateBox.dto.ts b/src/box/dto/updateBox.dto.ts index 4df8d75f..1198609d 100644 --- a/src/box/dto/updateBox.dto.ts +++ b/src/box/dto/updateBox.dto.ts @@ -1,6 +1,6 @@ import {IsArray, IsEnum, IsMongoId, IsNumber, IsOptional, IsString, ValidateNested} from "class-validator"; import {SessionStage} from "../enum/SessionStage.enum"; -import {ObjectId} from "mongoose"; +import {ObjectId} from "mongodb"; import {Type} from "class-transformer"; import {Tester} from "../schemas/tester.schema"; import {DailyTask} from "../../dailyTasks/dailyTasks.schema"; diff --git a/src/box/util/isTestingSession.ts b/src/box/util/isTestingSession.ts new file mode 100644 index 00000000..5bc780a4 --- /dev/null +++ b/src/box/util/isTestingSession.ts @@ -0,0 +1,10 @@ +import {envVars} from "../../common/service/envHandler/envVars"; + +/** + * Determines whenever the API runs in testing session environment + * + * @return true if in testing environment or false if not + */ +export default function isTestingSession() { + return envVars.ENVIRONMENT === 'TESTING_SESSION'; +} diff --git a/src/common/service/envHandler/envVars.ts b/src/common/service/envHandler/envVars.ts index cc4793e2..3b9b1768 100644 --- a/src/common/service/envHandler/envVars.ts +++ b/src/common/service/envHandler/envVars.ts @@ -1,13 +1,14 @@ import * as dotenv from "dotenv"; +import * as process from "node:process"; dotenv.config(); // Please remember to add env name here, before you add it to the record type EnvName = - 'PORT' | 'JWT_SECRET' | 'JWT_EXPIRES' | 'PSW_MEMORY' | 'PSW_TIME' | 'PSW_PARALLELISM' | - 'MONGO_USERNAME' | 'MONGO_PASSWORD' | 'MONGO_HOST' | 'MONGO_PORT' | 'MONGO_DB_NAME' | - 'OWNCLOUD_HOST' | 'OWNCLOUD_PORT' | 'OWNCLOUD_USER' | 'OWNCLOUD_PASSWORD' | 'OWNCLOUD_LOG_FILES_SECRET' | 'OWNCLOUD_LOG_FILES_ROOT' | - 'REDIS_PASSWORD' | 'REDIS_HOST' | 'REDIS_PORT' | + 'PORT' | 'JWT_SECRET' | 'JWT_EXPIRES' | 'PSW_MEMORY' | 'PSW_TIME' | 'PSW_PARALLELISM' | 'ENVIRONMENT' | + 'MONGO_USERNAME' | 'MONGO_PASSWORD' | 'MONGO_HOST' | 'MONGO_PORT' | 'MONGO_DB_NAME' | + 'OWNCLOUD_HOST' | 'OWNCLOUD_PORT' | 'OWNCLOUD_USER' | 'OWNCLOUD_PASSWORD' | 'OWNCLOUD_LOG_FILES_SECRET' | 'OWNCLOUD_LOG_FILES_ROOT' | + 'REDIS_PASSWORD' | 'REDIS_HOST' | 'REDIS_PORT' | 'MOSQUITTO_HOST' | 'MOSQUITTO_PORT' | 'MOSQUITTO_SUBSCRIBER' | 'MOSQUITTO_SUBSCRIBER_PASSWORD' | 'MOSQUITTO_PUBLISHER' | 'MOSQUITTO_PUBLISHER_PASSWORD'; /** @@ -18,6 +19,7 @@ type EnvName = * @property PSW_MEMORY - Password setting. * @property PSW_TIME - Password setting. * @property PSW_PARALLELISM - Password setting. + * @property ENVIRONMENT - Environment where the API runs, 'PRODUCTION' | 'TESTING_SESSION', default is PRODUCTION * @property MONGO_USERNAME - The username for MongoDB authentication. * @property MONGO_PASSWORD - The password for MongoDB authentication. * @property MONGO_HOST - The MongoDB host address. @@ -46,6 +48,7 @@ export const envVars: Record = { PSW_MEMORY: process.env.PSW_MEMORY, PSW_TIME: process.env.PSW_TIME, PSW_PARALLELISM: process.env.PSW_PARALLELISM, + ENVIRONMENT: process.env.ENVIRONMENT ?? 'PRODUCTION', MONGO_USERNAME: process.env.MONGO_USERNAME, MONGO_PASSWORD: process.env.MONGO_PASSWORD,