diff --git a/src/main/java/me/itzg/helpers/curseforge/CurseForgeApiClient.java b/src/main/java/me/itzg/helpers/curseforge/CurseForgeApiClient.java index 0430e39b..3971a401 100644 --- a/src/main/java/me/itzg/helpers/curseforge/CurseForgeApiClient.java +++ b/src/main/java/me/itzg/helpers/curseforge/CurseForgeApiClient.java @@ -51,13 +51,13 @@ public class CurseForgeApiClient implements AutoCloseable { public CurseForgeApiClient(String apiBaseUrl, String apiKey, SharedFetch.Options sharedFetchOptions, String gameId ) { - if (apiKey == null || apiKey.isEmpty()) { + if (apiKey == null || apiKey.trim().isEmpty()) { throw new InvalidParameterException("CurseForge API key is required"); } this.preparedFetch = Fetch.sharedFetch("install-curseforge", (sharedFetchOptions != null ? sharedFetchOptions : SharedFetch.Options.builder().build()) - .withHeader(API_KEY_HEADER, apiKey) + .withHeader(API_KEY_HEADER, apiKey.trim()) ); this.uriBuilder = UriBuilder.withBaseUrl(apiBaseUrl); this.gameId = gameId; diff --git a/src/test/java/me/itzg/helpers/curseforge/CurseForgeApiClientTest.java b/src/test/java/me/itzg/helpers/curseforge/CurseForgeApiClientTest.java new file mode 100644 index 00000000..27f86420 --- /dev/null +++ b/src/test/java/me/itzg/helpers/curseforge/CurseForgeApiClientTest.java @@ -0,0 +1,40 @@ +package me.itzg.helpers.curseforge; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo; +import com.github.tomakehurst.wiremock.junit5.WireMockTest; +import java.util.Collections; +import me.itzg.helpers.http.SharedFetch.Options; +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; + +@WireMockTest +class CurseForgeApiClientTest { + + @Test + void apiKeyHeaderIsTrimmed(WireMockRuntimeInfo wmInfo) { + @Language("JSON") final String body = "{\"data\": []}"; + stubFor(get("/v1/categories?gameId=test&classesOnly=true") + .willReturn(aResponse() + .withBody(body) + .withHeader("Content-Type", "application/json") + ) + ); + + final CategoryInfo result; + try (CurseForgeApiClient client = new CurseForgeApiClient(wmInfo.getHttpBaseUrl(), "key\n", Options.builder().build(), + "test" + )) { + result = client.loadCategoryInfo(Collections.singleton("mc-mods")) + .block(); + } + + assertThat(result).isNotNull(); + + verify(getRequestedFor(urlEqualTo("/v1/categories?gameId=test&classesOnly=true")) + .withHeader("x-api-key", equalTo("key")) + ); + } +} \ No newline at end of file