Skip to content

Commit

Permalink
Merge pull request #96 from bystro/SendRequestAsHTMLformVer2.0
Browse files Browse the repository at this point in the history
Sending POST request as HTML form
  • Loading branch information
tyx authored Feb 1, 2018
2 parents 3463bcc + 28397bb commit 5421575
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 83 deletions.
35 changes: 35 additions & 0 deletions features/send_HTML_form_request.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Feature: Test request to API sent like a HTML form
In order to test my API
As a developper
I want to be able to perform HTTP request with HTML form data

Scenario: Sending POST request as a HTML form
When I send a POST request to "post-html-form" as HTML form with body:
| object | name | value |
| field | username | pablo |
| field | password | money |
| field | terms_accepted | 1 |
Then the response status code should be 200
And the response should be in JSON
And the JSON node "content_type_header_value" should contain "application/x-www-form-urlencoded"
And the JSON node "post_fields_count" should be equal to "3"
And the JSON node "post_fields.username" should be equal to "pablo"
And the JSON node "post_fields.password" should be equal to "money"
And the JSON node "post_fields.terms_accepted" should be equal to "1"

Scenario: Sending POST request as a HTML form with files
When I send a POST request to "post-html-form-with-files" as HTML form with body:
| object | name | value |
| field | username | pablo |
| field | password | money |
| field | terms_accepted | 1 |
| file | test-img | features/bootstrap/fixtures/test-img.jpg |
| file | json-schema | features/bootstrap/fixtures/json-schema.json |
Then the response status code should be 200
And the response should be in JSON
And the JSON node "content_type_header_value" should contain "multipart/form-data"
And the JSON node "post_fields_count" should be equal to "3"
And the JSON node "post_files_count" should be equal to "2"
And the JSON node "post_fields.username" should be equal to "pablo"
And the JSON node "post_fields.password" should be equal to "money"
And the JSON node "post_fields.terms_accepted" should be equal to "1"
20 changes: 1 addition & 19 deletions features/send_request.feature
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,4 @@ Feature: Test send API request
Then the response status code should be 200
And the JSON node "headers.header" should have 1 element
And the JSON node "headers.header[0]" should be equal to "value2"

Scenario: Attaching files and sending POST request
Given I add "Content-type" header equal to "application/json"
And I attach the following files:
| name | path |
| json-schema | features/bootstrap/fixtures/json-schema.json |
| test-img | features/bootstrap/fixtures/test-img.jpg |
When I send a POST request to "post-with-files" with parameters:
| username | pablo |
| password | money |
| terms_accepted | 1 |
Then the response status code should be 200
And the response should be in JSON
And the JSON node "post_files_count" should be equal to "2"
And the JSON node "post_fields.username" should be equal to "pablo"
And the JSON node "post_fields.password" should be equal to "money"
And the JSON node "post_fields.terms_accepted" should be equal to "1"
And the JSON node "content_type_header_value" should not contain "application/json"
And the JSON node "content_type_header_value" should contain "multipart/form-data"

98 changes: 98 additions & 0 deletions src/Html/Form.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace Ubirak\RestApiBehatExtension\Html;

class Form
{
private $body = [];

private $contentTypeHeaderValue = '';

public function __construct(array $body)
{
$this->body = $body;
}

public function getBody()
{
if ($this->bodyHasFileObject()) {
return $this->getMultipartStreamBody();
}

return $this->getNameValuePairBody();
}

/**
*
* @return string
*/
public function getContentTypeHeaderValue()
{
return $this->contentTypeHeaderValue;
}

/**
*
* @param string $value
*/
private function setContentTypeHeaderValue($value)
{
$this->contentTypeHeaderValue = $value;
}

/**
*
* @return boolean
*/
private function bodyHasFileObject()
{
foreach ($this->body as $element) {
if ($element['object'] == 'file') {
return true;
}
}

return false;
}

/**
*
* @return \GuzzleHttp\Psr7\MultipartStream
*/
private function getMultipartStreamBody()
{
$multiparts = array_map(
function ($element) {

if ($element['object'] == 'file') {
return ['name' => $element['name'], 'contents' => fopen($element['value'], 'r')];
}

return ['name' => $element['name'], 'contents' => $element['value']];
}, $this->body
);

$boundary = sha1(uniqid('', true));

$this->setContentTypeHeaderValue('multipart/form-data; boundary=' . $boundary);

return new \GuzzleHttp\Psr7\MultipartStream($multiparts, $boundary);
}

/**
*
* @return string
*/
private function getNameValuePairBody()
{
$body = [];
foreach ($this->body as $element) {
$body[$element['name']] = $element['value'];
}

$this->setContentTypeHeaderValue('application/x-www-form-urlencoded');

return http_build_query($body, null, '&');
}

}
48 changes: 3 additions & 45 deletions src/Rest/RestApiBrowser.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ class RestApiBrowser
/** @var array */
private $requestHeaders = [];

/** @var array */
private $requestFiles = [];

/** @var ResponseStorage */
private $responseStorage;

Expand Down Expand Up @@ -103,7 +100,9 @@ public function sendRequest($method, $uri, $body = null)
}

if (is_array($body)) {
$body = $this->buildMultipartBody($body);
$html = new \Ubirak\RestApiBehatExtension\Html\Form($body);
$body = $html->getBody();
$this->setRequestHeader('Content-Type', $html->getContentTypeHeaderValue());
}

$this->request = $this->messageFactory->createRequest($method, $uri, $this->requestHeaders, $body);
Expand Down Expand Up @@ -164,47 +163,6 @@ private function removeRequestHeader($headerName)
}
}

/**
* @param string $name
* @param string $path
*/
public function addFileToRequest($name, $path)
{
$this->requestFiles[] = [
'name' => $name,
'path' => $path,
];
}

/**
* @param array $body
*
* @return \GuzzleHttp\Psr7\MultipartStream
*/
private function buildMultipartBody($body)
{
$multiparts = array_merge(
array_map(
function ($key, $value) {
return ['name' => $key, 'contents' => $value];
},
array_keys($body),
$body
),
array_map(
function ($file) {
return ['name' => $file['name'], 'contents' => fopen($file['path'], 'r')];
},
$this->requestFiles
)
);

$boundary = sha1(uniqid('', true));
$this->setRequestHeader('Content-Type', 'multipart/form-data; boundary='.$boundary);

return new \GuzzleHttp\Psr7\MultipartStream($multiparts, $boundary);
}

/**
* @param string $uri
*
Expand Down
28 changes: 11 additions & 17 deletions src/RestApiContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,21 @@ public function iSendARequestWithBody($method, $url, PyStringNode $body)
}

/**
* Sends HTTP request to specific URL with raw body from PyString.
*
* @param string $method request method
* @param string $url relative url
* @param TableNode $parameters
*
* @When /^(?:I )?send a ([A-Z]+) request to "([^"]+)" with parameters:$/
* @When I send a POST request to :url as HTML form with body:
*/
public function iSendARequestWithParameters($method, $url, TableNode $parameters = null)
public function iSendAPostRequestToAsHtmlFormWithBody($url, TableNode $body)
{
$this->restApiBrowser->sendRequest($method, $url, $parameters->getRowsHash());
}
$formElements = [];
foreach ($body as $element) {

/**
* @When I attach the following files:
*/
public function iAttachTheFollowingFiles(TableNode $files)
{
foreach ($files as $file) {
$this->restApiBrowser->addFileToRequest($file['name'], $file['path']);
if (!isset($element['object'])) {
throw new \Exception('You have to specify an object attribute');
}

$formElements[] = $element;
}

$this->restApiBrowser->sendRequest("POST", $url, $formElements);
}

/**
Expand Down
16 changes: 14 additions & 2 deletions www/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,23 @@ function (Request $request) {
);

$app->match(
'post-with-files',
function (Request $request) {
'post-html-form',
function (Request $request) {
return new JsonResponse([
'content_type_header_value' => $request->headers->get('content-type'),
'post_fields_count' => $request->request->count(),
'post_fields' => $request->request->all(),
]);
}
);

$app->match(
'post-html-form-with-files',
function (Request $request) {
return new JsonResponse([
'content_type_header_value' => $request->headers->get('content-type'),
'post_files_count' => count($request->files),
'post_fields_count' => $request->request->count(),
'post_fields' => $request->request->all(),
]);
}
Expand Down

0 comments on commit 5421575

Please sign in to comment.