From 4ef9b7efbc6fa9b9d70a2222f62eab8c3431e40b Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Thu, 5 Mar 2026 17:50:10 +0700 Subject: [PATCH 1/3] feat: add tests --- .../java/org/discordbots/api/DBLAPITest.java | 69 ++++++++++++ .../org/discordbots/api/DBLWidgetTest.java | 31 ++++++ .../api/interceptors/BaseInterceptor.java | 60 ++++++++++ .../api/interceptors/GetSelfInterceptor.java | 20 ++++ .../api/interceptors/GetVoteInterceptor.java | 22 ++++ .../api/interceptors/GetVotesInterceptor.java | 22 ++++ .../interceptors/PostCommandsInterceptor.java | 20 ++++ .../webhooks/DBLWebhooksTestSuite.java | 15 +++ .../java/org/discordbots/webhooks/Mocks.java | 47 ++++++++ .../webhooks/dropwizard/CustomServer.java | 16 +++ .../webhooks/dropwizard/CustomWebhooks.java | 35 ++++++ .../dropwizard/DBLDropwizardWebhooksTest.java | 68 ++++++++++++ .../webhooks/eclipsejetty/CustomWebhooks.java | 51 +++++++++ .../DBLEclipseJettyWebhooksTest.java | 105 ++++++++++++++++++ .../webhooks/springboot/CustomServer.java | 11 ++ .../CustomServerSecurityConfiguration.java | 16 +++ .../webhooks/springboot/CustomWebhooks.java | 49 ++++++++ .../springboot/DBLSpringBootWebhooksTest.java | 59 ++++++++++ src/test/resources/GetSelfResponse.json | 16 +++ src/test/resources/GetVoteResponse.json | 5 + src/test/resources/GetVotesResponse.json | 33 ++++++ .../resources/IntegrationCreatePayload.json | 19 ++++ .../resources/IntegrationDeletePayload.json | 6 + src/test/resources/LeadResponse.json | 3 + src/test/resources/PostCommands.json | 11 ++ src/test/resources/TestPayload.json | 17 +++ src/test/resources/VoteCreatePayload.json | 21 ++++ src/test/resources/dropwizard-test-config.yml | 7 ++ 28 files changed, 854 insertions(+) create mode 100644 src/test/java/org/discordbots/api/DBLAPITest.java create mode 100644 src/test/java/org/discordbots/api/DBLWidgetTest.java create mode 100644 src/test/java/org/discordbots/api/interceptors/BaseInterceptor.java create mode 100644 src/test/java/org/discordbots/api/interceptors/GetSelfInterceptor.java create mode 100644 src/test/java/org/discordbots/api/interceptors/GetVoteInterceptor.java create mode 100644 src/test/java/org/discordbots/api/interceptors/GetVotesInterceptor.java create mode 100644 src/test/java/org/discordbots/api/interceptors/PostCommandsInterceptor.java create mode 100644 src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java create mode 100644 src/test/java/org/discordbots/webhooks/Mocks.java create mode 100644 src/test/java/org/discordbots/webhooks/dropwizard/CustomServer.java create mode 100644 src/test/java/org/discordbots/webhooks/dropwizard/CustomWebhooks.java create mode 100644 src/test/java/org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java create mode 100644 src/test/java/org/discordbots/webhooks/eclipsejetty/CustomWebhooks.java create mode 100644 src/test/java/org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java create mode 100644 src/test/java/org/discordbots/webhooks/springboot/CustomServer.java create mode 100644 src/test/java/org/discordbots/webhooks/springboot/CustomServerSecurityConfiguration.java create mode 100644 src/test/java/org/discordbots/webhooks/springboot/CustomWebhooks.java create mode 100644 src/test/java/org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java create mode 100644 src/test/resources/GetSelfResponse.json create mode 100644 src/test/resources/GetVoteResponse.json create mode 100644 src/test/resources/GetVotesResponse.json create mode 100644 src/test/resources/IntegrationCreatePayload.json create mode 100644 src/test/resources/IntegrationDeletePayload.json create mode 100644 src/test/resources/LeadResponse.json create mode 100644 src/test/resources/PostCommands.json create mode 100644 src/test/resources/TestPayload.json create mode 100644 src/test/resources/VoteCreatePayload.json create mode 100644 src/test/resources/dropwizard-test-config.yml diff --git a/src/test/java/org/discordbots/api/DBLAPITest.java b/src/test/java/org/discordbots/api/DBLAPITest.java new file mode 100644 index 0000000..99fb651 --- /dev/null +++ b/src/test/java/org/discordbots/api/DBLAPITest.java @@ -0,0 +1,69 @@ +package org.discordbots.api; + +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import okhttp3.OkHttpClient; +import org.discordbots.api.entity.PaginatedVotes; +import org.discordbots.api.entity.UserSource; +import org.discordbots.api.interceptors.GetSelfInterceptor; +import org.discordbots.api.interceptors.GetVoteInterceptor; +import org.discordbots.api.interceptors.GetVotesInterceptor; +import org.discordbots.api.interceptors.PostCommandsInterceptor; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +public class DBLAPITest { + private static DBLAPI CLIENT; + + @BeforeAll + public static void setup() { + CLIENT = + new DBLAPI( + new OkHttpClient.Builder() + .addInterceptor(new GetSelfInterceptor()) + .addInterceptor(new GetVoteInterceptor()) + .addInterceptor(new GetVotesInterceptor()) + .addInterceptor(new PostCommandsInterceptor()) + .build()); + } + + @Test + public void getSelf() { + CLIENT.getSelf().toCompletableFuture().join(); + } + + @Test + public void postCommands() { + final JsonArray commands = + JsonParser.parseReader( + new InputStreamReader( + getClass().getClassLoader().getResourceAsStream("PostCommands.json"), + StandardCharsets.UTF_8)) + .getAsJsonArray(); + + CLIENT.postCommands(commands).toCompletableFuture().join(); + } + + @ParameterizedTest + @EnumSource(UserSource.class) + public void getVote(final UserSource userSource) { + CLIENT.getVote(userSource, "123456").toCompletableFuture().join(); + } + + @Test + @SuppressWarnings("unused") + public void getVotes() { + final PaginatedVotes firstPage = + CLIENT + .getVotes(OffsetDateTime.of(2026, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + .toCompletableFuture() + .join(); + final PaginatedVotes secondPage = firstPage.next().toCompletableFuture().join(); + } +} diff --git a/src/test/java/org/discordbots/api/DBLWidgetTest.java b/src/test/java/org/discordbots/api/DBLWidgetTest.java new file mode 100644 index 0000000..1d8780f --- /dev/null +++ b/src/test/java/org/discordbots/api/DBLWidgetTest.java @@ -0,0 +1,31 @@ +package org.discordbots.api; + +import org.discordbots.api.entity.ProjectType; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +public class DBLWidgetTest { + @ParameterizedTest + @EnumSource(ProjectType.class) + public void large(final ProjectType projectType) { + DBLWidget.large(projectType, "123456"); + } + + @ParameterizedTest + @EnumSource(ProjectType.class) + public void votes(final ProjectType projectType) { + DBLWidget.votes(projectType, "123456"); + } + + @ParameterizedTest + @EnumSource(ProjectType.class) + public void owner(final ProjectType projectType) { + DBLWidget.owner(projectType, "123456"); + } + + @ParameterizedTest + @EnumSource(ProjectType.class) + public void social(final ProjectType projectType) { + DBLWidget.social(projectType, "123456"); + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/BaseInterceptor.java b/src/test/java/org/discordbots/api/interceptors/BaseInterceptor.java new file mode 100644 index 0000000..63147a6 --- /dev/null +++ b/src/test/java/org/discordbots/api/interceptors/BaseInterceptor.java @@ -0,0 +1,60 @@ +package org.discordbots.api.interceptors; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import okhttp3.HttpUrl; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + +public abstract class BaseInterceptor implements Interceptor { + @SuppressWarnings("FieldMayBeFinal") + private String response; + + public BaseInterceptor() { + try { + final String className = getClass().getSimpleName(); + + final InputStream inputStream = + BaseInterceptor.class.getResourceAsStream( + "/" + className.substring(0, className.length() - 11) + "Response.json"); + + response = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } catch (final IOException | NullPointerException ignored) { + response = ""; + } + } + + protected abstract boolean isCorrect(final String method, final String path, final HttpUrl url); + + protected abstract int getStatusCode(); + + protected abstract String getMessage(); + + @Override + public Response intercept(final Chain chain) throws IOException { + final Request request = chain.request(); + + final HttpUrl url = request.url(); + final String path = String.join("/", url.pathSegments()); + + if (url.host().equals("top.gg") + && path.startsWith("api/v1") + && isCorrect(request.method(), path, url)) { + return new Response.Builder() + .request(request) + .protocol(Protocol.HTTP_1_1) + .code(getStatusCode()) + .message(getMessage()) + .body(ResponseBody.create(response, MediaType.get("application/json"))) + .addHeader("content-type", "application/json") + .build(); + } + + return chain.proceed(request); + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/GetSelfInterceptor.java b/src/test/java/org/discordbots/api/interceptors/GetSelfInterceptor.java new file mode 100644 index 0000000..33cc308 --- /dev/null +++ b/src/test/java/org/discordbots/api/interceptors/GetSelfInterceptor.java @@ -0,0 +1,20 @@ +package org.discordbots.api.interceptors; + +import okhttp3.HttpUrl; + +public class GetSelfInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("GET") && path.endsWith("/projects/@me"); + } + + @Override + protected int getStatusCode() { + return 200; + } + + @Override + protected String getMessage() { + return "OK"; + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/GetVoteInterceptor.java b/src/test/java/org/discordbots/api/interceptors/GetVoteInterceptor.java new file mode 100644 index 0000000..dd99906 --- /dev/null +++ b/src/test/java/org/discordbots/api/interceptors/GetVoteInterceptor.java @@ -0,0 +1,22 @@ +package org.discordbots.api.interceptors; + +import okhttp3.HttpUrl; + +public class GetVoteInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("GET") + && path.contains("/projects/@me/votes/") + && url.queryParameter("source") != null; + } + + @Override + protected int getStatusCode() { + return 200; + } + + @Override + protected String getMessage() { + return "OK"; + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/GetVotesInterceptor.java b/src/test/java/org/discordbots/api/interceptors/GetVotesInterceptor.java new file mode 100644 index 0000000..829329b --- /dev/null +++ b/src/test/java/org/discordbots/api/interceptors/GetVotesInterceptor.java @@ -0,0 +1,22 @@ +package org.discordbots.api.interceptors; + +import okhttp3.HttpUrl; + +public class GetVotesInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("GET") + && path.endsWith("/projects/@me/votes") + && (url.queryParameter("startDate") != null || url.queryParameter("cursor") != null); + } + + @Override + protected int getStatusCode() { + return 200; + } + + @Override + protected String getMessage() { + return "OK"; + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/PostCommandsInterceptor.java b/src/test/java/org/discordbots/api/interceptors/PostCommandsInterceptor.java new file mode 100644 index 0000000..9ff895e --- /dev/null +++ b/src/test/java/org/discordbots/api/interceptors/PostCommandsInterceptor.java @@ -0,0 +1,20 @@ +package org.discordbots.api.interceptors; + +import okhttp3.HttpUrl; + +public class PostCommandsInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("POST") && path.endsWith("/projects/@me/commands"); + } + + @Override + protected int getStatusCode() { + return 204; + } + + @Override + protected String getMessage() { + return "No Content"; + } +} diff --git a/src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java b/src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java new file mode 100644 index 0000000..66f58ae --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java @@ -0,0 +1,15 @@ +package org.discordbots.webhooks; + +import org.discordbots.webhooks.dropwizard.DBLDropwizardWebhooksTest; +import org.discordbots.webhooks.eclipsejetty.DBLEclipseJettyWebhooksTest; +import org.discordbots.webhooks.springboot.DBLSpringBootWebhooksTest; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectClasses({ + DBLDropwizardWebhooksTest.class, + DBLEclipseJettyWebhooksTest.class, + DBLSpringBootWebhooksTest.class +}) +public class DBLWebhooksTestSuite {} diff --git a/src/test/java/org/discordbots/webhooks/Mocks.java b/src/test/java/org/discordbots/webhooks/Mocks.java new file mode 100644 index 0000000..c471d13 --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/Mocks.java @@ -0,0 +1,47 @@ +package org.discordbots.webhooks; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.util.HexFormat; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +public class Mocks { + public final String integrationCreatePayload; + public final String integrationDeletePayload; + public final String testPayload; + public final String voteCreatePayload; + + public Mocks() throws IOException, NullPointerException { + integrationCreatePayload = read("IntegrationCreate"); + integrationDeletePayload = read("IntegrationDelete"); + testPayload = read("Test"); + voteCreatePayload = read("VoteCreate"); + } + + private static String read(final String name) throws IOException, NullPointerException { + final InputStream inputStream = Mocks.class.getResourceAsStream("/" + name + "Payload.json"); + + return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } + + public static String signature(final String secret, final String body) + throws NoSuchAlgorithmException, InvalidKeyException { + final long timestamp = Instant.now().getEpochSecond(); + + final SecretKeySpec key = + new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); + final Mac hmac = Mac.getInstance("HmacSHA256"); + + hmac.init(key); + + final byte[] digest = + hmac.doFinal(String.format("%s.%s", timestamp, body).getBytes(StandardCharsets.UTF_8)); + + return "t=" + Long.toString(timestamp) + ",v1=" + HexFormat.of().formatHex(digest); + } +} diff --git a/src/test/java/org/discordbots/webhooks/dropwizard/CustomServer.java b/src/test/java/org/discordbots/webhooks/dropwizard/CustomServer.java new file mode 100644 index 0000000..0885b6c --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/dropwizard/CustomServer.java @@ -0,0 +1,16 @@ +package org.discordbots.webhooks.dropwizard; + +import io.dropwizard.core.Application; +import io.dropwizard.core.Configuration; +import io.dropwizard.core.setup.Environment; + +public class CustomServer extends Application { + public static void main(final String[] args) throws Exception { + new CustomServer().run(args); + } + + @Override + public void run(final Configuration config, final Environment env) { + env.jersey().register(new CustomWebhooks()); + } +} diff --git a/src/test/java/org/discordbots/webhooks/dropwizard/CustomWebhooks.java b/src/test/java/org/discordbots/webhooks/dropwizard/CustomWebhooks.java new file mode 100644 index 0000000..246abd8 --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/dropwizard/CustomWebhooks.java @@ -0,0 +1,35 @@ +package org.discordbots.webhooks.dropwizard; + +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Response; +import org.discordbots.webhooks.payload.IntegrationCreatePayload; +import org.discordbots.webhooks.payload.IntegrationDeletePayload; +import org.discordbots.webhooks.payload.TestPayload; +import org.discordbots.webhooks.payload.VoteCreatePayload; + +@Path("/webhook") +public class CustomWebhooks extends DBLWebhooks { + public CustomWebhooks() { + super(System.getenv("TOPGG_WEBHOOK_SECRET")); + } + + @Override + public Response onIntegrationCreate(final IntegrationCreatePayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:integrationCreate," + trace).build(); + } + + @Override + public Response onIntegrationDelete(final IntegrationDeletePayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:integrationDelete," + trace).build(); + } + + @Override + public Response onTest(final TestPayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:test," + trace).build(); + } + + @Override + public Response onVoteCreate(final VoteCreatePayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:voteCreate," + trace).build(); + } +} diff --git a/src/test/java/org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java b/src/test/java/org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java new file mode 100644 index 0000000..0456eee --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java @@ -0,0 +1,68 @@ +package org.discordbots.webhooks.dropwizard; + +import io.dropwizard.core.Configuration; +import io.dropwizard.testing.ResourceHelpers; +import io.dropwizard.testing.junit5.DropwizardAppExtension; +import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import org.discordbots.webhooks.Mocks; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(DropwizardExtensionsSupport.class) +public class DBLDropwizardWebhooksTest { + private static final DropwizardAppExtension APP = + new DropwizardAppExtension<>( + CustomServer.class, ResourceHelpers.resourceFilePath("dropwizard-test-config.yml")); + + private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); + private static final String TRACE = "trace"; + private static Mocks MOCKS; + + @BeforeAll + public static void setup() throws IOException, NullPointerException { + MOCKS = new Mocks(); + } + + private void send(final String name, final String payload) + throws NoSuchAlgorithmException, InvalidKeyException { + final Response response = + APP.client() + .target(String.format("http://localhost:%d/webhook", APP.getLocalPort())) + .request() + .header("Content-Type", "application/json") + .header("x-topgg-signature", Mocks.signature(SECRET, payload)) + .header("x-topgg-trace", TRACE) + .post(Entity.entity(payload, MediaType.APPLICATION_JSON)); + + Assertions.assertEquals(200, response.getStatus()); + Assertions.assertEquals("dw:" + name + "," + TRACE, response.readEntity(String.class)); + } + + @Test + public void integrationCreate() throws NoSuchAlgorithmException, InvalidKeyException { + send("integrationCreate", MOCKS.integrationCreatePayload); + } + + @Test + public void integrationDelete() throws NoSuchAlgorithmException, InvalidKeyException { + send("integrationDelete", MOCKS.integrationDeletePayload); + } + + @Test + public void test() throws NoSuchAlgorithmException, InvalidKeyException { + send("test", MOCKS.testPayload); + } + + @Test + public void voteCreate() throws NoSuchAlgorithmException, InvalidKeyException { + send("voteCreate", MOCKS.voteCreatePayload); + } +} diff --git a/src/test/java/org/discordbots/webhooks/eclipsejetty/CustomWebhooks.java b/src/test/java/org/discordbots/webhooks/eclipsejetty/CustomWebhooks.java new file mode 100644 index 0000000..3bcfdcf --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/eclipsejetty/CustomWebhooks.java @@ -0,0 +1,51 @@ +package org.discordbots.webhooks.eclipsejetty; + +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import org.discordbots.webhooks.payload.IntegrationCreatePayload; +import org.discordbots.webhooks.payload.IntegrationDeletePayload; +import org.discordbots.webhooks.payload.TestPayload; +import org.discordbots.webhooks.payload.VoteCreatePayload; + +public class CustomWebhooks extends DBLWebhooks { + public CustomWebhooks() { + super(System.getenv("TOPGG_WEBHOOK_SECRET")); + } + + private void reply(final String name, final HttpServletResponse response, final String trace) { + try { + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().write("ej:" + name + "," + trace); + } catch (final IOException ignored) { + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + + @Override + public void onIntegrationCreate( + final HttpServletResponse response, + final IntegrationCreatePayload payload, + final String trace) { + reply("integrationCreate", response, trace); + } + + @Override + public void onIntegrationDelete( + final HttpServletResponse response, + final IntegrationDeletePayload payload, + final String trace) { + reply("integrationDelete", response, trace); + } + + @Override + public void onTest( + final HttpServletResponse response, final TestPayload payload, final String trace) { + reply("test", response, trace); + } + + @Override + public void onVoteCreate( + final HttpServletResponse response, final VoteCreatePayload payload, final String trace) { + reply("voteCreate", response, trace); + } +} diff --git a/src/test/java/org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java b/src/test/java/org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java new file mode 100644 index 0000000..7450a20 --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java @@ -0,0 +1,105 @@ +package org.discordbots.webhooks.eclipsejetty; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.ProtocolException; +import java.net.URI; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import org.discordbots.webhooks.Mocks; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.server.Server; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class DBLEclipseJettyWebhooksTest { + private static Server SERVER = null; + + private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); + private static final String TRACE = "trace"; + private static Mocks MOCKS; + + @BeforeAll + public static void setup() throws IOException, NullPointerException, Exception { + MOCKS = new Mocks(); + + SERVER = new Server(8080); + + final ServletContextHandler context = new ServletContextHandler(); + + context.setContextPath("/"); + context.addServlet(new ServletHolder(new CustomWebhooks()), "/webhook"); + + SERVER.setHandler(context); + SERVER.start(); + } + + private void send(final String name, final String payload) + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + final HttpURLConnection connection = + (HttpURLConnection) URI.create("http://localhost:8080/webhook").toURL().openConnection(); + + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("x-topgg-signature", Mocks.signature(SECRET, payload)); + connection.setRequestProperty("x-topgg-trace", TRACE); + connection.setDoOutput(true); + + try (final OutputStream outputStream = connection.getOutputStream()) { + final byte[] payloadBytes = payload.getBytes("utf-8"); + + outputStream.write(payloadBytes, 0, payloadBytes.length); + } + + Assertions.assertEquals(200, connection.getResponseCode()); + + try (final BufferedReader reader = + new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) { + final StringBuilder response = new StringBuilder(); + String responseLine; + + while ((responseLine = reader.readLine()) != null) { + response.append(responseLine.trim()); + } + + Assertions.assertEquals("ej:" + name + "," + TRACE, response.toString()); + } + } + + @Test + public void integrationCreate() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("integrationCreate", MOCKS.integrationCreatePayload); + } + + @Test + public void integrationDelete() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("integrationDelete", MOCKS.integrationDeletePayload); + } + + @Test + public void test() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("test", MOCKS.testPayload); + } + + @Test + public void voteCreate() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("voteCreate", MOCKS.voteCreatePayload); + } + + @AfterAll + public static void cleanup() throws Exception { + if (SERVER != null) { + SERVER.stop(); + } + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/CustomServer.java b/src/test/java/org/discordbots/webhooks/springboot/CustomServer.java new file mode 100644 index 0000000..e5c584f --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/springboot/CustomServer.java @@ -0,0 +1,11 @@ +package org.discordbots.webhooks.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomServer { + public static void main(final String[] args) throws Exception { + SpringApplication.run(CustomServer.class, args); + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/CustomServerSecurityConfiguration.java b/src/test/java/org/discordbots/webhooks/springboot/CustomServerSecurityConfiguration.java new file mode 100644 index 0000000..9805872 --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/springboot/CustomServerSecurityConfiguration.java @@ -0,0 +1,16 @@ +package org.discordbots.webhooks.springboot; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +public class CustomServerSecurityConfiguration { + @Bean + public SecurityFilterChain filterChain(final HttpSecurity http) { + return http.csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) + .build(); + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/CustomWebhooks.java b/src/test/java/org/discordbots/webhooks/springboot/CustomWebhooks.java new file mode 100644 index 0000000..c6eca75 --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/springboot/CustomWebhooks.java @@ -0,0 +1,49 @@ +package org.discordbots.webhooks.springboot; + +import org.discordbots.webhooks.payload.IntegrationCreatePayload; +import org.discordbots.webhooks.payload.IntegrationDeletePayload; +import org.discordbots.webhooks.payload.TestPayload; +import org.discordbots.webhooks.payload.VoteCreatePayload; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CustomWebhooks extends DBLWebhooks { + public CustomWebhooks() { + super(System.getenv("TOPGG_WEBHOOK_SECRET")); + } + + @PostMapping("/webhook") + public ResponseEntity main( + @RequestBody final String body, + @RequestHeader("x-topgg-signature") final String signature, + @RequestHeader("x-topgg-trace") final String trace) { + return dispatch(body, signature, trace); + } + + @Override + public ResponseEntity onIntegrationCreate( + final IntegrationCreatePayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:integrationCreate," + trace); + } + + @Override + public ResponseEntity onIntegrationDelete( + final IntegrationDeletePayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:integrationDelete," + trace); + } + + @Override + public ResponseEntity onTest(final TestPayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:test," + trace); + } + + @Override + public ResponseEntity onVoteCreate(final VoteCreatePayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:voteCreate," + trace); + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java b/src/test/java/org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java new file mode 100644 index 0000000..8405f4e --- /dev/null +++ b/src/test/java/org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java @@ -0,0 +1,59 @@ +package org.discordbots.webhooks.springboot; + +import java.io.IOException; +import org.discordbots.webhooks.Mocks; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@SpringBootTest +@AutoConfigureMockMvc +public class DBLSpringBootWebhooksTest { + private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); + private static final String TRACE = "trace"; + private static Mocks MOCKS; + + @Autowired private MockMvc mvc; + + @BeforeAll + public static void setup() throws IOException, NullPointerException { + MOCKS = new Mocks(); + } + + private void send(final String name, final String payload) throws IOException, Exception { + mvc.perform( + MockMvcRequestBuilders.post("/webhook") + .content(payload) + .header("x-topgg-signature", Mocks.signature(SECRET, payload)) + .header("x-topgg-trace", TRACE) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.content().string("sb:" + name + "," + TRACE)); + } + + @Test + public void integrationCreate() throws IOException, Exception { + send("integrationCreate", MOCKS.integrationCreatePayload); + } + + @Test + public void integrationDelete() throws IOException, Exception { + send("integrationDelete", MOCKS.integrationDeletePayload); + } + + @Test + public void test() throws IOException, Exception { + send("test", MOCKS.testPayload); + } + + @Test + public void voteCreate() throws IOException, Exception { + send("voteCreate", MOCKS.voteCreatePayload); + } +} diff --git a/src/test/resources/GetSelfResponse.json b/src/test/resources/GetSelfResponse.json new file mode 100644 index 0000000..e74997b --- /dev/null +++ b/src/test/resources/GetSelfResponse.json @@ -0,0 +1,16 @@ +{ + "id": "364806029876555776", + "name": "Top.gg Lib Dev API Access", + "type": "bot", + "platform": "discord", + "headline": "API access for Top.gg Library Developers", + "tags": [ + "api", + "library", + "topgg" + ], + "votes": 4, + "votes_total": 34, + "review_score": 5, + "review_count": 2 +} \ No newline at end of file diff --git a/src/test/resources/GetVoteResponse.json b/src/test/resources/GetVoteResponse.json new file mode 100644 index 0000000..c6a0227 --- /dev/null +++ b/src/test/resources/GetVoteResponse.json @@ -0,0 +1,5 @@ +{ + "created_at": "2026-02-25T22:35:36.978392+00:00", + "expires_at": "2026-02-26T10:35:36.978392+00:00", + "weight": 1 +} \ No newline at end of file diff --git a/src/test/resources/GetVotesResponse.json b/src/test/resources/GetVotesResponse.json new file mode 100644 index 0000000..5eab378 --- /dev/null +++ b/src/test/resources/GetVotesResponse.json @@ -0,0 +1,33 @@ +{ + "cursor": "", + "data": [ + { + "user_id": "800506814562787328", + "platform_id": "1461830808796139662", + "weight": 2, + "created_at": "2026-01-17T23:36:06.34732Z", + "expires_at": "2026-01-18T11:36:06.34732Z" + }, + { + "user_id": "316026718115037184", + "platform_id": "481068576363773972", + "weight": 2, + "created_at": "2026-02-20T05:43:58.392411Z", + "expires_at": "2026-02-20T17:43:58.392411Z" + }, + { + "user_id": "794153497215045632", + "platform_id": "1425259851600101457", + "weight": 2, + "created_at": "2026-02-21T18:59:20.660734Z", + "expires_at": "2026-02-22T06:59:20.660734Z" + }, + { + "user_id": "8226924471638491136", + "platform_id": "661200758510977084", + "weight": 1, + "created_at": "2026-02-25T22:35:36.978392Z", + "expires_at": "2026-02-26T10:35:36.978392Z" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/IntegrationCreatePayload.json b/src/test/resources/IntegrationCreatePayload.json new file mode 100644 index 0000000..77df6b0 --- /dev/null +++ b/src/test/resources/IntegrationCreatePayload.json @@ -0,0 +1,19 @@ +{ + "type": "integration.create", + "data": { + "connection_id": "112402021105124", + "webhook_secret": "whs_abcd", + "project": { + "id": "1230954036934033243", + "platform": "discord", + "platform_id": "3949456393249234923", + "type": "bot" + }, + "user": { + "id": "3949456393249234923", + "platform_id": "3949456393249234923", + "name": "username", + "avatar_url": "" + } + } +} \ No newline at end of file diff --git a/src/test/resources/IntegrationDeletePayload.json b/src/test/resources/IntegrationDeletePayload.json new file mode 100644 index 0000000..cb44375 --- /dev/null +++ b/src/test/resources/IntegrationDeletePayload.json @@ -0,0 +1,6 @@ +{ + "type": "integration.delete", + "data": { + "connection_id": "112402021105124" + } +} \ No newline at end of file diff --git a/src/test/resources/LeadResponse.json b/src/test/resources/LeadResponse.json new file mode 100644 index 0000000..52b54a3 --- /dev/null +++ b/src/test/resources/LeadResponse.json @@ -0,0 +1,3 @@ +{ + "error": "Not Found" +} \ No newline at end of file diff --git a/src/test/resources/PostCommands.json b/src/test/resources/PostCommands.json new file mode 100644 index 0000000..071db3e --- /dev/null +++ b/src/test/resources/PostCommands.json @@ -0,0 +1,11 @@ +[ + { + "id": "1", + "type": 1, + "application_id": "1", + "name": "test", + "description": "command description", + "default_member_permissions": "", + "version": "1" + } +] \ No newline at end of file diff --git a/src/test/resources/TestPayload.json b/src/test/resources/TestPayload.json new file mode 100644 index 0000000..b7a7432 --- /dev/null +++ b/src/test/resources/TestPayload.json @@ -0,0 +1,17 @@ +{ + "type": "webhook.test", + "data": { + "user": { + "id": "160105994217586689", + "platform_id": "160105994217586689", + "name": "username", + "avatar_url": "" + }, + "project": { + "id": "803190510032756736", + "type": "bot", + "platform": "discord", + "platform_id": "160105994217586689" + } + } +} \ No newline at end of file diff --git a/src/test/resources/VoteCreatePayload.json b/src/test/resources/VoteCreatePayload.json new file mode 100644 index 0000000..6850196 --- /dev/null +++ b/src/test/resources/VoteCreatePayload.json @@ -0,0 +1,21 @@ +{ + "type": "vote.create", + "data": { + "id": "808499215864008704", + "weight": 1, + "created_at": "2026-02-09T00:47:14.2510149+00:00", + "expires_at": "2026-02-09T12:47:14.2510149+00:00", + "project": { + "id": "803190510032756736", + "type": "bot", + "platform": "discord", + "platform_id": "160105994217586689" + }, + "user": { + "id": "160105994217586689", + "platform_id": "160105994217586689", + "name": "username", + "avatar_url": "" + } + } +} \ No newline at end of file diff --git a/src/test/resources/dropwizard-test-config.yml b/src/test/resources/dropwizard-test-config.yml new file mode 100644 index 0000000..c8aa4d6 --- /dev/null +++ b/src/test/resources/dropwizard-test-config.yml @@ -0,0 +1,7 @@ +server: + applicationConnectors: + - type: http + port: 0 + adminConnectors: + - type: http + port: 0 \ No newline at end of file From ae2c68cac5482c5d233604727a4debd9749c9d7b Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:56:56 +0700 Subject: [PATCH 2/3] meta: remove all mentions of DBL --- .../top/api/TopggAPITests.java} | 138 ++++++------ .../top/api/TopggWidgetTests.java} | 62 +++--- .../api/interceptors/BaseInterceptor.java | 120 +++++----- .../api/interceptors/GetSelfInterceptor.java | 40 ++-- .../api/interceptors/GetVoteInterceptor.java | 44 ++-- .../api/interceptors/GetVotesInterceptor.java | 44 ++-- .../interceptors/PostCommandsInterceptor.java | 40 ++-- .../top}/webhooks/Mocks.java | 94 ++++---- .../top/webhooks/TopggWebhookTestSuite.java | 15 ++ .../webhooks/dropwizard/CustomServer.java | 32 +-- .../webhooks/dropwizard/CustomWebhooks.java | 70 +++--- .../TopggDropwizardWebhookTests.java} | 136 ++++++------ .../webhooks/eclipsejetty/CustomWebhooks.java | 102 ++++----- .../TopggEclipseJettyWebhookTests.java} | 210 +++++++++--------- .../webhooks/springboot/CustomServer.java | 22 +- .../CustomServerSecurityConfiguration.java | 32 +-- .../webhooks/springboot/CustomWebhooks.java | 98 ++++---- .../TopggSpringBootWebhookTests.java} | 118 +++++----- .../webhooks/DBLWebhooksTestSuite.java | 15 -- src/test/resources/GetSelfResponse.json | 30 +-- src/test/resources/GetVoteResponse.json | 8 +- src/test/resources/GetVotesResponse.json | 64 +++--- .../resources/IntegrationCreatePayload.json | 36 +-- .../resources/IntegrationDeletePayload.json | 10 +- src/test/resources/LeadResponse.json | 4 +- src/test/resources/PostCommands.json | 20 +- src/test/resources/TestPayload.json | 32 +-- src/test/resources/VoteCreatePayload.json | 40 ++-- src/test/resources/dropwizard-test-config.yml | 12 +- 29 files changed, 844 insertions(+), 844 deletions(-) rename src/test/java/{org/discordbots/api/DBLAPITest.java => gg/top/api/TopggAPITests.java} (77%) rename src/test/java/{org/discordbots/api/DBLWidgetTest.java => gg/top/api/TopggWidgetTests.java} (63%) rename src/test/java/{org/discordbots => gg/top}/api/interceptors/BaseInterceptor.java (94%) rename src/test/java/{org/discordbots => gg/top}/api/interceptors/GetSelfInterceptor.java (86%) rename src/test/java/{org/discordbots => gg/top}/api/interceptors/GetVoteInterceptor.java (87%) rename src/test/java/{org/discordbots => gg/top}/api/interceptors/GetVotesInterceptor.java (88%) rename src/test/java/{org/discordbots => gg/top}/api/interceptors/PostCommandsInterceptor.java (87%) rename src/test/java/{org/discordbots => gg/top}/webhooks/Mocks.java (95%) create mode 100644 src/test/java/gg/top/webhooks/TopggWebhookTestSuite.java rename src/test/java/{org/discordbots => gg/top}/webhooks/dropwizard/CustomServer.java (87%) rename src/test/java/{org/discordbots => gg/top}/webhooks/dropwizard/CustomWebhooks.java (71%) rename src/test/java/{org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java => gg/top/webhooks/dropwizard/TopggDropwizardWebhookTests.java} (92%) rename src/test/java/{org/discordbots => gg/top}/webhooks/eclipsejetty/CustomWebhooks.java (76%) rename src/test/java/{org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java => gg/top/webhooks/eclipsejetty/TopggEclipseJettyWebhookTests.java} (93%) rename src/test/java/{org/discordbots => gg/top}/webhooks/springboot/CustomServer.java (84%) rename src/test/java/{org/discordbots => gg/top}/webhooks/springboot/CustomServerSecurityConfiguration.java (89%) rename src/test/java/{org/discordbots => gg/top}/webhooks/springboot/CustomWebhooks.java (79%) rename src/test/java/{org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java => gg/top/webhooks/springboot/TopggSpringBootWebhookTests.java} (91%) delete mode 100644 src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java diff --git a/src/test/java/org/discordbots/api/DBLAPITest.java b/src/test/java/gg/top/api/TopggAPITests.java similarity index 77% rename from src/test/java/org/discordbots/api/DBLAPITest.java rename to src/test/java/gg/top/api/TopggAPITests.java index 99fb651..7624c9c 100644 --- a/src/test/java/org/discordbots/api/DBLAPITest.java +++ b/src/test/java/gg/top/api/TopggAPITests.java @@ -1,69 +1,69 @@ -package org.discordbots.api; - -import com.google.gson.JsonArray; -import com.google.gson.JsonParser; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import okhttp3.OkHttpClient; -import org.discordbots.api.entity.PaginatedVotes; -import org.discordbots.api.entity.UserSource; -import org.discordbots.api.interceptors.GetSelfInterceptor; -import org.discordbots.api.interceptors.GetVoteInterceptor; -import org.discordbots.api.interceptors.GetVotesInterceptor; -import org.discordbots.api.interceptors.PostCommandsInterceptor; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; - -public class DBLAPITest { - private static DBLAPI CLIENT; - - @BeforeAll - public static void setup() { - CLIENT = - new DBLAPI( - new OkHttpClient.Builder() - .addInterceptor(new GetSelfInterceptor()) - .addInterceptor(new GetVoteInterceptor()) - .addInterceptor(new GetVotesInterceptor()) - .addInterceptor(new PostCommandsInterceptor()) - .build()); - } - - @Test - public void getSelf() { - CLIENT.getSelf().toCompletableFuture().join(); - } - - @Test - public void postCommands() { - final JsonArray commands = - JsonParser.parseReader( - new InputStreamReader( - getClass().getClassLoader().getResourceAsStream("PostCommands.json"), - StandardCharsets.UTF_8)) - .getAsJsonArray(); - - CLIENT.postCommands(commands).toCompletableFuture().join(); - } - - @ParameterizedTest - @EnumSource(UserSource.class) - public void getVote(final UserSource userSource) { - CLIENT.getVote(userSource, "123456").toCompletableFuture().join(); - } - - @Test - @SuppressWarnings("unused") - public void getVotes() { - final PaginatedVotes firstPage = - CLIENT - .getVotes(OffsetDateTime.of(2026, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) - .toCompletableFuture() - .join(); - final PaginatedVotes secondPage = firstPage.next().toCompletableFuture().join(); - } -} +package gg.top.api; + +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import okhttp3.OkHttpClient; +import gg.top.api.entity.PaginatedVotes; +import gg.top.api.entity.UserSource; +import gg.top.api.interceptors.GetSelfInterceptor; +import gg.top.api.interceptors.GetVoteInterceptor; +import gg.top.api.interceptors.GetVotesInterceptor; +import gg.top.api.interceptors.PostCommandsInterceptor; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +public class TopggAPITests { + private static TopggAPI CLIENT; + + @BeforeAll + public static void setup() { + CLIENT = + new TopggAPI( + new OkHttpClient.Builder() + .addInterceptor(new GetSelfInterceptor()) + .addInterceptor(new GetVoteInterceptor()) + .addInterceptor(new GetVotesInterceptor()) + .addInterceptor(new PostCommandsInterceptor()) + .build()); + } + + @Test + public void getSelf() { + CLIENT.getSelf().toCompletableFuture().join(); + } + + @Test + public void postCommands() { + final JsonArray commands = + JsonParser.parseReader( + new InputStreamReader( + getClass().getClassLoader().getResourceAsStream("PostCommands.json"), + StandardCharsets.UTF_8)) + .getAsJsonArray(); + + CLIENT.postCommands(commands).toCompletableFuture().join(); + } + + @ParameterizedTest + @EnumSource(UserSource.class) + public void getVote(final UserSource userSource) { + CLIENT.getVote(userSource, "123456").toCompletableFuture().join(); + } + + @Test + @SuppressWarnings("unused") + public void getVotes() { + final PaginatedVotes firstPage = + CLIENT + .getVotes(OffsetDateTime.of(2026, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)) + .toCompletableFuture() + .join(); + final PaginatedVotes secondPage = firstPage.next().toCompletableFuture().join(); + } +} diff --git a/src/test/java/org/discordbots/api/DBLWidgetTest.java b/src/test/java/gg/top/api/TopggWidgetTests.java similarity index 63% rename from src/test/java/org/discordbots/api/DBLWidgetTest.java rename to src/test/java/gg/top/api/TopggWidgetTests.java index 1d8780f..20b43e3 100644 --- a/src/test/java/org/discordbots/api/DBLWidgetTest.java +++ b/src/test/java/gg/top/api/TopggWidgetTests.java @@ -1,31 +1,31 @@ -package org.discordbots.api; - -import org.discordbots.api.entity.ProjectType; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; - -public class DBLWidgetTest { - @ParameterizedTest - @EnumSource(ProjectType.class) - public void large(final ProjectType projectType) { - DBLWidget.large(projectType, "123456"); - } - - @ParameterizedTest - @EnumSource(ProjectType.class) - public void votes(final ProjectType projectType) { - DBLWidget.votes(projectType, "123456"); - } - - @ParameterizedTest - @EnumSource(ProjectType.class) - public void owner(final ProjectType projectType) { - DBLWidget.owner(projectType, "123456"); - } - - @ParameterizedTest - @EnumSource(ProjectType.class) - public void social(final ProjectType projectType) { - DBLWidget.social(projectType, "123456"); - } -} +package gg.top.api; + +import gg.top.api.entity.ProjectType; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +public class TopggWidgetTests { + @ParameterizedTest + @EnumSource(ProjectType.class) + public void large(final ProjectType projectType) { + TopggWidget.large(projectType, "123456"); + } + + @ParameterizedTest + @EnumSource(ProjectType.class) + public void votes(final ProjectType projectType) { + TopggWidget.votes(projectType, "123456"); + } + + @ParameterizedTest + @EnumSource(ProjectType.class) + public void owner(final ProjectType projectType) { + TopggWidget.owner(projectType, "123456"); + } + + @ParameterizedTest + @EnumSource(ProjectType.class) + public void social(final ProjectType projectType) { + TopggWidget.social(projectType, "123456"); + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/BaseInterceptor.java b/src/test/java/gg/top/api/interceptors/BaseInterceptor.java similarity index 94% rename from src/test/java/org/discordbots/api/interceptors/BaseInterceptor.java rename to src/test/java/gg/top/api/interceptors/BaseInterceptor.java index 63147a6..e3dfc73 100644 --- a/src/test/java/org/discordbots/api/interceptors/BaseInterceptor.java +++ b/src/test/java/gg/top/api/interceptors/BaseInterceptor.java @@ -1,60 +1,60 @@ -package org.discordbots.api.interceptors; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import okhttp3.HttpUrl; -import okhttp3.Interceptor; -import okhttp3.MediaType; -import okhttp3.Protocol; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.ResponseBody; - -public abstract class BaseInterceptor implements Interceptor { - @SuppressWarnings("FieldMayBeFinal") - private String response; - - public BaseInterceptor() { - try { - final String className = getClass().getSimpleName(); - - final InputStream inputStream = - BaseInterceptor.class.getResourceAsStream( - "/" + className.substring(0, className.length() - 11) + "Response.json"); - - response = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); - } catch (final IOException | NullPointerException ignored) { - response = ""; - } - } - - protected abstract boolean isCorrect(final String method, final String path, final HttpUrl url); - - protected abstract int getStatusCode(); - - protected abstract String getMessage(); - - @Override - public Response intercept(final Chain chain) throws IOException { - final Request request = chain.request(); - - final HttpUrl url = request.url(); - final String path = String.join("/", url.pathSegments()); - - if (url.host().equals("top.gg") - && path.startsWith("api/v1") - && isCorrect(request.method(), path, url)) { - return new Response.Builder() - .request(request) - .protocol(Protocol.HTTP_1_1) - .code(getStatusCode()) - .message(getMessage()) - .body(ResponseBody.create(response, MediaType.get("application/json"))) - .addHeader("content-type", "application/json") - .build(); - } - - return chain.proceed(request); - } -} +package gg.top.api.interceptors; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import okhttp3.HttpUrl; +import okhttp3.Interceptor; +import okhttp3.MediaType; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + +public abstract class BaseInterceptor implements Interceptor { + @SuppressWarnings("FieldMayBeFinal") + private String response; + + public BaseInterceptor() { + try { + final String className = getClass().getSimpleName(); + + final InputStream inputStream = + BaseInterceptor.class.getResourceAsStream( + "/" + className.substring(0, className.length() - 11) + "Response.json"); + + response = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } catch (final IOException | NullPointerException ignored) { + response = ""; + } + } + + protected abstract boolean isCorrect(final String method, final String path, final HttpUrl url); + + protected abstract int getStatusCode(); + + protected abstract String getMessage(); + + @Override + public Response intercept(final Chain chain) throws IOException { + final Request request = chain.request(); + + final HttpUrl url = request.url(); + final String path = String.join("/", url.pathSegments()); + + if (url.host().equals("top.gg") + && path.startsWith("api/v1") + && isCorrect(request.method(), path, url)) { + return new Response.Builder() + .request(request) + .protocol(Protocol.HTTP_1_1) + .code(getStatusCode()) + .message(getMessage()) + .body(ResponseBody.create(response, MediaType.get("application/json"))) + .addHeader("content-type", "application/json") + .build(); + } + + return chain.proceed(request); + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/GetSelfInterceptor.java b/src/test/java/gg/top/api/interceptors/GetSelfInterceptor.java similarity index 86% rename from src/test/java/org/discordbots/api/interceptors/GetSelfInterceptor.java rename to src/test/java/gg/top/api/interceptors/GetSelfInterceptor.java index 33cc308..31f80d4 100644 --- a/src/test/java/org/discordbots/api/interceptors/GetSelfInterceptor.java +++ b/src/test/java/gg/top/api/interceptors/GetSelfInterceptor.java @@ -1,20 +1,20 @@ -package org.discordbots.api.interceptors; - -import okhttp3.HttpUrl; - -public class GetSelfInterceptor extends BaseInterceptor { - @Override - protected boolean isCorrect(final String method, final String path, final HttpUrl url) { - return method.equals("GET") && path.endsWith("/projects/@me"); - } - - @Override - protected int getStatusCode() { - return 200; - } - - @Override - protected String getMessage() { - return "OK"; - } -} +package gg.top.api.interceptors; + +import okhttp3.HttpUrl; + +public class GetSelfInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("GET") && path.endsWith("/projects/@me"); + } + + @Override + protected int getStatusCode() { + return 200; + } + + @Override + protected String getMessage() { + return "OK"; + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/GetVoteInterceptor.java b/src/test/java/gg/top/api/interceptors/GetVoteInterceptor.java similarity index 87% rename from src/test/java/org/discordbots/api/interceptors/GetVoteInterceptor.java rename to src/test/java/gg/top/api/interceptors/GetVoteInterceptor.java index dd99906..730de7b 100644 --- a/src/test/java/org/discordbots/api/interceptors/GetVoteInterceptor.java +++ b/src/test/java/gg/top/api/interceptors/GetVoteInterceptor.java @@ -1,22 +1,22 @@ -package org.discordbots.api.interceptors; - -import okhttp3.HttpUrl; - -public class GetVoteInterceptor extends BaseInterceptor { - @Override - protected boolean isCorrect(final String method, final String path, final HttpUrl url) { - return method.equals("GET") - && path.contains("/projects/@me/votes/") - && url.queryParameter("source") != null; - } - - @Override - protected int getStatusCode() { - return 200; - } - - @Override - protected String getMessage() { - return "OK"; - } -} +package gg.top.api.interceptors; + +import okhttp3.HttpUrl; + +public class GetVoteInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("GET") + && path.contains("/projects/@me/votes/") + && url.queryParameter("source") != null; + } + + @Override + protected int getStatusCode() { + return 200; + } + + @Override + protected String getMessage() { + return "OK"; + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/GetVotesInterceptor.java b/src/test/java/gg/top/api/interceptors/GetVotesInterceptor.java similarity index 88% rename from src/test/java/org/discordbots/api/interceptors/GetVotesInterceptor.java rename to src/test/java/gg/top/api/interceptors/GetVotesInterceptor.java index 829329b..d1cfb41 100644 --- a/src/test/java/org/discordbots/api/interceptors/GetVotesInterceptor.java +++ b/src/test/java/gg/top/api/interceptors/GetVotesInterceptor.java @@ -1,22 +1,22 @@ -package org.discordbots.api.interceptors; - -import okhttp3.HttpUrl; - -public class GetVotesInterceptor extends BaseInterceptor { - @Override - protected boolean isCorrect(final String method, final String path, final HttpUrl url) { - return method.equals("GET") - && path.endsWith("/projects/@me/votes") - && (url.queryParameter("startDate") != null || url.queryParameter("cursor") != null); - } - - @Override - protected int getStatusCode() { - return 200; - } - - @Override - protected String getMessage() { - return "OK"; - } -} +package gg.top.api.interceptors; + +import okhttp3.HttpUrl; + +public class GetVotesInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("GET") + && path.endsWith("/projects/@me/votes") + && (url.queryParameter("startDate") != null || url.queryParameter("cursor") != null); + } + + @Override + protected int getStatusCode() { + return 200; + } + + @Override + protected String getMessage() { + return "OK"; + } +} diff --git a/src/test/java/org/discordbots/api/interceptors/PostCommandsInterceptor.java b/src/test/java/gg/top/api/interceptors/PostCommandsInterceptor.java similarity index 87% rename from src/test/java/org/discordbots/api/interceptors/PostCommandsInterceptor.java rename to src/test/java/gg/top/api/interceptors/PostCommandsInterceptor.java index 9ff895e..0b42629 100644 --- a/src/test/java/org/discordbots/api/interceptors/PostCommandsInterceptor.java +++ b/src/test/java/gg/top/api/interceptors/PostCommandsInterceptor.java @@ -1,20 +1,20 @@ -package org.discordbots.api.interceptors; - -import okhttp3.HttpUrl; - -public class PostCommandsInterceptor extends BaseInterceptor { - @Override - protected boolean isCorrect(final String method, final String path, final HttpUrl url) { - return method.equals("POST") && path.endsWith("/projects/@me/commands"); - } - - @Override - protected int getStatusCode() { - return 204; - } - - @Override - protected String getMessage() { - return "No Content"; - } -} +package gg.top.api.interceptors; + +import okhttp3.HttpUrl; + +public class PostCommandsInterceptor extends BaseInterceptor { + @Override + protected boolean isCorrect(final String method, final String path, final HttpUrl url) { + return method.equals("POST") && path.endsWith("/projects/@me/commands"); + } + + @Override + protected int getStatusCode() { + return 204; + } + + @Override + protected String getMessage() { + return "No Content"; + } +} diff --git a/src/test/java/org/discordbots/webhooks/Mocks.java b/src/test/java/gg/top/webhooks/Mocks.java similarity index 95% rename from src/test/java/org/discordbots/webhooks/Mocks.java rename to src/test/java/gg/top/webhooks/Mocks.java index c471d13..446850b 100644 --- a/src/test/java/org/discordbots/webhooks/Mocks.java +++ b/src/test/java/gg/top/webhooks/Mocks.java @@ -1,47 +1,47 @@ -package org.discordbots.webhooks; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.time.Instant; -import java.util.HexFormat; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -public class Mocks { - public final String integrationCreatePayload; - public final String integrationDeletePayload; - public final String testPayload; - public final String voteCreatePayload; - - public Mocks() throws IOException, NullPointerException { - integrationCreatePayload = read("IntegrationCreate"); - integrationDeletePayload = read("IntegrationDelete"); - testPayload = read("Test"); - voteCreatePayload = read("VoteCreate"); - } - - private static String read(final String name) throws IOException, NullPointerException { - final InputStream inputStream = Mocks.class.getResourceAsStream("/" + name + "Payload.json"); - - return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); - } - - public static String signature(final String secret, final String body) - throws NoSuchAlgorithmException, InvalidKeyException { - final long timestamp = Instant.now().getEpochSecond(); - - final SecretKeySpec key = - new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); - final Mac hmac = Mac.getInstance("HmacSHA256"); - - hmac.init(key); - - final byte[] digest = - hmac.doFinal(String.format("%s.%s", timestamp, body).getBytes(StandardCharsets.UTF_8)); - - return "t=" + Long.toString(timestamp) + ",v1=" + HexFormat.of().formatHex(digest); - } -} +package gg.top.webhooks; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.util.HexFormat; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; + +public class Mocks { + public final String integrationCreatePayload; + public final String integrationDeletePayload; + public final String testPayload; + public final String voteCreatePayload; + + public Mocks() throws IOException, NullPointerException { + integrationCreatePayload = read("IntegrationCreate"); + integrationDeletePayload = read("IntegrationDelete"); + testPayload = read("Test"); + voteCreatePayload = read("VoteCreate"); + } + + private static String read(final String name) throws IOException, NullPointerException { + final InputStream inputStream = Mocks.class.getResourceAsStream("/" + name + "Payload.json"); + + return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } + + public static String signature(final String secret, final String body) + throws NoSuchAlgorithmException, InvalidKeyException { + final long timestamp = Instant.now().getEpochSecond(); + + final SecretKeySpec key = + new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); + final Mac hmac = Mac.getInstance("HmacSHA256"); + + hmac.init(key); + + final byte[] digest = + hmac.doFinal(String.format("%s.%s", timestamp, body).getBytes(StandardCharsets.UTF_8)); + + return "t=" + Long.toString(timestamp) + ",v1=" + HexFormat.of().formatHex(digest); + } +} diff --git a/src/test/java/gg/top/webhooks/TopggWebhookTestSuite.java b/src/test/java/gg/top/webhooks/TopggWebhookTestSuite.java new file mode 100644 index 0000000..50c3026 --- /dev/null +++ b/src/test/java/gg/top/webhooks/TopggWebhookTestSuite.java @@ -0,0 +1,15 @@ +package gg.top.webhooks; + +import gg.top.webhooks.dropwizard.TopggDropwizardWebhookTests; +import gg.top.webhooks.eclipsejetty.TopggEclipseJettyWebhookTests; +import gg.top.webhooks.springboot.TopggSpringBootWebhookTests; +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectClasses({ + TopggDropwizardWebhookTests.class, + TopggEclipseJettyWebhookTests.class, + TopggSpringBootWebhookTests.class +}) +public class TopggWebhookTestSuite {} diff --git a/src/test/java/org/discordbots/webhooks/dropwizard/CustomServer.java b/src/test/java/gg/top/webhooks/dropwizard/CustomServer.java similarity index 87% rename from src/test/java/org/discordbots/webhooks/dropwizard/CustomServer.java rename to src/test/java/gg/top/webhooks/dropwizard/CustomServer.java index 0885b6c..3ab3d52 100644 --- a/src/test/java/org/discordbots/webhooks/dropwizard/CustomServer.java +++ b/src/test/java/gg/top/webhooks/dropwizard/CustomServer.java @@ -1,16 +1,16 @@ -package org.discordbots.webhooks.dropwizard; - -import io.dropwizard.core.Application; -import io.dropwizard.core.Configuration; -import io.dropwizard.core.setup.Environment; - -public class CustomServer extends Application { - public static void main(final String[] args) throws Exception { - new CustomServer().run(args); - } - - @Override - public void run(final Configuration config, final Environment env) { - env.jersey().register(new CustomWebhooks()); - } -} +package gg.top.webhooks.dropwizard; + +import io.dropwizard.core.Application; +import io.dropwizard.core.Configuration; +import io.dropwizard.core.setup.Environment; + +public class CustomServer extends Application { + public static void main(final String[] args) throws Exception { + new CustomServer().run(args); + } + + @Override + public void run(final Configuration config, final Environment env) { + env.jersey().register(new CustomWebhooks()); + } +} diff --git a/src/test/java/org/discordbots/webhooks/dropwizard/CustomWebhooks.java b/src/test/java/gg/top/webhooks/dropwizard/CustomWebhooks.java similarity index 71% rename from src/test/java/org/discordbots/webhooks/dropwizard/CustomWebhooks.java rename to src/test/java/gg/top/webhooks/dropwizard/CustomWebhooks.java index 246abd8..2fbedaf 100644 --- a/src/test/java/org/discordbots/webhooks/dropwizard/CustomWebhooks.java +++ b/src/test/java/gg/top/webhooks/dropwizard/CustomWebhooks.java @@ -1,35 +1,35 @@ -package org.discordbots.webhooks.dropwizard; - -import jakarta.ws.rs.Path; -import jakarta.ws.rs.core.Response; -import org.discordbots.webhooks.payload.IntegrationCreatePayload; -import org.discordbots.webhooks.payload.IntegrationDeletePayload; -import org.discordbots.webhooks.payload.TestPayload; -import org.discordbots.webhooks.payload.VoteCreatePayload; - -@Path("/webhook") -public class CustomWebhooks extends DBLWebhooks { - public CustomWebhooks() { - super(System.getenv("TOPGG_WEBHOOK_SECRET")); - } - - @Override - public Response onIntegrationCreate(final IntegrationCreatePayload payload, final String trace) { - return Response.status(Response.Status.OK).entity("dw:integrationCreate," + trace).build(); - } - - @Override - public Response onIntegrationDelete(final IntegrationDeletePayload payload, final String trace) { - return Response.status(Response.Status.OK).entity("dw:integrationDelete," + trace).build(); - } - - @Override - public Response onTest(final TestPayload payload, final String trace) { - return Response.status(Response.Status.OK).entity("dw:test," + trace).build(); - } - - @Override - public Response onVoteCreate(final VoteCreatePayload payload, final String trace) { - return Response.status(Response.Status.OK).entity("dw:voteCreate," + trace).build(); - } -} +package gg.top.webhooks.dropwizard; + +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Response; +import gg.top.webhooks.payload.IntegrationCreatePayload; +import gg.top.webhooks.payload.IntegrationDeletePayload; +import gg.top.webhooks.payload.TestPayload; +import gg.top.webhooks.payload.VoteCreatePayload; + +@Path("/webhook") +public class CustomWebhooks extends TopggWebhooks { + public CustomWebhooks() { + super(System.getenv("TOPGG_WEBHOOK_SECRET")); + } + + @Override + public Response onIntegrationCreate(final IntegrationCreatePayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:integrationCreate," + trace).build(); + } + + @Override + public Response onIntegrationDelete(final IntegrationDeletePayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:integrationDelete," + trace).build(); + } + + @Override + public Response onTest(final TestPayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:test," + trace).build(); + } + + @Override + public Response onVoteCreate(final VoteCreatePayload payload, final String trace) { + return Response.status(Response.Status.OK).entity("dw:voteCreate," + trace).build(); + } +} diff --git a/src/test/java/org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java b/src/test/java/gg/top/webhooks/dropwizard/TopggDropwizardWebhookTests.java similarity index 92% rename from src/test/java/org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java rename to src/test/java/gg/top/webhooks/dropwizard/TopggDropwizardWebhookTests.java index 0456eee..22a8404 100644 --- a/src/test/java/org/discordbots/webhooks/dropwizard/DBLDropwizardWebhooksTest.java +++ b/src/test/java/gg/top/webhooks/dropwizard/TopggDropwizardWebhookTests.java @@ -1,68 +1,68 @@ -package org.discordbots.webhooks.dropwizard; - -import io.dropwizard.core.Configuration; -import io.dropwizard.testing.ResourceHelpers; -import io.dropwizard.testing.junit5.DropwizardAppExtension; -import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; -import jakarta.ws.rs.client.Entity; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import java.io.IOException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import org.discordbots.webhooks.Mocks; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -@ExtendWith(DropwizardExtensionsSupport.class) -public class DBLDropwizardWebhooksTest { - private static final DropwizardAppExtension APP = - new DropwizardAppExtension<>( - CustomServer.class, ResourceHelpers.resourceFilePath("dropwizard-test-config.yml")); - - private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); - private static final String TRACE = "trace"; - private static Mocks MOCKS; - - @BeforeAll - public static void setup() throws IOException, NullPointerException { - MOCKS = new Mocks(); - } - - private void send(final String name, final String payload) - throws NoSuchAlgorithmException, InvalidKeyException { - final Response response = - APP.client() - .target(String.format("http://localhost:%d/webhook", APP.getLocalPort())) - .request() - .header("Content-Type", "application/json") - .header("x-topgg-signature", Mocks.signature(SECRET, payload)) - .header("x-topgg-trace", TRACE) - .post(Entity.entity(payload, MediaType.APPLICATION_JSON)); - - Assertions.assertEquals(200, response.getStatus()); - Assertions.assertEquals("dw:" + name + "," + TRACE, response.readEntity(String.class)); - } - - @Test - public void integrationCreate() throws NoSuchAlgorithmException, InvalidKeyException { - send("integrationCreate", MOCKS.integrationCreatePayload); - } - - @Test - public void integrationDelete() throws NoSuchAlgorithmException, InvalidKeyException { - send("integrationDelete", MOCKS.integrationDeletePayload); - } - - @Test - public void test() throws NoSuchAlgorithmException, InvalidKeyException { - send("test", MOCKS.testPayload); - } - - @Test - public void voteCreate() throws NoSuchAlgorithmException, InvalidKeyException { - send("voteCreate", MOCKS.voteCreatePayload); - } -} +package gg.top.webhooks.dropwizard; + +import io.dropwizard.core.Configuration; +import io.dropwizard.testing.ResourceHelpers; +import io.dropwizard.testing.junit5.DropwizardAppExtension; +import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import gg.top.webhooks.Mocks; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(DropwizardExtensionsSupport.class) +public class TopggDropwizardWebhookTests { + private static final DropwizardAppExtension APP = + new DropwizardAppExtension<>( + CustomServer.class, ResourceHelpers.resourceFilePath("dropwizard-test-config.yml")); + + private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); + private static final String TRACE = "trace"; + private static Mocks MOCKS; + + @BeforeAll + public static void setup() throws IOException, NullPointerException { + MOCKS = new Mocks(); + } + + private void send(final String name, final String payload) + throws NoSuchAlgorithmException, InvalidKeyException { + final Response response = + APP.client() + .target(String.format("http://localhost:%d/webhook", APP.getLocalPort())) + .request() + .header("Content-Type", "application/json") + .header("x-topgg-signature", Mocks.signature(SECRET, payload)) + .header("x-topgg-trace", TRACE) + .post(Entity.entity(payload, MediaType.APPLICATION_JSON)); + + Assertions.assertEquals(200, response.getStatus()); + Assertions.assertEquals("dw:" + name + "," + TRACE, response.readEntity(String.class)); + } + + @Test + public void integrationCreate() throws NoSuchAlgorithmException, InvalidKeyException { + send("integrationCreate", MOCKS.integrationCreatePayload); + } + + @Test + public void integrationDelete() throws NoSuchAlgorithmException, InvalidKeyException { + send("integrationDelete", MOCKS.integrationDeletePayload); + } + + @Test + public void test() throws NoSuchAlgorithmException, InvalidKeyException { + send("test", MOCKS.testPayload); + } + + @Test + public void voteCreate() throws NoSuchAlgorithmException, InvalidKeyException { + send("voteCreate", MOCKS.voteCreatePayload); + } +} diff --git a/src/test/java/org/discordbots/webhooks/eclipsejetty/CustomWebhooks.java b/src/test/java/gg/top/webhooks/eclipsejetty/CustomWebhooks.java similarity index 76% rename from src/test/java/org/discordbots/webhooks/eclipsejetty/CustomWebhooks.java rename to src/test/java/gg/top/webhooks/eclipsejetty/CustomWebhooks.java index 3bcfdcf..01998b2 100644 --- a/src/test/java/org/discordbots/webhooks/eclipsejetty/CustomWebhooks.java +++ b/src/test/java/gg/top/webhooks/eclipsejetty/CustomWebhooks.java @@ -1,51 +1,51 @@ -package org.discordbots.webhooks.eclipsejetty; - -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import org.discordbots.webhooks.payload.IntegrationCreatePayload; -import org.discordbots.webhooks.payload.IntegrationDeletePayload; -import org.discordbots.webhooks.payload.TestPayload; -import org.discordbots.webhooks.payload.VoteCreatePayload; - -public class CustomWebhooks extends DBLWebhooks { - public CustomWebhooks() { - super(System.getenv("TOPGG_WEBHOOK_SECRET")); - } - - private void reply(final String name, final HttpServletResponse response, final String trace) { - try { - response.setStatus(HttpServletResponse.SC_OK); - response.getWriter().write("ej:" + name + "," + trace); - } catch (final IOException ignored) { - response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } - - @Override - public void onIntegrationCreate( - final HttpServletResponse response, - final IntegrationCreatePayload payload, - final String trace) { - reply("integrationCreate", response, trace); - } - - @Override - public void onIntegrationDelete( - final HttpServletResponse response, - final IntegrationDeletePayload payload, - final String trace) { - reply("integrationDelete", response, trace); - } - - @Override - public void onTest( - final HttpServletResponse response, final TestPayload payload, final String trace) { - reply("test", response, trace); - } - - @Override - public void onVoteCreate( - final HttpServletResponse response, final VoteCreatePayload payload, final String trace) { - reply("voteCreate", response, trace); - } -} +package gg.top.webhooks.eclipsejetty; + +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import gg.top.webhooks.payload.IntegrationCreatePayload; +import gg.top.webhooks.payload.IntegrationDeletePayload; +import gg.top.webhooks.payload.TestPayload; +import gg.top.webhooks.payload.VoteCreatePayload; + +public class CustomWebhooks extends TopggWebhooks { + public CustomWebhooks() { + super(System.getenv("TOPGG_WEBHOOK_SECRET")); + } + + private void reply(final String name, final HttpServletResponse response, final String trace) { + try { + response.setStatus(HttpServletResponse.SC_OK); + response.getWriter().write("ej:" + name + "," + trace); + } catch (final IOException ignored) { + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + + @Override + public void onIntegrationCreate( + final HttpServletResponse response, + final IntegrationCreatePayload payload, + final String trace) { + reply("integrationCreate", response, trace); + } + + @Override + public void onIntegrationDelete( + final HttpServletResponse response, + final IntegrationDeletePayload payload, + final String trace) { + reply("integrationDelete", response, trace); + } + + @Override + public void onTest( + final HttpServletResponse response, final TestPayload payload, final String trace) { + reply("test", response, trace); + } + + @Override + public void onVoteCreate( + final HttpServletResponse response, final VoteCreatePayload payload, final String trace) { + reply("voteCreate", response, trace); + } +} diff --git a/src/test/java/org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java b/src/test/java/gg/top/webhooks/eclipsejetty/TopggEclipseJettyWebhookTests.java similarity index 93% rename from src/test/java/org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java rename to src/test/java/gg/top/webhooks/eclipsejetty/TopggEclipseJettyWebhookTests.java index 7450a20..aedf587 100644 --- a/src/test/java/org/discordbots/webhooks/eclipsejetty/DBLEclipseJettyWebhooksTest.java +++ b/src/test/java/gg/top/webhooks/eclipsejetty/TopggEclipseJettyWebhookTests.java @@ -1,105 +1,105 @@ -package org.discordbots.webhooks.eclipsejetty; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.ProtocolException; -import java.net.URI; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import org.discordbots.webhooks.Mocks; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.ServletHolder; -import org.eclipse.jetty.server.Server; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -public class DBLEclipseJettyWebhooksTest { - private static Server SERVER = null; - - private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); - private static final String TRACE = "trace"; - private static Mocks MOCKS; - - @BeforeAll - public static void setup() throws IOException, NullPointerException, Exception { - MOCKS = new Mocks(); - - SERVER = new Server(8080); - - final ServletContextHandler context = new ServletContextHandler(); - - context.setContextPath("/"); - context.addServlet(new ServletHolder(new CustomWebhooks()), "/webhook"); - - SERVER.setHandler(context); - SERVER.start(); - } - - private void send(final String name, final String payload) - throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { - final HttpURLConnection connection = - (HttpURLConnection) URI.create("http://localhost:8080/webhook").toURL().openConnection(); - - connection.setRequestMethod("POST"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("x-topgg-signature", Mocks.signature(SECRET, payload)); - connection.setRequestProperty("x-topgg-trace", TRACE); - connection.setDoOutput(true); - - try (final OutputStream outputStream = connection.getOutputStream()) { - final byte[] payloadBytes = payload.getBytes("utf-8"); - - outputStream.write(payloadBytes, 0, payloadBytes.length); - } - - Assertions.assertEquals(200, connection.getResponseCode()); - - try (final BufferedReader reader = - new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) { - final StringBuilder response = new StringBuilder(); - String responseLine; - - while ((responseLine = reader.readLine()) != null) { - response.append(responseLine.trim()); - } - - Assertions.assertEquals("ej:" + name + "," + TRACE, response.toString()); - } - } - - @Test - public void integrationCreate() - throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { - send("integrationCreate", MOCKS.integrationCreatePayload); - } - - @Test - public void integrationDelete() - throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { - send("integrationDelete", MOCKS.integrationDeletePayload); - } - - @Test - public void test() - throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { - send("test", MOCKS.testPayload); - } - - @Test - public void voteCreate() - throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { - send("voteCreate", MOCKS.voteCreatePayload); - } - - @AfterAll - public static void cleanup() throws Exception { - if (SERVER != null) { - SERVER.stop(); - } - } -} +package gg.top.webhooks.eclipsejetty; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.ProtocolException; +import java.net.URI; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import gg.top.webhooks.Mocks; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.server.Server; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class TopggEclipseJettyWebhookTests { + private static Server SERVER = null; + + private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); + private static final String TRACE = "trace"; + private static Mocks MOCKS; + + @BeforeAll + public static void setup() throws IOException, NullPointerException, Exception { + MOCKS = new Mocks(); + + SERVER = new Server(8080); + + final ServletContextHandler context = new ServletContextHandler(); + + context.setContextPath("/"); + context.addServlet(new ServletHolder(new CustomWebhooks()), "/webhook"); + + SERVER.setHandler(context); + SERVER.start(); + } + + private void send(final String name, final String payload) + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + final HttpURLConnection connection = + (HttpURLConnection) URI.create("http://localhost:8080/webhook").toURL().openConnection(); + + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("x-topgg-signature", Mocks.signature(SECRET, payload)); + connection.setRequestProperty("x-topgg-trace", TRACE); + connection.setDoOutput(true); + + try (final OutputStream outputStream = connection.getOutputStream()) { + final byte[] payloadBytes = payload.getBytes("utf-8"); + + outputStream.write(payloadBytes, 0, payloadBytes.length); + } + + Assertions.assertEquals(200, connection.getResponseCode()); + + try (final BufferedReader reader = + new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"))) { + final StringBuilder response = new StringBuilder(); + String responseLine; + + while ((responseLine = reader.readLine()) != null) { + response.append(responseLine.trim()); + } + + Assertions.assertEquals("ej:" + name + "," + TRACE, response.toString()); + } + } + + @Test + public void integrationCreate() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("integrationCreate", MOCKS.integrationCreatePayload); + } + + @Test + public void integrationDelete() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("integrationDelete", MOCKS.integrationDeletePayload); + } + + @Test + public void test() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("test", MOCKS.testPayload); + } + + @Test + public void voteCreate() + throws NoSuchAlgorithmException, InvalidKeyException, ProtocolException, IOException { + send("voteCreate", MOCKS.voteCreatePayload); + } + + @AfterAll + public static void cleanup() throws Exception { + if (SERVER != null) { + SERVER.stop(); + } + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/CustomServer.java b/src/test/java/gg/top/webhooks/springboot/CustomServer.java similarity index 84% rename from src/test/java/org/discordbots/webhooks/springboot/CustomServer.java rename to src/test/java/gg/top/webhooks/springboot/CustomServer.java index e5c584f..b062fd8 100644 --- a/src/test/java/org/discordbots/webhooks/springboot/CustomServer.java +++ b/src/test/java/gg/top/webhooks/springboot/CustomServer.java @@ -1,11 +1,11 @@ -package org.discordbots.webhooks.springboot; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class CustomServer { - public static void main(final String[] args) throws Exception { - SpringApplication.run(CustomServer.class, args); - } -} +package gg.top.webhooks.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomServer { + public static void main(final String[] args) throws Exception { + SpringApplication.run(CustomServer.class, args); + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/CustomServerSecurityConfiguration.java b/src/test/java/gg/top/webhooks/springboot/CustomServerSecurityConfiguration.java similarity index 89% rename from src/test/java/org/discordbots/webhooks/springboot/CustomServerSecurityConfiguration.java rename to src/test/java/gg/top/webhooks/springboot/CustomServerSecurityConfiguration.java index 9805872..81d96fa 100644 --- a/src/test/java/org/discordbots/webhooks/springboot/CustomServerSecurityConfiguration.java +++ b/src/test/java/gg/top/webhooks/springboot/CustomServerSecurityConfiguration.java @@ -1,16 +1,16 @@ -package org.discordbots.webhooks.springboot; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.web.SecurityFilterChain; - -@Configuration -public class CustomServerSecurityConfiguration { - @Bean - public SecurityFilterChain filterChain(final HttpSecurity http) { - return http.csrf(csrf -> csrf.disable()) - .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) - .build(); - } -} +package gg.top.webhooks.springboot; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +public class CustomServerSecurityConfiguration { + @Bean + public SecurityFilterChain filterChain(final HttpSecurity http) { + return http.csrf(csrf -> csrf.disable()) + .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) + .build(); + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/CustomWebhooks.java b/src/test/java/gg/top/webhooks/springboot/CustomWebhooks.java similarity index 79% rename from src/test/java/org/discordbots/webhooks/springboot/CustomWebhooks.java rename to src/test/java/gg/top/webhooks/springboot/CustomWebhooks.java index c6eca75..0c2eb4a 100644 --- a/src/test/java/org/discordbots/webhooks/springboot/CustomWebhooks.java +++ b/src/test/java/gg/top/webhooks/springboot/CustomWebhooks.java @@ -1,49 +1,49 @@ -package org.discordbots.webhooks.springboot; - -import org.discordbots.webhooks.payload.IntegrationCreatePayload; -import org.discordbots.webhooks.payload.IntegrationDeletePayload; -import org.discordbots.webhooks.payload.TestPayload; -import org.discordbots.webhooks.payload.VoteCreatePayload; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class CustomWebhooks extends DBLWebhooks { - public CustomWebhooks() { - super(System.getenv("TOPGG_WEBHOOK_SECRET")); - } - - @PostMapping("/webhook") - public ResponseEntity main( - @RequestBody final String body, - @RequestHeader("x-topgg-signature") final String signature, - @RequestHeader("x-topgg-trace") final String trace) { - return dispatch(body, signature, trace); - } - - @Override - public ResponseEntity onIntegrationCreate( - final IntegrationCreatePayload payload, final String trace) { - return ResponseEntity.status(HttpStatus.OK).body("sb:integrationCreate," + trace); - } - - @Override - public ResponseEntity onIntegrationDelete( - final IntegrationDeletePayload payload, final String trace) { - return ResponseEntity.status(HttpStatus.OK).body("sb:integrationDelete," + trace); - } - - @Override - public ResponseEntity onTest(final TestPayload payload, final String trace) { - return ResponseEntity.status(HttpStatus.OK).body("sb:test," + trace); - } - - @Override - public ResponseEntity onVoteCreate(final VoteCreatePayload payload, final String trace) { - return ResponseEntity.status(HttpStatus.OK).body("sb:voteCreate," + trace); - } -} +package gg.top.webhooks.springboot; + +import gg.top.webhooks.payload.IntegrationCreatePayload; +import gg.top.webhooks.payload.IntegrationDeletePayload; +import gg.top.webhooks.payload.TestPayload; +import gg.top.webhooks.payload.VoteCreatePayload; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CustomWebhooks extends TopggWebhooks { + public CustomWebhooks() { + super(System.getenv("TOPGG_WEBHOOK_SECRET")); + } + + @PostMapping("/webhook") + public ResponseEntity main( + @RequestBody final String body, + @RequestHeader("x-topgg-signature") final String signature, + @RequestHeader("x-topgg-trace") final String trace) { + return dispatch(body, signature, trace); + } + + @Override + public ResponseEntity onIntegrationCreate( + final IntegrationCreatePayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:integrationCreate," + trace); + } + + @Override + public ResponseEntity onIntegrationDelete( + final IntegrationDeletePayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:integrationDelete," + trace); + } + + @Override + public ResponseEntity onTest(final TestPayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:test," + trace); + } + + @Override + public ResponseEntity onVoteCreate(final VoteCreatePayload payload, final String trace) { + return ResponseEntity.status(HttpStatus.OK).body("sb:voteCreate," + trace); + } +} diff --git a/src/test/java/org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java b/src/test/java/gg/top/webhooks/springboot/TopggSpringBootWebhookTests.java similarity index 91% rename from src/test/java/org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java rename to src/test/java/gg/top/webhooks/springboot/TopggSpringBootWebhookTests.java index 8405f4e..a7e5bd4 100644 --- a/src/test/java/org/discordbots/webhooks/springboot/DBLSpringBootWebhooksTest.java +++ b/src/test/java/gg/top/webhooks/springboot/TopggSpringBootWebhookTests.java @@ -1,59 +1,59 @@ -package org.discordbots.webhooks.springboot; - -import java.io.IOException; -import org.discordbots.webhooks.Mocks; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; - -@SpringBootTest -@AutoConfigureMockMvc -public class DBLSpringBootWebhooksTest { - private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); - private static final String TRACE = "trace"; - private static Mocks MOCKS; - - @Autowired private MockMvc mvc; - - @BeforeAll - public static void setup() throws IOException, NullPointerException { - MOCKS = new Mocks(); - } - - private void send(final String name, final String payload) throws IOException, Exception { - mvc.perform( - MockMvcRequestBuilders.post("/webhook") - .content(payload) - .header("x-topgg-signature", Mocks.signature(SECRET, payload)) - .header("x-topgg-trace", TRACE) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(MockMvcResultMatchers.status().is(200)) - .andExpect(MockMvcResultMatchers.content().string("sb:" + name + "," + TRACE)); - } - - @Test - public void integrationCreate() throws IOException, Exception { - send("integrationCreate", MOCKS.integrationCreatePayload); - } - - @Test - public void integrationDelete() throws IOException, Exception { - send("integrationDelete", MOCKS.integrationDeletePayload); - } - - @Test - public void test() throws IOException, Exception { - send("test", MOCKS.testPayload); - } - - @Test - public void voteCreate() throws IOException, Exception { - send("voteCreate", MOCKS.voteCreatePayload); - } -} +package gg.top.webhooks.springboot; + +import java.io.IOException; +import gg.top.webhooks.Mocks; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@SpringBootTest +@AutoConfigureMockMvc +public class TopggSpringBootWebhookTests { + private static final String SECRET = System.getenv("TOPGG_WEBHOOK_SECRET"); + private static final String TRACE = "trace"; + private static Mocks MOCKS; + + @Autowired private MockMvc mvc; + + @BeforeAll + public static void setup() throws IOException, NullPointerException { + MOCKS = new Mocks(); + } + + private void send(final String name, final String payload) throws IOException, Exception { + mvc.perform( + MockMvcRequestBuilders.post("/webhook") + .content(payload) + .header("x-topgg-signature", Mocks.signature(SECRET, payload)) + .header("x-topgg-trace", TRACE) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.status().is(200)) + .andExpect(MockMvcResultMatchers.content().string("sb:" + name + "," + TRACE)); + } + + @Test + public void integrationCreate() throws IOException, Exception { + send("integrationCreate", MOCKS.integrationCreatePayload); + } + + @Test + public void integrationDelete() throws IOException, Exception { + send("integrationDelete", MOCKS.integrationDeletePayload); + } + + @Test + public void test() throws IOException, Exception { + send("test", MOCKS.testPayload); + } + + @Test + public void voteCreate() throws IOException, Exception { + send("voteCreate", MOCKS.voteCreatePayload); + } +} diff --git a/src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java b/src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java deleted file mode 100644 index 66f58ae..0000000 --- a/src/test/java/org/discordbots/webhooks/DBLWebhooksTestSuite.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.discordbots.webhooks; - -import org.discordbots.webhooks.dropwizard.DBLDropwizardWebhooksTest; -import org.discordbots.webhooks.eclipsejetty.DBLEclipseJettyWebhooksTest; -import org.discordbots.webhooks.springboot.DBLSpringBootWebhooksTest; -import org.junit.platform.suite.api.SelectClasses; -import org.junit.platform.suite.api.Suite; - -@Suite -@SelectClasses({ - DBLDropwizardWebhooksTest.class, - DBLEclipseJettyWebhooksTest.class, - DBLSpringBootWebhooksTest.class -}) -public class DBLWebhooksTestSuite {} diff --git a/src/test/resources/GetSelfResponse.json b/src/test/resources/GetSelfResponse.json index e74997b..f75608b 100644 --- a/src/test/resources/GetSelfResponse.json +++ b/src/test/resources/GetSelfResponse.json @@ -1,16 +1,16 @@ -{ - "id": "364806029876555776", - "name": "Top.gg Lib Dev API Access", - "type": "bot", - "platform": "discord", - "headline": "API access for Top.gg Library Developers", - "tags": [ - "api", - "library", - "topgg" - ], - "votes": 4, - "votes_total": 34, - "review_score": 5, - "review_count": 2 +{ + "id": "364806029876555776", + "name": "Top.gg Lib Dev API Access", + "type": "bot", + "platform": "discord", + "headline": "API access for Top.gg Library Developers", + "tags": [ + "api", + "library", + "topgg" + ], + "votes": 4, + "votes_total": 34, + "review_score": 5, + "review_count": 2 } \ No newline at end of file diff --git a/src/test/resources/GetVoteResponse.json b/src/test/resources/GetVoteResponse.json index c6a0227..5a4a60c 100644 --- a/src/test/resources/GetVoteResponse.json +++ b/src/test/resources/GetVoteResponse.json @@ -1,5 +1,5 @@ -{ - "created_at": "2026-02-25T22:35:36.978392+00:00", - "expires_at": "2026-02-26T10:35:36.978392+00:00", - "weight": 1 +{ + "created_at": "2026-02-25T22:35:36.978392+00:00", + "expires_at": "2026-02-26T10:35:36.978392+00:00", + "weight": 1 } \ No newline at end of file diff --git a/src/test/resources/GetVotesResponse.json b/src/test/resources/GetVotesResponse.json index 5eab378..a8c84f6 100644 --- a/src/test/resources/GetVotesResponse.json +++ b/src/test/resources/GetVotesResponse.json @@ -1,33 +1,33 @@ -{ - "cursor": "", - "data": [ - { - "user_id": "800506814562787328", - "platform_id": "1461830808796139662", - "weight": 2, - "created_at": "2026-01-17T23:36:06.34732Z", - "expires_at": "2026-01-18T11:36:06.34732Z" - }, - { - "user_id": "316026718115037184", - "platform_id": "481068576363773972", - "weight": 2, - "created_at": "2026-02-20T05:43:58.392411Z", - "expires_at": "2026-02-20T17:43:58.392411Z" - }, - { - "user_id": "794153497215045632", - "platform_id": "1425259851600101457", - "weight": 2, - "created_at": "2026-02-21T18:59:20.660734Z", - "expires_at": "2026-02-22T06:59:20.660734Z" - }, - { - "user_id": "8226924471638491136", - "platform_id": "661200758510977084", - "weight": 1, - "created_at": "2026-02-25T22:35:36.978392Z", - "expires_at": "2026-02-26T10:35:36.978392Z" - } - ] +{ + "cursor": "", + "data": [ + { + "user_id": "800506814562787328", + "platform_id": "1461830808796139662", + "weight": 2, + "created_at": "2026-01-17T23:36:06.34732Z", + "expires_at": "2026-01-18T11:36:06.34732Z" + }, + { + "user_id": "316026718115037184", + "platform_id": "481068576363773972", + "weight": 2, + "created_at": "2026-02-20T05:43:58.392411Z", + "expires_at": "2026-02-20T17:43:58.392411Z" + }, + { + "user_id": "794153497215045632", + "platform_id": "1425259851600101457", + "weight": 2, + "created_at": "2026-02-21T18:59:20.660734Z", + "expires_at": "2026-02-22T06:59:20.660734Z" + }, + { + "user_id": "8226924471638491136", + "platform_id": "661200758510977084", + "weight": 1, + "created_at": "2026-02-25T22:35:36.978392Z", + "expires_at": "2026-02-26T10:35:36.978392Z" + } + ] } \ No newline at end of file diff --git a/src/test/resources/IntegrationCreatePayload.json b/src/test/resources/IntegrationCreatePayload.json index 77df6b0..44a7793 100644 --- a/src/test/resources/IntegrationCreatePayload.json +++ b/src/test/resources/IntegrationCreatePayload.json @@ -1,19 +1,19 @@ -{ - "type": "integration.create", - "data": { - "connection_id": "112402021105124", - "webhook_secret": "whs_abcd", - "project": { - "id": "1230954036934033243", - "platform": "discord", - "platform_id": "3949456393249234923", - "type": "bot" - }, - "user": { - "id": "3949456393249234923", - "platform_id": "3949456393249234923", - "name": "username", - "avatar_url": "" - } - } +{ + "type": "integration.create", + "data": { + "connection_id": "112402021105124", + "webhook_secret": "whs_abcd", + "project": { + "id": "1230954036934033243", + "platform": "discord", + "platform_id": "3949456393249234923", + "type": "bot" + }, + "user": { + "id": "3949456393249234923", + "platform_id": "3949456393249234923", + "name": "username", + "avatar_url": "" + } + } } \ No newline at end of file diff --git a/src/test/resources/IntegrationDeletePayload.json b/src/test/resources/IntegrationDeletePayload.json index cb44375..7f16505 100644 --- a/src/test/resources/IntegrationDeletePayload.json +++ b/src/test/resources/IntegrationDeletePayload.json @@ -1,6 +1,6 @@ -{ - "type": "integration.delete", - "data": { - "connection_id": "112402021105124" - } +{ + "type": "integration.delete", + "data": { + "connection_id": "112402021105124" + } } \ No newline at end of file diff --git a/src/test/resources/LeadResponse.json b/src/test/resources/LeadResponse.json index 52b54a3..c9ac3cb 100644 --- a/src/test/resources/LeadResponse.json +++ b/src/test/resources/LeadResponse.json @@ -1,3 +1,3 @@ -{ - "error": "Not Found" +{ + "error": "Not Found" } \ No newline at end of file diff --git a/src/test/resources/PostCommands.json b/src/test/resources/PostCommands.json index 071db3e..03c3e53 100644 --- a/src/test/resources/PostCommands.json +++ b/src/test/resources/PostCommands.json @@ -1,11 +1,11 @@ -[ - { - "id": "1", - "type": 1, - "application_id": "1", - "name": "test", - "description": "command description", - "default_member_permissions": "", - "version": "1" - } +[ + { + "id": "1", + "type": 1, + "application_id": "1", + "name": "test", + "description": "command description", + "default_member_permissions": "", + "version": "1" + } ] \ No newline at end of file diff --git a/src/test/resources/TestPayload.json b/src/test/resources/TestPayload.json index b7a7432..933fddd 100644 --- a/src/test/resources/TestPayload.json +++ b/src/test/resources/TestPayload.json @@ -1,17 +1,17 @@ -{ - "type": "webhook.test", - "data": { - "user": { - "id": "160105994217586689", - "platform_id": "160105994217586689", - "name": "username", - "avatar_url": "" - }, - "project": { - "id": "803190510032756736", - "type": "bot", - "platform": "discord", - "platform_id": "160105994217586689" - } - } +{ + "type": "webhook.test", + "data": { + "user": { + "id": "160105994217586689", + "platform_id": "160105994217586689", + "name": "username", + "avatar_url": "" + }, + "project": { + "id": "803190510032756736", + "type": "bot", + "platform": "discord", + "platform_id": "160105994217586689" + } + } } \ No newline at end of file diff --git a/src/test/resources/VoteCreatePayload.json b/src/test/resources/VoteCreatePayload.json index 6850196..9f0991e 100644 --- a/src/test/resources/VoteCreatePayload.json +++ b/src/test/resources/VoteCreatePayload.json @@ -1,21 +1,21 @@ -{ - "type": "vote.create", - "data": { - "id": "808499215864008704", - "weight": 1, - "created_at": "2026-02-09T00:47:14.2510149+00:00", - "expires_at": "2026-02-09T12:47:14.2510149+00:00", - "project": { - "id": "803190510032756736", - "type": "bot", - "platform": "discord", - "platform_id": "160105994217586689" - }, - "user": { - "id": "160105994217586689", - "platform_id": "160105994217586689", - "name": "username", - "avatar_url": "" - } - } +{ + "type": "vote.create", + "data": { + "id": "808499215864008704", + "weight": 1, + "created_at": "2026-02-09T00:47:14.2510149+00:00", + "expires_at": "2026-02-09T12:47:14.2510149+00:00", + "project": { + "id": "803190510032756736", + "type": "bot", + "platform": "discord", + "platform_id": "160105994217586689" + }, + "user": { + "id": "160105994217586689", + "platform_id": "160105994217586689", + "name": "username", + "avatar_url": "" + } + } } \ No newline at end of file diff --git a/src/test/resources/dropwizard-test-config.yml b/src/test/resources/dropwizard-test-config.yml index c8aa4d6..8ec87ea 100644 --- a/src/test/resources/dropwizard-test-config.yml +++ b/src/test/resources/dropwizard-test-config.yml @@ -1,7 +1,7 @@ -server: - applicationConnectors: - - type: http - port: 0 - adminConnectors: - - type: http +server: + applicationConnectors: + - type: http + port: 0 + adminConnectors: + - type: http port: 0 \ No newline at end of file From b7b4ab955c2184df39df9b8657a3571a26f70c4a Mon Sep 17 00:00:00 2001 From: null <60427892+null8626@users.noreply.github.com> Date: Wed, 11 Mar 2026 20:37:59 +0700 Subject: [PATCH 3/3] fix: reflect new changes on widget throughout tests --- .../java/gg/top/api/TopggWidgetTests.java | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/src/test/java/gg/top/api/TopggWidgetTests.java b/src/test/java/gg/top/api/TopggWidgetTests.java index 20b43e3..1ab53eb 100644 --- a/src/test/java/gg/top/api/TopggWidgetTests.java +++ b/src/test/java/gg/top/api/TopggWidgetTests.java @@ -1,31 +1,49 @@ package gg.top.api; +import java.util.stream.Stream; + +import gg.top.api.entity.Platform; import gg.top.api.entity.ProjectType; + import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class TopggWidgetTests { + @SuppressWarnings("unused") + static Stream platformsAndProjectTypes() { + final Stream.Builder streamBuilder = Stream.builder(); + + for (final Platform platform : Platform.values()) { + for (final ProjectType projectType : ProjectType.values()) { + streamBuilder.add(Arguments.of(platform, projectType)); + } + } + + return streamBuilder.build(); + } + @ParameterizedTest - @EnumSource(ProjectType.class) - public void large(final ProjectType projectType) { - TopggWidget.large(projectType, "123456"); + @MethodSource("platformsAndProjectTypes") + public void large(final Platform platform, final ProjectType projectType) { + TopggWidget.large(platform, projectType, "123456"); } @ParameterizedTest - @EnumSource(ProjectType.class) - public void votes(final ProjectType projectType) { - TopggWidget.votes(projectType, "123456"); + @MethodSource("platformsAndProjectTypes") + public void votes(final Platform platform, final ProjectType projectType) { + TopggWidget.votes(platform, projectType, "123456"); } @ParameterizedTest - @EnumSource(ProjectType.class) - public void owner(final ProjectType projectType) { - TopggWidget.owner(projectType, "123456"); + @MethodSource("platformsAndProjectTypes") + public void owner(final Platform platform, final ProjectType projectType) { + TopggWidget.owner(platform, projectType, "123456"); } @ParameterizedTest - @EnumSource(ProjectType.class) - public void social(final ProjectType projectType) { - TopggWidget.social(projectType, "123456"); + @MethodSource("platformsAndProjectTypes") + public void social(final Platform platform, final ProjectType projectType) { + TopggWidget.social(platform, projectType, "123456"); } }