Skip to content

Commit

Permalink
Merge pull request #28 from imbo/issue/18-response-reason-phrase
Browse files Browse the repository at this point in the history
Add step for asserting the response reason phrase
  • Loading branch information
christeredvartsen committed Dec 2, 2016
2 parents 9f88e68 + 7aba044 commit e196694
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 18 deletions.
6 changes: 6 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Changelog for Behat API Extension
=================================

vx.x.x
------
__N/A__

* #18: New step: Assert response reason phrase

v1.0.4
------
__2016-10-26__
Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ When I send :filePath as :mimeType to :path using HTTP :method
Then the response code is :code
Then the response code is not :code
Then the response reason phrase is :phrase
Then the response is :group
Then the response is not :group
Then the :header response header exists
Expand Down Expand Up @@ -220,6 +221,19 @@ Match the response code to `:code`. If the optional `not` is added, the response
| Then the response code is `404` | `404` | No | No | Yes |
| Then the response code is not `304` | `304` | Yes | No | Yes |

#### Then the response reason phrase is `:phrase`

Match the response reason phrase to `:phrase`.

*Assume that these steps match a response with `200 OK` as a status line.*

**Examples:**

| Step | :phrase | Test passes? |
| ----------------------------------------- | ------- | ------------ |
| Then the response reason phrase is "`OK`" | `OK` | Yes |
| Then the response reason phrase is "`ok`" | `ok` | No |

#### Then the response is (not) `:group`

Match the response code to a group. If the optional `not` is added, the response should **not** be in the specified group.
Expand Down
10 changes: 10 additions & 0 deletions features/bootstrap/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,15 @@
]);
});

/**
* Return a response with a custom reason phrase
*/
$app->get('/customReasonPhrase', function(Application $app) {
return (new Response())->setStatusCode(
isset($_GET['code']) ? $_GET['code'] : 200,
isset($_GET['phrase']) ? $_GET['phrase'] : null
);
});

// Run the application
$app->run();
53 changes: 35 additions & 18 deletions features/thens.feature
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,23 @@ Feature: Test Then steps
Scenario: Use all Given steps in a scenario
When I request "/"
Then the response code is 200
Then the response code is not 400
Then the response is success
Then the response is not "client error"
Then the "X-Foo" response header exists
Then the "X-Bar" response header does not exist
Then the "x-foo" response header is foo
Then the "x-foo" response header matches "/FOO/i"
Then the response body is:
And the response code is not 400
And the response reason phrase is "OK"
And the response is success
And the response is not "client error"
And the "X-Foo" response header exists
And the "X-Bar" response header does not exist
And the "x-foo" response header is foo
And the "x-foo" response header matches "/FOO/i"
And the response body is:
'''
{"null":null,"string":"value","integer":42,"float":4.2,"boolean true":true,"boolean false":false,"list":[1,2,3,[1],{"foo":"bar"}],"sub":{"string":"value","integer":42,"float":4.2,"boolean true":true,"boolean false":false,"list":[1,2,3,[1],{"foo":"bar"}]}}
'''
Then the response body matches:
And the response body matches:
'''
/"list":\[.*?\]/
'''
Then the response body contains:
And the response body contains:
'''
{
"null": null,
Expand Down Expand Up @@ -74,10 +75,10 @@ Feature: Test Then steps
When I run "behat features/thens.feature"
Then it should pass with:
"""
............
.............
1 scenario (1 passed)
12 steps (12 passed)
13 steps (13 passed)
"""

Scenario: Use Then steps to verify responses with arrays
Expand All @@ -90,11 +91,11 @@ Feature: Test Then steps
[1, 2, 3]
'''
Then the response body is an array of length 3
Then the response body is an array with a length of at most 3
Then the response body is an array with a length of at most 4
Then the response body is an array with a length of at least 1
Then the response body is an array with a length of at least 2
Then the response body is an array with a length of at least 3
And the response body is an array with a length of at most 3
And the response body is an array with a length of at most 4
And the response body is an array with a length of at least 1
And the response body is an array with a length of at least 2
And the response body is an array with a length of at least 3
"""
When I run "behat features/thens-array.feature"
Then it should pass with:
Expand All @@ -115,7 +116,7 @@ Feature: Test Then steps
[]
'''
Then the response body is an array of length 0
Then the response body is an empty array
And the response body is an empty array
"""
When I run "behat features/thens-empty-array.feature"
Then it should pass with:
Expand Down Expand Up @@ -170,3 +171,19 @@ Feature: Test Then steps
4 steps (4 passed)
"""

Scenario: Verify a custom response reason phrase
Given a file named "features/thens.feature" with:
"""
Feature: Set up the request
Scenario: Verify a custom response reason phrase
When I request "/customReasonPhrase?phrase=foo"
Then the response reason phrase is "foo"
"""
When I run "behat features/thens.feature"
Then it should pass with:
"""
..
1 scenario (1 passed)
2 steps (2 passed)
"""
14 changes: 14 additions & 0 deletions src/Context/ApiContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,20 @@ public function thenTheResponseCodeIsNot($code) {
);
}

/**
* Assert HTTP reason phrase
*
* @param string $phrase Expected HTTP reason phrase
* @Then the response reason phrase is :phrase
*/
public function thenTheResponseReasonPhraseIs($phrase) {
Assertion::same($phrase, $actual = $this->response->getReasonPhrase(), sprintf(
'Invalid HTTP response reason phrase, expected "%s", got "%s"',
$phrase,
$actual
));
}

/**
* Checks if the HTTP response code is in a group
*
Expand Down
48 changes: 48 additions & 0 deletions tests/Context/ApiContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1053,4 +1053,52 @@ public function testDontAllowRequestBodyWithFormParameters() {
$this->context->whenIRequestPathWithBody('/some/path', 'POST', new PyStringNode(['some body'], 1));
}

/**
* Data provider
*
* @return []
*/
public function getResponseCodesAndReasonPhrases() {
return [
200 => [
'code' => 200,
'phrase' => 'OK',
],
300 => [
'code' => 300,
'phrase' => 'Multiple Choices',
],
400 => [
'code' => 400,
'phrase' => 'Bad Request',
],
500 => [
'code' => 500,
'phrase' => 'Internal Server Error',
],
];
}

/**
* @dataProvider getResponseCodesAndReasonPhrases
* @covers ::thenTheResponseReasonPhraseIs
* @param int $code The HTTP response code
* @param string $phrase The HTTP response reason phrase
*/
public function testCanAssertResponseReasonPhrase($code, $phrase) {
$this->mockHandler->append(new Response($code, [], null, 1.1, $phrase));
$this->context->whenIRequestPath('/some/path');
$this->context->thenTheResponseReasonPhraseIs($phrase);
}

/**
* @covers ::thenTheResponseReasonPhraseIs
* @expectedException Assert\InvalidArgumentException
* @expectedExceptionMessage Invalid HTTP response reason phrase, expected "ok", got "OK"
*/
public function testAssertResponseReasonPhraseCanFail() {
$this->mockHandler->append(new Response());
$this->context->whenIRequestPath('/some/path');
$this->context->thenTheResponseReasonPhraseIs('ok');
}
}

0 comments on commit e196694

Please sign in to comment.