+ * Use {@link GenericContainer#withAccessToHost(boolean)} to force the host access mechanism + *
+ * Use {@link org.testcontainers.Testcontainers#exposeHostPorts(int...)} to expose host machine ports to containers + *
+ * Use {@link GenericContainer#INTERNAL_HOST_HOSTNAME} to calculate hostname for callback + * + * @see Testcontainers Networking + */ +@Testcontainers +class WebhooksExtensionTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(WebhooksExtensionTest.class); + private static final String WIREMOCK_PATH = "/wiremock/callback-trigger"; + private static final String APPLICATION_PATH = "/application/callback-receiver"; + + + TestHttpServer applicationServer = TestHttpServer.newInstance(); + @Container + WireMockContainer wiremockServer = new WireMockContainer(TestConfig.WIREMOCK_2_IMAGE) + .withLogConsumer(new Slf4jLogConsumer(LOGGER)) + .withCliArg("--global-response-templating") + .withMapping("webhook-callback-template", WebhooksExtensionTest.class, "webhook-callback-template.json") + .withExtensions("Webhooks", + Collections.singleton("org.wiremock.webhooks.Webhooks"), + Collections.singleton(Paths.get("target", "test-wiremock-extension", "wiremock-webhooks-extension-2.35.0.jar").toFile())) + .withAccessToHost(true); // Force the host access mechanism + + @Test + void callbackUsingJsonStub() throws Exception { + // given + exposeHostPorts(applicationServer.getPort()); // Exposing host ports to the container + + String wiremockUrl = wiremockServer.getUrl(WIREMOCK_PATH); + String applicationCallbackUrl = String.format("http://%s:%d%s", GenericContainer.INTERNAL_HOST_HOSTNAME, applicationServer.getPort(), APPLICATION_PATH); + + // when + HttpResponse response = new TestHttpClient().post( + wiremockUrl, + "{\"callbackMethod\": \"PUT\", \"callbackUrl\": \"" + applicationCallbackUrl + "\"}" + ); + + // then + assertThat(response).as("Wiremock Response").isNotNull().satisfies(it -> { + assertThat(it.getStatusCode()).as("Wiremock Response Status").isEqualTo(200); + assertThat(it.getBody()).as("Wiremock Response Body") + .contains("Please wait callback") + .contains("PUT") + .contains(applicationCallbackUrl); + }); + + await().atMost(Duration.ofMillis(5000)).untilAsserted(() -> { + assertThat(applicationServer.getRecordedRequests()).as("Received Callback") + .hasSize(1) + .first().usingRecursiveComparison() + .isEqualTo(new TestHttpServer.RecordedRequest("PUT", APPLICATION_PATH, "Async processing Finished")); + }); + } + +} diff --git a/src/test/java/org/wiremock/integrations/testcontainers/wiremock2/WireMockContainerExtensionsCombinationTest.java b/src/test/java/org/wiremock/integrations/testcontainers/wiremock2/WireMockContainerExtensionsCombinationTest.java new file mode 100644 index 0000000..1bc30ca --- /dev/null +++ b/src/test/java/org/wiremock/integrations/testcontainers/wiremock2/WireMockContainerExtensionsCombinationTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023 WireMock Inc, Oleg Nenashev and all project contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.wiremock.integrations.testcontainers.wiremock2; + +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.wiremock.integrations.testcontainers.TestConfig; +import org.wiremock.integrations.testcontainers.WireMockContainer; +import org.wiremock.integrations.testcontainers.testsupport.http.HttpResponse; +import org.wiremock.integrations.testcontainers.testsupport.http.TestHttpClient; + +import java.nio.file.Paths; +import java.util.Collections; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests the WireMock extension loading. + * It uses multiple external Jars supplied by the Maven Dependency Plugin. + */ +@Testcontainers +class WireMockContainerExtensionsCombinationTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(WireMockContainerExtensionsCombinationTest.class); + + @Container + WireMockContainer wiremockServer = new WireMockContainer(TestConfig.WIREMOCK_2_IMAGE) + .withLogConsumer(new Slf4jLogConsumer(LOGGER)) + .withMapping("json-body-transformer", WireMockContainerExtensionsCombinationTest.class, "json-body-transformer.json") + .withExtensions("Webhook", + Collections.singleton("org.wiremock.webhooks.Webhooks"), + Collections.singleton(Paths.get("target", "test-wiremock-extension", "wiremock-webhooks-extension-2.35.0.jar").toFile())) + .withExtensions("JSON Body Transformer", + Collections.singleton("com.ninecookies.wiremock.extensions.JsonBodyTransformer"), + Collections.singleton(Paths.get("target", "test-wiremock-extension", "wiremock-extensions-0.4.1-jar-with-dependencies.jar").toFile())); + + @Test + void testJSONBodyTransformer() throws Exception { + // given + String url = wiremockServer.getUrl("/json-body-transformer"); + String body = "{\"name\":\"John Doe\"}"; + + // when + HttpResponse response = new TestHttpClient().post(url, body); + + // then + assertThat(response.getBody()) + .as("Wrong response body") + .contains("Hello, John Doe!"); + } +} diff --git a/src/test/resources/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsWebhookTest/webhook-callback-template.json b/src/test/resources/org/wiremock/integrations/testcontainers/WireMockContainerWebhooksTest/webhook-callback-template.json similarity index 100% rename from src/test/resources/org/wiremock/integrations/testcontainers/WireMockContainerExtensionsWebhookTest/webhook-callback-template.json rename to src/test/resources/org/wiremock/integrations/testcontainers/WireMockContainerWebhooksTest/webhook-callback-template.json diff --git a/src/test/resources/org/wiremock/integrations/testcontainers/wiremock2/WebhooksExtensionTest/webhook-callback-template.json b/src/test/resources/org/wiremock/integrations/testcontainers/wiremock2/WebhooksExtensionTest/webhook-callback-template.json new file mode 100644 index 0000000..1e509ea --- /dev/null +++ b/src/test/resources/org/wiremock/integrations/testcontainers/wiremock2/WebhooksExtensionTest/webhook-callback-template.json @@ -0,0 +1,31 @@ +{ + "request": { + "method": "POST", + "urlPath": "/wiremock/callback-trigger" + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/json" + }, + "jsonBody": { + "message": "Please wait callback", + "method": "{{jsonPath request.body '$.callbackMethod'}}", + "url": "{{jsonPath request.body '$.callbackUrl'}}" + } + }, + "postServeActions": [ + { + "name": "webhook", + "parameters": { + "method": "{{jsonPath originalRequest.body '$.callbackMethod'}}", + "url": "{{jsonPath originalRequest.body '$.callbackUrl'}}", + "body": "Async processing Finished", + "delay": { + "type": "fixed", + "milliseconds": 1000 + } + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/org/wiremock/integrations/testcontainers/wiremock2/WireMockContainerExtensionsCombinationTest/json-body-transformer.json b/src/test/resources/org/wiremock/integrations/testcontainers/wiremock2/WireMockContainerExtensionsCombinationTest/json-body-transformer.json new file mode 100644 index 0000000..2874cec --- /dev/null +++ b/src/test/resources/org/wiremock/integrations/testcontainers/wiremock2/WireMockContainerExtensionsCombinationTest/json-body-transformer.json @@ -0,0 +1,16 @@ +{ + "request": { + "method": "POST", + "url": "/json-body-transformer" + }, + "response": { + "status": 201, + "headers": { + "content-type": "application/json" + }, + "jsonBody": { + "message": "Hello, $(name)!" + }, + "transformers" : ["json-body-transformer"] + } +} \ No newline at end of file