Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: validator for non null and non empty parameter #56

Merged
merged 10 commits into from
May 6, 2024
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"ext-curl": "*",
"ext-dom": "*",
"ext-libxml": "*",
"apimatic/core-interfaces": "~0.1.0",
"apimatic/core-interfaces": "~0.1.4",
"apimatic/jsonmapper": "^3.1.1",
"php-jsonpointer/php-jsonpointer": "^3.0.2"
},
Expand Down
558 changes: 292 additions & 266 deletions composer.lock

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions src/Request/Parameters/FormParam.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ private function __construct(string $key, $value)

/**
* Sets encoding header with the key and value provided.
*
* @param string $key
* @param string $value
*/
public function encodingHeader(string $key, string $value): self
{
Expand Down
20 changes: 17 additions & 3 deletions src/Request/Parameters/Parameter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
namespace Core\Request\Parameters;

use Closure;
use CoreInterfaces\Core\Request\ParamInterface;
use Core\Utils\CoreHelper;
use CoreInterfaces\Core\Request\NonEmptyParamInterface;
use CoreInterfaces\Core\Request\TypeValidatorInterface;
use InvalidArgumentException;
use Throwable;

abstract class Parameter implements ParamInterface
abstract class Parameter implements NonEmptyParamInterface
{
protected $key;
protected $value;
Expand Down Expand Up @@ -63,7 +64,8 @@ private function extractFromArray(string $key, $defaultValue): self
}

/**
* Marks the value of the parameter as required and throws an exception on validate if the value is missing.
* Marks the value of the parameter as required and
* throws an exception on validate if the value is missing.
*/
public function required(): self
{
Expand All @@ -73,6 +75,18 @@ public function required(): self
return $this;
}

/**
* Marks the value of the parameter as required + non-empty and
* throws an exception on validate if the value is missing.
*/
public function requiredNonEmpty(): self
{
if (CoreHelper::isNullOrEmpty($this->value)) {
$this->valueMissing = true;
}
return $this;
}

/**
* Serializes the parameter using the method provided.
*
Expand Down
36 changes: 36 additions & 0 deletions src/Utils/CoreHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ public static function isAssociative(array $array): bool
return false;
}

/**
* Check if provided value is null or empty.
*
* @param $value mixed Value to be checked.
* @return bool True if given value is empty of null.
*/
public static function isNullOrEmpty($value): bool
{
if (is_string($value) && $value == '0') {
return false;
}
return empty($value);
}

/**
* Check if all the given value or values are present in the provided list.
*
Expand Down Expand Up @@ -150,4 +164,26 @@ public static function getOsInfo(string $osFamily = PHP_OS_FAMILY, string $funct
}
return $osFamily . '-' . call_user_func($functionName, 'r');
}

/**
* Return base64 encoded string for given username and password, prepended with Basic substring.
*/
public static function getBasicAuthEncodedString(string $username, string $password): string
{
if ($username == '' || $password == '') {
return '';
}
return 'Basic ' . base64_encode("$username:$password");
}

/**
* Return the accessToken prepended with Bearer substring.
*/
public static function getBearerAuthString(string $accessToken): string
{
if ($accessToken == '') {
return '';
}
return 'Bearer ' . $accessToken;
}
}
33 changes: 33 additions & 0 deletions tests/AuthenticationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ public function testHeaderAuthWithMissingField()
MockHelper::getClient()->validateAuth($auth);
}

public function testHeaderAuthWithEmptyField()
{
$this->expectException(AuthValidationException::class);
$this->expectExceptionMessage("Following authentication credentials are required:" .
"\n-> Missing required header field: token");

$auth = Auth::or('headerWithEmpty');
MockHelper::getClient()->validateAuth($auth);
}

public function testHeaderOrQueryAuth1()
{
$request = new Request('http://localhost:3000');
Expand Down Expand Up @@ -85,6 +95,19 @@ public function testHeaderWithMissingFieldOrQueryAuth()
);
}

public function testHeaderWithEmptyFieldOrQueryAuth()
{
$request = new Request('http://localhost:3000');
$auth = Auth::or('headerWithEmpty', 'query');
MockHelper::getClient()->validateAuth($auth)->apply($request);

$this->assertEquals([], $request->getHeaders());
$this->assertEquals(
'http://localhost:3000?token=someAuthToken&authorization=accessToken',
$request->getQueryUrl()
);
}

public function testHeaderOrQueryAuthWithMissingFields()
{
$this->expectException(AuthValidationException::class);
Expand Down Expand Up @@ -122,6 +145,16 @@ public function testHeaderWithMissingFieldAndQueryAuth()
MockHelper::getClient()->validateAuth($auth);
}

public function testHeaderWithEmptyFieldAndQueryAuth()
{
$this->expectException(AuthValidationException::class);
$this->expectExceptionMessage("Following authentication credentials are required:" .
"\n-> Missing required header field: token");

$auth = Auth::and('headerWithEmpty', 'query');
MockHelper::getClient()->validateAuth($auth);
}

public function testHeaderAndQueryAuthWithMissingFields()
{
$this->expectException(AuthValidationException::class);
Expand Down
4 changes: 2 additions & 2 deletions tests/Mocking/Authentication/FormAuthManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class FormAuthManager extends CoreAuth
public function __construct($token, $accessToken)
{
parent::__construct(
FormParam::init('token', $token)->required(),
FormParam::init('authorization', $accessToken)->required()
FormParam::init('token', $token)->requiredNonEmpty(),
FormParam::init('authorization', $accessToken)->requiredNonEmpty()
);
}
}
4 changes: 2 additions & 2 deletions tests/Mocking/Authentication/HeaderAuthManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class HeaderAuthManager extends CoreAuth
public function __construct($token, $accessToken)
{
parent::__construct(
HeaderParam::init('token', $token)->required(),
HeaderParam::init('authorization', $accessToken)->required()
HeaderParam::init('token', $token)->requiredNonEmpty(),
HeaderParam::init('authorization', $accessToken)->requiredNonEmpty()
);
}
}
4 changes: 2 additions & 2 deletions tests/Mocking/Authentication/QueryAuthManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class QueryAuthManager extends CoreAuth
public function __construct($token, $accessToken)
{
parent::__construct(
QueryParam::init('token', $token)->required(),
QueryParam::init('authorization', $accessToken)->required()
QueryParam::init('token', $token)->requiredNonEmpty(),
QueryParam::init('authorization', $accessToken)->requiredNonEmpty()
);
}
}
1 change: 1 addition & 0 deletions tests/Mocking/MockHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public static function getClient(): Client
->authManagers([
"header" => new HeaderAuthManager('someAuthToken', 'accessToken'),
"headerWithNull" => new HeaderAuthManager('someAuthToken', null),
"headerWithEmpty" => new HeaderAuthManager('', 'accessToken'),
"query" => new QueryAuthManager('someAuthToken', 'accessToken'),
"queryWithNull" => new QueryAuthManager(null, 'accessToken'),
"form" => new FormAuthManager('someAuthToken', 'accessToken'),
Expand Down
35 changes: 35 additions & 0 deletions tests/UtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ public function testCoreHelperConvertToNullableString()
$this->assertEquals("false", CoreHelper::convertToNullableString("false"));
}

public function testIsNullOrEmpty()
{
$this->assertTrue(CoreHelper::isNullOrEmpty(0));
$this->assertTrue(CoreHelper::isNullOrEmpty([]));
$this->assertTrue(CoreHelper::isNullOrEmpty(''));
$this->assertTrue(CoreHelper::isNullOrEmpty(null));
$this->assertTrue(CoreHelper::isNullOrEmpty(false));
$this->assertFalse(CoreHelper::isNullOrEmpty('0'));
$this->assertFalse(CoreHelper::isNullOrEmpty('some value'));
}

public function testOsInfo()
{
$expected = PHP_OS_FAMILY . '-' . php_uname('r');
Expand All @@ -199,6 +210,30 @@ public function testDisabledOsVersion()
$this->assertEquals(PHP_OS_FAMILY, CoreHelper::getOsInfo(PHP_OS_FAMILY, 'unknown_func'));
}

public function testBasicAuthEncodedString()
{
$expected = 'Basic dXNlcm5hbWU6X1BhNTV3MHJk';
$this->assertEquals($expected, CoreHelper::getBasicAuthEncodedString('username', '_Pa55w0rd'));
}

public function testEmptyBasicAuthEncodedString()
{
$this->assertEmpty(CoreHelper::getBasicAuthEncodedString('', '_Pa55w0rd'));
$this->assertEmpty(CoreHelper::getBasicAuthEncodedString('username', ''));
$this->assertEmpty(CoreHelper::getBasicAuthEncodedString('', ''));
}

public function testBearerAuthString()
{
$expected = 'Bearer my-token';
$this->assertEquals($expected, CoreHelper::getBearerAuthString('my-token'));
}

public function testEmptyBearerAuthString()
{
$this->assertEmpty(CoreHelper::getBearerAuthString(''));
}

public function testFromSimpleDateFailure()
{
$this->expectException(InvalidArgumentException::class);
Expand Down
Loading