From b4af922ac255e6cdc71f804bdcb9768271c70dcc Mon Sep 17 00:00:00 2001 From: tueem Date: Mon, 17 Feb 2025 09:15:54 +0100 Subject: [PATCH 01/12] change: getInteractionType check changed from class based to context based check --- .../tomatentum/marinara/registry/InteractionRegistry.java | 2 +- .../net/tomatentum/marinara/wrapper/LibraryWrapper.java | 2 +- .../marinara/wrapper/javacord/JavacordWrapper.java | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java index c771761..27a2152 100644 --- a/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java +++ b/lib/src/main/java/net/tomatentum/marinara/registry/InteractionRegistry.java @@ -66,7 +66,7 @@ public class InteractionRegistry { } public void handle(Object context) { - InteractionType type = marinara.getWrapper().getInteractionType(context.getClass()); + InteractionType type = marinara.getWrapper().getInteractionType(context); logger.debug("Received {} interaction ", context); interactionMethods.forEach((m) -> { if (m.getType().equals(type) && m.canRun(context)) { diff --git a/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java b/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java index 4fe8ef9..81da4eb 100644 --- a/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java +++ b/lib/src/main/java/net/tomatentum/marinara/wrapper/LibraryWrapper.java @@ -29,7 +29,7 @@ public abstract class LibraryWrapper { interactionSubscriber.remove(consumer); } - public abstract InteractionType getInteractionType(Class clazz); + public abstract InteractionType getInteractionType(Object context); public abstract void registerSlashCommands(SlashCommandDefinition[] defs); public abstract Object convertCommandOption(Object context, SlashCommandOptionType type, String optionName); diff --git a/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java b/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java index 7059094..3ba8adf 100644 --- a/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java +++ b/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java @@ -42,10 +42,10 @@ public class JavacordWrapper extends LibraryWrapper { } @Override - public InteractionType getInteractionType(Class clazz) { - if (ApplicationCommandInteraction.class.isAssignableFrom(clazz)) + public InteractionType getInteractionType(Object context) { + if (ApplicationCommandInteraction.class.isAssignableFrom(context.getClass())) return InteractionType.COMMAND; - if (ButtonInteraction.class.isAssignableFrom(clazz)) + if (ButtonInteraction.class.isAssignableFrom(context.getClass())) return InteractionType.BUTTON; return null; -- 2.47.2 From f4dbdc302d53e1f5b86a0a5734bb5c2717cf2e35 Mon Sep 17 00:00:00 2001 From: tueem Date: Mon, 17 Feb 2025 19:44:52 +0100 Subject: [PATCH 02/12] fix: improve consistency --- .../marinara/wrapper/javacord/JavacordWrapper.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java b/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java index 946c8e9..e8555bb 100644 --- a/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java +++ b/wrapper/javacord/src/main/java/net/tomatentum/marinara/wrapper/javacord/JavacordWrapper.java @@ -119,17 +119,16 @@ public class JavacordWrapper extends LibraryWrapper { private org.javacord.api.interaction.SlashCommandOption convertSubCommandGroupDef(SlashCommandDefinition def, SubCommandGroup subGroup) { SubCommand[] subCommands = def.getSubCommands(subGroup.name()); - org.javacord.api.interaction.SlashCommandOption[] convertedSubCommands = (org.javacord.api.interaction.SlashCommandOption[]) Arrays.stream(subCommands).map(this::convertSubCommandDef).toArray(); + List convertedSubCommands = Arrays.stream(subCommands).map(this::convertSubCommandDef).toList(); return org.javacord.api.interaction.SlashCommandOption.createWithOptions( org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND_GROUP, subGroup.name(), subGroup.description(), - Arrays.asList(convertedSubCommands)); + convertedSubCommands); } private org.javacord.api.interaction.SlashCommandOption convertSubCommandDef(SubCommand sub) { - List convertedOptions = new ArrayList<>(); - Arrays.stream(sub.options()).map(this::convertOptionDef).forEach(convertedOptions::add); + List convertedOptions = Arrays.stream(sub.options()).map(this::convertOptionDef).toList(); return org.javacord.api.interaction.SlashCommandOption.createWithOptions( org.javacord.api.interaction.SlashCommandOptionType.SUB_COMMAND, sub.name(), -- 2.47.2 From caeaec19268fb602d54706bd1a161dd552aa9470 Mon Sep 17 00:00:00 2001 From: tueem Date: Mon, 17 Feb 2025 19:45:18 +0100 Subject: [PATCH 03/12] add: fromValue method to SlashCommandOptionType --- .../commands/option/SlashCommandOptionType.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/option/SlashCommandOptionType.java b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/option/SlashCommandOptionType.java index ce80c6f..581bd30 100644 --- a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/option/SlashCommandOptionType.java +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/option/SlashCommandOptionType.java @@ -23,4 +23,13 @@ public enum SlashCommandOptionType { public int getValue() { return value; } + + public static SlashCommandOptionType fromValue(int value) { + for (SlashCommandOptionType type : values()) { + if (type.getValue() == value) { + return type; + } + } + return UNKNOWN; + } } -- 2.47.2 From ca822909e37926f8629116ac19357157018a72e6 Mon Sep 17 00:00:00 2001 From: tueem Date: Mon, 17 Feb 2025 19:55:03 +0100 Subject: [PATCH 04/12] fix: consistency --- .../tomatentum/marinara/interaction/commands/EnumChoices.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/EnumChoices.java b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/EnumChoices.java index 58d82d9..1001db3 100644 --- a/lib/src/main/java/net/tomatentum/marinara/interaction/commands/EnumChoices.java +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/commands/EnumChoices.java @@ -67,7 +67,7 @@ public record EnumChoices(Class> enumClass, ChoiceType type, S return null; } } - return choices.toArray(new SlashCommandOptionChoice[0]); + return choices.toArray(SlashCommandOptionChoice[]::new); } public static enum ChoiceType { -- 2.47.2 From ad19ed6adac5d92aa62a18c5e9d255cfcffe70b6 Mon Sep 17 00:00:00 2001 From: tueem Date: Mon, 17 Feb 2025 20:13:31 +0100 Subject: [PATCH 05/12] add First prototype of Discord4J wrapper --- gradle/libs.versions.toml | 2 + settings.gradle.kts | 4 + wrapper/discord4j/build.gradle.kts | 41 ++++ .../Discord4JContextObjectProvider.java | 102 +++++++++ .../wrapper/discord4j/Discord4JWrapper.java | 201 ++++++++++++++++++ 5 files changed, 350 insertions(+) create mode 100644 wrapper/discord4j/build.gradle.kts create mode 100644 wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java create mode 100644 wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index de79cc7..0d4720c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,10 +5,12 @@ junit-jupiter = "5.10.2" log4j = "2.24.1" javacord = "3.8.0" +discord4j = "3.2.7" geantyref = "2.0.0" [libraries] junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } log4j = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j"} javacord = { module = "org.javacord:javacord", version.ref = "javacord"} +discord4j = { module = "com.discord4j:discord4j-core", version.ref = "discord4j"} geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref"} diff --git a/settings.gradle.kts b/settings.gradle.kts index 06c8680..d885dc5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -13,5 +13,9 @@ plugins { rootProject.name = "Marinara" include(":lib") include(":wrapper-javacord") +include(":wrapper-discord4j") + project(":wrapper-javacord").projectDir = file("wrapper/javacord") +project(":wrapper-discord4j").projectDir = file("wrapper/discord4j") + diff --git a/wrapper/discord4j/build.gradle.kts b/wrapper/discord4j/build.gradle.kts new file mode 100644 index 0000000..49da9dc --- /dev/null +++ b/wrapper/discord4j/build.gradle.kts @@ -0,0 +1,41 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * This generated file contains a sample Java library project to get you started. + * For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.8/userguide/building_java_projects.html in the Gradle documentation. + */ + +plugins { + // Apply the java-library plugin for API and implementation separation. + `java-library` +} + +repositories { + // Use Maven Central for resolving dependencies. + mavenCentral() +} + +dependencies { + // Use JUnit Jupiter for testing. + testImplementation(libs.junit.jupiter) + + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + implementation(libs.log4j) + implementation(libs.discord4j) { + exclude(module="discord4j-voice") + } + implementation(libs.geantyref) + implementation(project(":lib")) +} + +// Apply a specific Java toolchain to ease working on different environments. +java { + toolchain { + languageVersion = JavaLanguageVersion.of(23) + } +} + +tasks.named("test") { + // Use JUnit Platform for unit tests. + useJUnitPlatform() +} diff --git a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java new file mode 100644 index 0000000..82b42ff --- /dev/null +++ b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java @@ -0,0 +1,102 @@ +package net.tomatentum.marinara.wrapper.discord4j; + +import java.util.List; + +import discord4j.core.event.domain.interaction.ChatInputAutoCompleteEvent; +import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; +import discord4j.core.event.domain.interaction.ComponentInteractionEvent; +import discord4j.core.object.command.ApplicationCommandInteractionOption; +import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; +import net.tomatentum.marinara.wrapper.ContextObjectProvider; + +public class Discord4JContextObjectProvider implements ContextObjectProvider { + + @Override + public Object convertCommandOption(Object context, String optionName) { + if (!(context instanceof ChatInputInteractionEvent)) + return null; + ChatInputInteractionEvent interactionEvent = (ChatInputInteractionEvent) context; + + List subOptions = Discord4JWrapper.SUB_FILTER.apply(interactionEvent.getOptions()); + + if (subOptions.isEmpty()) + return getOptionValue(interactionEvent.getOption(optionName).get()); + + + ApplicationCommandInteractionOption subCommandOption = interactionEvent.getOptions().getFirst(); + subOptions = Discord4JWrapper.SUB_FILTER.apply(subCommandOption.getOptions()); + + if (!subOptions.isEmpty()) + subCommandOption = subOptions.getFirst(); + + return getOptionValue(interactionEvent.getOption(optionName).get()); + + } + + private Object getOptionValue(ApplicationCommandInteractionOption option) { + if (!option.getValue().isPresent()) + return null; + SlashCommandOptionType type = getOptionType(option); + + switch (type) { + case ATTACHMENT: + return option.getValue().get().asAttachment(); + case BOOLEAN: + return option.getValue().get().asBoolean(); + case CHANNEL: + return option.getValue().get().asChannel(); + case DOUBLE: + return option.getValue().get().asDouble(); + case INTEGER: + return option.getValue().get().asLong(); + case MENTIONABLE: + return option.getValue().get().asSnowflake(); + case ROLE: + return option.getValue().get().asRole(); + case STRING: + return option.getValue().get().asString(); + case USER: + return option.getValue().get().asUser(); + default: + return null; + } + } + + private SlashCommandOptionType getOptionType(ApplicationCommandInteractionOption option) { + return SlashCommandOptionType.fromValue(option.getType().getValue()); + } + + @Override + public Object getComponentContextObject(Object context, Class type) { + ComponentInteractionEvent componentInteractionEvent = (ComponentInteractionEvent) context; + switch (type.getName()) { + case "discord4j.core.object.entity.Message": + return componentInteractionEvent.getMessage(); + default: + return getInteractionContextObject(context, type); + } + } + + @Override + public Object getInteractionContextObject(Object context, Class type) { + ComponentInteractionEvent componentInteractionEvent = (ComponentInteractionEvent) context; + switch (type.getName()) { + case "discord4j.core.object.entity.channel.MessageChannel": + return componentInteractionEvent.getInteraction().getChannel().block(); + case "discord4j.core.object.entity.Guild": + return componentInteractionEvent.getInteraction().getGuild().block(); + case "discord4j.core.object.entity.Member": + return componentInteractionEvent.getInteraction().getMember().orElse(null); + case "discord4j.core.object.entity.User": + return componentInteractionEvent.getInteraction().getUser(); + } + return null; + } + + @Override + public Object getAutocompleteFocusedOption(Object context) { + ChatInputAutoCompleteEvent interaction = (ChatInputAutoCompleteEvent) context; + return getOptionValue(interaction.getFocusedOption()); + } + +} diff --git a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java new file mode 100644 index 0000000..4471161 --- /dev/null +++ b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java @@ -0,0 +1,201 @@ +package net.tomatentum.marinara.wrapper.discord4j; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import org.apache.logging.log4j.Logger; + +import discord4j.core.GatewayDiscordClient; +import discord4j.core.event.domain.interaction.ButtonInteractionEvent; +import discord4j.core.event.domain.interaction.ChatInputAutoCompleteEvent; +import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; +import discord4j.core.event.domain.interaction.InteractionCreateEvent; +import discord4j.core.object.command.ApplicationCommandInteractionOption; +import discord4j.core.object.command.ApplicationCommandOption.Type; +import discord4j.discordjson.json.ApplicationCommandOptionChoiceData; +import discord4j.discordjson.json.ApplicationCommandOptionData; +import discord4j.discordjson.json.ApplicationCommandRequest; + +import io.leangen.geantyref.AnnotationFormatException; +import io.leangen.geantyref.TypeFactory; +import net.tomatentum.marinara.interaction.InteractionType; +import net.tomatentum.marinara.interaction.commands.ExecutableSlashCommandDefinition; +import net.tomatentum.marinara.interaction.commands.SlashCommandDefinition; +import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; +import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; +import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOptionChoice; +import net.tomatentum.marinara.interaction.commands.annotation.SubCommand; +import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; +import net.tomatentum.marinara.util.LoggerUtil; +import net.tomatentum.marinara.wrapper.ContextObjectProvider; +import net.tomatentum.marinara.wrapper.LibraryWrapper; +import reactor.core.publisher.Mono; + +public class Discord4JWrapper extends LibraryWrapper { + + public static final Function, List> SUB_FILTER = (i) -> + i.stream() + .filter(o -> o.getType().equals(Type.SUB_COMMAND) || o.getType().equals(Type.SUB_COMMAND_GROUP)) + .toList(); + + public static final Function, List> ARG_FILTER = (i) -> + i.stream() + .filter(o -> !o.getType().equals(Type.SUB_COMMAND) && !o.getType().equals(Type.SUB_COMMAND_GROUP)) + .toList(); + + private GatewayDiscordClient api; + private Discord4JContextObjectProvider contextObjectProvider; + + private Logger logger = LoggerUtil.getLogger(getClass()); + + public Discord4JWrapper(GatewayDiscordClient api) { + this.api = api; + this.contextObjectProvider = new Discord4JContextObjectProvider(); + api.on(InteractionCreateEvent.class) + .subscribe(event -> handleInteraction(event)); + Mono.just("test").subscribe(logger::debug); + + logger.info("Discord4J wrapper loaded!"); + } + + @Override + public InteractionType getInteractionType(Object context) { + if (ChatInputAutoCompleteEvent.class.isAssignableFrom(context.getClass())) + return InteractionType.AUTOCOMPLETE; + if (ChatInputInteractionEvent.class.isAssignableFrom(context.getClass())) + return InteractionType.COMMAND; + if (ButtonInteractionEvent.class.isAssignableFrom(context.getClass())) + return InteractionType.BUTTON; + + return null; + } + + @Override + public void registerSlashCommands(SlashCommandDefinition[] defs) { + HashMap> serverCommands = new HashMap<>(); + List globalCommands = new ArrayList<>(); + long applicationId = api.getRestClient().getApplicationId().block(); + + for (SlashCommandDefinition slashCommandDefinition : defs) { + ApplicationCommandRequest request = convertSlashCommand(slashCommandDefinition); + if (slashCommandDefinition.getFullSlashCommand().serverIds().length > 0) { + for (long serverId : slashCommandDefinition.getFullSlashCommand().serverIds()) { + serverCommands.putIfAbsent(serverId, new ArrayList<>()); + serverCommands.get(serverId).add(request); + } + }else + globalCommands.add(request); + } + + for (long serverId : serverCommands.keySet()) { + api.getRestClient().getApplicationService().bulkOverwriteGuildApplicationCommand(applicationId, serverId, serverCommands.get(serverId)); + } + api.getRestClient().getApplicationService().bulkOverwriteGlobalApplicationCommand(applicationId, globalCommands); + } + + @Override + public ExecutableSlashCommandDefinition getCommandDefinition(Object context) { + if (!(context instanceof ChatInputInteractionEvent)) + return null; + + ChatInputInteractionEvent interaction = (ChatInputInteractionEvent) context; + ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder(); + List options = SUB_FILTER.apply(interaction.getOptions()); + + try { + builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", interaction.getCommandName()))); + if (!options.isEmpty()) { + if (!ARG_FILTER.apply(options.getFirst().getOptions()).isEmpty()) { + builder.setSubCommandGroup(TypeFactory.annotation(SubCommandGroup.class, Map.of("name", options.getFirst().getName()))); + builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", SUB_FILTER.apply(options.getFirst().getOptions()).getFirst().getName()))); + }else + builder.setSubCommand(TypeFactory.annotation(SubCommand.class, Map.of("name", options.getFirst().getName()))); + } + } catch (AnnotationFormatException e) { + logger.fatal(e); + } + + return builder.build(); + } + + private ApplicationCommandRequest convertSlashCommand(SlashCommandDefinition def) { + List options = new ArrayList<>(); + SlashCommand cmd = def.getFullSlashCommand(); + if (!def.isRootCommand()) { + Arrays.stream(def.getSubCommands(null)).map(this::convertSubCommandDef).forEach(options::add); + Arrays.stream(def.getSubCommandGroups()).map((x) -> convertSubCommandGroupDef(def, x)).forEach(options::add); + }else { + Arrays.stream(cmd.options()).map(this::convertOptionDef).forEach(options::add); + } + + return ApplicationCommandRequest.builder() + .name(cmd.name()) + .description(cmd.description()) + .options(options) + .build(); + } + + private ApplicationCommandOptionData convertSubCommandGroupDef(SlashCommandDefinition def, SubCommandGroup subGroup) { + SubCommand[] subCommands = def.getSubCommands(subGroup.name()); + List convertedSubCommands = Arrays.stream(subCommands).map(this::convertSubCommandDef).toList(); + return ApplicationCommandOptionData.builder() + .type(Type.SUB_COMMAND_GROUP.getValue()) + .name(subGroup.name()) + .description(subGroup.description()) + .options(convertedSubCommands) + .build(); + } + + private ApplicationCommandOptionData convertSubCommandDef(SubCommand sub) { + List convertedOptions = Arrays.stream(sub.options()).map(this::convertOptionDef).toList(); + return ApplicationCommandOptionData.builder() + .type(Type.SUB_COMMAND_GROUP.getValue()) + .name(sub.name()) + .description(sub.description()) + .options(convertedOptions) + .build(); + } + + private ApplicationCommandOptionData convertOptionDef(SlashCommandOption option) { + Type type = Enum.valueOf(Type.class, option.type().toString()); + return ApplicationCommandOptionData.builder() + .type(type.getValue()) + .name(option.name()) + .description(option.description()) + .required(option.required()) + .autocomplete(option.autocomplete()) + .choices(convertChoices(option)) + .build(); + } + + private List convertChoices(SlashCommandOption option) { + List convertedChoices = new ArrayList<>(); + for (SlashCommandOptionChoice choice : ExecutableSlashCommandDefinition.getActualChoices(option)) { + var builder = ApplicationCommandOptionChoiceData.builder(); + builder.name(choice.name()); + if (choice.longValue() != Long.MAX_VALUE) + builder.value(choice.longValue()); + if (choice.doubleValue() != Double.MAX_VALUE) + builder.value(choice.doubleValue()); + if (!choice.stringValue().isEmpty()) + builder.value(choice.stringValue()); + } + return convertedChoices; + } + + @Override + public String getButtonId(Object context) { + ButtonInteractionEvent button = (ButtonInteractionEvent) context; + return button.getCustomId(); + } + + @Override + public ContextObjectProvider getContextObjectProvider() { + return this.contextObjectProvider; + } + +} -- 2.47.2 From dbad1570585881ae44b223a4fef06e590349eab7 Mon Sep 17 00:00:00 2001 From: tueem Date: Mon, 17 Feb 2025 20:24:40 +0100 Subject: [PATCH 06/12] adjust actions to add new wrapper --- .gitea/workflows/gradle-build.yaml | 5 ++++- .gitea/workflows/gradle-test.yaml | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/gradle-build.yaml b/.gitea/workflows/gradle-build.yaml index 9f89304..d9a3eda 100644 --- a/.gitea/workflows/gradle-build.yaml +++ b/.gitea/workflows/gradle-build.yaml @@ -38,7 +38,10 @@ jobs: run: chmod +x gradlew; ./gradlew assemble - name: Move artifacts - run: mkdir artifacts; mv lib/build/libs/*.jar artifacts; mv wrapper/javacord/build/libs/*.jar artifacts; + run: | + mkdir artifacts; mv lib/build/libs/*.jar artifacts; + mv wrapper/javacord/build/libs/*.jar artifacts; + mv wrapper/discord4j/build/libs/*.jar artifacts; - name: Upload artifact uses: christopherhx/gitea-upload-artifact@v4 diff --git a/.gitea/workflows/gradle-test.yaml b/.gitea/workflows/gradle-test.yaml index 62fe064..af12cbc 100644 --- a/.gitea/workflows/gradle-test.yaml +++ b/.gitea/workflows/gradle-test.yaml @@ -44,6 +44,7 @@ jobs: mkdir test-results/; [ -d lib/build/test-results/test/ ] && mv lib/build/test-results/test/*.xml test-results/; [ -d wrapper/javacord/build/test-results/test/ ] && mv wrapper/javacord/build/test-results/test/*.xml test-results/; + [ -d wrapper/discord4j/build/test-results/test/ ] && mv wrapper/discord4j/build/test-results/test/*.xml test-results/; - name: Upload Test Result uses: christopherhx/gitea-upload-artifact@v4 -- 2.47.2 From f81602f5db259d33ff32974dd07983317f8fae8f Mon Sep 17 00:00:00 2001 From: Tueem Date: Mon, 17 Feb 2025 23:59:08 +0100 Subject: [PATCH 07/12] restructure and add discord4j test stub --- .../test/discord4j/AutoCompleteTest.java | 23 ++++ .../marinara/test/discord4j/ButtonTest.java | 27 ++++ .../test/discord4j/InteractionCheckTest.java | 47 +++++++ .../test/discord4j/SlashCommandTest.java | 53 +++++++ .../test/discord4j/TestAutocomplete.java | 23 ++++ .../marinara/test/discord4j/TestButton.java | 42 ++++++ .../test/discord4j/TestChoiceEnum.java | 20 +++ .../marinara/test/discord4j/TestCommand.java | 32 +++++ .../test/discord4j/TestInteractionCheck.java | 37 +++++ .../mocks/AutocompleteInteractionMock.java | 17 +++ .../mocks/ButtonInteractionMock.java | 25 ++++ .../test/discord4j/mocks/ChannelMock.java | 130 ++++++++++++++++++ .../test/discord4j/mocks/InteractionMock.java | 41 ++++++ .../mocks/SlashCommandInteractionMock.java | 16 +++ .../SlashCommandInteractionOptionMock.java | 25 ++++ .../test/discord4j/mocks/UserMock.java | 11 ++ .../test/{ => javacord}/AutoCompleteTest.java | 6 +- .../test/{ => javacord}/ButtonTest.java | 6 +- .../{ => javacord}/InteractionCheckTest.java | 8 +- .../test/{ => javacord}/SlashCommandTest.java | 4 +- .../test/{ => javacord}/TestAutocomplete.java | 2 +- .../test/{ => javacord}/TestButton.java | 4 +- .../test/{ => javacord}/TestChoiceEnum.java | 2 +- .../test/{ => javacord}/TestCommand.java | 2 +- .../{ => javacord}/TestInteractionCheck.java | 2 +- .../mocks/AutocompleteInteractionMock.java | 2 +- .../mocks/ButtonInteractionMock.java | 2 +- .../{ => javacord}/mocks/ChannelMock.java | 2 +- .../{ => javacord}/mocks/DiscordApiMock.java | 2 +- .../{ => javacord}/mocks/MessageMock.java | 2 +- .../test/{ => javacord}/mocks/ServerMock.java | 2 +- .../mocks/SlashCommandInteractionMock.java | 2 +- .../SlashCommandInteractionOptionMock.java | 2 +- .../test/{ => javacord}/mocks/UserMock.java | 2 +- 34 files changed, 596 insertions(+), 27 deletions(-) create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestChoiceEnum.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestInteractionCheck.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/AutoCompleteTest.java (79%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/ButtonTest.java (81%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/InteractionCheckTest.java (87%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/SlashCommandTest.java (91%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/TestAutocomplete.java (93%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/TestButton.java (91%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/TestChoiceEnum.java (89%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/TestCommand.java (95%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/TestInteractionCheck.java (95%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/AutocompleteInteractionMock.java (99%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/ButtonInteractionMock.java (98%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/ChannelMock.java (99%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/DiscordApiMock.java (99%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/MessageMock.java (99%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/ServerMock.java (99%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/SlashCommandInteractionMock.java (98%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/SlashCommandInteractionOptionMock.java (97%) rename wrapper/javacord/src/test/java/net/tomatentum/marinara/test/{ => javacord}/mocks/UserMock.java (99%) diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java new file mode 100644 index 0000000..40cc7b0 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java @@ -0,0 +1,23 @@ +package net.tomatentum.marinara.test.discord4j; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import net.tomatentum.marinara.Marinara; +import net.tomatentum.marinara.test.discord4j.mocks.AutocompleteInteractionMock; +import net.tomatentum.marinara.test.discord4j.mocks.DiscordApiMock; +import net.tomatentum.marinara.wrapper.LibraryWrapper; +import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; + +public class AutoCompleteTest { + + @Test + public void testAutocomplete() { + LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); //null okay as we don't use the discord API in this test. + Marinara marinara = Marinara.load(wrapper); + marinara.getRegistry().addInteractions(new TestAutocomplete()); + wrapper.handleInteraction(new AutocompleteInteractionMock()); + assertTrue(AutocompleteInteractionMock.didAutocompleteRun); + } +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java new file mode 100644 index 0000000..c8b013f --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java @@ -0,0 +1,27 @@ +package net.tomatentum.marinara.test.discord4j; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +import net.tomatentum.marinara.Marinara; +import net.tomatentum.marinara.test.discord4j.mocks.ButtonInteractionMock; +import net.tomatentum.marinara.test.discord4j.mocks.DiscordApiMock; +import net.tomatentum.marinara.wrapper.LibraryWrapper; +import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; + +@TestInstance(Lifecycle.PER_CLASS) +public class ButtonTest { + + @Test + public void testButtonExecution() { + LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); //null okay as we don't use the discord API in this test. + Marinara marinara = Marinara.load(wrapper); + marinara.getRegistry().addInteractions(new TestButton()); + wrapper.handleInteraction(new ButtonInteractionMock("test")); + assertTrue(TestButton.didRun); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java new file mode 100644 index 0000000..027dc4a --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java @@ -0,0 +1,47 @@ +package net.tomatentum.marinara.test.discord4j; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.javacord.api.entity.permission.PermissionType; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +import net.tomatentum.marinara.Marinara; +import net.tomatentum.marinara.test.discord4j.mocks.ButtonInteractionMock; +import net.tomatentum.marinara.test.discord4j.mocks.DiscordApiMock; +import net.tomatentum.marinara.test.discord4j.mocks.ServerMock; +import net.tomatentum.marinara.wrapper.LibraryWrapper; +import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; +import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck; + +@TestInstance(Lifecycle.PER_CLASS) +public class InteractionCheckTest { + + @Test + public void testInteractionCheck() { + LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); + Marinara marinara = Marinara.load(wrapper); + marinara.getCheckRegistry().addCheck(new TestInteractionCheck()); + marinara.getRegistry().addInteractions(new TestButton()); + wrapper.handleInteraction(new ButtonInteractionMock("test")); + assertTrue(TestInteractionCheck.preExecuted); + assertTrue(TestInteractionCheck.postExecuted); + } + + @Test + public void testPermissionCheck() { + LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); + Marinara marinara = Marinara.load(wrapper); + marinara.getCheckRegistry().addCheck(new PermissionCheck()); + marinara.getRegistry().addInteractions(new TestButton()); + wrapper.handleInteraction(new ButtonInteractionMock("permissionCheck")); + assertTrue(TestButton.didPermRun); + TestButton.didPermRun = false; + ServerMock.TESTPERMISSION = PermissionType.ATTACH_FILE; + wrapper.handleInteraction(new ButtonInteractionMock("permissionCheck")); + assertFalse(TestButton.didPermRun); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java new file mode 100644 index 0000000..6cc294a --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java @@ -0,0 +1,53 @@ +package net.tomatentum.marinara.test.discord4j; + +import org.javacord.api.DiscordApi; +import org.javacord.api.DiscordApiBuilder; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +import net.tomatentum.marinara.Marinara; +import net.tomatentum.marinara.test.discord4j.mocks.SlashCommandInteractionMock; +import net.tomatentum.marinara.wrapper.LibraryWrapper; +import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; +@TestInstance(Lifecycle.PER_CLASS) +public class SlashCommandTest { + + String DISCORD_TOKEN = System.getenv("DISCORD_TEST_TOKEN"); + DiscordApi api; + + @BeforeAll + void setUp() { + api = new DiscordApiBuilder() + .setToken(DISCORD_TOKEN) + .login().join(); + } + + @AfterAll + void tearDown() { + api.disconnect(); + api = null; + } + + @Test + void testSlashCommand() { + Marinara marinara = Marinara.load(new JavacordWrapper(api)); + marinara.getRegistry().addInteractions(new TestCommand()); + marinara.getRegistry().registerCommands(); + System.out.println("Success!"); + } + + @Test + void testSlashCommandExecution() { + LibraryWrapper wrapper = new JavacordWrapper(api); + Marinara marinara = Marinara.load(wrapper); + marinara.getRegistry().addInteractions(new TestCommand()); + + wrapper.handleInteraction(new SlashCommandInteractionMock()); + } + + + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java new file mode 100644 index 0000000..391d67d --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java @@ -0,0 +1,23 @@ +package net.tomatentum.marinara.test.discord4j; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; + +import org.javacord.api.interaction.AutocompleteInteraction; + +import net.tomatentum.marinara.interaction.InteractionHandler; +import net.tomatentum.marinara.interaction.annotation.AutoComplete; +import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; + +public class TestAutocomplete implements InteractionHandler { + + @SlashCommand(name = "test") + @AutoComplete + public void autocomplete(AutocompleteInteraction context, String value) { + System.out.println("Success!"); + assertEquals(value, "test"); + context.respondWithChoices(Collections.emptyList()); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java new file mode 100644 index 0000000..d991392 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java @@ -0,0 +1,42 @@ +package net.tomatentum.marinara.test.discord4j; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.javacord.api.entity.channel.TextChannel; +import org.javacord.api.entity.message.Message; +import org.javacord.api.entity.permission.PermissionType; +import org.javacord.api.entity.server.Server; +import org.javacord.api.entity.user.User; +import org.javacord.api.interaction.ButtonInteraction; + +import net.tomatentum.marinara.interaction.InteractionHandler; +import net.tomatentum.marinara.interaction.annotation.Button; +import net.tomatentum.marinara.test.discord4j.TestInteractionCheck.TestCheck; +import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck.HasPermission; + +public class TestButton implements InteractionHandler { + + + public static boolean didRun = false; + @Button("test") + @TestCheck + public void exec(ButtonInteraction interaction, TextChannel channel, Message message, User member, Server server) { + assertNotNull(interaction); + assertNotNull(channel); + assertNotNull(message); + assertNotNull(member); + assertNotNull(server); + didRun = true; + System.out.println("Success!"); + } + + public static boolean didPermRun = false; + + @Button("permissionCheck") + @HasPermission({PermissionType.ADMINISTRATOR}) + public void exec(ButtonInteraction interaction) { + didPermRun = true; + System.out.println("It worked!"); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestChoiceEnum.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestChoiceEnum.java new file mode 100644 index 0000000..66ab699 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestChoiceEnum.java @@ -0,0 +1,20 @@ +package net.tomatentum.marinara.test.discord4j; + +import net.tomatentum.marinara.interaction.commands.ChoiceValueProvider; + +public enum TestChoiceEnum implements ChoiceValueProvider { + TestValue("testValue"), + FooBar("fooBar"), + Spongebob("spongebob"); + + private String value; + + private TestChoiceEnum(String value) { + this.value = value; + } + @Override + public String getChoiceValue() { + return value; + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java new file mode 100644 index 0000000..95c439f --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java @@ -0,0 +1,32 @@ +package net.tomatentum.marinara.test.discord4j; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.javacord.api.interaction.SlashCommandInteraction; + +import net.tomatentum.marinara.interaction.InteractionHandler; +import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; +import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; +import net.tomatentum.marinara.interaction.commands.option.SlashCommandOptionType; + +public class TestCommand implements InteractionHandler { + @SlashCommand( + name = "test", + description = "testingen", + serverIds = { + 1037753048602255440L + }, + options = { + @SlashCommandOption( + name = "foo", + description = "foo bar is very fooby", + type = SlashCommandOptionType.STRING, + choiceEnum = TestChoiceEnum.class + ) + } + ) + public void exec(SlashCommandInteraction interaction, String test) { + assertEquals(test, "test"); + System.out.println("Success!"); + } +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestInteractionCheck.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestInteractionCheck.java new file mode 100644 index 0000000..fcb794d --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestInteractionCheck.java @@ -0,0 +1,37 @@ +package net.tomatentum.marinara.test.discord4j; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import net.tomatentum.marinara.checks.InteractionCheck; + +public class TestInteractionCheck implements InteractionCheck { + + public static boolean preExecuted = false; + public static boolean postExecuted = false; + + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + public static @interface TestCheck { + } + + @Override + public boolean preExec(Object context, TestCheck annotation) { + assertNotNull(annotation); + assertNotNull(context); + preExecuted = true; + return true; + } + + @Override + public void postExec(Object context, TestCheck annotation) { + assertNotNull(annotation); + assertNotNull(context); + postExecuted = true; + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java new file mode 100644 index 0000000..226ba1d --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java @@ -0,0 +1,17 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import discord4j.core.GatewayDiscordClient; +import discord4j.core.event.domain.interaction.ChatInputAutoCompleteEvent; +import discord4j.core.object.command.Interaction; +import discord4j.gateway.ShardInfo; + +public class AutocompleteInteractionMock extends ChatInputAutoCompleteEvent { + + public AutocompleteInteractionMock(GatewayDiscordClient gateway, ShardInfo shardInfo, Interaction interaction) { + super(gateway, shardInfo, interaction); + //TODO Auto-generated constructor stub + } + + public static boolean didAutocompleteRun = false; + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java new file mode 100644 index 0000000..0583329 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java @@ -0,0 +1,25 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import discord4j.core.event.domain.interaction.ButtonInteractionEvent; +import discord4j.core.object.command.Interaction; + +public class ButtonInteractionMock extends ButtonInteractionEvent { + + private String customId; + + public ButtonInteractionMock(String customId) { + super(null, null, null); + this.customId = customId; + } + + @Override + public String getCustomId() { + return customId; + } + + @Override + public Interaction getInteraction() { + return new InteractionMock(); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java new file mode 100644 index 0000000..ba491fe --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java @@ -0,0 +1,130 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import java.time.Instant; +import java.util.Optional; +import java.util.function.Consumer; + +import org.reactivestreams.Publisher; + +import discord4j.common.util.Snowflake; +import discord4j.core.GatewayDiscordClient; +import discord4j.core.object.entity.Message; +import discord4j.core.object.entity.channel.MessageChannel; +import discord4j.core.retriever.EntityRetrievalStrategy; +import discord4j.core.spec.MessageCreateSpec; +import discord4j.core.spec.legacy.LegacyMessageCreateSpec; +import discord4j.rest.entity.RestChannel; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +public class ChannelMock implements MessageChannel { + + @Override + public Type getType() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getType'"); + } + + @Override + public Mono delete(String reason) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'delete'"); + } + + @Override + public RestChannel getRestChannel() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getRestChannel'"); + } + + @Override + public Snowflake getId() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getId'"); + } + + @Override + public GatewayDiscordClient getClient() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getClient'"); + } + + @Override + public Optional getLastMessageId() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getLastMessageId'"); + } + + @Override + public Mono getLastMessage() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getLastMessage'"); + } + + @Override + public Mono getLastMessage(EntityRetrievalStrategy retrievalStrategy) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getLastMessage'"); + } + + @Override + public Optional getLastPinTimestamp() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getLastPinTimestamp'"); + } + + @Override + public Mono createMessage(Consumer spec) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'createMessage'"); + } + + @Override + public Mono createMessage(MessageCreateSpec spec) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'createMessage'"); + } + + @Override + public Mono type() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'type'"); + } + + @Override + public Flux typeUntil(Publisher until) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'typeUntil'"); + } + + @Override + public Flux getMessagesBefore(Snowflake messageId) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getMessagesBefore'"); + } + + @Override + public Flux getMessagesAfter(Snowflake messageId) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getMessagesAfter'"); + } + + @Override + public Mono getMessageById(Snowflake id) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getMessageById'"); + } + + @Override + public Mono getMessageById(Snowflake id, EntityRetrievalStrategy retrievalStrategy) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getMessageById'"); + } + + @Override + public Flux getPinnedMessages() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getPinnedMessages'"); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java new file mode 100644 index 0000000..4de0152 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java @@ -0,0 +1,41 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import java.util.Optional; + +import discord4j.core.object.command.Interaction; +import discord4j.core.object.entity.Guild; +import discord4j.core.object.entity.Message; +import discord4j.core.object.entity.User; +import discord4j.core.object.entity.channel.MessageChannel; +import reactor.core.publisher.Mono; + +public class InteractionMock extends Interaction + { + + public InteractionMock() { + super(null, null); + } + + @Override + public Optional getMessage() { + //return Optional.of(new MessageMock()); + return Optional.empty(); + } + + @Override + public Mono getChannel() { + return Mono.just(new ChannelMock()); + } + + @Override + public Mono getGuild() { + //return Mono.just(new ServerMock()); + return Mono.empty(); + } + + @Override + public User getUser() { + return new UserMock(); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java new file mode 100644 index 0000000..07ad550 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java @@ -0,0 +1,16 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; + +public class SlashCommandInteractionMock extends ChatInputInteractionEvent { + + public SlashCommandInteractionMock() { + super(null, null, null); + } + + @Override + public String getCommandName() { + return "test"; + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java new file mode 100644 index 0000000..2c67577 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java @@ -0,0 +1,25 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import java.util.Optional; + +import discord4j.core.object.command.ApplicationCommandInteractionOption; +import discord4j.core.object.command.ApplicationCommandInteractionOptionValue; +import discord4j.core.object.command.ApplicationCommandOption.Type; + +public class SlashCommandInteractionOptionMock extends ApplicationCommandInteractionOption { + + public SlashCommandInteractionOptionMock() { + super(null, null, null, null); + } + + @Override + public String getName() { + return "foo"; + } + + @Override + public Optional getValue() { + return Optional.of(new ApplicationCommandInteractionOptionValue(null, null, Type.STRING.getValue(), "test", null)); + } + +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java new file mode 100644 index 0000000..0d8851d --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java @@ -0,0 +1,11 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import discord4j.core.object.entity.User; + +public class UserMock extends User { + + public UserMock() { + super(null, null); + } + +} diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/AutoCompleteTest.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/AutoCompleteTest.java similarity index 79% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/AutoCompleteTest.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/AutoCompleteTest.java index 443c2b4..9c5fc32 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/AutoCompleteTest.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/AutoCompleteTest.java @@ -1,12 +1,12 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.mocks.AutocompleteInteractionMock; -import net.tomatentum.marinara.test.mocks.DiscordApiMock; +import net.tomatentum.marinara.test.javacord.mocks.AutocompleteInteractionMock; +import net.tomatentum.marinara.test.javacord.mocks.DiscordApiMock; import net.tomatentum.marinara.wrapper.LibraryWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/ButtonTest.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/ButtonTest.java similarity index 81% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/ButtonTest.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/ButtonTest.java index db08352..1040ceb 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/ButtonTest.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/ButtonTest.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -7,8 +7,8 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.mocks.ButtonInteractionMock; -import net.tomatentum.marinara.test.mocks.DiscordApiMock; +import net.tomatentum.marinara.test.javacord.mocks.ButtonInteractionMock; +import net.tomatentum.marinara.test.javacord.mocks.DiscordApiMock; import net.tomatentum.marinara.wrapper.LibraryWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/InteractionCheckTest.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/InteractionCheckTest.java similarity index 87% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/InteractionCheckTest.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/InteractionCheckTest.java index aed9f5a..be5d8e1 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/InteractionCheckTest.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/InteractionCheckTest.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -9,9 +9,9 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.mocks.ButtonInteractionMock; -import net.tomatentum.marinara.test.mocks.DiscordApiMock; -import net.tomatentum.marinara.test.mocks.ServerMock; +import net.tomatentum.marinara.test.javacord.mocks.ButtonInteractionMock; +import net.tomatentum.marinara.test.javacord.mocks.DiscordApiMock; +import net.tomatentum.marinara.test.javacord.mocks.ServerMock; import net.tomatentum.marinara.wrapper.LibraryWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/SlashCommandTest.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/SlashCommandTest.java similarity index 91% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/SlashCommandTest.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/SlashCommandTest.java index f7a2c49..fa077af 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/SlashCommandTest.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/SlashCommandTest.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import org.javacord.api.DiscordApi; import org.javacord.api.DiscordApiBuilder; @@ -9,7 +9,7 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.mocks.SlashCommandInteractionMock; +import net.tomatentum.marinara.test.javacord.mocks.SlashCommandInteractionMock; import net.tomatentum.marinara.wrapper.LibraryWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; @TestInstance(Lifecycle.PER_CLASS) diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestAutocomplete.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestAutocomplete.java similarity index 93% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestAutocomplete.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestAutocomplete.java index c38f4a2..d9063bb 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestAutocomplete.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestAutocomplete.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestButton.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestButton.java similarity index 91% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestButton.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestButton.java index 23a7dbf..f838e5e 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestButton.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestButton.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -11,7 +11,7 @@ import org.javacord.api.interaction.ButtonInteraction; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.annotation.Button; -import net.tomatentum.marinara.test.TestInteractionCheck.TestCheck; +import net.tomatentum.marinara.test.javacord.TestInteractionCheck.TestCheck; import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck.HasPermission; public class TestButton implements InteractionHandler { diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestChoiceEnum.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestChoiceEnum.java similarity index 89% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestChoiceEnum.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestChoiceEnum.java index 1c7fd0a..1423ef9 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestChoiceEnum.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestChoiceEnum.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import net.tomatentum.marinara.interaction.commands.ChoiceValueProvider; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestCommand.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestCommand.java similarity index 95% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestCommand.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestCommand.java index 2716fea..e7aca90 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestCommand.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestCommand.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestInteractionCheck.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestInteractionCheck.java similarity index 95% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestInteractionCheck.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestInteractionCheck.java index ed1339b..3e7ea48 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/TestInteractionCheck.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/TestInteractionCheck.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test; +package net.tomatentum.marinara.test.javacord; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/AutocompleteInteractionMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/AutocompleteInteractionMock.java similarity index 99% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/AutocompleteInteractionMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/AutocompleteInteractionMock.java index 29d64b9..20460f6 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/AutocompleteInteractionMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/AutocompleteInteractionMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.util.ArrayList; import java.util.EnumSet; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ButtonInteractionMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ButtonInteractionMock.java similarity index 98% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ButtonInteractionMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ButtonInteractionMock.java index 3e3e8fd..a80320e 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ButtonInteractionMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ButtonInteractionMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.util.EnumSet; import java.util.List; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ChannelMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ChannelMock.java similarity index 99% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ChannelMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ChannelMock.java index 472751e..6048b0c 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ChannelMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ChannelMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.util.Collection; import java.util.List; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/DiscordApiMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/DiscordApiMock.java similarity index 99% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/DiscordApiMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/DiscordApiMock.java index d0e952f..ccc26b0 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/DiscordApiMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/DiscordApiMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.time.Duration; import java.util.Collection; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/MessageMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/MessageMock.java similarity index 99% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/MessageMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/MessageMock.java index 248fffd..186bce2 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/MessageMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/MessageMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.time.Instant; import java.util.Collection; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ServerMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ServerMock.java similarity index 99% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ServerMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ServerMock.java index 275c8ab..f07f85a 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/ServerMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/ServerMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/SlashCommandInteractionMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/SlashCommandInteractionMock.java similarity index 98% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/SlashCommandInteractionMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/SlashCommandInteractionMock.java index 1f04e89..8a66a77 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/SlashCommandInteractionMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/SlashCommandInteractionMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.util.Arrays; import java.util.EnumSet; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/SlashCommandInteractionOptionMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/SlashCommandInteractionOptionMock.java similarity index 97% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/SlashCommandInteractionOptionMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/SlashCommandInteractionOptionMock.java index b102a21..478427b 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/SlashCommandInteractionOptionMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/SlashCommandInteractionOptionMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.util.Collections; import java.util.List; diff --git a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/UserMock.java b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/UserMock.java similarity index 99% rename from wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/UserMock.java rename to wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/UserMock.java index 7258b04..6511209 100644 --- a/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/mocks/UserMock.java +++ b/wrapper/javacord/src/test/java/net/tomatentum/marinara/test/javacord/mocks/UserMock.java @@ -1,4 +1,4 @@ -package net.tomatentum.marinara.test.mocks; +package net.tomatentum.marinara.test.javacord.mocks; import java.awt.Color; import java.time.Instant; -- 2.47.2 From 8d27ec28db83094d4a053e7c920cdbc49d0d8e80 Mon Sep 17 00:00:00 2001 From: tueem Date: Tue, 18 Feb 2025 11:21:32 +0100 Subject: [PATCH 08/12] fix: remove Test Line, allow api to be null, fix getCommandDefinition to also allow ChatInputAutoCompleteEvent --- .../wrapper/discord4j/Discord4JWrapper.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java index 4471161..66df289 100644 --- a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java +++ b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JWrapper.java @@ -33,7 +33,6 @@ import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup; import net.tomatentum.marinara.util.LoggerUtil; import net.tomatentum.marinara.wrapper.ContextObjectProvider; import net.tomatentum.marinara.wrapper.LibraryWrapper; -import reactor.core.publisher.Mono; public class Discord4JWrapper extends LibraryWrapper { @@ -55,9 +54,9 @@ public class Discord4JWrapper extends LibraryWrapper { public Discord4JWrapper(GatewayDiscordClient api) { this.api = api; this.contextObjectProvider = new Discord4JContextObjectProvider(); - api.on(InteractionCreateEvent.class) - .subscribe(event -> handleInteraction(event)); - Mono.just("test").subscribe(logger::debug); + if (api != null) + api.on(InteractionCreateEvent.class) + .subscribe(event -> handleInteraction(event)); logger.info("Discord4J wrapper loaded!"); } @@ -99,15 +98,24 @@ public class Discord4JWrapper extends LibraryWrapper { @Override public ExecutableSlashCommandDefinition getCommandDefinition(Object context) { - if (!(context instanceof ChatInputInteractionEvent)) + List options; + String commandName; + + if (context instanceof ChatInputInteractionEvent) { + ChatInputInteractionEvent interaction = (ChatInputInteractionEvent) context; + options = SUB_FILTER.apply(interaction.getOptions()); + commandName = interaction.getCommandName(); + }else if (context instanceof ChatInputAutoCompleteEvent) { + ChatInputAutoCompleteEvent interaction = (ChatInputAutoCompleteEvent) context; + options = SUB_FILTER.apply(interaction.getOptions()); + commandName = interaction.getCommandName(); + }else return null; - ChatInputInteractionEvent interaction = (ChatInputInteractionEvent) context; ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder(); - List options = SUB_FILTER.apply(interaction.getOptions()); try { - builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", interaction.getCommandName()))); + builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", commandName))); if (!options.isEmpty()) { if (!ARG_FILTER.apply(options.getFirst().getOptions()).isEmpty()) { builder.setSubCommandGroup(TypeFactory.annotation(SubCommandGroup.class, Map.of("name", options.getFirst().getName()))); -- 2.47.2 From 20471fefeaa860aaf6bd33d105f470f7ef5db112 Mon Sep 17 00:00:00 2001 From: tueem Date: Wed, 19 Feb 2025 09:01:42 +0100 Subject: [PATCH 09/12] fix: logging causing NullPointerException --- .../marinara/interaction/methods/InteractionMethod.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java index fa383e3..ddc3618 100644 --- a/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java +++ b/lib/src/main/java/net/tomatentum/marinara/interaction/methods/InteractionMethod.java @@ -97,7 +97,7 @@ public abstract class InteractionMethod { }else parameter = getParameter(context, i-1); - logger.trace("Found parameter {}={} for method {}", parameter.getClass().toString(), parameter, ReflectionUtil.getFullMethodName(method)); + logger.trace("Found parameter {}={} for method {}", parameter != null ? parameter.getClass().toString() : " ", parameter, ReflectionUtil.getFullMethodName(method)); parameters.add(parameter); } return parameters.toArray(); -- 2.47.2 From 858fab5e3233012d8b8000e9e44de1310e8b0fba Mon Sep 17 00:00:00 2001 From: tueem Date: Wed, 19 Feb 2025 09:02:52 +0100 Subject: [PATCH 10/12] fix: Message ContextObject returning Optional --- .../wrapper/discord4j/Discord4JContextObjectProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java index 82b42ff..d16f789 100644 --- a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java +++ b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/Discord4JContextObjectProvider.java @@ -71,7 +71,7 @@ public class Discord4JContextObjectProvider implements ContextObjectProvider { ComponentInteractionEvent componentInteractionEvent = (ComponentInteractionEvent) context; switch (type.getName()) { case "discord4j.core.object.entity.Message": - return componentInteractionEvent.getMessage(); + return componentInteractionEvent.getMessage().orElse(null); default: return getInteractionContextObject(context, type); } -- 2.47.2 From 842fcfe5ac2de1f1abfab1c4b6838584d3dd3490 Mon Sep 17 00:00:00 2001 From: tueem Date: Wed, 19 Feb 2025 10:50:19 +0100 Subject: [PATCH 11/12] add PermissionCheck --- .../discord4j/checks/PermissionCheck.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/checks/PermissionCheck.java diff --git a/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/checks/PermissionCheck.java b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/checks/PermissionCheck.java new file mode 100644 index 0000000..7497c20 --- /dev/null +++ b/wrapper/discord4j/src/main/java/net/tomatentum/marinara/wrapper/discord4j/checks/PermissionCheck.java @@ -0,0 +1,42 @@ +package net.tomatentum.marinara.wrapper.discord4j.checks; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Optional; + +import discord4j.core.event.domain.interaction.InteractionCreateEvent; +import discord4j.core.object.entity.Member; +import discord4j.rest.util.Permission; +import discord4j.rest.util.PermissionSet; +import net.tomatentum.marinara.checks.InteractionCheck; + +public class PermissionCheck implements InteractionCheck { + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public static @interface HasPermission { + public Permission[] value(); + } + + @Override + public boolean preExec(Object context, HasPermission annotation) { + throw new UnsupportedOperationException("Unimplemented method 'preExec'"); + } + + public boolean preExec(InteractionCreateEvent context, HasPermission annotation) { + Optional member = context.getInteraction().getMember(); + if (member.isEmpty()) + return false; + PermissionSet ownPerms = PermissionSet.of(annotation.value()); + PermissionSet permSet = member.get().getBasePermissions().block(); + return permSet.containsAll(ownPerms); + } + + @Override + public void postExec(Object context, HasPermission annotation) { + + } + +} \ No newline at end of file -- 2.47.2 From 8943d6d4a45f81c36ccb7ecf355ccd46abb5cc70 Mon Sep 17 00:00:00 2001 From: tueem Date: Wed, 19 Feb 2025 10:50:30 +0100 Subject: [PATCH 12/12] add tests --- gradle/libs.versions.toml | 2 + wrapper/discord4j/build.gradle.kts | 3 +- .../test/discord4j/AutoCompleteTest.java | 36 ++++- .../marinara/test/discord4j/ButtonTest.java | 12 +- .../test/discord4j/InteractionCheckTest.java | 51 +++++-- .../test/discord4j/SlashCommandTest.java | 47 +++++-- .../test/discord4j/TestAutocomplete.java | 7 +- .../marinara/test/discord4j/TestButton.java | 23 ++-- .../marinara/test/discord4j/TestCommand.java | 5 +- .../mocks/AutocompleteInteractionMock.java | 17 --- .../mocks/ButtonInteractionMock.java | 25 ---- .../test/discord4j/mocks/ChannelMock.java | 130 ------------------ .../test/discord4j/mocks/CommonMocks.java | 55 ++++++++ .../test/discord4j/mocks/InteractionMock.java | 41 ------ .../mocks/SlashCommandInteractionMock.java | 16 --- .../SlashCommandInteractionOptionMock.java | 25 ---- .../test/discord4j/mocks/UserMock.java | 11 -- 17 files changed, 183 insertions(+), 323 deletions(-) delete mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java delete mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java delete mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java create mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/CommonMocks.java delete mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java delete mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java delete mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java delete mode 100644 wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0d4720c..021ee38 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,6 +7,7 @@ log4j = "2.24.1" javacord = "3.8.0" discord4j = "3.2.7" geantyref = "2.0.0" +mockito = "5.15.2" [libraries] junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } @@ -14,3 +15,4 @@ log4j = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j"} javacord = { module = "org.javacord:javacord", version.ref = "javacord"} discord4j = { module = "com.discord4j:discord4j-core", version.ref = "discord4j"} geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref"} +mockito = {module = "org.mockito:mockito-core", version.ref = "mockito"} diff --git a/wrapper/discord4j/build.gradle.kts b/wrapper/discord4j/build.gradle.kts index 49da9dc..dbbc261 100644 --- a/wrapper/discord4j/build.gradle.kts +++ b/wrapper/discord4j/build.gradle.kts @@ -18,11 +18,12 @@ repositories { dependencies { // Use JUnit Jupiter for testing. testImplementation(libs.junit.jupiter) + testImplementation(libs.mockito) testRuntimeOnly("org.junit.platform:junit-platform-launcher") implementation(libs.log4j) implementation(libs.discord4j) { - exclude(module="discord4j-voice") +// exclude(module="discord4j-voice") } implementation(libs.geantyref) implementation(project(":lib")) diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java index 40cc7b0..62a9259 100644 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/AutoCompleteTest.java @@ -1,23 +1,45 @@ package net.tomatentum.marinara.test.discord4j; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Optional; import org.junit.jupiter.api.Test; +import discord4j.core.event.domain.interaction.ChatInputAutoCompleteEvent; +import discord4j.core.object.command.ApplicationCommandInteractionOption; +import discord4j.core.object.command.ApplicationCommandInteractionOptionValue; +import discord4j.core.object.command.ApplicationCommandOption.Type; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.discord4j.mocks.AutocompleteInteractionMock; -import net.tomatentum.marinara.test.discord4j.mocks.DiscordApiMock; import net.tomatentum.marinara.wrapper.LibraryWrapper; -import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; +import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; public class AutoCompleteTest { @Test public void testAutocomplete() { - LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); //null okay as we don't use the discord API in this test. + ApplicationCommandInteractionOption optionMock = mock(); + ChatInputAutoCompleteEvent autoCompleteEventMock = mock(); + + when(optionMock.getName()).thenReturn("foo"); + when(optionMock.getType()).thenReturn(Type.STRING); + when(optionMock.getValue()).thenReturn( + Optional.of( + new ApplicationCommandInteractionOptionValue(null, null, Type.STRING.getValue(), "test", null) + )); + + when(autoCompleteEventMock.getCommandName()).thenReturn("test"); + when(autoCompleteEventMock.getOptions()).thenReturn(new ArrayList<>()); + when(autoCompleteEventMock.getFocusedOption()).thenReturn(optionMock); + + LibraryWrapper wrapper = new Discord4JWrapper(null); //null okay as we don't use the discord API in this test. Marinara marinara = Marinara.load(wrapper); marinara.getRegistry().addInteractions(new TestAutocomplete()); - wrapper.handleInteraction(new AutocompleteInteractionMock()); - assertTrue(AutocompleteInteractionMock.didAutocompleteRun); + wrapper.handleInteraction(autoCompleteEventMock); + verify(autoCompleteEventMock).respondWithSuggestions(any()); } } diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java index c8b013f..bb0c70b 100644 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/ButtonTest.java @@ -6,21 +6,23 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; +import discord4j.core.event.domain.interaction.ButtonInteractionEvent; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.discord4j.mocks.ButtonInteractionMock; -import net.tomatentum.marinara.test.discord4j.mocks.DiscordApiMock; +import net.tomatentum.marinara.test.discord4j.mocks.CommonMocks; import net.tomatentum.marinara.wrapper.LibraryWrapper; -import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; +import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; @TestInstance(Lifecycle.PER_CLASS) public class ButtonTest { @Test public void testButtonExecution() { - LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); //null okay as we don't use the discord API in this test. + ButtonInteractionEvent buttonEventMock = CommonMocks.getButtonEventMock("test"); + + LibraryWrapper wrapper = new Discord4JWrapper(null); //null okay as we don't use the discord API in this test. Marinara marinara = Marinara.load(wrapper); marinara.getRegistry().addInteractions(new TestButton()); - wrapper.handleInteraction(new ButtonInteractionMock("test")); + wrapper.handleInteraction(buttonEventMock); assertTrue(TestButton.didRun); } diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java index 027dc4a..0e7874c 100644 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/InteractionCheckTest.java @@ -2,46 +2,69 @@ package net.tomatentum.marinara.test.discord4j; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Optional; -import org.javacord.api.entity.permission.PermissionType; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; +import discord4j.core.event.domain.interaction.ButtonInteractionEvent; +import discord4j.core.object.command.Interaction; +import discord4j.core.object.entity.Member; +import discord4j.rest.util.Permission; +import discord4j.rest.util.PermissionSet; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.discord4j.mocks.ButtonInteractionMock; -import net.tomatentum.marinara.test.discord4j.mocks.DiscordApiMock; -import net.tomatentum.marinara.test.discord4j.mocks.ServerMock; +import net.tomatentum.marinara.test.discord4j.mocks.CommonMocks; import net.tomatentum.marinara.wrapper.LibraryWrapper; -import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; -import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck; +import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; +import net.tomatentum.marinara.wrapper.discord4j.checks.PermissionCheck; +import reactor.core.publisher.Mono; @TestInstance(Lifecycle.PER_CLASS) public class InteractionCheckTest { @Test public void testInteractionCheck() { - LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); + ButtonInteractionEvent buttonEventMock = CommonMocks.getButtonEventMock("test"); + + LibraryWrapper wrapper = new Discord4JWrapper(null); Marinara marinara = Marinara.load(wrapper); marinara.getCheckRegistry().addCheck(new TestInteractionCheck()); marinara.getRegistry().addInteractions(new TestButton()); - wrapper.handleInteraction(new ButtonInteractionMock("test")); + wrapper.handleInteraction(buttonEventMock); + assertTrue(TestInteractionCheck.preExecuted); assertTrue(TestInteractionCheck.postExecuted); + assertTrue(TestButton.didRun); } @Test public void testPermissionCheck() { - LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); + Member memberMock = mock(); + Interaction interactionMock = mock(); + + when(memberMock.getBasePermissions()).thenReturn(Mono.just(PermissionSet.none())); + + when(interactionMock.getMember()).thenReturn(Optional.of(memberMock)); + + ButtonInteractionEvent buttonEventMock = CommonMocks.getButtonEventMock("permissionCheck", interactionMock); + + LibraryWrapper wrapper = new Discord4JWrapper(null); Marinara marinara = Marinara.load(wrapper); marinara.getCheckRegistry().addCheck(new PermissionCheck()); marinara.getRegistry().addInteractions(new TestButton()); - wrapper.handleInteraction(new ButtonInteractionMock("permissionCheck")); - assertTrue(TestButton.didPermRun); - TestButton.didPermRun = false; - ServerMock.TESTPERMISSION = PermissionType.ATTACH_FILE; - wrapper.handleInteraction(new ButtonInteractionMock("permissionCheck")); + + wrapper.handleInteraction(buttonEventMock); assertFalse(TestButton.didPermRun); + TestButton.didPermRun = false; + + when(memberMock.getBasePermissions()).thenReturn(Mono.just(PermissionSet.of(Permission.ATTACH_FILES))); + + wrapper.handleInteraction(buttonEventMock); + assertTrue(TestButton.didPermRun); } } diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java index 6cc294a..377f123 100644 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/SlashCommandTest.java @@ -1,39 +1,46 @@ package net.tomatentum.marinara.test.discord4j; -import org.javacord.api.DiscordApi; -import org.javacord.api.DiscordApiBuilder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.Optional; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance.Lifecycle; +import discord4j.core.DiscordClient; +import discord4j.core.GatewayDiscordClient; +import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; +import discord4j.core.object.command.ApplicationCommandInteractionOption; +import discord4j.core.object.command.ApplicationCommandInteractionOptionValue; +import discord4j.core.object.command.ApplicationCommandOption.Type; import net.tomatentum.marinara.Marinara; -import net.tomatentum.marinara.test.discord4j.mocks.SlashCommandInteractionMock; import net.tomatentum.marinara.wrapper.LibraryWrapper; -import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper; +import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; @TestInstance(Lifecycle.PER_CLASS) public class SlashCommandTest { String DISCORD_TOKEN = System.getenv("DISCORD_TEST_TOKEN"); - DiscordApi api; + GatewayDiscordClient client; @BeforeAll void setUp() { - api = new DiscordApiBuilder() - .setToken(DISCORD_TOKEN) - .login().join(); + client = DiscordClient.create(DISCORD_TOKEN).login().block(); } @AfterAll void tearDown() { - api.disconnect(); - api = null; + client.logout().block(); + client = null; } @Test void testSlashCommand() { - Marinara marinara = Marinara.load(new JavacordWrapper(api)); + Marinara marinara = Marinara.load(new Discord4JWrapper(client)); marinara.getRegistry().addInteractions(new TestCommand()); marinara.getRegistry().registerCommands(); System.out.println("Success!"); @@ -41,11 +48,25 @@ public class SlashCommandTest { @Test void testSlashCommandExecution() { - LibraryWrapper wrapper = new JavacordWrapper(api); + ApplicationCommandInteractionOption optionMock = mock(); + ChatInputInteractionEvent eventMock = mock(); + + when(optionMock.getName()).thenReturn("foo"); + when(optionMock.getType()).thenReturn(Type.STRING); + when(optionMock.getValue()).thenReturn( + Optional.of( + new ApplicationCommandInteractionOptionValue(null, null, Type.STRING.getValue(), "test", null) + )); + + when(eventMock.getCommandName()).thenReturn("test"); + when(eventMock.getOptions()).thenReturn(Arrays.asList(optionMock)); + when(eventMock.getOption("foo")).thenReturn(Optional.of(optionMock)); + + LibraryWrapper wrapper = new Discord4JWrapper(client); Marinara marinara = Marinara.load(wrapper); marinara.getRegistry().addInteractions(new TestCommand()); - wrapper.handleInteraction(new SlashCommandInteractionMock()); + wrapper.handleInteraction(eventMock); } diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java index 391d67d..d216805 100644 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestAutocomplete.java @@ -4,8 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Collections; -import org.javacord.api.interaction.AutocompleteInteraction; - +import discord4j.core.event.domain.interaction.ChatInputAutoCompleteEvent; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.annotation.AutoComplete; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; @@ -14,10 +13,10 @@ public class TestAutocomplete implements InteractionHandler { @SlashCommand(name = "test") @AutoComplete - public void autocomplete(AutocompleteInteraction context, String value) { + public void autocomplete(ChatInputAutoCompleteEvent context, String value) { System.out.println("Success!"); assertEquals(value, "test"); - context.respondWithChoices(Collections.emptyList()); + context.respondWithSuggestions(Collections.emptyList()); } } diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java index d991392..25a1c91 100644 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestButton.java @@ -2,17 +2,17 @@ package net.tomatentum.marinara.test.discord4j; import static org.junit.jupiter.api.Assertions.assertNotNull; -import org.javacord.api.entity.channel.TextChannel; -import org.javacord.api.entity.message.Message; -import org.javacord.api.entity.permission.PermissionType; -import org.javacord.api.entity.server.Server; -import org.javacord.api.entity.user.User; -import org.javacord.api.interaction.ButtonInteraction; - +import discord4j.core.event.domain.interaction.ButtonInteractionEvent; +import discord4j.core.object.entity.Guild; +import discord4j.core.object.entity.Member; +import discord4j.core.object.entity.Message; +import discord4j.core.object.entity.User; +import discord4j.core.object.entity.channel.MessageChannel; +import discord4j.rest.util.Permission; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.annotation.Button; import net.tomatentum.marinara.test.discord4j.TestInteractionCheck.TestCheck; -import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck.HasPermission; +import net.tomatentum.marinara.wrapper.discord4j.checks.PermissionCheck.HasPermission; public class TestButton implements InteractionHandler { @@ -20,11 +20,12 @@ public class TestButton implements InteractionHandler { public static boolean didRun = false; @Button("test") @TestCheck - public void exec(ButtonInteraction interaction, TextChannel channel, Message message, User member, Server server) { + public void exec(ButtonInteractionEvent interaction, MessageChannel channel, Message message, Member member, User user, Guild server) { assertNotNull(interaction); assertNotNull(channel); assertNotNull(message); assertNotNull(member); + assertNotNull(user); assertNotNull(server); didRun = true; System.out.println("Success!"); @@ -33,8 +34,8 @@ public class TestButton implements InteractionHandler { public static boolean didPermRun = false; @Button("permissionCheck") - @HasPermission({PermissionType.ADMINISTRATOR}) - public void exec(ButtonInteraction interaction) { + @HasPermission({Permission.ATTACH_FILES}) + public void exec(ButtonInteractionEvent interaction) { didPermRun = true; System.out.println("It worked!"); } diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java index 95c439f..8a98424 100644 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/TestCommand.java @@ -2,8 +2,7 @@ package net.tomatentum.marinara.test.discord4j; import static org.junit.jupiter.api.Assertions.assertEquals; -import org.javacord.api.interaction.SlashCommandInteraction; - +import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; @@ -25,7 +24,7 @@ public class TestCommand implements InteractionHandler { ) } ) - public void exec(SlashCommandInteraction interaction, String test) { + public void exec(ChatInputInteractionEvent event, String test) { assertEquals(test, "test"); System.out.println("Success!"); } diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java deleted file mode 100644 index 226ba1d..0000000 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/AutocompleteInteractionMock.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.tomatentum.marinara.test.discord4j.mocks; - -import discord4j.core.GatewayDiscordClient; -import discord4j.core.event.domain.interaction.ChatInputAutoCompleteEvent; -import discord4j.core.object.command.Interaction; -import discord4j.gateway.ShardInfo; - -public class AutocompleteInteractionMock extends ChatInputAutoCompleteEvent { - - public AutocompleteInteractionMock(GatewayDiscordClient gateway, ShardInfo shardInfo, Interaction interaction) { - super(gateway, shardInfo, interaction); - //TODO Auto-generated constructor stub - } - - public static boolean didAutocompleteRun = false; - -} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java deleted file mode 100644 index 0583329..0000000 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ButtonInteractionMock.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.tomatentum.marinara.test.discord4j.mocks; - -import discord4j.core.event.domain.interaction.ButtonInteractionEvent; -import discord4j.core.object.command.Interaction; - -public class ButtonInteractionMock extends ButtonInteractionEvent { - - private String customId; - - public ButtonInteractionMock(String customId) { - super(null, null, null); - this.customId = customId; - } - - @Override - public String getCustomId() { - return customId; - } - - @Override - public Interaction getInteraction() { - return new InteractionMock(); - } - -} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java deleted file mode 100644 index ba491fe..0000000 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/ChannelMock.java +++ /dev/null @@ -1,130 +0,0 @@ -package net.tomatentum.marinara.test.discord4j.mocks; - -import java.time.Instant; -import java.util.Optional; -import java.util.function.Consumer; - -import org.reactivestreams.Publisher; - -import discord4j.common.util.Snowflake; -import discord4j.core.GatewayDiscordClient; -import discord4j.core.object.entity.Message; -import discord4j.core.object.entity.channel.MessageChannel; -import discord4j.core.retriever.EntityRetrievalStrategy; -import discord4j.core.spec.MessageCreateSpec; -import discord4j.core.spec.legacy.LegacyMessageCreateSpec; -import discord4j.rest.entity.RestChannel; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -public class ChannelMock implements MessageChannel { - - @Override - public Type getType() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getType'"); - } - - @Override - public Mono delete(String reason) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'delete'"); - } - - @Override - public RestChannel getRestChannel() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getRestChannel'"); - } - - @Override - public Snowflake getId() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getId'"); - } - - @Override - public GatewayDiscordClient getClient() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getClient'"); - } - - @Override - public Optional getLastMessageId() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getLastMessageId'"); - } - - @Override - public Mono getLastMessage() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getLastMessage'"); - } - - @Override - public Mono getLastMessage(EntityRetrievalStrategy retrievalStrategy) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getLastMessage'"); - } - - @Override - public Optional getLastPinTimestamp() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getLastPinTimestamp'"); - } - - @Override - public Mono createMessage(Consumer spec) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'createMessage'"); - } - - @Override - public Mono createMessage(MessageCreateSpec spec) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'createMessage'"); - } - - @Override - public Mono type() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'type'"); - } - - @Override - public Flux typeUntil(Publisher until) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'typeUntil'"); - } - - @Override - public Flux getMessagesBefore(Snowflake messageId) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getMessagesBefore'"); - } - - @Override - public Flux getMessagesAfter(Snowflake messageId) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getMessagesAfter'"); - } - - @Override - public Mono getMessageById(Snowflake id) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getMessageById'"); - } - - @Override - public Mono getMessageById(Snowflake id, EntityRetrievalStrategy retrievalStrategy) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getMessageById'"); - } - - @Override - public Flux getPinnedMessages() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getPinnedMessages'"); - } - -} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/CommonMocks.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/CommonMocks.java new file mode 100644 index 0000000..f000365 --- /dev/null +++ b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/CommonMocks.java @@ -0,0 +1,55 @@ +package net.tomatentum.marinara.test.discord4j.mocks; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Optional; + +import discord4j.core.event.domain.interaction.ButtonInteractionEvent; +import discord4j.core.object.command.Interaction; +import discord4j.core.object.entity.Guild; +import discord4j.core.object.entity.Member; +import discord4j.core.object.entity.Message; +import discord4j.core.object.entity.User; +import discord4j.core.object.entity.channel.MessageChannel; +import reactor.core.publisher.Mono; + +public class CommonMocks { + public static Interaction getInteractionMock() { + Interaction interaction = mock(Interaction.class); + Message message = mock(Message.class); + MessageChannel channel = mock(MessageChannel.class); + Guild guild = mock(Guild.class); + User user = mock(User.class); + Member member = mock(Member.class); + + + when(interaction.getMessage()).thenReturn(Optional.of(message)); + when(interaction.getChannel()).thenReturn(Mono.just(channel)); + when(interaction.getGuild()).thenReturn(Mono.just(guild)); + when(interaction.getUser()).thenReturn(user); + when(interaction.getMember()).thenReturn(Optional.of(member)); + + + return interaction; + } + + public static ButtonInteractionEvent getButtonEventMock(String customId) { + ButtonInteractionEvent buttonEventMock = mock(ButtonInteractionEvent.class); + + when(buttonEventMock.getCustomId()).thenReturn(customId); + Interaction interactionMock = getInteractionMock(); + when(buttonEventMock.getInteraction()).thenReturn(interactionMock); + Optional message = interactionMock.getMessage(); + when (buttonEventMock.getMessage()).thenReturn(message); + return buttonEventMock; + } + + public static ButtonInteractionEvent getButtonEventMock(String customId, Interaction interaction) { + ButtonInteractionEvent buttonEventMock = mock(ButtonInteractionEvent.class); + + when(buttonEventMock.getCustomId()).thenReturn(customId); + when(buttonEventMock.getInteraction()).thenReturn(interaction); + return buttonEventMock; + } +} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java deleted file mode 100644 index 4de0152..0000000 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/InteractionMock.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.tomatentum.marinara.test.discord4j.mocks; - -import java.util.Optional; - -import discord4j.core.object.command.Interaction; -import discord4j.core.object.entity.Guild; -import discord4j.core.object.entity.Message; -import discord4j.core.object.entity.User; -import discord4j.core.object.entity.channel.MessageChannel; -import reactor.core.publisher.Mono; - -public class InteractionMock extends Interaction - { - - public InteractionMock() { - super(null, null); - } - - @Override - public Optional getMessage() { - //return Optional.of(new MessageMock()); - return Optional.empty(); - } - - @Override - public Mono getChannel() { - return Mono.just(new ChannelMock()); - } - - @Override - public Mono getGuild() { - //return Mono.just(new ServerMock()); - return Mono.empty(); - } - - @Override - public User getUser() { - return new UserMock(); - } - -} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java deleted file mode 100644 index 07ad550..0000000 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionMock.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.tomatentum.marinara.test.discord4j.mocks; - -import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; - -public class SlashCommandInteractionMock extends ChatInputInteractionEvent { - - public SlashCommandInteractionMock() { - super(null, null, null); - } - - @Override - public String getCommandName() { - return "test"; - } - -} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java deleted file mode 100644 index 2c67577..0000000 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/SlashCommandInteractionOptionMock.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.tomatentum.marinara.test.discord4j.mocks; - -import java.util.Optional; - -import discord4j.core.object.command.ApplicationCommandInteractionOption; -import discord4j.core.object.command.ApplicationCommandInteractionOptionValue; -import discord4j.core.object.command.ApplicationCommandOption.Type; - -public class SlashCommandInteractionOptionMock extends ApplicationCommandInteractionOption { - - public SlashCommandInteractionOptionMock() { - super(null, null, null, null); - } - - @Override - public String getName() { - return "foo"; - } - - @Override - public Optional getValue() { - return Optional.of(new ApplicationCommandInteractionOptionValue(null, null, Type.STRING.getValue(), "test", null)); - } - -} diff --git a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java b/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java deleted file mode 100644 index 0d8851d..0000000 --- a/wrapper/discord4j/src/test/java/net/tomatentum/marinara/test/discord4j/mocks/UserMock.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.tomatentum.marinara.test.discord4j.mocks; - -import discord4j.core.object.entity.User; - -public class UserMock extends User { - - public UserMock() { - super(null, null); - } - -} -- 2.47.2