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

Using ProviderStateGenerator should not allow mock server to match any request #447

Closed
mefellows opened this issue Jun 20, 2024 · 7 comments
Labels
bug Indicates an unexpected problem or unintended behavior smartbear-supported SmartBear engineering team will support this issue. See https://docs.pact.io/help/smartbear triage This issue is yet to be triaged by a maintainer

Comments

@mefellows
Copy link
Member

Via: pact-foundation/pact-js#1088

Summary

When I add interaction like this:

pact.addInteraction({
        states: [{ description: 'A user' }],
        uponReceiving: 'get one user',
        withRequest: {
            method: 'GET',
            path: fromProviderState('${iri}', '/api/users/14f6626f-c51e-4311-ac52-182c8f2a7634')
        },
        willRespondWith: {
            status: 200,
            body: {
                id: '14f6626f-c51e-4311-ac52-182c8f2a7634'
            },
        },
    });

I expect mock server should return 404 for this request GET /any, but it return 200 with body {"id": "14f6626f-c51e-4311-ac52-182c8f2a7634"}

Expected behaviour

The request GET /any should return 404, and mock server should report the request GET /api/users/14f6626f-c51e-4311-ac52-182c8f2a7634 is expected but not received.

Actual behaviour

The request GET /any return 200 with json body that didn't belong to it.

Steps to reproduce

Here is the demo project https://github.com/tienvx/test-from-provider-state-generator

Relevant log files

[21:12:21.618] INFO (27131): 0.4.7: pact native library successfully found, and the correct version
2023-08-11T14:12:21.624175Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: detected pact:matcher:type, will configure a matcher
2023-08-11T14:12:21.624206Z DEBUG ThreadId(01) pact_ffi::mock_server::handles: detected pact:generator:type, will configure a generators
2023-08-11T14:12:21.624683Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/transport/http
core/transport/https
2023-08-11T14:12:21.624703Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/content-generator/binary
core/content-generator/json
core/content-matcher/json
core/content-matcher/multipart-form-data
core/content-matcher/text
core/content-matcher/xml
2023-08-11T14:12:21.624722Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries:
core/matcher/v1-equality
core/matcher/v2-max-type
core/matcher/v2-min-type
core/matcher/v2-minmax-type
core/matcher/v2-regex
core/matcher/v2-type
core/matcher/v3-content-type
core/matcher/v3-date
core/matcher/v3-datetime
core/matcher/v3-decimal-type
core/matcher/v3-includes
core/matcher/v3-integer-type
core/matcher/v3-null
core/matcher/v3-number-type
core/matcher/v3-time
core/matcher/v4-array-contains
core/matcher/v4-equals-ignore-order
core/matcher/v4-max-equals-ignore-order
core/matcher/v4-min-equals-ignore-order
core/matcher/v4-minmax-equals-ignore-order
core/matcher/v4-not-empty
core/matcher/v4-semver
2023-08-11T14:12:21.624852Z DEBUG ThreadId(01) pact_mock_server::mock_server: Started mock server on 127.0.0.1:36287
*
2023-08-11T14:12:21.641024Z DEBUG tokio-runtime-worker hyper::proto::h1::io: parsed 7 headers
2023-08-11T14:12:21.641032Z DEBUG tokio-runtime-worker hyper::proto::h1::conn: incoming body is empty
2023-08-11T14:12:21.641047Z DEBUG tokio-runtime-worker pact_mock_server::hyper_server: Creating pact request from hyper request
2023-08-11T14:12:21.641051Z DEBUG tokio-runtime-worker pact_mock_server::hyper_server: Extracting query from uri /any
2023-08-11T14:12:21.641067Z  INFO tokio-runtime-worker pact_mock_server::hyper_server: Received request GET /any
2023-08-11T14:12:21.641071Z DEBUG tokio-runtime-worker pact_mock_server::hyper_server: 
      ----------------------------------------------------------------------------------------
       method: GET
       path: /any
       query: None
       headers: Some({"host": ["127.0.0.1:36287"], "accept": ["*/*"], "accept-language": ["*"], "sec-fetch-mode": ["cors"], "accept-encoding": ["gzip", "deflate"], "connection": ["keep-alive"], "user-agent": ["undici"]})
       body: Empty
      ----------------------------------------------------------------------------------------
      
2023-08-11T14:12:21.641104Z  INFO tokio-runtime-worker pact_matching: comparing to expected HTTP Request ( method: GET, path: /api/users/14f6626f-c51e-4311-ac52-182c8f2a7634, query: None, headers: None, body: Missing )
2023-08-11T14:12:21.641108Z DEBUG tokio-runtime-worker pact_matching:      body: ''
2023-08-11T14:12:21.641109Z DEBUG tokio-runtime-worker pact_matching:      matching_rules: MatchingRules { rules: {PATH: MatchingRuleCategory { name: PATH, rules: {DocPath { path_tokens: [Root], expr: "$" }: RuleList { rules: [Type], rule_logic: And, cascaded: false }} }} }
2023-08-11T14:12:21.641116Z DEBUG tokio-runtime-worker pact_matching:      generators: Generators { categories: {PATH: {DocPath { path_tokens: [Root], expr: "$" }: ProviderStateGenerator("${iri}", None)}} }
2023-08-11T14:12:21.641131Z DEBUG tokio-runtime-worker pact_matching::matchers: String -> String: comparing '/api/users/14f6626f-c51e-4311-ac52-182c8f2a7634' to '/any' ==> true cascaded=false matcher=Type
2023-08-11T14:12:21.641139Z DEBUG tokio-runtime-worker pact_matching: expected content type = '*/*', actual content type = '*/*'
2023-08-11T14:12:21.641173Z DEBUG tokio-runtime-worker pact_matching: content type header matcher = 'RuleList { rules: [], rule_logic: And, cascaded: false }'
2023-08-11T14:12:21.641178Z DEBUG tokio-runtime-worker pact_matching: --> Mismatches: []
2023-08-11T14:12:21.641197Z DEBUG tokio-runtime-worker pact_mock_server::hyper_server: Test context = {"mockServer": Object {"port": Number(36287), "url": String("http://127.0.0.1:36287")}}
2023-08-11T14:12:21.641204Z  INFO tokio-runtime-worker pact_mock_server::hyper_server: Request matched, sending response
2023-08-11T14:12:21.641206Z DEBUG tokio-runtime-worker pact_mock_server::hyper_server: 
          ----------------------------------------------------------------------------------------
           status: 200
           headers: Some({"Content-Type": ["application/json"]})
           body: Present(45 bytes, application/json) '{"id":"14f6626f-c51e-4311-ac52-182c8f2a7634"}'
          ----------------------------------------------------------------------------------------
          
2023-08-11T14:12:21.641243Z DEBUG tokio-runtime-worker hyper::proto::h1::io: flushed 397 bytes
2023-08-11T14:12:21.646194Z DEBUG ThreadId(01) pact_matching::metrics: Could not get the tokio runtime, will not send metrics - there is no reactor running, must be called from the context of a Tokio 1.x runtime
2023-08-11T14:12:21.646203Z DEBUG ThreadId(01) pact_mock_server::server_manager: Shutting down mock server with ID 804f0cc0-02ce-47b5-ac0f-8c84f595b26c - MockServerMetrics { requests: 1, requests_by_path: {"/any": 1} }
2023-08-11T14:12:21.646209Z DEBUG ThreadId(01) pact_mock_server::mock_server: Mock server 804f0cc0-02ce-47b5-ac0f-8c84f595b26c shutdown - MockServerMetrics { requests: 1, requests_by_path: {"/any": 1} }
@mefellows mefellows added bug Indicates an unexpected problem or unintended behavior smartbear-supported SmartBear engineering team will support this issue. See https://docs.pact.io/help/smartbear triage This issue is yet to be triaged by a maintainer labels Jun 20, 2024
Copy link

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

@rholshausen
Copy link
Contributor

The interaction has been misconfigured with a type matcher for the path. This is a Pact-JS issue.

matching_rules: MatchingRules { rules: {PATH: MatchingRuleCategory { name: PATH, rules: {DocPath { path_tokens: [Root], expr: "$" }: RuleList { rules: [Type], rule_logic: And, cascaded: false }} }} }

@mefellows
Copy link
Member Author

Ah, good spot! So I need to think about how this function should be defined. It's currently both a matcher and a generator - I think it should not be a matcher itself, but potentially could also accept a matcher or expression in the example

e.g. matcher

    withRequest: {
        method: 'GET',
        path: fromProviderState('${iri}', regex(/..../, '/api/users/14f6626f-c51e-4311-ac52-182c8f2a7634'))
    },

or expression

    withRequest: {
        method: 'GET',
        path: fromProviderState('${iri}', "matching(regex, '\\xyz', '/api/users/14f6626f-c51e-4311-ac52-182c8f2a7634')")
    },

Which one (if any) is the right approach here?

@rholshausen
Copy link
Contributor

@mefellows
Copy link
Member Author

ok cool, thanks. Is it true that any expression can be used in the second part, or only expressions (of another kind) that contain the dynamically replaceable values?

@rholshausen
Copy link
Contributor

I don't know if that is true. It could be. It could also be false.

@mefellows
Copy link
Member Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior smartbear-supported SmartBear engineering team will support this issue. See https://docs.pact.io/help/smartbear triage This issue is yet to be triaged by a maintainer
Projects
None yet
Development

No branches or pull requests

2 participants