Skip to content

Commit

Permalink
Create effects concept (#117)
Browse files Browse the repository at this point in the history
* Create effects concept

* Fix effecthelper to test if EffectHelper is undefined instead of null
  • Loading branch information
Vylpes authored Nov 19, 2024
1 parent 32020c7 commit eed5ce4
Show file tree
Hide file tree
Showing 10 changed files with 525 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE `user_effect`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CREATE TABLE `user_effect` (
`Id` varchar(255) NOT NULL,
`WhenCreated` datetime NOT NULL,
`WhenUpdated` datetime NOT NULL,
`Name` varchar(255) NOT NULL,
`UserId` varchar(255) NOT NULL,
`Unused` int NOT NULL DEFAULT 0,
`WhenExpires` datetime NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
3 changes: 2 additions & 1 deletion jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
jest.setTimeout(1 * 1000); // 1 second
jest.resetModules();
jest.resetAllMocks();
jest.resetAllMocks();
jest.useFakeTimers();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"clean": "rm -rf node_modules/ dist/",
"build": "tsc",
"start": "node ./dist/bot.js",
"test": "echo true",
"test": "jest",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js",
Expand Down
60 changes: 60 additions & 0 deletions src/database/entities/app/UserEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {Column, Entity} from "typeorm";
import AppBaseEntity from "../../../contracts/AppBaseEntity";
import AppDataSource from "../../dataSources/appDataSource";

@Entity()
export default class UserEffect extends AppBaseEntity {
constructor(name: string, userId: string, unused: number, WhenExpires?: Date) {
super();

this.Name = name;
this.UserId = userId;
this.Unused = unused;
this.WhenExpires = WhenExpires;
}

@Column()
Name: string;

@Column()
UserId: string;

@Column()
Unused: number;

@Column({ nullable: true })
WhenExpires?: Date;

public AddUnused(amount: number) {
this.Unused += amount;
}

public UseEffect(whenExpires: Date): boolean {
if (this.Unused == 0) {
return false;
}

this.Unused -= 1;
this.WhenExpires = whenExpires;

return true;
}

public IsEffectActive(): boolean {
const now = new Date();

if (this.WhenExpires && now < this.WhenExpires) {
return true;
}

return false;
}

public static async FetchOneByUserIdAndName(userId: string, name: string): Promise<UserEffect | null> {
const repository = AppDataSource.getRepository(UserEffect);

const single = await repository.findOne({ where: { UserId: userId, Name: name } });

return single;
}
}
18 changes: 18 additions & 0 deletions src/database/migrations/app/0.9/1729962056556-createUserEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { MigrationInterface, QueryRunner } from "typeorm";
import MigrationHelper from "../../../../helpers/MigrationHelper";

export class CreateUserEffect1729962056556 implements MigrationInterface {

public async up(queryRunner: QueryRunner): Promise<void> {
MigrationHelper.Up("1729962056556-createUserEffect", "0.9", [
"01-table-userEffect",
], queryRunner);
}

public async down(queryRunner: QueryRunner): Promise<void> {
MigrationHelper.Down("1729962056556-createUserEffect", "0.9", [
"01-table-userEffect",
], queryRunner);
}

}
49 changes: 49 additions & 0 deletions src/helpers/EffectHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import UserEffect from "../database/entities/app/UserEffect";

export default class EffectHelper {
public static async AddEffectToUserInventory(userId: string, name: string, quantity: number = 1) {
let effect = await UserEffect.FetchOneByUserIdAndName(userId, name);

if (!effect) {
effect = new UserEffect(name, userId, quantity);
} else {
effect.AddUnused(quantity);
}

await effect.Save(UserEffect, effect);
}

public static async UseEffect(userId: string, name: string, whenExpires: Date): Promise<boolean> {
const effect = await UserEffect.FetchOneByUserIdAndName(userId, name);
const now = new Date();

if (!effect || effect.Unused == 0) {
return false;
}

if (effect.WhenExpires && now < effect.WhenExpires) {
return false;
}

effect.UseEffect(whenExpires);

await effect.Save(UserEffect, effect);

return true;
}

public static async HasEffect(userId: string, name: string): Promise<boolean> {
const effect = await UserEffect.FetchOneByUserIdAndName(userId, name);
const now = new Date();

if (!effect || !effect.WhenExpires) {
return false;
}

if (now > effect.WhenExpires) {
return false;
}

return true;
}
}
103 changes: 103 additions & 0 deletions tests/database/entities/app/UserEffect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import UserEffect from "../../../../src/database/entities/app/UserEffect";

let userEffect: UserEffect;
const now = new Date();

beforeEach(() => {
userEffect = new UserEffect("name", "userId", 1);
});

describe("AddUnused", () => {
beforeEach(() => {
userEffect.AddUnused(1);
});

test("EXPECT unused to be the amount more", () => {
expect(userEffect.Unused).toBe(2);
});
});

describe("UseEffect", () => {
describe("GIVEN Unused is 0", () => {
let result: boolean;

beforeEach(() => {
userEffect.Unused = 0;

result = userEffect.UseEffect(now);
});

test("EXPECT false returned", () => {
expect(result).toBe(false);
});

test("EXPECT details not to be changed", () => {
expect(userEffect.Unused).toBe(0);
expect(userEffect.WhenExpires).toBeUndefined();
});
});

describe("GIVEN Unused is greater than 0", () => {
let result: boolean;

beforeEach(() => {
result = userEffect.UseEffect(now);
});

test("EXPECT true returned", () => {
expect(result).toBe(true);
});

test("EXPECT Unused to be subtracted by 1", () => {
expect(userEffect.Unused).toBe(0);
});

test("EXPECT WhenExpires to be set", () => {
expect(userEffect.WhenExpires).toBe(now);
});
});
});

describe("IsEffectActive", () => {
describe("GIVEN WhenExpires is null", () => {
let result: boolean;

beforeEach(() => {
result = userEffect.IsEffectActive();
});

test("EXPECT false returned", () => {
expect(result).toBe(false);
});
});

describe("GIVEN WhenExpires is defined", () => {
describe("AND WhenExpires is in the past", () => {
let result: boolean;

beforeEach(() => {
userEffect.WhenExpires = new Date(now.getTime() - 100);

result = userEffect.IsEffectActive();
});

test("EXPECT false returned", () => {
expect(result).toBe(false);
});
});

describe("AND WhenExpires is in the future", () => {
let result: boolean;

beforeEach(() => {
userEffect.WhenExpires = new Date(now.getTime() + 100);

result = userEffect.IsEffectActive();
});

test("EXPECT true returned", () => {
expect(result).toBe(true);
});
});
});
});
Loading

0 comments on commit eed5ce4

Please sign in to comment.