Skip to content

Commit

Permalink
Validate subkey of a XML request (#11)
Browse files Browse the repository at this point in the history
Close #10
  • Loading branch information
DavidePastore authored Oct 6, 2016
1 parent 33d1965 commit b44f94d
Show file tree
Hide file tree
Showing 3 changed files with 294 additions and 0 deletions.
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,71 @@ Array
*/
```

## XML requests

You can also validate a XML request. Let's say your body request is:

Let's say you have a POST request with a XML in its body:

```xml
<person>
<type>emails</type>
<objectid>1</objectid>
<email>
<id>1</id>
<enable_mapping>1</enable_mapping>
<name>rq3r</name>
<created_at>2016-08-23 13:36:29</created_at>
<updated_at>2016-08-23 14:36:47</updated_at>
</email>
</person>
```

and you want to validate the `email.name` key. You can do it in this way:

```php
use Respect\Validation\Validator as v;

$app = new \Slim\App();

// Fetch DI Container
$container = $app->getContainer();
$container['apiValidation'] = function () {
//Create the validators
$typeValidator = v::alnum()->noWhitespace()->length(3, 5);
$emailNameValidator = v::alnum()->noWhitespace()->length(1, 2);
$validators = array(
'type' => $typeValidator,
'email' => array(
'name' => $emailNameValidator,
),
);

return new \DavidePastore\Slim\Validation\Validation($validators);
};
```


If you'll have an error, the result would be:

```php
//In your route
$errors = $this->apiValidation->getErrors();

print_r($errors);
/*
Array
(
[email.name] => Array
(
[0] => "rq3r" must have a length between 1 and 2
)

)
*/
```


## Translate errors

You can provide a callable function to translate the errors.
Expand Down
1 change: 1 addition & 0 deletions src/Validation.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ private function getNestedParam($params = [], $keys = [])
} else {
$firstKey = array_shift($keys);
if (array_key_exists($firstKey, $params)) {
$params = (array) $params;
$paramValue = $params[$firstKey];

return $this->getNestedParam($paramValue, $keys);
Expand Down
228 changes: 228 additions & 0 deletions tests/ValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@ public function setUpPost($json)
$this->response = new Response();
}

/**
* Setup for the XML POST requests.
*
* @param string $xml The XML to use to mock the body of the request.
*/
public function setUpXmlPost($xml)
{
$uri = Uri::createFromString('https://example.com:443/foo');
$headers = new Headers();
$headers->set('Content-Type', 'application/xml;charset=utf8');
$cookies = [];
$env = Environment::mock([
'SCRIPT_NAME' => '/index.php',
'REQUEST_URI' => '/foo',
'REQUEST_METHOD' => 'POST',
]);
$serverParams = $env->all();
$body = new RequestBody();
$body->write($xml);
$this->request = new Request('POST', $uri, $headers, $cookies, $serverParams, $body);
$this->response = new Response();
}

public function testValidationWithoutErrors()
{
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
Expand Down Expand Up @@ -547,4 +570,209 @@ public function testMoreComplexJsonValidationWithErrors()
$this->assertEquals($errors, $mw->getErrors());
$this->assertEquals($validators, $mw->getValidators());
}

public function testXmlValidationWithoutErrors()
{
$xml = '<person><name>Josh</name></person>';
$this->setUpXmlPost($xml);
$nameValidator = v::alnum()->noWhitespace()->length(1, 15);
$validators = array(
'name' => $nameValidator,
);
$mw = new Validation($validators);

$next = function ($req, $res) {
return $res;
};

$response = $mw($this->request, $this->response, $next);

$this->assertFalse($mw->hasErrors());
$this->assertEquals($validators, $mw->getValidators());
}

public function testXmlValidationWithErrors()
{
$xml = '<person><name>jsonusername</name></person>';
$this->setUpXmlPost($xml);
$nameValidator = v::alnum()->noWhitespace()->length(1, 5);
$validators = array(
'name' => $nameValidator,
);
$mw = new Validation($validators);

$next = function ($req, $res) {
return $res;
};

$response = $mw($this->request, $this->response, $next);

$errors = array(
'name' => array(
'"jsonusername" must have a length between 1 and 5',
),
);

$this->assertEquals($errors, $mw->getErrors());
$this->assertEquals($validators, $mw->getValidators());
}

public function testComplexXmlValidationWithoutErrors()
{
$xml = '<person>
<type>emails</type>
<objectid>1</objectid>
<email>
<id>1</id>
<enable_mapping>1</enable_mapping>
<name>rq3r</name>
<created_at>2016-08-23 13:36:29</created_at>
<updated_at>2016-08-23 14:36:47</updated_at>
</email>
</person>';
$this->setUpXmlPost($xml);
$typeValidator = v::alnum()->noWhitespace()->length(3, 8);
$emailNameValidator = v::alnum()->noWhitespace()->length(1, 5);
$emailIdValidator = v::numeric()->positive()->between(1, 20);
$validators = array(
'type' => $typeValidator,
'email' => array(
'id' => $emailIdValidator,
'name' => $emailNameValidator,
),
);
$mw = new Validation($validators);

$next = function ($req, $res) {
return $res;
};

$response = $mw($this->request, $this->response, $next);

$this->assertFalse($mw->hasErrors());
$this->assertEquals($validators, $mw->getValidators());
}

public function testComplexXmlValidationWithErrors()
{
$xml = '<person>
<type>emails</type>
<objectid>1</objectid>
<email>
<id>1</id>
<enable_mapping>1</enable_mapping>
<name>rq3r</name>
<created_at>2016-08-23 13:36:29</created_at>
<updated_at>2016-08-23 14:36:47</updated_at>
</email>
</person>';
$this->setUpXmlPost($xml);
$typeValidator = v::alnum()->noWhitespace()->length(3, 5);
$emailNameValidator = v::alnum()->noWhitespace()->length(1, 2);
$validators = array(
'type' => $typeValidator,
'email' => array(
'name' => $emailNameValidator,
),
);
$mw = new Validation($validators);

$next = function ($req, $res) {
return $res;
};

$response = $mw($this->request, $this->response, $next);

$errors = array(
'type' => array(
'"emails" must have a length between 3 and 5',
),
'email.name' => array(
'"rq3r" must have a length between 1 and 2',
),
);

$this->assertEquals($errors, $mw->getErrors());
$this->assertEquals($validators, $mw->getValidators());
}

public function testMoreComplexXmlValidationWithoutErrors()
{
$xml = '<person>
<finally>notvalid</finally>
<email>
<finally>notvalid</finally>
<sub>
<finally>notvalid</finally>
<sub-sub>
<finally>123</finally>
</sub-sub>
</sub>
</email>
</person>';
$this->setUpXmlPost($xml);
$finallyValidator = v::numeric()->positive()->between(1, 200);
$validators = array(
'email' => array(
'sub' => array(
'sub-sub' => array(
'finally' => $finallyValidator,
),
),
),
);
$mw = new Validation($validators);

$next = function ($req, $res) {
return $res;
};

$response = $mw($this->request, $this->response, $next);

$this->assertFalse($mw->hasErrors());
$this->assertEquals($validators, $mw->getValidators());
}

public function testMoreComplexXmlValidationWithErrors()
{
$xml = '<person>
<finally>22</finally>
<email>
<finally>33</finally>
<sub>
<finally>97</finally>
<sub-sub>
<finally>321</finally>
</sub-sub>
</sub>
</email>
</person>';
$this->setUpXmlPost($xml);
$finallyValidator = v::numeric()->positive()->between(1, 200);
$validators = array(
'email' => array(
'sub' => array(
'sub-sub' => array(
'finally' => $finallyValidator,
),
),
),
);
$mw = new Validation($validators);

$next = function ($req, $res) {
return $res;
};

$response = $mw($this->request, $this->response, $next);

$errors = array(
'email.sub.sub-sub.finally' => array(
'"321" must be lower than or equals 200',
),
);

$this->assertEquals($errors, $mw->getErrors());
$this->assertEquals($validators, $mw->getValidators());
}
}

0 comments on commit b44f94d

Please sign in to comment.