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

Provider States Ignoring Parameter Types #298

Open
adamrodger opened this issue Jun 28, 2023 · 2 comments
Open

Provider States Ignoring Parameter Types #298

adamrodger opened this issue Jun 28, 2023 · 2 comments
Labels
smartbear-supported SmartBear engineering team will support this issue. See https://docs.pact.io/help/smartbear

Comments

@adamrodger
Copy link
Contributor

If I create an interaction with a provider state parameter that I specify as a string, e.g. in PactNet:

this.pact
    .UponReceiving("a request for an order by ID")
        // 👇👇👇 note that the parameter is a string
        .Given("an order with ID {id} exists", new Dictionary<string, string> { ["id"] = "1" })
        .WithRequest(HttpMethod.Get, "/api/orders/1")
        .WithHeader("Accept", "application/json")
    .WillRespond()
        .WithStatus(HttpStatusCode.OK)
        .WithJsonBody(new { ... });

Then when the interaction is written to the Pact file, the parameter has been converted to a number:

{
  "description": "a request for an order by ID",
  "pending": false,
  "providerStates": [
    {
      "name": "an order with ID {id} exists",
      "params": {
        // 👇👇👇 note that the parameter is now an integer, even though I specified a string
        "id": 1
      }
    }
  ],
  "request": {
    "headers": {
      "Accept": [
        "application/json"
      ]
    },
    "method": "GET",
    "path": "/api/orders/1"
  },
  "response": {
    "body": {
      "content": {
        "date": "2023-06-28T12:13:14.0000000+01:00",
        "id": 1,
        "status": "Pending"
      },
      "contentType": "application/json",
      "encoded": false
    },
    "headers": {
      "Content-Type": [
        "application/json"
      ]
    },
    "status": 200
  },
  "type": "Synchronous/HTTP"
},

This makes writing provider state middleware really tricky, because I now have to guess what the FFI is going to do with converting my types, and I also have to deal with converting everything back to the correct type again, even though I told it the correct type in the first place.

The provider state endpoint will get the following body in a POST request:

{
  "action": "setup",
  // 👇👇👇 note that the parameter is now an integer, even though I specified a string
  "params": { "id": 1 },
  "state":"an order with ID {id} exists"
}

Given that different parameters can have different types and there may be many provider states, that means my only option to deserialise that to Dictionary<string, object> and then deal with all the hassle of having to check what type that object actually is for every provider state handler and then do the conversion myself.

That's really not an ergonomic experience and makes writing provider state handlers really tedious.

Please can it just retain the type that I told it to have instead of trying to be clever and converting the type to something that I don't want?

@adamrodger
Copy link
Contributor Author

For example, if you try to deserialise the provider state body that's POSTed to DIctionary<string, object>, you get really awkward types in the values. You can't do something like this:

record ProviderStateDto(string State, Dictionary<string, object> Params);

Dictionary<string, object> parameters = JsonConvert.Deserialise<ProviderState>(request.Body);
int id = (int)parameters["id"];

Otherwise you get an invalid cast exception:

image

That's because the deserialiser doesn't have any type information to work with, and thus the parameters dictionary contains a bunch of typed objects:

image

So now you need to do pattern matching or something against the types to work out what's actually in there so you can unwrap it properly. You need to do this with every single provider state parameter you ever use, which is very tedious.

@rholshausen rholshausen added the smartbear-supported SmartBear engineering team will support this issue. See https://docs.pact.io/help/smartbear label Feb 19, 2024
Copy link

🤖 Great news! We've labeled this issue as smartbear-supported and created a tracking ticket in PactFlow's Jira (PACT-1838). We'll keep work public and post updates here. Meanwhile, feel free to check out our docs. Thanks for your patience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
smartbear-supported SmartBear engineering team will support this issue. See https://docs.pact.io/help/smartbear
Projects
None yet
Development

No branches or pull requests

2 participants