Add friendly name and active effect to user effect list embed #422
5 changed files with 361 additions and 21 deletions
|
@ -63,7 +63,7 @@ export default class UserEffect extends AppBaseEntity {
|
||||||
|
|
||||||
const query = await repository.createQueryBuilder("effect")
|
const query = await repository.createQueryBuilder("effect")
|
||||||
.where("effect.UserId = :userId", { userId })
|
.where("effect.UserId = :userId", { userId })
|
||||||
.where("effect.Unused > 0")
|
.andWhere("effect.Unused > 0")
|
||||||
.orderBy("effect.Name", "ASC")
|
.orderBy("effect.Name", "ASC")
|
||||||
.skip(page * itemsPerPage)
|
.skip(page * itemsPerPage)
|
||||||
.take(itemsPerPage)
|
.take(itemsPerPage)
|
||||||
|
@ -71,4 +71,16 @@ export default class UserEffect extends AppBaseEntity {
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async FetchActiveEffectByUserId(userId: string): Promise<UserEffect | null> {
|
||||||
|
const repository = AppDataSource.getRepository(UserEffect);
|
||||||
|
|
||||||
|
const query = await repository.createQueryBuilder("effect")
|
||||||
|
.where("effect.UserId = :userId", { userId })
|
||||||
|
.andWhere("effect.WhenExpires IS NOT NULL")
|
||||||
|
.andWhere("effect.WhenExpires > :now", { now: new Date() })
|
||||||
|
.getOne();
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ export default class EffectHelper {
|
||||||
const itemsPerPage = 10;
|
const itemsPerPage = 10;
|
||||||
|
|
||||||
const query = await UserEffect.FetchAllByUserIdPaginated(userId, page - 1, itemsPerPage);
|
const query = await UserEffect.FetchAllByUserIdPaginated(userId, page - 1, itemsPerPage);
|
||||||
|
const activeEffect = await UserEffect.FetchActiveEffectByUserId(userId);
|
||||||
|
|
||||||
const effects = query[0];
|
const effects = query[0];
|
||||||
const count = query[1];
|
const count = query[1];
|
||||||
|
@ -82,7 +83,7 @@ export default class EffectHelper {
|
||||||
let description = "*none*";
|
let description = "*none*";
|
||||||
|
|
||||||
if (effects.length > 0) {
|
if (effects.length > 0) {
|
||||||
description = effects.map(x => `${x.Name} x${x.Unused}`).join("\n");
|
description = effects.map(x => `${EffectDetails.get(x.Name)?.friendlyName} x${x.Unused}`).join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
|
@ -91,6 +92,21 @@ export default class EffectHelper {
|
||||||
.setColor(EmbedColours.Ok)
|
.setColor(EmbedColours.Ok)
|
||||||
.setFooter({ text: `Page ${page} of ${totalPages}` });
|
.setFooter({ text: `Page ${page} of ${totalPages}` });
|
||||||
|
|
||||||
|
if (activeEffect) {
|
||||||
|
embed.addFields([
|
||||||
|
{
|
||||||
|
name: "Active",
|
||||||
|
value: `${EffectDetails.get(activeEffect.Name)?.friendlyName}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Expires",
|
||||||
|
value: `<t:${Math.round(activeEffect.WhenExpires!.getTime() / 1000)}>`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
.addComponents(
|
.addComponents(
|
||||||
new ButtonBuilder()
|
new ButtonBuilder()
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
describe("GetRandomCardUnclaimed", () => {
|
|
||||||
test.todo("GIVEN chance is within bronze chance, EXPECT bronze card returned");
|
|
||||||
|
|
||||||
test.todo("GIVEN chance is within silver chance, EXPECT silver card");
|
|
||||||
|
|
||||||
test.todo("GIVEN chance is within gold chance, EXPECT gold card returned");
|
|
||||||
|
|
||||||
test.todo("GIVEN chance is within manga chance, EXPECT manga card returned");
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("GetRandomCardByRarityUnclaimed", () => {
|
|
||||||
test.todo("GIVEN user has no claimed cards, EXPECT random card returned");
|
|
||||||
|
|
||||||
test.todo("GIVEN no cards are found in memory, EXPECT undefined returned");
|
|
||||||
|
|
||||||
test.todo("GIVEN no series metadata is found for random card, EXPECT undefined returned");
|
|
||||||
|
|
||||||
test.todo("GIVEN user has claimed cards, EXPECT random card to NOT be this card");
|
|
||||||
});
|
|
115
tests/helpers/EffectHelper.test.ts
Normal file
115
tests/helpers/EffectHelper.test.ts
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
import EffectHelper from "../../src/helpers/EffectHelper";
|
||||||
|
import UserEffect from "../../src/database/entities/app/UserEffect";
|
||||||
|
|
||||||
|
jest.mock("../../src/database/entities/app/UserEffect");
|
||||||
|
|
||||||
|
describe("GenerateEffectEmbed", () => {
|
||||||
|
test("GIVEN user has an effect, EXPECT detailed embed to be returned", async () => {
|
||||||
|
// Arrange
|
||||||
|
(UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
Name: "unclaimed",
|
||||||
|
Unused: 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await EffectHelper.GenerateEffectEmbed("userId", 1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN user has more than 1 page of effects, EXPECT pagination enabled", async () => {
|
||||||
|
const effects: {
|
||||||
|
Name: string,
|
||||||
|
Unused: number,
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 15; i++) {
|
||||||
|
effects.push({
|
||||||
|
Name: "unclaimed",
|
||||||
|
Unused: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
(UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([
|
||||||
|
effects,
|
||||||
|
15,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await EffectHelper.GenerateEffectEmbed("userId", 1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN user is on a page other than 1, EXPECT pagination enabled", async () => {
|
||||||
|
const effects: {
|
||||||
|
Name: string,
|
||||||
|
Unused: number,
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < 15; i++) {
|
||||||
|
effects.push({
|
||||||
|
Name: "unclaimed",
|
||||||
|
Unused: 1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
(UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([
|
||||||
|
effects,
|
||||||
|
15,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await EffectHelper.GenerateEffectEmbed("userId", 2);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN user does NOT have an effect, EXPECT empty embed to be returned", async () => {
|
||||||
|
// Arrange
|
||||||
|
(UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([
|
||||||
|
[],
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await EffectHelper.GenerateEffectEmbed("userId", 1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("GIVEN there is an active effect, EXPECT field added", async () => {
|
||||||
|
// Arrange
|
||||||
|
(UserEffect.FetchAllByUserIdPaginated as jest.Mock).mockResolvedValue([
|
||||||
|
[
|
||||||
|
{
|
||||||
|
Name: "unclaimed",
|
||||||
|
Unused: 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
(UserEffect.FetchActiveEffectByUserId as jest.Mock).mockResolvedValue({
|
||||||
|
Name: "unclaimed",
|
||||||
|
WhenExpires: new Date(1738174052),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = await EffectHelper.GenerateEffectEmbed("userId", 1);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
216
tests/helpers/__snapshots__/EffectHelper.test.ts.snap
Normal file
216
tests/helpers/__snapshots__/EffectHelper.test.ts.snap
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`GenerateEffectEmbed GIVEN there is an active effect, EXPECT field added 1`] = `
|
||||||
|
{
|
||||||
|
"embed": {
|
||||||
|
"color": 3166394,
|
||||||
|
"description": "Unclaimed Chance Up x1",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"inline": true,
|
||||||
|
"name": "Active",
|
||||||
|
"value": "Unclaimed Chance Up",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inline": true,
|
||||||
|
"name": "Expires",
|
||||||
|
"value": "<t:1738174>",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"footer": {
|
||||||
|
"icon_url": undefined,
|
||||||
|
"text": "Page 1 of 1",
|
||||||
|
},
|
||||||
|
"title": "Effects",
|
||||||
|
},
|
||||||
|
"row": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 0",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Previous",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 2",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Next",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"type": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GenerateEffectEmbed GIVEN user does NOT have an effect, EXPECT empty embed to be returned 1`] = `
|
||||||
|
{
|
||||||
|
"embed": {
|
||||||
|
"color": 3166394,
|
||||||
|
"description": "*none*",
|
||||||
|
"footer": {
|
||||||
|
"icon_url": undefined,
|
||||||
|
"text": "Page 1 of 1",
|
||||||
|
},
|
||||||
|
"title": "Effects",
|
||||||
|
},
|
||||||
|
"row": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 0",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Previous",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 2",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Next",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"type": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GenerateEffectEmbed GIVEN user has an effect, EXPECT detailed embed to be returned 1`] = `
|
||||||
|
{
|
||||||
|
"embed": {
|
||||||
|
"color": 3166394,
|
||||||
|
"description": "Unclaimed Chance Up x1",
|
||||||
|
"footer": {
|
||||||
|
"icon_url": undefined,
|
||||||
|
"text": "Page 1 of 1",
|
||||||
|
},
|
||||||
|
"title": "Effects",
|
||||||
|
},
|
||||||
|
"row": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 0",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Previous",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 2",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Next",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"type": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GenerateEffectEmbed GIVEN user has more than 1 page of effects, EXPECT pagination enabled 1`] = `
|
||||||
|
{
|
||||||
|
"embed": {
|
||||||
|
"color": 3166394,
|
||||||
|
"description": "Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1",
|
||||||
|
"footer": {
|
||||||
|
"icon_url": undefined,
|
||||||
|
"text": "Page 1 of 2",
|
||||||
|
},
|
||||||
|
"title": "Effects",
|
||||||
|
},
|
||||||
|
"row": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 0",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Previous",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 2",
|
||||||
|
"disabled": false,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Next",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"type": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GenerateEffectEmbed GIVEN user is on a page other than 1, EXPECT pagination enabled 1`] = `
|
||||||
|
{
|
||||||
|
"embed": {
|
||||||
|
"color": 3166394,
|
||||||
|
"description": "Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1
|
||||||
|
Unclaimed Chance Up x1",
|
||||||
|
"footer": {
|
||||||
|
"icon_url": undefined,
|
||||||
|
"text": "Page 2 of 2",
|
||||||
|
},
|
||||||
|
"title": "Effects",
|
||||||
|
},
|
||||||
|
"row": {
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 1",
|
||||||
|
"disabled": false,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Previous",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"custom_id": "effects list 3",
|
||||||
|
"disabled": true,
|
||||||
|
"emoji": undefined,
|
||||||
|
"label": "Next",
|
||||||
|
"style": 1,
|
||||||
|
"type": 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"type": 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
Loading…
Reference in a new issue