From 1c76389b57166f4fec3725efae079d44deab2b06 Mon Sep 17 00:00:00 2001 From: Alexandre Patelli Date: Mon, 29 Jan 2024 08:39:29 +0100 Subject: [PATCH] Handling path matching request using last mock in priority (#209) (cherry picked from commit b6cdeba4bd3d3f0383d6188d8570be15f92d8f45) --- .../decathlon/tzatziki/utils/MockFaster.java | 39 ++++++++++++++----- .../com/decathlon/tzatziki/steps/http.feature | 12 +++++- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/mockfaster/src/main/java/com/decathlon/tzatziki/utils/MockFaster.java b/mockfaster/src/main/java/com/decathlon/tzatziki/utils/MockFaster.java index 27863b4c..668f2865 100644 --- a/mockfaster/src/main/java/com/decathlon/tzatziki/utils/MockFaster.java +++ b/mockfaster/src/main/java/com/decathlon/tzatziki/utils/MockFaster.java @@ -18,13 +18,24 @@ import org.mockserver.closurecallback.websocketregistry.LocalCallbackRegistry; import org.mockserver.collections.CircularPriorityQueue; import org.mockserver.integration.ClientAndServer; -import org.mockserver.matchers.*; +import org.mockserver.matchers.HttpRequestMatcher; +import org.mockserver.matchers.HttpRequestPropertiesMatcher; +import org.mockserver.matchers.JsonStringMatcher; +import org.mockserver.matchers.MatchType; +import org.mockserver.matchers.TimeToLive; +import org.mockserver.matchers.Times; import org.mockserver.mock.Expectation; import org.mockserver.mock.HttpState; import org.mockserver.mock.SortableExpectationId; import org.mockserver.mock.action.ExpectationResponseCallback; import org.mockserver.mock.listeners.MockServerMatcherNotifier; -import org.mockserver.model.*; +import org.mockserver.model.Body; +import org.mockserver.model.Header; +import org.mockserver.model.HttpRequest; +import org.mockserver.model.HttpResponse; +import org.mockserver.model.LogEventRequestAndResponse; +import org.mockserver.model.NottableSchemaString; +import org.mockserver.model.Parameter; import org.mockserver.netty.MockServerUnificationInitializer; import org.mockserver.verify.VerificationTimes; @@ -40,7 +51,10 @@ import static com.decathlon.tzatziki.utils.Fields.getValue; import static com.decathlon.tzatziki.utils.Unchecked.unchecked; import static java.util.function.Function.identity; -import static java.util.stream.Collectors.*; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; @Slf4j @NoArgsConstructor(access = AccessLevel.PRIVATE) @@ -178,16 +192,21 @@ public static Integer localPort() { private static final Set PATH_PATTERNS = new LinkedHashSet<>(); public static List retrieveRequestResponses(HttpRequest httpRequest) { - PATH_PATTERNS.stream() - .map(pathPattern -> pathPattern.matcher(httpRequest.getPath().getValue())) - .filter(Matcher::matches) - .filter(matcher -> matcher.groupCount() > 0) - .findFirst() - .ifPresent(matcher -> { + List patternArrayList = new ArrayList<>(PATH_PATTERNS); + Collections.reverse(patternArrayList); + for (Pattern pattern : patternArrayList) { + Matcher matcher = pattern.matcher(httpRequest.getPath().getValue()); + if (matcher.matches()) { + if (matcher.groupCount() > 0) { for (int i = 1; i <= matcher.groupCount(); i++) { httpRequest.withPathParameter("param" + i, matcher.group(i)); + } - }); + } + break; + } + } + List requestResponses = new ArrayList<>(); CompletableFuture waiter = new CompletableFuture<>(); unchecked(HTTP_STATE::get).getMockServerLog().retrieveRequestResponses(httpRequest, logEventRequestAndResponses -> { diff --git a/tzatziki-http/src/test/resources/com/decathlon/tzatziki/steps/http.feature b/tzatziki-http/src/test/resources/com/decathlon/tzatziki/steps/http.feature index d539ad2c..6fb19358 100644 --- a/tzatziki-http/src/test/resources/com/decathlon/tzatziki/steps/http.feature +++ b/tzatziki-http/src/test/resources/com/decathlon/tzatziki/steps/http.feature @@ -1461,4 +1461,14 @@ Feature: to interact with an http service and setup mocks Scenario: Http status codes are extended and not limited to MockServer ones Given that getting on "http://backend/tooManyRequest" will return a status TOO_MANY_REQUESTS_429 - Then getting on "http://backend/tooManyRequest" returns a status TOO_MANY_REQUESTS_429 \ No newline at end of file + Then getting on "http://backend/tooManyRequest" returns a status TOO_MANY_REQUESTS_429 + + + Scenario: Conflicting pattern are properly handled and last mock is prioritized + Given that getting on "http://backend/test/S(\d)/path/C(\d)" will return a status TOO_MANY_REQUESTS_429 + + And that getting on "http://backend/test/S1/path/C2" will return a status OK_200 + + Then getting on "http://backend/test/S1/path/C2" returns a status OK_200 + + And "http://backend/test/S1/path/C2" has received a GET \ No newline at end of file