Skip to content
This repository was archived by the owner on Nov 13, 2025. It is now read-only.

Commit 9b550d2

Browse files
committed
Fixed possibility for multiple commands with the same name exists
1 parent 13962be commit 9b550d2

File tree

6 files changed

+114
-6
lines changed

6 files changed

+114
-6
lines changed

Slack-GPT-Socket.sln.DotSettings.user

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@
2020
<TestId>NUnit3x::8513CAC6-F4FB-4821-B229-7B2E31E1DA66::net7.0::Slack_GPT_Tests.Handlers.CommandHandlerTests.WhatsNewCommand_Ok</TestId>
2121
<TestId>NUnit3x::8513CAC6-F4FB-4821-B229-7B2E31E1DA66::net7.0::Slack_GPT_Tests.Handlers.CommandHandlerTests.WhatsNewCommand_Error</TestId>
2222
<TestId>NUnit3x::8513CAC6-F4FB-4821-B229-7B2E31E1DA66::net7.0::Slack_GPT_Tests.TestLiteDB.TestNullConnectionString_Ok</TestId>
23+
<TestId>NUnit3x::8513CAC6-F4FB-4821-B229-7B2E31E1DA66::net7.0::Slack_GPT_Tests.Handlers.CommandHandlerTests.CommandsCommand_AddOverwrite_Ok</TestId>
24+
<TestId>NUnit3x::8513CAC6-F4FB-4821-B229-7B2E31E1DA66::net7.0::Slack_GPT_Tests.Handlers.CommandHandlerTests.CommandsCommand_RemoveSingle_Ok</TestId>
2325
</TestAncestor>
2426
&lt;/SessionState&gt;</s:String></wpf:ResourceDictionary>

Slack-GPT-Socket/SlackHandlers/Command/CommandsCommandStrategy.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,12 @@ private SlashCommandResponse AddCommand(SlashCommand command, string restOfComma
127127
? null
128128
: command.UserId
129129
};
130-
_userCommandDb.AddCommand(newCommand);
130+
if (!_userCommandDb.AddCommand(newCommand))
131+
{
132+
return CommandStrategyUtils.SlashCommandResponse(
133+
$"Command {newCommand.Command} already exists. " +
134+
$"Use /commands remove {newCommand.Command} to remove it first.");
135+
}
131136
return CommandStrategyUtils.SlashCommandResponse(
132137
$"Added command {newCommand.Command} described as {newCommand.Description}\n" +
133138
$"\tPrompt:{newCommand.Prompt}.\n" +

Slack-GPT-Socket/SlackHandlers/Command/WhatsNewCommandStrategy.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33

44
namespace Slack_GPT_Socket.Command;
55

6+
/// <summary>
7+
/// Handles the whatsnew command. Basically just a wrapper for the GitHub API, to get the latest release notes.
8+
/// </summary>
69
public class WhatsNewCommandStrategy : ICommandStrategy
710
{
811
private readonly GitHubClient _github;
@@ -18,6 +21,11 @@ public WhatsNewCommandStrategy()
1821

1922
public string Command => "whatsnew";
2023

24+
/// <summary>
25+
/// Returns the latest release notes.
26+
/// </summary>
27+
/// <param name="command"></param>
28+
/// <returns></returns>
2129
public async Task<SlashCommandResponse> Execute(SlashCommand command)
2230
{
2331
var versionString = command.Text.Substring(8).Trim();
@@ -31,7 +39,11 @@ public async Task<SlashCommandResponse> Execute(SlashCommand command)
3139

3240
if (latestRelease == null)
3341
return CommandStrategyUtils.SlashCommandResponse($"No release found for current version. {currentVersion}");
34-
35-
return CommandStrategyUtils.SlashCommandResponse(latestRelease.Body);
42+
43+
return CommandStrategyUtils.SlashCommandResponse(
44+
$"*{latestRelease.TagName}*\n" +
45+
$"{latestRelease.Body}\n" +
46+
$"\n" +
47+
$"\t{latestRelease.HtmlUrl}");
3648
}
3749
}

Slack-GPT-Socket/Utilities/LiteDB/IUserCommandDb.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public interface IUserCommandDb
1919
/// Adds a command to the database.
2020
/// </summary>
2121
/// <param name="command"></param>
22-
void AddCommand(GptUserCommand command);
22+
bool AddCommand(GptUserCommand command);
2323

2424
/// <summary>
2525
/// Removes a command from the database.

Slack-GPT-Socket/Utilities/LiteDB/UserCommandDB.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,23 @@ public UserCommandDb(ILiteDatabase database)
2525
}
2626

2727
/// <inheritdoc />
28-
public void AddCommand(GptUserCommand command)
28+
public bool AddCommand(GptUserCommand command)
2929
{
30+
var dbCommand = FindCommand(command.Command, command.UserId);
31+
if (dbCommand != null) return false;
3032
_commands.Insert(command);
33+
return true;
3134
}
3235

3336
/// <inheritdoc />
3437
public void RemoveCommand(GptUserCommand command)
3538
{
36-
_commands.DeleteMany(x => x.Command == command.Command && x.UserId == command.UserId);
39+
// Find the command in the database to ensure that the ID is correct.
40+
var dbCommand = FindCommand(command.Command, command.UserId);
41+
42+
// If we do that, first remove command will remove local commands, then global commands.
43+
// Instead all global and user at once.
44+
_commands.DeleteMany(x => x.Command == dbCommand.Command && x.UserId == dbCommand.UserId);
3745
}
3846

3947
/// <inheritdoc />

Slack-GPT-Tests/Handlers/CommandHandlerTests.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,85 @@ public async Task WhatsNewCommand_Error()
317317
// Assert
318318
AssertCommandResult(response, "No release found");
319319
}
320+
321+
[Test]
322+
[TestCase(true)]
323+
[TestCase(false)]
324+
public async Task CommandsCommand_AddOverwrite_Ok(bool isGlobal)
325+
{
326+
// Arrange
327+
var addCommand1 = new SlashCommand
328+
{
329+
Text = $"commands add -command prompt1 {(isGlobal ? "-global" : "")}",
330+
UserId = "U0123ID"
331+
};
332+
var addCommand2 = new SlashCommand
333+
{
334+
Text = $"commands add -command prompt2 {(isGlobal ? "-global" : "")}",
335+
UserId = "U0123ID"
336+
};
337+
var listCommand = new SlashCommand
338+
{
339+
Text = "commands",
340+
UserId = "U0123ID"
341+
};
342+
var listCommandDetails = new SlashCommand
343+
{
344+
Text = "commands help -command",
345+
UserId = "U0123ID"
346+
};
347+
348+
349+
// Act
350+
var add1 = await _commandManager.Execute(addCommand1);
351+
var add2 = await _commandManager.Execute(addCommand2);
352+
var list = await _commandManager.Execute(listCommand);
353+
var listDetails = await _commandManager.Execute(listCommandDetails);
354+
355+
// Assert
356+
AssertCommandResult(add1, "Added command");
357+
AssertCommandResult(add2, "already exists");
358+
AssertCommandResult(list, "-command");
359+
AssertCommandResult(listDetails, "prompt1");
360+
}
361+
362+
[Test]
363+
public async Task CommandsCommand_RemoveSingle_Ok()
364+
{
365+
// Arrange
366+
var addCommand1 = new SlashCommand
367+
{
368+
Text = $"commands add -command prompt1 -global",
369+
UserId = "U0123ID"
370+
};
371+
var addCommand2 = new SlashCommand
372+
{
373+
Text = $"commands add -command prompt2",
374+
UserId = "U0123ID"
375+
};
376+
var listCommand = new SlashCommand
377+
{
378+
Text = "commands",
379+
UserId = "U0123ID"
380+
};
381+
var removeCommand = new SlashCommand
382+
{
383+
Text = "commands remove -command",
384+
UserId = "U0123ID"
385+
};
386+
387+
// Act
388+
var add1 = await _commandManager.Execute(addCommand1);
389+
var add2 = await _commandManager.Execute(addCommand2);
390+
var list1 = await _commandManager.Execute(listCommand);
391+
var remove1 = await _commandManager.Execute(removeCommand);
392+
var list2 = await _commandManager.Execute(listCommand);
393+
394+
// Assert
395+
AssertCommandResult(add1, "Added command");
396+
AssertCommandResult(add2, "already exists");
397+
AssertCommandResult(list1, "-command [Global]");
398+
AssertCommandResult(remove1, "Removed command -command.");
399+
AssertCommandResult(list2, "No commands found.");
400+
}
320401
}

0 commit comments

Comments
 (0)