WIP: Update the drop mechanic to take currency on drop instead of claim #428

Draft
Vylpes wants to merge 6 commits from feature/CD-415 into develop
13 changed files with 42 additions and 52 deletions

View file

@ -1,7 +1,6 @@
import { ButtonInteraction } from "discord.js";
import { ButtonEvent } from "../type/buttonEvent";
import Inventory from "../database/entities/app/Inventory";
import { CoreClient } from "../client/client";
import { default as eClaim } from "../database/entities/app/Claim";
import AppLogger from "../client/appLogger";
import User from "../database/entities/app/User";
@ -23,10 +22,10 @@ export default class Claim extends ButtonEvent {
const userId = interaction.user.id;
const whenDropped = interaction.message.createdAt;
const lastClaimableDate = new Date(Date.now() - (1000 * 60 * 5)); // 5 minutes ago
const lastClaimableDate = new Date(Date.now() - (1000 * 60 * 2)); // 2 minutes ago
if (whenDropped < lastClaimableDate) {
await interaction.channel.send(`${interaction.user}, Cards can only be claimed within 5 minutes of it being dropped!`);
await interaction.channel.send(`${interaction.user}, Cards can only be claimed within 2 minutes of it being dropped!`);
return;
}
@ -36,11 +35,6 @@ export default class Claim extends ButtonEvent {
AppLogger.LogSilly("Button/Claim", `${user.Id} has ${user.Currency} currency`);
if (!user.RemoveCurrency(CardConstants.ClaimCost)) {
await interaction.channel.send(`${interaction.user}, Not enough currency! You need ${CardConstants.ClaimCost} currency, you have ${user.Currency}!`);
return;
}
const claimed = await eClaim.FetchOneByClaimId(claimId);
if (claimed) {
@ -48,13 +42,6 @@ export default class Claim extends ButtonEvent {
return;
}
if (claimId == CoreClient.ClaimId && userId != droppedBy) {
await interaction.channel.send(`${interaction.user}, The latest dropped card can only be claimed by the user who dropped it!`);
return;
}
await user.Save(User, user);
let inventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber);
if (!inventory) {

View file

@ -35,11 +35,13 @@ export default class Reroll extends ButtonEvent {
AppLogger.LogInfo("Commands/Drop", `New user (${interaction.user.id}) saved to the database`);
}
if (user.Currency < CardConstants.ClaimCost) {
if (!user.RemoveCurrency(CardConstants.ClaimCost)) {
await interaction.reply(`Not enough currency! You need ${CardConstants.ClaimCost} currency, you have ${user.Currency}!`);
return;
}
await user.Save(User, user);
const randomCard = await GetCardsHelper.FetchCard(interaction.user.id);
if (!randomCard) {
@ -78,8 +80,6 @@ export default class Reroll extends ButtonEvent {
files: files,
components: [ row ],
});
CoreClient.ClaimId = claimId;
} catch (e) {
AppLogger.LogError("Button/Reroll", `Error sending next drop for card ${randomCard.card.id}: ${e}`);

View file

@ -31,7 +31,6 @@ export class CoreClient extends Client {
private _webhooks: Webhooks;
private _timerHelper: TimerHelper;
public static ClaimId: string;
public static Environment: Environment;
public static AllowDrops: boolean;
public static Cards: SeriesMetadata[];

View file

@ -43,11 +43,13 @@ export default class Drop extends Command {
AppLogger.LogInfo("Commands/Drop", `New user (${interaction.user.id}) saved to the database`);
}
if (user.Currency < CardConstants.ClaimCost) {
if (!user.RemoveCurrency(CardConstants.ClaimCost)) {
await interaction.reply(ErrorMessages.NotEnoughCurrency(CardConstants.ClaimCost, user.Currency));
return;
}
await user.Save(User, user);
const randomCard = await GetCardsHelper.FetchCard(interaction.user.id);
if (!randomCard) {
@ -86,8 +88,6 @@ export default class Drop extends Command {
components: [ row ],
});
CoreClient.ClaimId = claimId;
} catch (e) {
AppLogger.LogError("Commands/Drop", `Error sending next drop for card ${randomCard.card.id}: ${e}`);

View file

@ -81,7 +81,5 @@ export default class Dropnumber extends Command {
await interaction.editReply("Unable to send next drop. Please try again, and report this if it keeps happening. Code: UNKNOWN");
}
}
CoreClient.ClaimId = claimId;
}
}

View file

@ -83,7 +83,5 @@ export default class Droprarity extends Command {
await interaction.editReply("Unable to send next drop. Please try again, and report this if it keeps happening. Code: UNKNOWN");
}
}
CoreClient.ClaimId = claimId;
}
}

View file

@ -3,7 +3,6 @@ import { DropResult } from "../../contracts/SeriesMetadata";
import AppLogger from "../../client/appLogger";
import { CardRarityToColour, CardRarityToString } from "../../constants/CardRarity";
import StringTools from "../StringTools";
import CardConstants from "../../constants/CardConstants";
export default class DropEmbedHelper {
public static GenerateDropEmbed(drop: DropResult, quantityClaimed: number, imageFileName: string, claimedBy?: string, currency?: number): EmbedBuilder {
@ -74,12 +73,16 @@ export default class DropEmbedHelper {
.addComponents(
new ButtonBuilder()
.setCustomId(`claim ${drop.card.id} ${claimId} ${userId}`)
.setLabel(`Claim (${CardConstants.ClaimCost} 🪙)`)
.setStyle(ButtonStyle.Primary)
.setLabel("Claim")
.setStyle(ButtonStyle.Success)
.setDisabled(disabled),
new ButtonBuilder()
.setCustomId(`sacrifice confirm ${userId} ${drop.card.id} 1`)
.setLabel(`Sacrifice`)
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId("reroll")
.setLabel("Reroll")
.setStyle(ButtonStyle.Secondary));
.setEmoji("🔁")
.setStyle(ButtonStyle.Primary),);
}
}

View file

@ -4,7 +4,7 @@ import Claim from "../database/entities/app/Claim";
export default async function PurgeClaims() {
const claims = await Claim.FetchAll(Claim);
const whenLastClaimable = new Date(Date.now() - (1000 * 60 * 5)); // 5 minutes ago
const whenLastClaimable = new Date(Date.now() - (1000 * 60 * 2)); // 2 minutes ago
const expiredClaims = claims.filter(x => x.WhenCreated < whenLastClaimable);

View file

@ -1,7 +1,6 @@
import { ButtonInteraction, TextChannel } from "discord.js";
import Claim from "../../src/buttonEvents/Claim";
import { ButtonInteraction as ButtonInteractionType } from "../__types__/discord.js";
import User from "../../src/database/entities/app/User";
import GenerateButtonInteractionMock from "../__functions__/discord.js/GenerateButtonInteractionMock";
jest.mock("../../src/client/appLogger");
@ -85,25 +84,7 @@ test("GIVEN interaction.message was created more than 5 minutes ago, EXPECT erro
// Assert
expect(interaction.channel!.send).toHaveBeenCalledTimes(1);
expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Cards can only be claimed within 5 minutes of it being dropped!");
expect(interaction.editReply).not.toHaveBeenCalled();
});
test("GIVEN user.RemoveCurrency fails, EXPECT error", async () => {
// Arrange
User.FetchOneById = jest.fn().mockResolvedValue({
RemoveCurrency: jest.fn().mockReturnValue(false),
Currency: 5,
});
// Act
const claim = new Claim();
await claim.execute(interaction as unknown as ButtonInteraction);
// Assert
expect(interaction.channel!.send).toHaveBeenCalledTimes(1);
expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Not enough currency! You need 10 currency, you have 5!");
expect(interaction.channel!.send).toHaveBeenCalledWith("[object Object], Cards can only be claimed within 2 minutes of it being dropped!");
expect(interaction.editReply).not.toHaveBeenCalled();
});

View file

@ -0,0 +1,7 @@
describe("GIVEN valid conditions", () => {
test.todo("EXPECT user.RemoveCurrency to be called");
test.todo("GIVEN user is saved");
});
test.todo("GIVEN user.RemoveCurrency fails, EXPECT error replied");

View file

@ -0,0 +1,7 @@
describe("GIVEN valid conditions", () => {
test.todo("EXPECT user.RemoveCurrency to be called");
test.todo("GIVEN user is saved");
});
test.todo("GIVEN user.RemoveCurrency fails, EXPECT error replied");

View file

@ -0,0 +1,3 @@
describe("GenerateDropButtons", () => {
test.todo("EXPECT row to be returned");
});

View file

@ -0,0 +1,7 @@
describe("PurgeClaims", () => {
test.todo("EXPECT claims to be fetched");
test.todo("EXPECT Claim.RemoveMany to remove the claims older than 2 minutes");
test.todo("EXPECT info logged");
});