pact-ruby icon indicating copy to clipboard operation
pact-ruby copied to clipboard

Feat/provider params

Open tucker-m opened this issue 6 years ago • 10 comments

This allows the provider state to change some values in the request before the interaction is replayed. It's related to the pull request I made in the pact-support repository, here: https://github.com/pact-foundation/pact-support/pull/57.

I'd love to know what you think about doing this. We've been using my fork where I work, and have been finding it to be a great way of handling IDs in URLs, and also authorization headers.

tucker-m avatar Jun 13 '18 23:06 tucker-m

This is fantastic, and I'm glad it's working for you, but I am unable to merge this into the main codebase because it doesn't conform to the pact-specification. Pact is about more than just the Ruby codebase - in fact, the Ruby user group is one of the smaller communities. Keeping the implementations in sync is important for interoperability.

I'd like to get something like this into the next pact spec version however. @uglyog is this a "thing" in v3 or v4? Is this what generators do?

bethesque avatar Jun 14 '18 04:06 bethesque

This is awesome.

Yes, this has overlap with the generators. What we could do, is define a specific generator that can replace the values from what is setup in the provider state. That way we do not have to introduce any new elements to the pact file format, just define the generator. See https://github.com/pact-foundation/pact-specification/tree/version-3#introduce-example-generators for more info.

I might try spike out an implementation in Pact-JVM.

uglyog avatar Jun 14 '18 09:06 uglyog

I must admit that was my first impression. It's even better than a usual generator, though, because it means we can support any type of value or logic behind creating that value, instead of relying on a fixed set of them.

For example, the Date generator might not work if the time must be something in the past or future, within a specific period. This would give the user flexibility over how its created.

+1

mefellows avatar Jun 15 '18 04:06 mefellows

Oh, right. I thought generators allowed you to put in your own values. So, yes, we really want this.

bethesque avatar Jun 15 '18 06:06 bethesque

I've been doing a dirty hack with my HAL pacts, where I put a placeholder URL in on the consumer side, that I then replace with the real URL when I run the verification. This allows my consumer tests not to have to "know" what the real provider URLs are, ensuring the intent of hypermedia is actually fulfilled. I want to put this properly into the pact spec, and imagine it would be similar to the above solution.

bethesque avatar Jun 15 '18 06:06 bethesque

Thanks for the feedback! I'm so glad to hear that there is interest in adding this capability. I figured that it would need to be added to the spec, but I wasn't sure how to go about doing that.

Would this be something in version 3, or version 4? If it's done as a new type of generator, does that mean it could be in version 3?

tucker-m avatar Jun 18 '18 20:06 tucker-m

Generators are V3. @bethesque we could try use the generators from the Rust implementation. We should just be able to create a Gem where you pass the body and the generator hash, and get a new body back.

rholshausen avatar Jun 18 '18 23:06 rholshausen

Hey @tucker-m for your contributions, this was a very cool feature

Thanks for this, sorry for the delay.

So this relates to https://github.com/pact-foundation/pact-support/pull/57

so is this basically supported by v3 with generators? (and this can be closed?)

YOU54F avatar Apr 25 '22 13:04 YOU54F

Ok so been digging a bit further, this was introduced into the spec in v4

https://github.com/pact-foundation/pact-specification/tree/version-4?tab=readme-ov-file#supported-generators

Generator Attributes Description Example JSON
ProviderState V4 {"expression": "/api/user/${id}", "type": "ProviderState"} Generates a value that is looked up from the provider state context using the given expression

bit of a cookie trail here https://github.com/pact-foundation/pact-reference/issues/116 which was linked in the pact v4 rfc

so we would need the matching rules to change from

        "path": "/food_item/5",
         "headers": {
          "Authorization": "Bearer faketoken"
        },
        "matchingRules": {
          "$.path": {
            "match": "provider_param",
            "fill_string": "/food_item/:{id}"
          },
          "$.headers.Authorization": {
            "match": "provider_param",
            "fill_string": "Bearer :{auth_token}"
          }
        }

to be

        "path": "/food_item/5",
         "headers": {
          "Authorization": "Bearer faketoken"
        },
        "matchingRules": {
          "$.path": {
            "type": "ProviderState"
            "expression": "/food_item/${id}"
          },
          "$.headers.Authorization": {
            "type": "ProviderState"
            "expression": "Bearer ${auth_token}"
          }
        }

We would need to scope the matcher/generator to V4 (it isn't listed in the V3 matcher spec).

I'll check what the pact_ffi library does if it is told to process a v3 spec, and we provide this matcher.

YOU54F avatar Aug 06 '24 14:08 YOU54F

See additional comments here in the associated change for pact-support

https://github.com/pact-foundation/pact-support/pull/57#issuecomment-2289150032

Will convert to a draft and pick up a continuation of this for progress towards https://github.com/pact-foundation/pact-ruby/issues/319

YOU54F avatar Aug 14 '24 15:08 YOU54F