Skip to content

Conversation

Zabuzard
Copy link
Member

@Zabuzard Zabuzard commented Jan 25, 2022

Overview

Implements and closes #213 . Adds unit tests to the tag system, i.e.

  • TagSystem,
  • TagCommand,
  • TagsCommand and
  • TagManageCommand.

The tests themselves should be rather self-explanatory.

Majority of changes in this PR are not logic changes but come from the fact that we made Config mockable, and hence had to get rid of the singleton - which bleeds into almost all commands.

Features

While at it, we had to implement multiple more general features from which other unit tests will also benefit in the future:

Database

We added a method Database.createMemoryDatabase(...) to conveniently use an in-memory database for testing. An usage can be seen in TagsCommandTest, where it is called @Before each test.

Mockito

The whole mockito test suite, in particular revolving around JdaTester has been enhanced and generally supports more calls now.

And we also added some bigger features to it:

Button events

In order to test button events, we added a JdaTester#createButtonClickEvent() method that returns a builder that can create mocks of the event, similar to how JdaTester#createSlashCommandEvent(...) works.

The API of this builder is very similar to JDAs Method interface and similar:

// Default message with a delete button
jdaTester.createButtonClickEvent()
  .actionRows(ActionRow.of(Button.of(ButtonStyle.DANGER, "1", "Delete"))
  .buildWithSingleButton();

or

// More complex message with a user who clicked the button that is not the message author and multiple buttons
Button clickedButton = Button.of(ButtonStyle.PRIMARY, "1", "Next");

jdaTester.createButtonClickEvent()
  .message(new MessageBuilder()
    .setContent("See the following entry")
    .setEmbeds(
      new EmbedBuilder()
        .setDescription("John")
        .build())
  .build())
  .userWhoClicked(jdaTester.createMemberSpy(5))
  .actionRows(
    ActionRow.of(Button.of(ButtonStyle.PRIMARY, "1", "PREVIOUS"),
    clickedButton)
  .build(clickedButton);
Command spies

There is now a method JdaTester#spySlashCommand(command) that makes it possible to work with a command that is spied upon and additionally is setup properly. For example, it works with a mocked component ID generator.

Member spies

We also added a method JdaTester#createMemberSpy(userId) that is able to create valid member instances which are spied upon. Useful for testing things that require members. For example buttons that have been clicked by a user different to the message author.

USER option for slash command events

We enhanced the SlashCommandEventBuilder and added overloads option(String, User) and option(String, Member).

So now it also supports options with types USER, not just String. For example:

Member member = jdaTester.createMemberSpy(1);

var event = jdaTester.createSlashCommandEvent(command)
  .option("id", "foo");
  .option("reply-to", member)
  .build();

To make this work, the implementation had to be changed a bit. Therefore, other types can now also easily be added in the future.

Setting the user who triggered a slash command event

The SlashCommandEventBuilder now has a method userWhoTriggered(user) that can be used to set the member who triggered the event. Useful for mocking, for example to adjust permissions of a user who wants to use the ban command.

RestAction mocking

JdaTester now has two methods to create success and failure mocks of RestActions. This can be very useful when testing stuff that involves calls such as TextChannel#retrieveMessageById or similar. Example:

var jdaTester = new JdaTester();

var message = new MessageBuilder("Hello World!").build();
var action = jdaTester.createSucceededActionMock(message);

doReturn(action).when(jdaTester.getTextChannelSpy()).retrieveMessageById("1");

or also

var jdaTester = new JdaTester();

var reason = new FooException();
var action = jdaTester.createFailedActionMock(reason);

doReturn(action).when(jdaTester.getTextChannelSpy()).retrieveMessageById("1");

Checklist

Unit tests

  • TagSystem
  • TagsCommand
  • TagCommand
  • TagManageCommand - raw
  • TagManageCommand - create
  • TagManageCommand - create-with-message
  • TagManageCommand - edit
  • TagManageCommand - edit-with-message
  • TagManageCommand - delete

Mocking

  • spySlashCommand
  • createButtonClickEvent
  • add USER as option to SlashCommandEventBuilder
  • userWhoTriggered(user) for SlashCommandEventBuilder
  • Config.getInstance() mocking
  • RestAction<T> mocking (success & failure)
  • Discord API exception mocking

@Zabuzard Zabuzard added enhancement New feature or request priority: normal labels Jan 25, 2022
@Zabuzard Zabuzard added this to the Improvement phase 1 milestone Jan 25, 2022
@Zabuzard Zabuzard self-assigned this Jan 25, 2022
@Zabuzard Zabuzard changed the title Feature/unit test tags Add unit tests for tag-system Jan 25, 2022
@Zabuzard Zabuzard force-pushed the feature/unit_test_tags branch 3 times, most recently from cde96b7 to db4627d Compare February 2, 2022 14:50
@Zabuzard Zabuzard marked this pull request as ready for review February 9, 2022 13:43
@Zabuzard Zabuzard requested review from a team as code owners February 9, 2022 13:43
@Heatmanofurioso
Copy link
Contributor

I usually follow a convention on the Display Names of tests, where I describe my GIVEN, WHEN, THEN in the test name itself.

Would you think it's a good idea to adapt to that convention @Zabuzard ? Probably starting on this PR "hence me asking it here"

@Heatmanofurioso Heatmanofurioso self-requested a review February 14, 2022 09:19
@Tais993
Copy link
Member

Tais993 commented Feb 15, 2022

If possible, could you make it so this PR becomes 2 commits.

1 updating JDATester, and ButtonClickEventBuilder etc
1 adding the tests

This makes imho more sense

@Zabuzard Zabuzard force-pushed the feature/unit_test_tags branch 2 times, most recently from 3d12f2b to fc9083a Compare February 15, 2022 14:32
@Zabuzard
Copy link
Member Author

Zabuzard commented Feb 15, 2022

If possible, could you make it so this PR becomes 2 commits.

1 updating JDATester, and ButtonClickEventBuilder etc 1 adding the tests

This makes imho more sense

I beautified the commit history (no code changes). Cheers
(Its important to keep the Config change separate, since this will cause a lot of merge conflicts and that way resolving those will be simpler)

@Zabuzard Zabuzard requested a review from Tais993 February 15, 2022 14:33
This is a quite simple change but it touches a lot of files. All of them now require the config as parameter instead of using global singleton access.

This makes it possible to mock the Config (needed for the unit tests).
enabling mockito inline extension to make it possible to mock final classes
* Added ButtonClickEvent generation and mocking
* Added USER option to SlashCommandEventBuilder
* Added `userWhoTriggered(user)` to slash command event builder
* Added mocked rest actions (success & failure), and discord exceptions
* and improved ping tests
@Zabuzard Zabuzard force-pushed the feature/unit_test_tags branch from 14128cd to 3bb3a75 Compare February 15, 2022 14:42
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

0.0% 0.0% Coverage
0.0% 0.0% Duplication

@Zabuzard Zabuzard merged commit b4c1947 into develop Feb 16, 2022
@Zabuzard Zabuzard deleted the feature/unit_test_tags branch February 16, 2022 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: normal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add unit tests to the tag commands

3 participants