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

[V3] pact matchers on namespaced xml elments fail on provider test #632

Open
3 of 5 tasks
dpakach opened this issue Mar 23, 2021 · 7 comments
Open
3 of 5 tasks

[V3] pact matchers on namespaced xml elments fail on provider test #632

dpakach opened this issue Mar 23, 2021 · 7 comments
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@dpakach
Copy link

dpakach commented Mar 23, 2021

Software versions

Please provide at least OS and version of pact-js

  • OS: ubuntu 20.04
  • Consumer Pact library: "10.0.0-beta.33"
  • Provider Pact library:
  • Node Version: v12.21.0

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
  • 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

Matchers on namespaced xml should work
eg.

       new XmlBuilder('1.0', '', 'root').build(root => {
          root.setAttributes({"xmlns:h":"http://www.w3.org/TR/html4/"})
          root.appendElement('data', '', data => {
            data.appendElement("h:data", "", MatchersV3.string("random"))
              .appendElement('id', '', MatchersV3.fromProviderState("${id}", "42"))
        })

when the server handler is

<?xml version="1.0" encoding="UTF-8"?>
  <root xmlns:h="http://www.w3.org/TR/html4/">
      <data>
          <h:data>testData</h:data>
          <id>42</id>
      </data>
  </root>

Actual behaviour

The provider test fail with this error

Failures:

1) Verifying a pact between TransactionService and AccountService Given set id - a request to get the plain data returns a response which 
    1.1) has a matching body
           $.root.data.http://www.w3.org/TR/html4/:data.#text -> Expected 'random' to be equal to 'testData'

Steps to reproduce

See the bug reproduced in dpakach#2
Test on https://github.com/dpakach/pact-js/pull/2/files#diff-656f935c93a4d4ea910cb4961f3463c434eb6ea7cbe8d51e2c7b0b3fd4c5ae0cR68

@individual-it
Copy link
Contributor

I believe this will be fixed by #636 / #672

@individual-it
Copy link
Contributor

@dpakach please retest with beta36 and close if the issue is solved

@dpakach
Copy link
Author

dpakach commented Jun 3, 2021

@individual-it the issue is not fixed yet, the tests doesn't catch it because the interaction names are same in following tests
https://github.com/pact-foundation/pact-js/blob/feat/v3.0.0/examples/v3/provider-state-injected/consumer/transaction-service.test.js#L79
https://github.com/pact-foundation/pact-js/blob/feat/v3.0.0/examples/v3/provider-state-injected/consumer/transaction-service.test.js#L105

To reproduce the issue, change L105 in the file to a request to get the XML data and run the tests


Failures:

1) Verifying a pact between TransactionService and AccountService Given set id - a request to get the xml data returns a response which 
    1.1) has a matching body
           $.root.data.http://www.w3.org/TR/html4/:data.#text -> Expected 'random' to be equal to 'testData'

@individual-it
Copy link
Contributor

I think we have multiple issues here:

  1. the matcher in the pact json file needs to have the identifier of the namespace mentioned not the name
    this json works:
       "response": {
        "body": "<?xml version='1.0'?><root xmlns:h='myns'><data><h:data>random</h:data><id>42</id></data></root>",
        "headers": {
          "Content-Type": "application/xml; charset=utf-8"
        },
        "matchingRules": {
          "body": {
            "$.root.data.myns:data.#text": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
    
    this does not work:
      "response": {
        "body": "<?xml version='1.0'?><root xmlns:h='myns'><data><h:data>random</h:data><id>42</id></data></root>",
        "headers": {
          "Content-Type": "application/xml; charset=utf-8"
        },
        "matchingRules": {
          "body": {
            "$.root.data.h:data.#text": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
    
    only difference is $.root.data.myns:data.#text" vs. "$.root.data.h:data.#text"
  2. namespace identifiers cannot contain dots
    <?xml version='1.0'?><root xmlns:h='my.ns'><data><h:data>random</h:data><id>42</id></data></root> would become $.root.data.my.ns:data.#text , but the dot is used to seperate the elements and by that breaks the system

@individual-it
Copy link
Contributor

this notation works $.root.data['my.ns:data'].#text also with complex namespaces "$.root.data['http://www.w3.org/TR/html4/:data'].#text"

this is also the notation pact-reference uses e.g.: https://github.com/pact-foundation/pact-reference/blob/ebb11df0da1e8424fc5853b953b724ffb0e87e48/rust/pact_matching/src/xml.rs#L1020

@individual-it
Copy link
Contributor

I think the namespaces are not taken in account at all xml.rs:create_element_from_json has a namespace attribute

namespaces: &mut HashMap<String, String>

but its not used and when called it set to an empty hashmap
match create_element_from_json(doc, None, obj, matching_rules, generators, &vec!["$"], false, &mut hashmap!{}) {

@individual-it
Copy link
Contributor

more debugging:
pact-reference seems not to understand that the matcher is attached to that element. The element from the XML comes with resolved namespace, but in the matching rule only the name-space name is mentioned so it does not join those
[2021-06-04T04:56:21Z TRACE pact_matching::models::matchingrules] matcher_is_defined: for category body and path ["$", "root", "data", "http://www.w3.org/TR/html4/:data", "#text"] -> false

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
Projects
None yet
Development

No branches or pull requests

2 participants