-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add command to submit anonymous feedback
- Loading branch information
1 parent
3ce2d88
commit f88e59f
Showing
3 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { Discord, ModalComponent, Slash } from "discordx"; | ||
import { | ||
ActionRowBuilder, | ||
CommandInteraction, | ||
EmbedBuilder, | ||
ModalBuilder, | ||
ModalSubmitInteraction, TextChannel, | ||
TextInputBuilder | ||
} from "discord.js"; | ||
import getConfigValue from "../utils/getConfigValue"; | ||
|
||
@Discord() | ||
class FeedbackCommand { | ||
@Slash({ | ||
name: "feedback", | ||
description: "Leave anonymous feedback around the community" | ||
}) | ||
async onInteract( | ||
interaction: CommandInteraction | ||
): Promise<void> { | ||
const modal = new ModalBuilder() | ||
.setTitle("Anonymous Feedback") | ||
.setCustomId("feedback-form"); | ||
|
||
const feedbackInput = new TextInputBuilder() | ||
.setCustomId("feedback-input") | ||
.setLabel("Your Feedback") | ||
.setStyle(2); | ||
|
||
modal.addComponents( | ||
new ActionRowBuilder<TextInputBuilder>().addComponents( | ||
feedbackInput | ||
) | ||
); | ||
|
||
await interaction.showModal(modal); | ||
} | ||
|
||
@ModalComponent({ | ||
id: "feedback-form" | ||
}) | ||
async onModalSubmit(interaction: ModalSubmitInteraction): Promise<void> { | ||
const [feedbackInput] = ["feedback-input"].map(id => interaction.fields.getTextInputValue(id)); | ||
|
||
const feedbackChannelId = getConfigValue<string>("FEEDBACK_CHANNEL"); | ||
const feedbackChannel = await interaction.guild?.channels.fetch(feedbackChannelId) as TextChannel; | ||
|
||
const embed = new EmbedBuilder() | ||
|
||
embed.setTitle("New Anonymous Feedback"); | ||
embed.setDescription(feedbackInput); | ||
|
||
const message = await feedbackChannel?.send({ | ||
embeds: [embed] | ||
}); | ||
|
||
await message.startThread({ | ||
name: "Discuss Anonymous Feedback", | ||
}); | ||
|
||
await interaction.reply({ | ||
content: `Thank you, the following feedback has been submitted:`, | ||
ephemeral: true, | ||
embeds: [embed] | ||
}); | ||
} | ||
} | ||
|
||
|
||
export default FeedbackCommand; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import {createSandbox, SinonSandbox, SinonStub} from "sinon"; | ||
import FeedbackCommand from "../../src/commands/FeedbackCommand"; | ||
import {CommandInteraction, ModalSubmitInteraction} from "discord.js"; | ||
import {expect} from "chai"; | ||
|
||
describe("FeedbackCommand", () => { | ||
let sandbox: SinonSandbox; | ||
let command: FeedbackCommand; | ||
|
||
beforeEach(() => { | ||
sandbox = createSandbox(); | ||
command = new FeedbackCommand(); | ||
}); | ||
|
||
afterEach(() => sandbox.restore()); | ||
|
||
describe("onInteract()", () => { | ||
it("sends a feedback modal to the user", async () => { | ||
const showModalMock = sandbox.stub(); | ||
|
||
await command.onInteract({ | ||
showModal: showModalMock | ||
} as unknown as CommandInteraction); | ||
|
||
expect(showModalMock.calledOnce).to.be.true; | ||
expect(JSON.stringify(showModalMock.args[0][0])).to.equal(JSON.stringify({ | ||
title: "Anonymous Feedback", | ||
custom_id: "feedback-form", | ||
components: [ | ||
{ | ||
type: 1, | ||
components: [ | ||
{ | ||
type: 4, | ||
custom_id: "feedback-input", | ||
label: "Your Feedback", | ||
style: 2 | ||
} | ||
] | ||
} | ||
] | ||
})); | ||
}); | ||
}); | ||
|
||
describe("onModalSubmit()", () => { | ||
let interaction: ModalSubmitInteraction; | ||
let startThreadMock: SinonStub; | ||
let sendMock: SinonStub; | ||
let replyMock: SinonStub; | ||
let fetchMock: SinonStub; | ||
|
||
beforeEach(() => { | ||
startThreadMock = sandbox.stub(); | ||
replyMock = sandbox.stub(); | ||
|
||
sendMock = sandbox.stub().resolves({ | ||
startThread: startThreadMock | ||
}); | ||
|
||
fetchMock = sandbox.stub().resolves({ | ||
send: sendMock | ||
}); | ||
|
||
interaction = { | ||
fields: { | ||
getTextInputValue: (_id: string) => 'Feedback submitted goes here' | ||
}, | ||
guild: { | ||
channels: { | ||
fetch: fetchMock | ||
} | ||
}, | ||
reply: replyMock | ||
} as unknown as ModalSubmitInteraction | ||
}) | ||
|
||
it("sends a copy of the feedback to the feedback channel and creates a thread", async () => { | ||
await command.onModalSubmit(interaction); | ||
|
||
expect(fetchMock.calledOnce).to.be.true; | ||
|
||
expect(sendMock.calledOnce).to.be.true; | ||
expect(JSON.stringify(sendMock.args[0][0])).to.equal(JSON.stringify({ | ||
embeds: [ | ||
{ | ||
title: "New Anonymous Feedback", | ||
description: "Feedback submitted goes here" | ||
} | ||
] | ||
})); | ||
|
||
expect(startThreadMock.calledOnce).to.be.true; | ||
}); | ||
|
||
it("sends a copy of the feedback to the submitter", async () => { | ||
await command.onModalSubmit(interaction); | ||
|
||
expect(fetchMock.calledOnce).to.be.true; | ||
|
||
expect(replyMock.calledOnce).to.be.true; | ||
expect(JSON.stringify(replyMock.args[0][0])).to.equal(JSON.stringify({ | ||
content: "Thank you, the following feedback has been submitted:", | ||
ephemeral: true, | ||
embeds: [ | ||
{ | ||
title: "New Anonymous Feedback", | ||
description: "Feedback submitted goes here" | ||
} | ||
] | ||
})); | ||
}); | ||
}); | ||
}); |