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

[SDK-2752] Expand test coverage and finish migration to Pest framework #552

Merged
merged 34 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0594c4b
tests: Expand test coverage
evansims Aug 24, 2021
da10e75
tests: Expand test coverage
evansims Aug 24, 2021
376829c
tests: Expand test coverage
evansims Aug 24, 2021
07f185a
tests: Fix unit tests running in Windows
evansims Aug 24, 2021
74a44c6
Merge branch 'main' into expand-test-coverage
evansims Aug 26, 2021
66463e3
tests: Expand test coverage
evansims Aug 26, 2021
5d859ab
fix: handleInvitation() should return a URL
evansims Aug 26, 2021
a8d9d3b
fix: Improve ConfigurableMixin type validation
evansims Aug 26, 2021
3596e89
tests: Code style pass
evansims Aug 26, 2021
00d33dc
tests: Address test warning about dynamic class names
evansims Aug 26, 2021
aa7d2e3
tests: Expand test coverage
evansims Aug 28, 2021
a164278
Merge branch 'main' into expand-test-coverage
evansims Aug 30, 2021
68c05a9
Fix merge conflicts
evansims Aug 30, 2021
5c3a2fb
tests: Fix test warning; PHP < 8.0 doesn't support `mixed` as a typehint
evansims Aug 30, 2021
e9a4d2c
change: Rename InMemoryStore to MemoryStore to follow naming conventi…
evansims Aug 30, 2021
16ab3ff
tests: Update Psr6StoreTest to PEST format.
evansims Aug 30, 2021
7a59ce3
tests: Expand test coverage
evansims Aug 30, 2021
93174b1
tests: Improvements to toolkit::every() tests
evansims Aug 31, 2021
bbe5f9e
tests: Fix lack of splat operator support for assoc arrays in PHP < 8.0
evansims Aug 31, 2021
0b27b22
tests: Updates for PHP < 8.0 warnings
evansims Aug 31, 2021
65fbc38
tests: Expand test coverage
evansims Aug 31, 2021
6879d8f
tests: Expand test coverage
evansims Aug 31, 2021
2a741bb
tests: Transition to PEST expectations
evansims Aug 31, 2021
d82d20b
tests: Expand test coverage
evansims Aug 31, 2021
c2281df
tests: Update test coverage
evansims Aug 31, 2021
011d31f
Add Pest dependencies
laravel-shift Aug 31, 2021
f18faa9
Adopt expectation API
laravel-shift Aug 31, 2021
94b5ec9
Shift cleanup
laravel-shift Aug 31, 2021
08e152c
tests: Adopt Pest-style exception expectations syntax
evansims Aug 31, 2021
f8be6e8
tests: Expand test coverage
evansims Aug 31, 2021
5a40275
tests: Expand test coverage
evansims Aug 31, 2021
b278235
Add `hyperf/event` for PSR-4 unit testing
evansims Aug 31, 2021
7ea708f
tests: Expand test coverage
evansims Aug 31, 2021
0fe5a85
tests: Resolve phpstan warnings
evansims Aug 31, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,19 @@
"psr/http-message-implementation": "^1.0"
},
"require-dev": {
"symfony/cache": "^4.4 || ^5.2",
"ergebnis/phpstan-rules": "^0.15",
"firebase/php-jwt": "^5.0",
"hyperf/event": "^2.2",
"infection/infection": "^0.23",
"mockery/mockery": "^1.4",
"nunomaduro/phpinsights": "^2.0",
"nyholm/psr7": "^1.4",
"pestphp/pest": "^1.0",
"pestphp/pest-plugin-parallel": "^0.2.0",
"php-http/mock-client": "^1.4",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-strict-rules": "^0.12",
"symfony/cache": "^4.4 || ^5.2",
"thecodingmachine/phpstan-strict-rules": "^0.12",
"vimeo/psalm": "^4.7"
},
Expand Down
2 changes: 1 addition & 1 deletion phpinsights.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
'src/Configuration/SdkConfiguration.php',
'src/Configuration/SdkState.php',
'src/Store/SessionStore.php',
'src/Store/InMemoryStorage.php',
'src/Store/MemoryStore.php',
'src/Store/Psr6Store.php',
],
],
Expand Down
4 changes: 2 additions & 2 deletions src/API/Management/ManagementEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ final public function getHttpClient(): HttpClient
*/
final public function getLastRequest(): ?HttpRequest
{
return $this->httpClient->getLastRequest();
return $this->getHttpClient()->getLastRequest();
}

/**
* Return a ResponsePaginator instance configured for the last HttpRequest.
*/
final public function getResponsePaginator(): HttpResponsePaginator
{
return new HttpResponsePaginator($this->httpClient);
return new HttpResponsePaginator($this->getHttpClient());
}
}
8 changes: 4 additions & 4 deletions src/API/Management/Tenants.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ final class Tenants extends ManagementEndpoint
*
* @link https://auth0.com/docs/api/management/v2#!/Tenants/tenant_settings_route
*/
public function get(
public function getSettings(
?RequestOptions $options = null
): ResponseInterface {
return $this->getHttpClient()
Expand All @@ -48,15 +48,15 @@ public function get(
*
* @link https://auth0.com/docs/api/management/v2#!/Tenants/patch_settings
*/
public function update(
public function updateSettings(
array $body,
?RequestOptions $options = null
): ResponseInterface {
[$body] = Toolkit::filter([$body])->string()->trim();
[$body] = Toolkit::filter([$body])->array()->trim();

Toolkit::assert([
[$body, \Auth0\SDK\Exception\ArgumentException::missing('body')],
])->isString();
])->isArray();

return $this->getHttpClient()
->method('patch')
Expand Down
68 changes: 41 additions & 27 deletions src/Auth0.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,34 @@ public function signup(
], $params));
}

/**
* If invitation parameters are present in the request, handle extraction and return a URL for redirection to Universal Login to accept. Returns null if no invitation parameters were found.
*
* @param string|null $redirectUrl Optional. URI to return to after logging out. Defaults to the SDK's configured redirectUri.
* @param array<int|string|null>|null $params Additional parameters to include with the request.
*
* @throws \Auth0\SDK\Exception\ConfigurationException When a Client ID is not configured.
* @throws \Auth0\SDK\Exception\ConfigurationException When `redirectUri` is not specified, and supplied SdkConfiguration does not have a default redirectUri configured.
*
* @link https://auth0.com/docs/universal-login/new-experience
* @link https://auth0.com/docs/api/authentication#login
*/
public function handleInvitation(
?string $redirectUrl = null,
?array $params = null
): ?string {
$invite = $this->getInvitationParameters();

if ($invite !== null) {
return $this->login($redirectUrl, Toolkit::merge([
'invitation' => (string) $invite->invitation,
'organization' => (string) $invite->organization,
], $params));
}

return null;
}

/**
* Delete any persistent data and clear out all stored properties, and return the URI to Auth0 /logout endpoint for redirection.
*
Expand All @@ -173,16 +201,19 @@ public function logout(

/**
* Delete any persistent data and clear out all stored properties.
*
* @oaram bool $transient When true, data in transient storage is also cleared.
*/
public function clear(): self
{
public function clear(
bool $transient = true
): self {
// Delete all data in the session storage medium.
if ($this->configuration()->hasSessionStorage()) {
$this->configuration->getSessionStorage()->purge();
}

// Delete all data in the transient storage medium.
if ($this->configuration()->hasTransientStorage()) {
if ($this->configuration()->hasTransientStorage() && $transient === true) {
$this->configuration->getTransientStorage()->purge();
}

Expand Down Expand Up @@ -273,6 +304,8 @@ public function exchange(
return false;
}

$this->clear(false);

if ($state === null || ! $this->getTransientStore()->verify('state', $state)) {
$this->clear();
throw \Auth0\SDK\Exception\StateException::invalidState();
Expand All @@ -287,10 +320,6 @@ public function exchange(
}
}

if ($this->getState()->hasUser()) {
$this->clear();
}

$response = $this->authentication()->codeExchange($code, $redirectUri, $codeVerifier);

if (! HttpResponse::wasSuccessful($response)) {
Expand Down Expand Up @@ -622,18 +651,20 @@ public function setAccessTokenExpiration(
* Get the specified parameter from POST or GET, depending on configured response mode.
*
* @param string $parameterName Name of the parameter to pull from the request.
* @param int $filter Defaults to FILTER_SANITIZE_STRING. The type of PHP filter_var() filter to apply.
*/
public function getRequestParameter(
string $parameterName
string $parameterName,
int $filter = FILTER_SANITIZE_STRING
): ?string {
$responseMode = $this->configuration()->getResponseMode();

if ($responseMode === 'query' && isset($_GET[$parameterName])) {
return filter_var($_GET[$parameterName], FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
return filter_var($_GET[$parameterName], $filter, FILTER_NULL_ON_FAILURE);
}

if ($responseMode === 'form_post' && isset($_POST[$parameterName])) {
return filter_var($_POST[$parameterName], FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
return filter_var($_POST[$parameterName], $filter, FILTER_NULL_ON_FAILURE);
}

return null;
Expand All @@ -659,23 +690,6 @@ public function getInvitationParameters(): ?object
return null;
}

/**
* If invitation parameters are present in the request, handle extraction and automatically redirect to Universal Login.
*/
public function handleInvitation(): self
{
$invite = $this->getInvitationParameters();

if ($invite !== null) {
$this->login(null, [
'invitation' => (string) $invite->invitation,
'organization' => (string) $invite->organization,
]);
}

return $this;
}

/**
* Create a transient storage handler using the configured transientStorage medium.
*/
Expand Down
29 changes: 2 additions & 27 deletions src/Configuration/SdkConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ private function setupStateCookies(): void
* Setup SDK factories.
*
* @throws NotFoundException When a PSR-18 or PSR-17 are not configured, and cannot be discovered.
*
* @codeCoverageIgnore
*/
private function setupStateFactories(): void
{
Expand Down Expand Up @@ -450,20 +452,6 @@ private function onStateChange(
throw \Auth0\SDK\Exception\ConfigurationException::invalidAlgorithm();
}

if ($propertyName === 'tokenMaxAge' || $propertyName === 'tokenLeeway') {
if (is_int($propertyValue)) {
// Value was passed as an int, perfect.
return $propertyValue;
}

if (is_numeric($propertyValue)) {
// Value was passed as a string, but it is numeric so cast to int.
return (int) $propertyValue;
}

throw \Auth0\SDK\Exception\ConfigurationException::validationFailed($propertyName);
}

if (in_array($propertyName, ['organization', 'audience'], true)) {
if (is_array($propertyValue) && count($propertyValue) !== 0) {
return $propertyValue;
Expand All @@ -475,19 +463,6 @@ private function onStateChange(
return $propertyValue;
}

/**
* Fires when a validation event fails to pass, such as a bad parameter type being used.
*
* @param string $parameter The name of the parameter that failed validation.
*
* @throws ConfigurationException When invoked.
*/
private function onValidationException(
string $parameter
): void {
throw \Auth0\SDK\Exception\ConfigurationException::validationFailed($parameter);
}

/**
* Setup SDK validators based on strategy type.
*/
Expand Down
53 changes: 31 additions & 22 deletions src/Mixins/ConfigurableMixin.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,24 @@ public function __call(
$arguments[0] = [ $arguments[0] ];
}

[$arguments] = Toolkit::filter([$arguments])->array()->trim();
$arguments = array_filter(
Toolkit::filter($arguments)->array()->trim(),
static function ($val): bool {
return $val !== null && count($val) !== 0;
}
);

if (count($arguments) !== 0) {
if (is_array($this->configuredState[$propertyName]->value)) {
$this->changeState($propertyName, array_merge($this->configuredState[$propertyName]->value, $arguments[0]));
return $this;
}

if ($this->configuredState[$propertyName]->value === null) {
$this->changeState($propertyName, $arguments[0]);
return $this;
}

$this->changeState($propertyName, $arguments[0]);
return $this;
}

return $this->configuredState[$propertyName]->value;
return $this;
}

throw \Auth0\SDK\Exception\ConfigurationException::getMissing($propertyName);
Expand All @@ -101,7 +102,7 @@ public function __call(
throw \Auth0\SDK\Exception\ConfigurationException::getMissing($propertyName);
}

return;
throw \Auth0\SDK\Exception\ArgumentException::unknownMethod($functionName);
}

/**
Expand Down Expand Up @@ -148,7 +149,7 @@ private function setState(
// TODO: Replace get_class() w/ ::class when 7.x support is dropped.

// phpcs:ignore
$constructor = new \ReflectionMethod(get_class($this) . '::__construct');
$constructor = new \ReflectionMethod(get_class($this), '__construct');
$parameters = $constructor->getParameters();
$arguments = $args[0];
$usingArgumentsArray = false;
Expand Down Expand Up @@ -226,9 +227,6 @@ private function changeState(
string $propertyName,
$propertyValue
): void {
$propertyType = gettype($propertyValue);
$expectedType = $this->configuredState[$propertyName]->type;

if ($this->configurationImmutable) {
throw \Auth0\SDK\Exception\ConfigurationException::setImmutable();
}
Expand All @@ -237,18 +235,29 @@ private function changeState(
throw \Auth0\SDK\Exception\ConfigurationException::setMissing($propertyName);
}

if ($propertyType !== $expectedType) {
if (! ($propertyType === 'boolean' && $expectedType === 'bool') &&
! ($propertyType === 'integer' && $expectedType === 'int')) {
if ($propertyValue === null && ! $this->configuredState[$propertyName]->allowsNull) {
throw \Auth0\SDK\Exception\ConfigurationException::setIncompatible($propertyName, $expectedType, $propertyType);
}
$propertyType = gettype($propertyValue);

if ($propertyValue !== null && $this->configuredState[$propertyName]->allowsNull) {
if (! is_object($propertyValue) || ! ($propertyValue instanceof $expectedType)) {
throw \Auth0\SDK\Exception\ConfigurationException::setIncompatibleNullable($propertyName, $expectedType, $propertyType);
}
$normalizedPropertyTypes = [
'boolean' => 'bool',
'integer' => 'int',
];

$propertyType = $normalizedPropertyTypes[$propertyType] ?? $propertyType;

$allowedTypes = [$this->configuredState[$propertyName]->type];
$expectedType = $this->configuredState[$propertyName]->type;

if ($this->configuredState[$propertyName]->allowsNull) {
$allowedTypes[] = 'NULL';
}

if (! in_array($propertyType, $allowedTypes, true)) {
if (! $propertyValue instanceof $expectedType) {
if ($this->configuredState[$propertyName]->allowsNull) {
throw \Auth0\SDK\Exception\ConfigurationException::setIncompatibleNullable($propertyName, $expectedType, $propertyType);
}

throw \Auth0\SDK\Exception\ConfigurationException::setIncompatible($propertyName, $expectedType, $propertyType);
}
}

Expand Down
Loading