Compare commits

..

No commits in common. "8943d6d4a45f81c36ccb7ecf355ccd46abb5cc70" and "f81602f5db259d33ff32974dd07983317f8fae8f" have entirely different histories.

21 changed files with 333 additions and 243 deletions

View File

@ -7,7 +7,6 @@ log4j = "2.24.1"
javacord = "3.8.0" javacord = "3.8.0"
discord4j = "3.2.7" discord4j = "3.2.7"
geantyref = "2.0.0" geantyref = "2.0.0"
mockito = "5.15.2"
[libraries] [libraries]
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }
@ -15,4 +14,3 @@ log4j = { module = "org.apache.logging.log4j:log4j-api", version.ref = "log4j"}
javacord = { module = "org.javacord:javacord", version.ref = "javacord"} javacord = { module = "org.javacord:javacord", version.ref = "javacord"}
discord4j = { module = "com.discord4j:discord4j-core", version.ref = "discord4j"} discord4j = { module = "com.discord4j:discord4j-core", version.ref = "discord4j"}
geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref"} geantyref = { module = "io.leangen.geantyref:geantyref", version.ref = "geantyref"}
mockito = {module = "org.mockito:mockito-core", version.ref = "mockito"}

View File

@ -97,7 +97,7 @@ public abstract class InteractionMethod {
}else }else
parameter = getParameter(context, i-1); parameter = getParameter(context, i-1);
logger.trace("Found parameter {}={} for method {}", parameter != null ? parameter.getClass().toString() : " ", parameter, ReflectionUtil.getFullMethodName(method)); logger.trace("Found parameter {}={} for method {}", parameter.getClass().toString(), parameter, ReflectionUtil.getFullMethodName(method));
parameters.add(parameter); parameters.add(parameter);
} }
return parameters.toArray(); return parameters.toArray();

View File

@ -18,12 +18,11 @@ repositories {
dependencies { dependencies {
// Use JUnit Jupiter for testing. // Use JUnit Jupiter for testing.
testImplementation(libs.junit.jupiter) testImplementation(libs.junit.jupiter)
testImplementation(libs.mockito)
testRuntimeOnly("org.junit.platform:junit-platform-launcher") testRuntimeOnly("org.junit.platform:junit-platform-launcher")
implementation(libs.log4j) implementation(libs.log4j)
implementation(libs.discord4j) { implementation(libs.discord4j) {
// exclude(module="discord4j-voice") exclude(module="discord4j-voice")
} }
implementation(libs.geantyref) implementation(libs.geantyref)
implementation(project(":lib")) implementation(project(":lib"))

View File

@ -71,7 +71,7 @@ public class Discord4JContextObjectProvider implements ContextObjectProvider {
ComponentInteractionEvent componentInteractionEvent = (ComponentInteractionEvent) context; ComponentInteractionEvent componentInteractionEvent = (ComponentInteractionEvent) context;
switch (type.getName()) { switch (type.getName()) {
case "discord4j.core.object.entity.Message": case "discord4j.core.object.entity.Message":
return componentInteractionEvent.getMessage().orElse(null); return componentInteractionEvent.getMessage();
default: default:
return getInteractionContextObject(context, type); return getInteractionContextObject(context, type);
} }

View File

@ -33,6 +33,7 @@ import net.tomatentum.marinara.interaction.commands.annotation.SubCommandGroup;
import net.tomatentum.marinara.util.LoggerUtil; import net.tomatentum.marinara.util.LoggerUtil;
import net.tomatentum.marinara.wrapper.ContextObjectProvider; import net.tomatentum.marinara.wrapper.ContextObjectProvider;
import net.tomatentum.marinara.wrapper.LibraryWrapper; import net.tomatentum.marinara.wrapper.LibraryWrapper;
import reactor.core.publisher.Mono;
public class Discord4JWrapper extends LibraryWrapper { public class Discord4JWrapper extends LibraryWrapper {
@ -54,9 +55,9 @@ public class Discord4JWrapper extends LibraryWrapper {
public Discord4JWrapper(GatewayDiscordClient api) { public Discord4JWrapper(GatewayDiscordClient api) {
this.api = api; this.api = api;
this.contextObjectProvider = new Discord4JContextObjectProvider(); this.contextObjectProvider = new Discord4JContextObjectProvider();
if (api != null)
api.on(InteractionCreateEvent.class) api.on(InteractionCreateEvent.class)
.subscribe(event -> handleInteraction(event)); .subscribe(event -> handleInteraction(event));
Mono.just("test").subscribe(logger::debug);
logger.info("Discord4J wrapper loaded!"); logger.info("Discord4J wrapper loaded!");
} }
@ -98,24 +99,15 @@ public class Discord4JWrapper extends LibraryWrapper {
@Override @Override
public ExecutableSlashCommandDefinition getCommandDefinition(Object context) { public ExecutableSlashCommandDefinition getCommandDefinition(Object context) {
List<ApplicationCommandInteractionOption> options; if (!(context instanceof ChatInputInteractionEvent))
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; return null;
ChatInputInteractionEvent interaction = (ChatInputInteractionEvent) context;
ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder(); ExecutableSlashCommandDefinition.Builder builder = new ExecutableSlashCommandDefinition.Builder();
List<ApplicationCommandInteractionOption> options = SUB_FILTER.apply(interaction.getOptions());
try { try {
builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", commandName))); builder.setApplicationCommand(TypeFactory.annotation(SlashCommand.class, Map.of("name", interaction.getCommandName())));
if (!options.isEmpty()) { if (!options.isEmpty()) {
if (!ARG_FILTER.apply(options.getFirst().getOptions()).isEmpty()) { if (!ARG_FILTER.apply(options.getFirst().getOptions()).isEmpty()) {
builder.setSubCommandGroup(TypeFactory.annotation(SubCommandGroup.class, Map.of("name", options.getFirst().getName()))); builder.setSubCommandGroup(TypeFactory.annotation(SubCommandGroup.class, Map.of("name", options.getFirst().getName())));

View File

@ -1,42 +0,0 @@
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<PermissionCheck.HasPermission> {
@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> 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) {
}
}

View File

@ -1,45 +1,23 @@
package net.tomatentum.marinara.test.discord4j; package net.tomatentum.marinara.test.discord4j;
import static org.mockito.ArgumentMatchers.any; import static org.junit.jupiter.api.Assertions.assertTrue;
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 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.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.LibraryWrapper;
import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper;
public class AutoCompleteTest { public class AutoCompleteTest {
@Test @Test
public void testAutocomplete() { public void testAutocomplete() {
ApplicationCommandInteractionOption optionMock = mock(); LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); //null okay as we don't use the discord API in this test.
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 marinara = Marinara.load(wrapper);
marinara.getRegistry().addInteractions(new TestAutocomplete()); marinara.getRegistry().addInteractions(new TestAutocomplete());
wrapper.handleInteraction(autoCompleteEventMock); wrapper.handleInteraction(new AutocompleteInteractionMock());
verify(autoCompleteEventMock).respondWithSuggestions(any()); assertTrue(AutocompleteInteractionMock.didAutocompleteRun);
} }
} }

View File

@ -6,23 +6,21 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.TestInstance.Lifecycle;
import discord4j.core.event.domain.interaction.ButtonInteractionEvent;
import net.tomatentum.marinara.Marinara; import net.tomatentum.marinara.Marinara;
import net.tomatentum.marinara.test.discord4j.mocks.CommonMocks; 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.LibraryWrapper;
import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper;
@TestInstance(Lifecycle.PER_CLASS) @TestInstance(Lifecycle.PER_CLASS)
public class ButtonTest { public class ButtonTest {
@Test @Test
public void testButtonExecution() { public void testButtonExecution() {
ButtonInteractionEvent buttonEventMock = CommonMocks.getButtonEventMock("test"); LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock()); //null okay as we don't use the discord API in this 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 marinara = Marinara.load(wrapper);
marinara.getRegistry().addInteractions(new TestButton()); marinara.getRegistry().addInteractions(new TestButton());
wrapper.handleInteraction(buttonEventMock); wrapper.handleInteraction(new ButtonInteractionMock("test"));
assertTrue(TestButton.didRun); assertTrue(TestButton.didRun);
} }

View File

@ -2,69 +2,46 @@ package net.tomatentum.marinara.test.discord4j;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; 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.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; 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.Marinara;
import net.tomatentum.marinara.test.discord4j.mocks.CommonMocks; 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.LibraryWrapper;
import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper;
import net.tomatentum.marinara.wrapper.discord4j.checks.PermissionCheck; import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck;
import reactor.core.publisher.Mono;
@TestInstance(Lifecycle.PER_CLASS) @TestInstance(Lifecycle.PER_CLASS)
public class InteractionCheckTest { public class InteractionCheckTest {
@Test @Test
public void testInteractionCheck() { public void testInteractionCheck() {
ButtonInteractionEvent buttonEventMock = CommonMocks.getButtonEventMock("test"); LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock());
LibraryWrapper wrapper = new Discord4JWrapper(null);
Marinara marinara = Marinara.load(wrapper); Marinara marinara = Marinara.load(wrapper);
marinara.getCheckRegistry().addCheck(new TestInteractionCheck()); marinara.getCheckRegistry().addCheck(new TestInteractionCheck());
marinara.getRegistry().addInteractions(new TestButton()); marinara.getRegistry().addInteractions(new TestButton());
wrapper.handleInteraction(buttonEventMock); wrapper.handleInteraction(new ButtonInteractionMock("test"));
assertTrue(TestInteractionCheck.preExecuted); assertTrue(TestInteractionCheck.preExecuted);
assertTrue(TestInteractionCheck.postExecuted); assertTrue(TestInteractionCheck.postExecuted);
assertTrue(TestButton.didRun);
} }
@Test @Test
public void testPermissionCheck() { public void testPermissionCheck() {
Member memberMock = mock(); LibraryWrapper wrapper = new JavacordWrapper(new DiscordApiMock());
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 marinara = Marinara.load(wrapper);
marinara.getCheckRegistry().addCheck(new PermissionCheck()); marinara.getCheckRegistry().addCheck(new PermissionCheck());
marinara.getRegistry().addInteractions(new TestButton()); marinara.getRegistry().addInteractions(new TestButton());
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); assertTrue(TestButton.didPermRun);
TestButton.didPermRun = false;
ServerMock.TESTPERMISSION = PermissionType.ATTACH_FILE;
wrapper.handleInteraction(new ButtonInteractionMock("permissionCheck"));
assertFalse(TestButton.didPermRun);
} }
} }

View File

@ -1,46 +1,39 @@
package net.tomatentum.marinara.test.discord4j; package net.tomatentum.marinara.test.discord4j;
import static org.mockito.Mockito.mock; import org.javacord.api.DiscordApi;
import static org.mockito.Mockito.when; import org.javacord.api.DiscordApiBuilder;
import java.util.Arrays;
import java.util.Optional;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; 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.Marinara;
import net.tomatentum.marinara.test.discord4j.mocks.SlashCommandInteractionMock;
import net.tomatentum.marinara.wrapper.LibraryWrapper; import net.tomatentum.marinara.wrapper.LibraryWrapper;
import net.tomatentum.marinara.wrapper.discord4j.Discord4JWrapper; import net.tomatentum.marinara.wrapper.javacord.JavacordWrapper;
@TestInstance(Lifecycle.PER_CLASS) @TestInstance(Lifecycle.PER_CLASS)
public class SlashCommandTest { public class SlashCommandTest {
String DISCORD_TOKEN = System.getenv("DISCORD_TEST_TOKEN"); String DISCORD_TOKEN = System.getenv("DISCORD_TEST_TOKEN");
GatewayDiscordClient client; DiscordApi api;
@BeforeAll @BeforeAll
void setUp() { void setUp() {
client = DiscordClient.create(DISCORD_TOKEN).login().block(); api = new DiscordApiBuilder()
.setToken(DISCORD_TOKEN)
.login().join();
} }
@AfterAll @AfterAll
void tearDown() { void tearDown() {
client.logout().block(); api.disconnect();
client = null; api = null;
} }
@Test @Test
void testSlashCommand() { void testSlashCommand() {
Marinara marinara = Marinara.load(new Discord4JWrapper(client)); Marinara marinara = Marinara.load(new JavacordWrapper(api));
marinara.getRegistry().addInteractions(new TestCommand()); marinara.getRegistry().addInteractions(new TestCommand());
marinara.getRegistry().registerCommands(); marinara.getRegistry().registerCommands();
System.out.println("Success!"); System.out.println("Success!");
@ -48,25 +41,11 @@ public class SlashCommandTest {
@Test @Test
void testSlashCommandExecution() { void testSlashCommandExecution() {
ApplicationCommandInteractionOption optionMock = mock(); LibraryWrapper wrapper = new JavacordWrapper(api);
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 marinara = Marinara.load(wrapper);
marinara.getRegistry().addInteractions(new TestCommand()); marinara.getRegistry().addInteractions(new TestCommand());
wrapper.handleInteraction(eventMock); wrapper.handleInteraction(new SlashCommandInteractionMock());
} }

View File

@ -4,7 +4,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Collections; import java.util.Collections;
import discord4j.core.event.domain.interaction.ChatInputAutoCompleteEvent; import org.javacord.api.interaction.AutocompleteInteraction;
import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionHandler;
import net.tomatentum.marinara.interaction.annotation.AutoComplete; import net.tomatentum.marinara.interaction.annotation.AutoComplete;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand;
@ -13,10 +14,10 @@ public class TestAutocomplete implements InteractionHandler {
@SlashCommand(name = "test") @SlashCommand(name = "test")
@AutoComplete @AutoComplete
public void autocomplete(ChatInputAutoCompleteEvent context, String value) { public void autocomplete(AutocompleteInteraction context, String value) {
System.out.println("Success!"); System.out.println("Success!");
assertEquals(value, "test"); assertEquals(value, "test");
context.respondWithSuggestions(Collections.emptyList()); context.respondWithChoices(Collections.emptyList());
} }
} }

View File

@ -2,17 +2,17 @@ package net.tomatentum.marinara.test.discord4j;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import discord4j.core.event.domain.interaction.ButtonInteractionEvent; import org.javacord.api.entity.channel.TextChannel;
import discord4j.core.object.entity.Guild; import org.javacord.api.entity.message.Message;
import discord4j.core.object.entity.Member; import org.javacord.api.entity.permission.PermissionType;
import discord4j.core.object.entity.Message; import org.javacord.api.entity.server.Server;
import discord4j.core.object.entity.User; import org.javacord.api.entity.user.User;
import discord4j.core.object.entity.channel.MessageChannel; import org.javacord.api.interaction.ButtonInteraction;
import discord4j.rest.util.Permission;
import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionHandler;
import net.tomatentum.marinara.interaction.annotation.Button; import net.tomatentum.marinara.interaction.annotation.Button;
import net.tomatentum.marinara.test.discord4j.TestInteractionCheck.TestCheck; import net.tomatentum.marinara.test.discord4j.TestInteractionCheck.TestCheck;
import net.tomatentum.marinara.wrapper.discord4j.checks.PermissionCheck.HasPermission; import net.tomatentum.marinara.wrapper.javacord.checks.PermissionCheck.HasPermission;
public class TestButton implements InteractionHandler { public class TestButton implements InteractionHandler {
@ -20,12 +20,11 @@ public class TestButton implements InteractionHandler {
public static boolean didRun = false; public static boolean didRun = false;
@Button("test") @Button("test")
@TestCheck @TestCheck
public void exec(ButtonInteractionEvent interaction, MessageChannel channel, Message message, Member member, User user, Guild server) { public void exec(ButtonInteraction interaction, TextChannel channel, Message message, User member, Server server) {
assertNotNull(interaction); assertNotNull(interaction);
assertNotNull(channel); assertNotNull(channel);
assertNotNull(message); assertNotNull(message);
assertNotNull(member); assertNotNull(member);
assertNotNull(user);
assertNotNull(server); assertNotNull(server);
didRun = true; didRun = true;
System.out.println("Success!"); System.out.println("Success!");
@ -34,8 +33,8 @@ public class TestButton implements InteractionHandler {
public static boolean didPermRun = false; public static boolean didPermRun = false;
@Button("permissionCheck") @Button("permissionCheck")
@HasPermission({Permission.ATTACH_FILES}) @HasPermission({PermissionType.ADMINISTRATOR})
public void exec(ButtonInteractionEvent interaction) { public void exec(ButtonInteraction interaction) {
didPermRun = true; didPermRun = true;
System.out.println("It worked!"); System.out.println("It worked!");
} }

View File

@ -2,7 +2,8 @@ package net.tomatentum.marinara.test.discord4j;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent; import org.javacord.api.interaction.SlashCommandInteraction;
import net.tomatentum.marinara.interaction.InteractionHandler; import net.tomatentum.marinara.interaction.InteractionHandler;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommand;
import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption; import net.tomatentum.marinara.interaction.commands.annotation.SlashCommandOption;
@ -24,7 +25,7 @@ public class TestCommand implements InteractionHandler {
) )
} }
) )
public void exec(ChatInputInteractionEvent event, String test) { public void exec(SlashCommandInteraction interaction, String test) {
assertEquals(test, "test"); assertEquals(test, "test");
System.out.println("Success!"); System.out.println("Success!");
} }

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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<Void> 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<Snowflake> getLastMessageId() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getLastMessageId'");
}
@Override
public Mono<Message> getLastMessage() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getLastMessage'");
}
@Override
public Mono<Message> getLastMessage(EntityRetrievalStrategy retrievalStrategy) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getLastMessage'");
}
@Override
public Optional<Instant> getLastPinTimestamp() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getLastPinTimestamp'");
}
@Override
public Mono<Message> createMessage(Consumer<? super LegacyMessageCreateSpec> spec) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'createMessage'");
}
@Override
public Mono<Message> createMessage(MessageCreateSpec spec) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'createMessage'");
}
@Override
public Mono<Void> type() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'type'");
}
@Override
public Flux<Long> typeUntil(Publisher<?> until) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'typeUntil'");
}
@Override
public Flux<Message> getMessagesBefore(Snowflake messageId) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getMessagesBefore'");
}
@Override
public Flux<Message> getMessagesAfter(Snowflake messageId) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getMessagesAfter'");
}
@Override
public Mono<Message> getMessageById(Snowflake id) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getMessageById'");
}
@Override
public Mono<Message> getMessageById(Snowflake id, EntityRetrievalStrategy retrievalStrategy) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getMessageById'");
}
@Override
public Flux<Message> getPinnedMessages() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'getPinnedMessages'");
}
}

View File

@ -1,55 +0,0 @@
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> 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;
}
}

View File

@ -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<Message> getMessage() {
//return Optional.of(new MessageMock());
return Optional.empty();
}
@Override
public Mono<MessageChannel> getChannel() {
return Mono.just(new ChannelMock());
}
@Override
public Mono<Guild> getGuild() {
//return Mono.just(new ServerMock());
return Mono.empty();
}
@Override
public User getUser() {
return new UserMock();
}
}

View File

@ -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";
}
}

View File

@ -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<ApplicationCommandInteractionOptionValue> getValue() {
return Optional.of(new ApplicationCommandInteractionOptionValue(null, null, Type.STRING.getValue(), "test", null));
}
}

View File

@ -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);
}
}