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

Can't use matchers in body with 'Content-Type': 'application/x-www-form-urlencoded' #767

Open
4 of 5 tasks
colossatr0n opened this issue Nov 5, 2021 · 2 comments
Open
4 of 5 tasks
Labels
enhancement Indicates new feature requests

Comments

@colossatr0n
Copy link

Software versions

Please provide at least OS and version of pact-js

  • OS: Mac OSX 10.15.7
  • Versions:
    @pact-foundation/karma-pact: 3.1.0,
    @pact-foundation/pact: 9.16.5,
    @pact-foundation/pact-web: 9.16.5,

Issue Checklist

Please confirm the following:

  • I have upgraded to the latest
  • I have the read the FAQs in the Readme
  • I have triple checked, that there are no unhandled promises in my code and have read the section on intermittent test failures
  • I have set my log level to debug and attached a log file showing the complete request/response cycle
  • For bonus points and virtual high fives, I have created a reproduceable git repository (see below) to illustrate the problem

Expected behaviour

When using pact-web, matchers should be able to be used in the body when the content type is application/x-www-form-urlencoded.

Actual behaviour

Mock server logs report the following:

E, [2021-11-04T18:50:22.192860 #41190] ERROR -- : Error ocurred in mock service: NoMethodError - undefined method `ascii_only?' for #<Pact::Term:0x007fa5d60b4f40>

I believe this is related to #633.

Steps to reproduce

Create a test with the following interaction:

// Failing interaction that uses body matchers and form url encoded content type.
beforeAll(done => {
    provider.addInteraction({
        state: 'some state',
        uponReceiving: 'some request',
        withRequest: {
            method: 'POST',
            path: "/some/path",
            // ISSUE HERE 
            body: Matchers.regex(
                {
                    matcher:  "someFormParam=\\d+",
                    generate: "someFormParam=1",
                }
            ),
            headers: { 'Content-Type': 'application/x-www-form-urlencoded'}
        },
        willRespondWith: {
           status: 200,
            body: {}
        }
    }).then(done);
})

The above test will fail with the log error noted earlier.

Contrast that with this interaction, which will pass:

// Passing interaction that removes the body matcher.
beforeAll(done => {
    provider.addInteraction({
        state: 'some state',
        uponReceiving: 'some request',
        withRequest: {
            method: 'POST',
            path: "/some/path",
            // Body matcher replaced with string 
            body: "someFormParam=1"
            headers: { 'Content-Type': 'application/x-www-form-urlencoded'}
        },
        willRespondWith: {
           status: 200,
            body: {}
        }
    }).then(done);
})

Relevant log files

I, [2021-11-04T18:50:22.136830 #41190]  INFO -- : Received OPTIONS request for mock service administration endpoint DELETE /interactions. Returning CORS headers: {"Access-Control-Allow-Origin"=>"http://localhost:9876", "Access-Control-Allow-Headers"=>"content-type,x-pact-mock-service", "Access-Control-Allow-Methods"=>"DELETE, POST, GET, HEAD, PUT, TRACE, CONNECT, PATCH"}.
I, [2021-11-04T18:50:22.145129 #41190]  INFO -- : Cleared interactions
I, [2021-11-04T18:50:22.156703 #41190]  INFO -- : Registered expected interaction POST /some/path
D, [2021-11-04T18:50:22.157159 #41190] DEBUG -- : {
  "description": "some description",
  "providerState": "some state",
  "request": {
    "method": "POST",
    "path": "/some/path",
    "headers": {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    "body": {
      "json_class": "Pact::Term",
      "data": {
        "generate": "someFormParam=1",
        "matcher": {
          "json_class": "Regexp",
          "o": 0,
          "s": "someFormParam=\\d+"
        }
      }
    }
  },
  "response": {
    "status": 200,
    "headers": {
    },
    "body": { }
  },
  "metadata": null
}
I, [2021-11-04T18:50:22.191358 #41190]  INFO -- : Received request POST /some/path
D, [2021-11-04T18:50:22.191627 #41190] DEBUG -- : {
  "path": "/some/path",
  "query": "",
  "method": "post",
  "body": "someFormParam=1",
  "headers": {
    "Content-Length": "15",
    "Content-Type": "application/x-www-form-urlencoded",
    "X-Forwarded-Host": "localhost:9876",
    "X-Forwarded-Proto": "http",
    "X-Forwarded-Port": "9876",
    "X-Forwarded-For": "127.0.0.1",
    "Accept-Language": "en-US",
    "Accept-Encoding": "gzip, deflate, br",
    "Referer": "http://localhost:9876/context.html",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    "Origin": "http://localhost:9876",
    "Sec-Ch-Ua-Platform": "",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/95.0.4638.69 Safari/537.36",
    "Sec-Ch-Ua-Mobile": "?0",
    "Accept": "application/json, text/plain, */*",
    "Sec-Ch-Ua": "",
    "Connection": "keep-alive",
    "Host": "localhost:9876",
    "Version": "HTTP/1.1"
  }
}
E, [2021-11-04T18:50:22.192860 #41190] ERROR -- : Error ocurred in mock service: NoMethodError - undefined method `ascii_only?' for #<Pact::Term:0x007fa5d60b4f40>
E, [2021-11-04T18:50:22.192981 #41190] ERROR -- : /Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/ruby/lib/ruby/2.2.0/uri/common.rb:450:in `decode_www_form'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-support-1.17.0/lib/pact/shared/form_differ.rb:26:in `decode_www_form'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-support-1.17.0/lib/pact/shared/form_differ.rb:15:in `to_hash'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-support-1.17.0/lib/pact/shared/form_differ.rb:8:in `call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-support-1.17.0/lib/pact/consumer_contract/request.rb:72:in `body_diff'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-support-1.17.0/lib/pact/consumer_contract/request.rb:42:in `difference'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-support-1.17.0/lib/pact/consumer_contract/request.rb:28:in `matches?'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/mock_service/interactions/candidate_interactions.rb:8:in `block in matching_interactions'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/mock_service/interactions/candidate_interactions.rb:7:in `select'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/mock_service/interactions/candidate_interactions.rb:7:in `matching_interactions'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/mock_service/request_handlers/interaction_replay.rb:55:in `find_response'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/mock_service/request_handlers/interaction_replay.rb:45:in `respond'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/mock_service/request_handlers/base_request_handler.rb:17:in `call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/rack-2.1.4/lib/rack/cascade.rb:35:in `block in call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/rack-2.1.4/lib/rack/cascade.rb:26:in `each'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/rack-2.1.4/lib/rack/cascade.rb:26:in `call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/consumer/mock_service/cors_origin_header_middleware.rb:11:in `call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/consumer/mock_service/error_handler.rb:13:in `call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/mock_service/app.rb:34:in `call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/pact-mock_service-3.9.0/lib/pact/consumer/mock_service/set_location.rb:14:in `call'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/rack-2.1.4/lib/rack/handler/webrick.rb:88:in `service'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/webrick-1.3.1/lib/webrick/httpserver.rb:138:in `service'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/webrick-1.3.1/lib/webrick/httpserver.rb:94:in `run'
/Users/someuser/webapp/node_modules/@pact-foundation/pact-node/standalone/darwin-1.88.77/pact/lib/vendor/ruby/2.2.0/gems/webrick-1.3.1/lib/webrick/server.rb:191:in `block in start_thread'
I, [2021-11-04T18:50:22.201372 #41190]  INFO -- : Received OPTIONS request for mock service administration endpoint GET /interactions/verification. Returning CORS headers: {"Access-Control-Allow-Origin"=>"http://localhost:9876", "Access-Control-Allow-Headers"=>"content-type,x-pact-mock-service", "Access-Control-Allow-Methods"=>"DELETE, POST, GET, HEAD, PUT, TRACE, CONNECT, PATCH"}.
W, [2021-11-04T18:50:22.205640 #41190]  WARN -- : Verifying - actual interactions do not match expected interactions. 
Missing requests:
	POST /some/path



W, [2021-11-04T18:50:22.205722 #41190]  WARN -- : Missing requests:
	POST /some/path



I, [2021-11-04T18:50:22.209135 #41190]  INFO -- : Received OPTIONS request for mock service administration endpoint POST /pact. Returning CORS headers: {"Access-Control-Allow-Origin"=>"http://localhost:9876", "Access-Control-Allow-Headers"=>"content-type,x-pact-mock-service", "Access-Control-Allow-Methods"=>"DELETE, POST, GET, HEAD, PUT, TRACE, CONNECT, PATCH"}.
I, [2021-11-04T18:50:22.222491 #41190]  INFO -- : Cleared interactions
 

@colossatr0n colossatr0n added the bug Indicates an unexpected problem or unintended behavior label Nov 5, 2021
@mefellows
Copy link
Member

We don't support matchers on non-JSON or XML bodies at this time.

This could be marked as an enhancement, or (preferably) be supported via the new plugins process when ready.

@TimothyJones TimothyJones added enhancement and removed bug Indicates an unexpected problem or unintended behavior labels Nov 5, 2021
@mefellows
Copy link
Member

cc @uglyog

@mefellows mefellows added the enhancement Indicates new feature requests label Aug 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Indicates new feature requests
Projects
Status: New Issue
Development

No branches or pull requests

3 participants