Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading mapping models with JsonMatcher is not working correctly #504

Closed
cezarypiatekGC opened this issue Sep 17, 2020 · 19 comments
Closed
Labels

Comments

@cezarypiatekGC
Copy link

cezarypiatekGC commented Sep 17, 2020

Describe the bug

Loading mapping models with JsonMatcher for Body matcher from a file is not working correctly.

Steps to reproduce:

  1. Create mapping with JsonMatcher for the body and save it to file as follow
var requestBuilder = Request.Create()
	.WithPath("/api/v1.0/accounts/")
	.WithHeader("Content-Type", "application/json; charset=utf-8")
	.WithBody(new JsonMatcher(new { AccountIds = new[] { 1, 2, 3} }))
	.UsingPost();

var respondWithAProvider = wiremockServer.Given(requestBuilder, saveToFile: true);

var responseProvider = Response.Create()
	.WithStatusCode(200)
	.WithHeader("Content-Type", "application/json; charset=utf-8")
	.WithBody(JsonConvert.SerializeObject(new[] { 1, 2, 3 }));

wiremockServer.RespondWith(responseProvider);
  1. As a result I get a file with the following content
{
  "Guid": "7d1c7dcc-eba1-4c3a-bc82-0a444fe9fcd9",
  "Request": {
    "Path": {
      "Matchers": [
        {
          "Name": "WildcardMatcher",
          "Pattern": "/api/v1.0/accounts/",
          "IgnoreCase": false
        }
      ]
    },
    "Methods": [
      "POST"
    ],
    "Headers": [
      {
        "Name": "Content-Type",
        "Matchers": [
          {
            "Name": "WildcardMatcher",
            "Pattern": "application/json; charset=utf-8",
            "IgnoreCase": true
          }
        ]
      }
    ],
    "Body": {
      "Matcher": {
        "Name": "JsonMatcher",
        "Pattern": {
          "AccountIds": [1, 2, 3]
        },
        "IgnoreCase": false
      }
    }
  },
  "Response": {
    "StatusCode": 200,
    "BodyDestination": "SameAsSource",
    "Body": "[1,2,3]",
    "Headers": {
      "Content-Type": "application/json; charset=utf-8"
    }
  }
}
  1. Load mapping from file and feed it to the WireMock server
var content = File.ReadAllText(@"__admin\mappings\7d1c7dcc-eba1-4c3a-bc82-0a444fe9fcd9.json");
wiremockServer.WithMapping(content);

Expected behavior:

This is how requestBuilder looks like before saving mapping to a file
image

This is how requestBuilder looks like after loading from a file

image

The expectation is that the JsonMatcher works in the same way when loaded from a file and when created from the code. Currently, the pattern is always set to null when loading from a file.

Other notes

This is probably caused by this line where every pattern is cast to string (non-string values will result with a null)

string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.OfType<string>().ToArray() : new[] { matcher.Pattern as string };

@StefH
Copy link
Collaborator

StefH commented Sep 19, 2020

Hello @cezarypiatekGC . Thank you for your research.

@StefH
Copy link
Collaborator

StefH commented Sep 19, 2020

#505

@cezarypiatekGC : can you try preview version from MyGet : WireMock.Net.1.2.18-ci-13750.nupkg ?

@cezarypiatekGC
Copy link
Author

I've tested this preview package and there's still a difference between JsonMatcher before saving to file and after loading which affects how the matcher works.

Before saving to file

image

After loading from a file

image

JObject vs JArray

@StefH
Copy link
Collaborator

StefH commented Sep 19, 2020

Can you try new version WireMock.Net.1.2.18-ci-13754.nupkg (or higher)?

@cezarypiatekGC
Copy link
Author

cezarypiatekGC commented Sep 19, 2020

I've tried with WireMock.Net.1.2.18-ci-13754 but still, JsonMatcher has a different value and It's not working in the same way as it worked before saving to a file.

image

image

@StefH
Copy link
Collaborator

StefH commented Sep 20, 2020

Note that the Value property will not be the same, because in your initial code this is an anonymous object. And when the mapping is read from a .json file, this is a JObject. But the _valueAsJToken is used for matching, and this should be the same.

So can you make a full example (unit test) which demonstrates your issue?

@cezarypiatekGC
Copy link
Author

Ok, I will try to prepare a test or demo app that reproduces that problem.

@RiccoFerraro
Copy link

RiccoFerraro commented Sep 29, 2020

Hi guys, I also believe I'm having this problem. I have static mappings (generated via recording with wiremock.net) I just upgraded to 1.3.0. I've debugged into JsonMatcher and it appears _valueAsJToken is always a jtoken for a null object, This is even when there is a request body and specified JsonMatcher. The result, is that no matter what I supply in the payload, matching doesn't appear to happen in any way on the request body.
image
Not sure what I'm doing wrong here, but I feel like I've tried a million different things. Here is the mapping json for a particular request body:
image.

image

UPDATE:
On Further inspection it seems to have to do with converting the Patterns into an array? The Patterns object looks just fine, but the stringPattern is null.
image

@StefH
Copy link
Collaborator

StefH commented Sep 30, 2020

Hello @RiccoFerraro,

The 1.3.0 version does not have any preview fixed code for this issue, in order to test that you need MyGet version WireMock.Net.1.2.18-ci-13754.nupkg.
Or if you want to debug, you can use the PR : #505

And can you create a full working example please?

@RiccoFerraro
Copy link

Hi @StefH Will do. I'll get back to you on if the issue is in that alpha build

@StefH
Copy link
Collaborator

StefH commented Oct 7, 2020

Hello @RiccoFerraro,did you have time yet to verify ?

@RiccoFerraro
Copy link

@StefH Sorry I haven't had a chance yet. I will try to take a look at this sometime this week. I'll post here when I've tried it.

@RiccoFerraro
Copy link

RiccoFerraro commented Oct 12, 2020

@StefH Sorry for the delay, still haven't had a chance to test this fix out yet. I've been absolutely slammed with work and will get to it as soon as I get a second.

On a related note, I did notice something else about partial match scores that seemed off. (probably requires a little redesign). For our team to continue using wiremock.net we need to trust that the Http VERB is ALWAYS respected. I've been noticing that, even when a post call is fired, Get matches are being favored (given higher scores) over POST calls (in this case because of the bug mentioned above, the POST call has a lower score because it is failing to match on the body matcher). This seems off. It should match on the highest score, for only a single verb type. I can't imagine a scenario where someone is okay with a get request/response being returned for a post call in an integration test??? That would be a broken integration test to me. Can we introduce a flag to strictly enforce just the verb?

@StefH
Copy link
Collaborator

StefH commented Oct 12, 2020

@RiccoFerraro Thanks about your remark about the Http VERB. I did create a new Issue for this, and I'll take a look how to fix this.

@StefH
Copy link
Collaborator

StefH commented Oct 14, 2020

@RiccoFerraro Investigating + solving that Http Method issue will take some more time.

Are you able to verify this issue ?
Else I will just create a new version because some code is also verified by #513

@RiccoFerraro
Copy link

Hi @StefH, thanks for being so responsive. I'm sorry I don't have time to create test projects and try the all the different versions this week. What I can do is pull down the version in #513 and see if the problems I was having with post body matching are fixed. After that seems to work, I'll work on setting "ParitalMapping" to false to enforce strict mapping. Question, is it in an official nuget.org version? I can't use my-get outside of POC's.

@StefH
Copy link
Collaborator

StefH commented Oct 14, 2020

Hello @RiccoFerraro , I'll release a new version with this fix tonight and for now close this issue.

In case you have another problem please create a new issue.

@StefH StefH closed this as completed Oct 14, 2020
@RiccoFerraro
Copy link

RiccoFerraro commented Dec 11, 2020

Hi @StefH Great stuff on that fix! it appears to work as expected! Quick question, What is the expected behavior for record playback for repeated calls to the same endpoint with these settings in 1.3.7? What I'm apparently experiencing is wiremock doesn't seem to actually proxy the second call to the same endpoint, and instead is serving it's recorded response. This is a problem, because the expected behavior of the endpoint in question is that it changes between calls and i need to capture both responses. I have verified this by calling the endpoint directly in postman (with and without the wiremock server base url) and I get different response. Maybe this can be solved by reseting the server mid test?
image

@StefH
Copy link
Collaborator

StefH commented Dec 12, 2020

@RiccoFerraro
Did you already try "SaveMapping" = false and "SaveMappingToFile" = true ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants