Skip to content

Commit

Permalink
feat(strategies): added regex matches replacements for proxy response (
Browse files Browse the repository at this point in the history
…#15)

* feat(strategies): added regex matches replacements for proxy response

* docs: added documentation about proxyto generated with data from the request

* test: added test for the new feature (proxyto with data from the request)

* chore: created phar and added new box config file
  • Loading branch information
mcustiel authored Aug 2, 2023
1 parent fc05fda commit e40c252
Show file tree
Hide file tree
Showing 13 changed files with 335 additions and 119 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ vendor/
.project
.settings
composer.lock
tests/_output
tests/_support/_generated
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,28 @@ Content-Type: application/json
}
```

This is also supported to generate the proxy url as shown in the following example:

```
POST /__phiremock/expectations HTTP/1.1
Host: your.phiremock.host
Content-Type: application/json
{
"version": "2",
"on": {
"method": { "isSameString": "GET" },
"url": {"matches": "~^/example_service/(\w+)~"}
"headers": {
"Content-Type": {"isEqualTo": "application/json"}
}
},
"then": {
"proxyTo": "https://some.other.service/path/${url.1}"
}
}
```

### Conditions based in form data
For requests encoded with `application/x-www-form-urlencoded` and specifying this Content Type in the headers. Phiremock Server is capable of execute conditions on the values of the form fields.

Expand Down Expand Up @@ -636,7 +658,7 @@ Phiremock Server still supports expectations in the format of Phiremock V1. This

### Contributing:

Just submit a pull request. Don't forget to run tests and php-cs-fixer first and write documentation.
Just submit a pull request. Don't forget to run tests and php-cs-fixer first, and write documentation.

### Thanks to:

Expand Down
19 changes: 19 additions & 0 deletions box.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"directories" : [ "src" ],
"compactors": [ "KevinGH\\Box\\Compactor\\Php" ],
"dump-autoload": false,
"chmod" : "0755",
"main" : "bin/phiremock",
"output" : "phiremock.phar",
"stub" : true,
"files": [
"LICENSE"
],
"finder": [
{
"name": ["*.php"],
"exclude": ["Tests", "tests"],
"in": ["vendor", "."]
}
]
}
Binary file modified phiremock.phar
Binary file not shown.
39 changes: 36 additions & 3 deletions src/Factory/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
use Mcustiel\Phiremock\Server\Utils\ResponseStrategyLocator;
use Mcustiel\Phiremock\Server\Utils\Strategies\HttpResponseStrategy;
use Mcustiel\Phiremock\Server\Utils\Strategies\ProxyResponseStrategy;
use Mcustiel\Phiremock\Server\Utils\Strategies\RegexProxyResponseStrategy;
use Mcustiel\Phiremock\Server\Utils\Strategies\RegexResponseStrategy;
use Mcustiel\Phiremock\Server\Utils\Strategies\Utils\RegexReplacer;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Http\Client\ClientInterface;
Expand Down Expand Up @@ -114,7 +116,8 @@ public function createRegexResponseStrategy(): RegexResponseStrategy
'regexResponseStrategy',
new RegexResponseStrategy(
$this->createScenarioStorage(),
$this->createLogger()
$this->createLogger(),
$this->createRegexReplacer()
)
);
}
Expand All @@ -129,16 +132,46 @@ public function createProxyResponseStrategy(): ProxyResponseStrategy
$this->factoryCache->set(
'proxyResponseStrategy',
new ProxyResponseStrategy(
$this->createHttpClient(),
$this->createScenarioStorage(),
$this->createLogger()
$this->createLogger(),
$this->createHttpClient()
)
);
}

return $this->factoryCache->get('proxyResponseStrategy');
}

/** @throws Exception */
public function createRegexProxyResponseStrategy(): RegexProxyResponseStrategy
{
if (!$this->factoryCache->has('regexProxyResponseStrategy')) {
$this->factoryCache->set(
'regexProxyResponseStrategy',
new RegexProxyResponseStrategy(
$this->createScenarioStorage(),
$this->createLogger(),
$this->createHttpClient(),
$this->createRegexReplacer()
)
);
}

return $this->factoryCache->get('regexProxyResponseStrategy');
}

public function createRegexReplacer(): RegexReplacer
{
if (!$this->factoryCache->has('regexReplacer')) {
$this->factoryCache->set(
'regexReplacer',
new RegexReplacer()
);
}

return $this->factoryCache->get('regexReplacer');
}

public function createResponseStrategyLocator(): ResponseStrategyLocator
{
if (!$this->factoryCache->has('responseStrategyLocator')) {
Expand Down
5 changes: 5 additions & 0 deletions src/Utils/ResponseStrategyLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@ public function __construct(Factory $dependencyService)
public function getStrategyForExpectation(Expectation $expectation): ResponseStrategyInterface
{
if ($expectation->getResponse()->isProxyResponse()) {
if ($this->requestBodyOrUrlAreRegexp($expectation)) {
return $this->factory->createRegexProxyResponseStrategy();
}

return $this->factory->createProxyResponseStrategy();
}

if ($this->requestBodyOrUrlAreRegexp($expectation)) {
return $this->factory->createRegexResponseStrategy();
}
Expand Down
4 changes: 2 additions & 2 deletions src/Utils/Strategies/ProxyResponseStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ class ProxyResponseStrategy extends AbstractResponse implements ResponseStrategy
private $httpService;

public function __construct(
ClientInterface $httpService,
ScenarioStorage $scenarioStorage,
LoggerInterface $logger
LoggerInterface $logger,
ClientInterface $httpService
) {
parent::__construct($scenarioStorage, $logger);
$this->httpService = $httpService;
Expand Down
72 changes: 72 additions & 0 deletions src/Utils/Strategies/RegexProxyResponseStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
/**
* This file is part of Phiremock.
*
* Phiremock is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Phiremock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Phiremock. If not, see <http://www.gnu.org/licenses/>.
*/

namespace Mcustiel\Phiremock\Server\Utils\Strategies;

use Laminas\Diactoros\Uri;
use Mcustiel\Phiremock\Domain\Expectation;
use Mcustiel\Phiremock\Domain\ProxyResponse;
use Mcustiel\Phiremock\Server\Model\ScenarioStorage;
use Mcustiel\Phiremock\Server\Utils\Strategies\Utils\RegexReplacer;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Log\LoggerInterface;

class RegexProxyResponseStrategy extends AbstractResponse implements ResponseStrategyInterface
{
/** @var ClientInterface */
private $httpService;
/** @var RegexReplacer */
private $regexReplacer;

public function __construct(
ScenarioStorage $scenarioStorage,
LoggerInterface $logger,
ClientInterface $httpService,
RegexReplacer $regexReplacer
) {
parent::__construct($scenarioStorage, $logger);
$this->httpService = $httpService;
$this->regexReplacer = $regexReplacer;
}

/**
* {@inheritdoc}
*
* @see \Mcustiel\Phiremock\Server\Utils\Strategies\ResponseStrategyInterface::createResponse()
*/
public function createResponse(
Expectation $expectation,
ResponseInterface $transactionData,
ServerRequestInterface $request
): ResponseInterface {
/** @var ProxyResponse $response */
$response = $expectation->getResponse();
$url = $response->getUri()->asString();
$url = $this->regexReplacer->fillWithUrlMatches($expectation, $request, $url);
$url = $this->regexReplacer->fillWithBodyMatches($expectation, $request, $url);
$this->logger->debug('Proxying request to : ' . $url);
$this->processScenario($expectation);
$this->processDelay($response);

return $this->httpService->sendRequest(
$request->withUri(new Uri($url))
);
}
}
Loading

0 comments on commit e40c252

Please sign in to comment.