apiaryio / dredd

Language-agnostic HTTP API Testing Tool
https://dredd.org
MIT License
4.18k stars 278 forks source link

The example value can't be set to the value specified "required" and "boolean" in "Parameter" #677

Open motoyasu-saburi opened 7 years ago

motoyasu-saburi commented 7 years ago

The example value can't be set to the value specified "required" and "boolean" in "Parameter".

This pattern is not work .

## Group JobController

### GET /api/job{?boolParam}

+ Parameters
    + boolParam: false (required, boolean) - not work
    + boolParam: `false` (required, boolean) - not work
    + boolParam: "false" (required, boolean) - not work

+ Response 200
...

but, This pattern is working.

## Group JobController

### GET /api/job{?boolParam}

+ Parameters
    + boolParam: false (required, string) - this type is boolean...
    + boolParam: `false` (required, string) - this type is boolean...

+ Response 200
...

What's your dredd --version output?

3.10.9
honzajavorek commented 7 years ago

Thanks for reporting this! To fix this, we need to track it down and to create a reproducible example (test) if possible.

I think it can be a bug either in drafter itself or in how dredd-transactions process URI parameters. If you have any additional time to hunt this thing down, the first step would be to find out which one of these two dependencies causes it.

motoyasu-saburi commented 7 years ago

hi @honzajavorek Thanks for the quick reply! This is the minimum project file that fails.

dredd.yml

dry-run: null
hookfiles: null
language: nodejs
sandbox: false
server: null
server-wait: 3
init: false
custom: {}
names: false
only: []
reporter: []
output: []
header: []
sorted: false
user: null
inline-errors: false
details: false
method: []
color: true
level: info
timestamp: false
silent: false
path: []
hooks-worker-timeout: 5000
hooks-worker-connect-timeout: 1500
hooks-worker-connect-retry: 500
hooks-worker-after-connect-wait: 100
hooks-worker-term-timeout: 5000
hooks-worker-term-retry: 500
hooks-worker-handler-host: localhost
hooks-worker-handler-port: 61321
config: ./dredd.yml
blueprint: document.apib
endpoint: 'http://localhost:8080'

document.apib

FORMAT: 1A
HOST: http://localhost:8080

# stanby

# hoge [/api/jobs{?bar}]
## foo [GET]

+ Parameters
    + bar: `false` (required, boolean) - failed

+ Response 200

This is error at the time of execution.

info: Configuration './dredd.yml' found, ignoring other arguments.
error: Compilation error in file 'document.apib': Required URI parameter 'bar' has no example or default value. ( > hoge > foo)
warn: Compilation warning in file 'document.apib': Ambiguous URI parameter in template: /api/jobs{?bar}
No example value for required parameter in API description document: bar ( > hoge > foo)
error: Error when processing API description.

Can you tell me which file is likely to cause the problem? I will search if possible.

w-vi commented 7 years ago

It looks like drafter is not the problem as the output from drafter seems valid, no errors or warnings:

/home/wvi/bin/drafter -f json -u /home/wvi/src/drafter/x1.apib
{
  "element": "parseResult",
  "content": [
    {
      "element": "category",
      "meta": {
        "classes": [
          "api"
        ],
        "title": "stanby"
      },
      "attributes": {
        "meta": [
          {
            "element": "member",
            "meta": {
              "classes": [
                "user"
              ]
            },
            "content": {
              "key": {
                "element": "string",
                "content": "FORMAT"
              },
              "value": {
                "element": "string",
                "content": "1A"
              }
            }
          },
          {
            "element": "member",
            "meta": {
              "classes": [
                "user"
              ]
            },
            "content": {
              "key": {
                "element": "string",
                "content": "HOST"
              },
              "value": {
                "element": "string",
                "content": "http://localhost:8080"
              }
            }
          }
        ]
      },
      "content": [
        {
          "element": "category",
          "meta": {
            "classes": [
              "resourceGroup"
            ],
            "title": ""
          },
          "content": [
            {
              "element": "resource",
              "meta": {
                "title": "hoge"
              },
              "attributes": {
                "href": "/api/jobs{?bar}"
              },
              "content": [
                {
                  "element": "transition",
                  "meta": {
                    "title": "foo"
                  },
                  "attributes": {
                    "hrefVariables": {
                      "element": "hrefVariables",
                      "content": [
                        {
                          "element": "member",
                          "meta": {
                            "description": "failed"
                          },
                          "attributes": {
                            "typeAttributes": [
                              "required"
                            ]
                          },
                          "content": {
                            "key": {
                              "element": "string",
                              "content": "bar"
                            },
                            "value": {
                              "element": "boolean",
                              "content": false
                            }
                          }
                        }
                      ]
                    }
                  },
                  "content": [
                    {
                      "element": "httpTransaction",
                      "content": [
                        {
                          "element": "httpRequest",
                          "attributes": {
                            "method": "GET"
                          },
                          "content": []
                        },
                        {
                          "element": "httpResponse",
                          "attributes": {
                            "statusCode": "200"
                          },
                          "content": []
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

OK.
honzajavorek commented 7 years ago

Then this looks like a problem in Dredd Transactions, suspecting the compileParameters logic.

motoyasu-saburi commented 7 years ago

Thank you for quick response 😂

honzajavorek commented 7 years ago

@motoyasu-saburi Thank you for reporting this and looking into this! 😄

motoyasu-saburi commented 7 years ago

@honzajavorek I found this cause 😄 I thought about making a correction and sending pullRequest. but, I can't think of a good fix method. 😭

First cause is this condition. https://github.com/apiaryio/dredd-transactions/blob/5b7f09f1777797451098864257175869e5f6b43e/src/validate-parameters.coffee#L6

if param.required and not param.example and not param.default

As a result, this param is set to result.errors "Required URI parameter '" + paramName + "' has no example or default value.";

Second cause is this condition. If the first problem is resolved, it will result in an error here. https://github.com/apiaryio/dredd-transactions/blob/5b7f09f1777797451098864257175869e5f6b43e/src/expand-uri-template-with-parameters.coffee#L44

if param.example

value of param.example is exist. but, this value is (boolean)false.

As a result, Dredd go to else and get an error. https://github.com/apiaryio/dredd-transactions/blob/5b7f09f1777797451098864257175869e5f6b43e/src/expand-uri-template-with-parameters.coffee#L48


P.S.
compileParameters result

honzajavorek commented 7 years ago

@motoyasu-saburi That is an excellent investigation. Thank you! This is great.

I think we need to change both the conditions to check for null and undefined instead of just relying on falsy value to mean that there is nothing to work with. You can use CoffeeScript's ? operator, which should do this in quite a convenient way:

if param.example?
  ...

Here you can see how it compiles to JavaScript. I think that should solve the issue.

Would you like to send a Pull Request, including a test? The test would probably go here as I think this problem is valid for both API Blueprint and Swagger. If you're not familiar with Swagger, just write an API Blueprint fixture for the test case and I can help with providing an equivalent Swagger one. What do you think?

honzajavorek commented 7 years ago

I believe closing this issue closes https://github.com/apiaryio/dredd-transactions/issues/70 as well.