Skip to content

Commit

Permalink
Support except and only universally for strategies
Browse files Browse the repository at this point in the history
  • Loading branch information
shalvah committed Dec 25, 2023
1 parent 40fe571 commit aafa14f
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 9 deletions.
13 changes: 13 additions & 0 deletions src/Extracting/Extractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,19 @@ protected function iterateThroughStrategies(
continue;
}
$settings = $strategyClassOrTuple[1];

$routesToSkip = $settings['except'] ?? [];
$routesToInclude = $settings['only'] ?? [];

if (!empty($routesToSkip)) {
if (RoutePatternMatcher::matches($endpointData->route, $routesToSkip)) {
continue;
}
} elseif (!empty($routesToInclude)) {
if (!RoutePatternMatcher::matches($endpointData->route, $routesToInclude)) {
continue;
}
}
} else {
$strategyClass = $strategyClassOrTuple;
$settings = $rulesToApply;
Expand Down
35 changes: 32 additions & 3 deletions src/Extracting/Strategies/Responses/ResponseCalls.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function __invoke(ExtractedEndpointData $endpointData, array $routeRules

public function makeResponseCallIfConditionsPass(ExtractedEndpointData $endpointData, array $routeRules): ?array
{
$rulesToApply = $routeRules['response_calls'] ?? [];
$rulesToApply = $routeRules['response_calls'] ?? $routeRules;
if (!$this->shouldMakeApiCall($endpointData, $rulesToApply)) {
return null;
}
Expand Down Expand Up @@ -132,8 +132,10 @@ private function configureEnvironment(array $rulesToApply)
*
* @return Request
*/
protected function prepareRequest(Route $route, string $url, array $rulesToApply, array $urlParams,
array $bodyParams, array $queryParams, array $fileParameters, array $headers): Request
protected function prepareRequest(
Route $route, string $url, array $rulesToApply, array $urlParams,
array $bodyParams, array $queryParams, array $fileParameters, array $headers
): Request
{
$uri = Utils::getUrlWithBoundParameters($url, $urlParams);
$routeMethods = $this->getMethods($route);
Expand Down Expand Up @@ -368,4 +370,31 @@ protected function getResponseHeaders($response): array

return $formattedHeaders;
}

/**
* @param array $only The routes which this strategy should be applied to. Can not be specified with $except.
* Specify route names ("users.index", "users.*"), or method and path ("GET *", "POST /safe/*").
* @param array $except The routes which this strategy should be applied to. Can not be specified with $only.
* Specify route names ("users.index", "users.*"), or method and path ("GET *", "POST /safe/*").
* @param array $config Any extra Laravel config() values to before starting the response call.
* @param array $queryParams Query params to always send with the response call. Key-value array.
* @param array $bodyParams Body params to always send with the response call. Key-value array.
* @param array $fileParams File params to always send with the response call. Key-value array. Key is param name, value is file path.
* @param array $cookies Cookies to always send with the response call. Key-value array.
* @return array
*/
public static function withSettings(
array $only = ['GET *'],
array $except = [],
array $config = [],
array $queryParams = [],
array $bodyParams = [],
array $fileParams = [
// 'key' => 'storage/app/image.png',
],
array $cookies = [],
): array
{
return static::wrapWithSettings(...get_defined_vars());
}
}
30 changes: 28 additions & 2 deletions src/Extracting/Strategies/Strategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,35 @@ public function getConfig(): DocumentationConfig

/**
* @param ExtractedEndpointData $endpointData
* @param array $routeRules Array of rules for the ruleset which this route belongs to.
* @param array $settings Settings to be applied to this strategy while processing this route.
* In the past, this was "routeRules".
*
* @return array|null
*/
abstract public function __invoke(ExtractedEndpointData $endpointData, array $routeRules = []): ?array;
abstract public function __invoke(ExtractedEndpointData $endpointData, array $settings = []): ?array;

/**
* @param array $only The routes which this strategy should be applied to. Can not be specified with $except.
* Specify route names ("users.index", "users.*"), or method and path ("GET *", "POST /safe/*").
* @param array $except The routes which this strategy should be applied to. Can not be specified with $only.
* Specify route names ("users.index", "users.*"), or method and path ("GET *", "POST /safe/*").
* @return array{string,array} Tuple of strategy class FQN and specified settings.
*/
public static function wrapWithSettings(
array $only = ['*'],
array $except = [],
...$settings
): array
{
if (!empty($only) && !empty($except)) {
throw new \InvalidArgumentException(
"Both \$only and \$except cannot be specified in your ".static::class." settings"
);
}

return [
static::class,
$settings,
];
}
}
55 changes: 51 additions & 4 deletions tests/Unit/ExtractorStrategiesInvocationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public function only_specified_strategies_are_loaded()
}

/** @test */
public function supports_overrides()
public function supports_overrides_tuples()
{
$config = [
'strategies' => [
Expand All @@ -70,7 +70,7 @@ public function supports_overrides()


/** @test */
public function supports_strategy_tuples()
public function supports_strategy_settings_tuples()
{
$config = [
'strategies' => [
Expand All @@ -93,6 +93,51 @@ public function supports_strategy_tuples()
], $endpointData->headers);
}

/** @test */
public function respects_strategy_s_only_setting()
{
$config = [
'strategies' => [
'bodyParameters' => [
[EmptyStrategy1::class, ['only' => 'GET /test']]
],
'responses' => [],
],
];
$this->processRoute($config);
$this->assertFalse(EmptyStrategy1::$called);

$config['strategies']['bodyParameters'][0] =
[EmptyStrategy1::class, ['only' => ['GET api/*']]];
$this->processRoute($config);
$this->assertTrue(EmptyStrategy1::$called);
}

/** @test */
public function respects_strategy_s_except_setting()
{
$config = [
'strategies' => [
'bodyParameters' => [
[EmptyStrategy1::class, ['except' => 'GET /api*']]
],
'responses' => [],
],
];
$this->processRoute($config);
$this->assertFalse(EmptyStrategy1::$called);

$config['strategies']['bodyParameters'][0] =
[EmptyStrategy1::class, ['except' => ['*']]];
$this->processRoute($config);
$this->assertFalse(EmptyStrategy1::$called);

$config['strategies']['bodyParameters'][0] =
[EmptyStrategy1::class, ['except' => []]];
$this->processRoute($config);
$this->assertTrue(EmptyStrategy1::$called);
}

/** @test */
public function responses_from_different_strategies_get_added()
{
Expand Down Expand Up @@ -216,9 +261,11 @@ public function overwrites_metadata_from_previous_strategies_in_same_stage()
$this->assertArraySubset($expectedMetadata, $parsed->metadata->toArray());
}

protected function processRoute(array $config): ExtractedEndpointData
protected function processRoute(
array $config, $routeMethod = "GET", $routePath = "/api/test", $routeName = "dummy"
): ExtractedEndpointData
{
$route = $this->createRoute('GET', '/api/test', 'dummy');
$route = $this->createRoute($routeMethod, $routePath, $routeName);
$extractor = new Extractor(new DocumentationConfig($config));
return $extractor->processRoute($route);
}
Expand Down

0 comments on commit aafa14f

Please sign in to comment.