imbo / behat-api-extension

API extension for Behat, used to ease testing of JSON-based APIs
MIT License
109 stars 42 forks source link

Base URIs that include paths (e.g. /app_dev.php) are stripped on adding request path #20

Closed douglaslinsmeyer closed 7 years ago

douglaslinsmeyer commented 8 years ago

When configuring the extension, if you specify a base_uri that includes a request path segment; for example: base_uri: "http://localhost:8080/app_dev.php" the guzzle client strips the /app_dev.php portion of the URI when you later set the request path.

The extension should preserve any prefix paths you set in the base_uri configuration setting.

christeredvartsen commented 8 years ago

Do you then specify relative paths in the steps? Could you provide the relevant part of the configuration file and a feature file with some use cases that illustrates this issue?

douglaslinsmeyer commented 8 years ago

Do you then specify relative paths in the steps? Yes.

behat.yml:

default:
    extensions:
      Behat\Symfony2Extension: ~
      Imbo\BehatApiExtension:
        base_uri: "http://nocira.dev/app_dev.php"

Example feature:

Feature: Authentication

  Background:
    Given the following users exists:
      | displayName      | email                     | password  | role      | status   |
      | testuser         | testuser@nerdery.com      |  testpass | ROLE_USER | ACTIVE   |
      | inactive_user    | inactive_user@nerdery.com |  testpass | ROLE_USER | INACTIVE |

  Scenario: A valid user can authenticate
    Given I am authenticating as "testuser@nerdery.com" with password "testpass"
    When I request "/api/authenticate" using HTTP POST
    Then the response code is 200
    And the node "data" should exist in the response
douglaslinsmeyer commented 8 years ago

The specific use case I'm running into is, as I mentioned, "app_dev.php". If you're unfamiliar (I doubt!) it's extremely handy during development to utilize this gateway into the application to quickly troubleshoot. Also, simply the name "base_uri" implies one should be able to set a base URI, and not simply a base schema/host/port.

I've got a PR incoming shortly with a suggested fix.

christeredvartsen commented 8 years ago

hmm, this might be an issue with Guzzle (I haven't checked any of the code yet, so not at all sure). You want to end up with a path like http://nocira.dev/app_dev.php/api/authenticate while the actual URI ends up as http://nocira.dev/api/authenticate, right?

If you have a PR I would love to review it!

christeredvartsen commented 8 years ago

I think the only way to solve this is to add a config parameter that says something like useFullBaseUriForAbsolutePaths or something like that, so that the app_dev.php part is not stripped, even if you specify an absolute path (for instance /api/some/endpoint).

One other way is for you to include app_dev.php in the paths you are testing.

behat.yml

default:
    extensions:
      Behat\Symfony2Extension: ~
      Imbo\BehatApiExtension:
        base_uri: "http://nocira.dev/"

Example feature

Feature: Authentication

  Background:
    Given the following users exists:
      | displayName      | email                     | password  | role      | status   |
      | testuser         | testuser@nerdery.com      |  testpass | ROLE_USER | ACTIVE   |
      | inactive_user    | inactive_user@nerdery.com |  testpass | ROLE_USER | INACTIVE |

  Scenario: A valid user can authenticate
    Given I am authenticating as "testuser@nerdery.com" with password "testpass"
    When I request "/app_dev.php/api/authenticate" using HTTP POST
    Then the response code is 200
    And the node "data" should exist in the response
Alex-D commented 7 years ago

You should always keep the base_uri. That's the idea of a base URI. There is no absolute or relative path, you should just take that base_uri and concatenate with the rest of the URL in @When.

So please fix/accept the PR #21 :)

christeredvartsen commented 7 years ago

@douglaslinsmeyer Please add a trailing slash to the base_uri in the behat.yml file, and strip the first slash from the paths used in your tests. Adding the trailing slash to the base_uri will make Guzzle append relative URIs to it, instead of using the root (as per RFC 3986).

Alex-D commented 7 years ago

Edit: this example doesn't works

So we should have that in behat.yml:

default:
    extensions:
        Imbo\BehatApiExtension:
            base_url: http://domain.dev/app_test.php/

And make calls like:

When I request "avatars" using HTTP GET

for example to get "http://domain.dev/app_test.php/avatars"?

christeredvartsen commented 7 years ago

As far as I can tell that will work as expected, yes.

One other option would be to have the following config:

default:
    extensions:
        Imbo\BehatApiExtension:
            base_uri: http://domain.dev

and have steps like:

When I request "/app_test.php/avatars" using HTTP GET
Alex-D commented 7 years ago

OK Thanks :) But you will agree that's not a good pattern to move a part of base URI to each request ^^ I try it out!

christeredvartsen commented 7 years ago

That last example I gave is probably not the best way to do it, no. I'd go with your example.

Alex-D commented 7 years ago

OK, so due to some withUri the "app_test.php" is override by the test URI path. So my example can't works, your example works. I'm frustrated.

christeredvartsen commented 7 years ago

I'll have a look at the code later today and figure out what's going on.

christeredvartsen commented 7 years ago

@Alex-D and @douglaslinsmeyer: I did a small change with regards to how the paths are handled in #33. The paths you are having issues with can now be seen in the added test case.

As soon as the PR is merged the following should apply:

base_uri Path in test Resulting URI
http://localhost:8080/app_dev.php /api/authenticate http://localhost:8080/api/authenticate
http://localhost:8080/app_dev.php/ api/authenticate http://localhost:8080/app_dev.php/api/authenticate
http://localhost:8080 /app_dev.php/api/authenticate http://localhost:8080/app_dev.php/api/authenticate

As you can see the first one will still not work as the path is absolute, so it disregards the path added to base_uri, but the two other ones should now work.

Is it possible for you to test the dev-issue/20-base-uri version in your composer.json file before I merge to verify that it actually works for you?