mockserver icon indicating copy to clipboard operation
mockserver copied to clipboard

Supposely unmatched request always default to an expectation

Open gbmarc1 opened this issue 3 years ago • 3 comments

Describe the issue I have an openapi spec that creates multiple expectations. When calling an endpoint that does not exist (that does should not match any expectation), I would assume that the mock server would return 404. However, it always returns a reponse of a specific expectation that does NOT match.

For example: Request: curl --user name:password -v GET "http://localhost:1080/idontexists"

Response:


*   Trying 127.0.0.1:1080...
* Connected to localhost (127.0.0.1) port 1080 (#0)
* Server auth using Basic with user 'name'
> GET /idontexists HTTP/1.1
> Host: localhost:1080
> Authorization: Basic bmFtZTpwYXNzd29yZA==
> User-Agent: curl/7.83.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< content-type: application/json
< connection: keep-alive
< content-length: 648
<
{
    "fileId" : 0,
    "name" : "some_string_value",
    "projectId" : 0,
    "dataOwnerId" : 0,
    "language" : "some_string_value",
    "territory" : "some_string_value",
    "importType" : "comment",
    "workUnitId" : 0,
    "totalSubmittedData" : 0,
    "totalUniqueData" : 0,
    "createdDatumParts" : 0,
    "createdData" : 0,
    "createdProjectData" : 0,
    "createdWorkUnitData" : 0,
    "createdOnWorkUnitData" : "2018-11-13T20:20:39+00:00",
    "createdOn" : "2018-11-13T20:20:39+00:00",
    "modifiedOn" : "2018-11-13T20:20:39+00:00",
    "expiredOn" : "2018-11-13T20:20:39+00:00",
    "status" : "import-submitted",
    "progress" : 1.5,
    "error" : "some_string_value"
}* Connection #0 to host localhost left intact

The default response comes from a "not supported" operation that is added. It seems that its response becomes the default when not found.

multipart form data is not supported on requestBody, skipping operation:	"v1.datamgmt.projects.projectId.workUnit.workUnitId.workUnitData.files.post"	method:	"POST"	in open api:	

If I remove that operation in the .yaml file, the mock server behaves properly.

MockServer version I used mockserver/mockserver:mockserver-5.13.2 and mockserver/mockserver:latest and both have the same behaviour.

MockServer Log

{
  "method": "GET",
  "path": "/idontexists",
  "headers": {
    "content-length": [
      "0"
    ],
    "User-Agent": [
      "curl/7.83.1"
    ],
    "Host": [
      "localhost:1080"
    ],
    "Authorization": [
      "Basic bmFtZTpwYXNzd29yZA=="
    ],
    "Accept": [
      "*/*"
    ]
  },
  "keepAlive": true,
  "secure": false,
  "remoteAddress": "172.17.0.1"
}

gbmarc1 avatar Aug 01 '22 17:08 gbmarc1

Got the same issue...

karu971 avatar Aug 01 '22 17:08 karu971

I can't reproduce this even with an OpenAPI specification with a multipart/form-data field.

Perhaps there is an issue related to your specific OpenAPI specification or your specification includes a request that would match the curl you're making.

Please provide the specification so I can test with that.

jamesdbloom avatar Aug 17 '22 13:08 jamesdbloom

Hi, I get the same issue.

If content is multipart/form-data, httpRequestPropertiesMatcher is not added to httpRequestPropertiesMatchers. https://github.com/mock-server/mockserver/blob/master/mockserver-core/src/main/java/org/mockserver/matchers/HttpRequestsPropertiesMatcher.java#L438

            if (contentType.equals("multipart/form-data")) {
                logEntries.add(
                    new LogEntry()
                        .setLogLevel(ERROR)
                        .setMessageFormat("multipart form data is not supported on requestBody, skipping operation:{}method:{}in open api:{}")
                        .setArguments(methodOperationPair.getRight().getOperationId(), methodOperationPair.getLeft(), openAPIDefinition)
                );
                return;
            }

When httpRequestPropertiesMatchers is empty, always return true. https://github.com/mock-server/mockserver/blob/master/mockserver-core/src/main/java/org/mockserver/matchers/HttpRequestsPropertiesMatcher.java#L504

    public boolean matches(MatchDifference context, RequestDefinition requestDefinition) {
        boolean result = false;
        if (httpRequestPropertiesMatchers != null && !httpRequestPropertiesMatchers.isEmpty()) {
            for (HttpRequestPropertiesMatcher httpRequestPropertiesMatcher : httpRequestPropertiesMatchers) {
                if (context == null) {
                    if (MockServerLogger.isEnabled(Level.TRACE) && requestDefinition instanceof HttpRequest) {
                        context = new MatchDifference(configuration.detailedMatchFailures(), requestDefinition);
                    }
                    result = httpRequestPropertiesMatcher.matches(context, requestDefinition);
                } else {
                    MatchDifference singleMatchDifference = new MatchDifference(configuration.detailedMatchFailures(), context.getHttpRequest());
                    result = httpRequestPropertiesMatcher.matches(singleMatchDifference, requestDefinition);
                    context.addDifferences(singleMatchDifference.getAllDifferences());
                }
                if (result) {
                    break;
                }
            }
        } else {
            result = true;
        }
        return result;
    }

I think also multipart/form-data has to have httpRequestPropertiesMatcher.

gimbimloki avatar Sep 01 '23 15:09 gimbimloki