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: Allow add custom provider headers #627

Merged
merged 2 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions UPGRADE-10.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ This migrates from a CLI driven process for the Pact Framework, to an FFI proces
- `addUrl` - Verify Provider by Pact Url retrieved by Broker (Webhooks)
- `addBroker` Verify Provider by dynamically fetched Pacts (Provider change)
- `addFile` / `addDir` - Verify Provider by local file or directory
- `$config->addCustomProviderHeader("headerName", "headerValue")` is now available via `$config->getCustomHeaders()->addHeader("headerName", "headerValue")`

Example Usage:

Expand Down
2 changes: 1 addition & 1 deletion compatibility-suite/tests/Service/HttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private function formatQueryString(array $query): string
{
$result = [];

foreach($query as $key => $values) {
foreach ($query as $key => $values) {
foreach ($values as $value) {
$result[] = urlencode($key) . '=' . urlencode($value);
}
Expand Down
16 changes: 16 additions & 0 deletions docs/provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ public function testPactVerifyConsumers(): void
}
```

## Add Custom Headers Prior to Verification

Sometimes you may need to add custom headers to the requests that can't be persisted in a pact file.
e.g. an OAuth bearer token: `Authorization: Bearer 1a2b3c4d5e6f7g8h9i0k`

```php
$config->getCustomHeaders()
->addHeader('Authorization', 'Bearer 1a2b3c4d5e6f7g8h9i0k');
```

The requests will have custom headers added before being sent to the Provider API.

> Note: Custom headers are not the only approach for authentication and authorization. For other approaches, please refer to this [documentation](https://docs.pact.io/provider/handling_auth#4-modify-the-request-to-use-real-credentials).

> **Important Note:** You should only use this feature for headers that can not be persisted in the pact file. By modifying the request, you are potentially modifying the contract from the consumer tests!

## Verification Sources

There are four ways to verify Pact files. See the examples below.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace PhpPact\Consumer\Driver\Interaction;

use PhpPact\Consumer\Model\Interaction;

use PhpPact\Standalone\MockService\Model\VerifyResult;

interface InteractionDriverInterface extends DriverInterface
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace PhpPact\Standalone\ProviderVerifier\Model\Config;

class CustomHeaders implements CustomHeadersInterface
{
/**
* @var array<string, string>
*/
private array $headers = [];

/**
* @param array<string, string> $headers
*/
public function setHeaders(array $headers): self
{
$this->headers = [];
foreach ($headers as $name => $value) {
$this->addHeader($name, $value);
}

return $this;
}

public function addHeader(string $name, string $value): self
{
$this->headers[$name] = $value;

return $this;
}

/**
* @return array<string, string>
*/
public function getHeaders(): array
{
return $this->headers;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace PhpPact\Standalone\ProviderVerifier\Model\Config;

interface CustomHeadersInterface
{
/**
* @param array<string, string> $headers
*/
public function setHeaders(array $headers): self;

public function addHeader(string $name, string $value): self;

/**
* @return array<string, string>
*/
public function getHeaders(): array;
}
16 changes: 16 additions & 0 deletions src/PhpPact/Standalone/ProviderVerifier/Model/VerifierConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use PhpPact\Standalone\ProviderVerifier\Model\Config\CallingAppInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ConsumerFilters;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ConsumerFiltersInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\CustomHeaders;
use PhpPact\Standalone\ProviderVerifier\Model\Config\CustomHeadersInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\FilterInfo;
use PhpPact\Standalone\ProviderVerifier\Model\Config\FilterInfoInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ProviderInfo;
Expand Down Expand Up @@ -35,6 +37,7 @@ class VerifierConfig implements VerifierConfigInterface
private VerificationOptionsInterface $verificationOptions;
private ?PublishOptionsInterface $publishOptions = null;
private ConsumerFiltersInterface $consumerFilters;
private CustomHeadersInterface $customHeaders;

public function __construct()
{
Expand All @@ -44,6 +47,7 @@ public function __construct()
$this->providerState = new ProviderState();
$this->verificationOptions = new VerificationOptions();
$this->consumerFilters = new ConsumerFilters();
$this->customHeaders = new CustomHeaders();
}

public function setCallingApp(CallingAppInterface $callingApp): self
Expand Down Expand Up @@ -162,4 +166,16 @@ public function getVerificationOptions(): VerificationOptionsInterface
{
return $this->verificationOptions;
}

public function setCustomHeaders(CustomHeadersInterface $customHeaders): self
{
$this->customHeaders = $customHeaders;

return $this;
}

public function getCustomHeaders(): CustomHeadersInterface
{
return $this->customHeaders;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use PhpPact\Standalone\ProviderVerifier\Model\Config\CallingAppInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ConsumerFiltersInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\CustomHeadersInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\FilterInfoInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ProviderInfoInterface;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ProviderStateInterface;
Expand Down Expand Up @@ -58,4 +59,8 @@ public function getVerificationOptions(): VerificationOptionsInterface;
public function getLogLevel(): ?string;

public function setLogLevel(string $logLevel): self;

public function setCustomHeaders(CustomHeadersInterface $customHeaders): self;

public function getCustomHeaders(): CustomHeadersInterface;
}
13 changes: 13 additions & 0 deletions src/PhpPact/Standalone/ProviderVerifier/Verifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public function __construct(VerifierConfigInterface $config, private ?LoggerInte
$this->setVerificationOptions($config);
$this->setPublishOptions($config);
$this->setConsumerFilters($config);
$this->setCustomHeaders($config);
$this->setLogLevel($config);
}

Expand Down Expand Up @@ -125,6 +126,18 @@ private function setConsumerFilters(VerifierConfigInterface $config): void
);
}

private function setCustomHeaders(VerifierConfigInterface $config): void
{
foreach ($config->getCustomHeaders()->getHeaders() as $name => $value) {
$this->client->call(
'pactffi_verifier_add_custom_header',
$this->handle,
$name,
$value
);
}
}

private function setLogLevel(VerifierConfigInterface $config): void
{
if ($logLevel = $config->getLogLevel()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use PhpPact\Standalone\ProviderVerifier\Model\Config\CallingApp;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ConsumerFilters;
use PhpPact\Standalone\ProviderVerifier\Model\Config\CustomHeaders;
use PhpPact\Standalone\ProviderVerifier\Model\Config\FilterInfo;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ProviderInfo;
use PhpPact\Standalone\ProviderVerifier\Model\Config\ProviderState;
Expand All @@ -29,6 +30,7 @@ public function testSetters(): void
new ProviderTransport(),
new ProviderTransport(),
];
$customHeaders = new CustomHeaders();

$subject = new VerifierConfig();
$subject->setCallingApp($callingApp);
Expand All @@ -39,6 +41,7 @@ public function testSetters(): void
$subject->setPublishOptions($publishOptions);
$subject->setConsumerFilters($consumerFilters);
$subject->setProviderTransports($providerTransports);
$subject->setCustomHeaders($customHeaders);

$this->assertSame($callingApp, $subject->getCallingApp());
$this->assertSame($providerInfo, $subject->getProviderInfo());
Expand All @@ -49,5 +52,6 @@ public function testSetters(): void
$this->assertSame($publishOptions, $subject->getPublishOptions());
$this->assertSame($consumerFilters, $subject->getConsumerFilters());
$this->assertSame($providerTransports, $subject->getProviderTransports());
$this->assertSame($customHeaders, $subject->getCustomHeaders());
}
}
16 changes: 16 additions & 0 deletions tests/PhpPact/Standalone/ProviderVerifier/VerifierTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ private function setUpCalls(bool $hasProviderTags = true, bool $hasFilterConsume
$this->config->setPublishOptions($publishOptions);
$this->config->getConsumerFilters()
->setFilterConsumerNames($filterConsumerNames = $hasFilterConsumerNames ? ['http-consumer-1', 'http-consumer-2', 'message-consumer-2'] : []);
$this->config->getCustomHeaders()
->setHeaders($customHeaders = ['name-1' => 'value-1', 'name-2' => 'value-2']);
$this->config->setLogLevel($logLevel = 'info');
$this->calls = [
['pactffi_verifier_new_for_application', $callingAppName, $callingAppVersion, $this->handle],
Expand All @@ -104,6 +106,20 @@ private function setUpCalls(bool $hasProviderTags = true, bool $hasFilterConsume
$hasFilterConsumerNames ? count($filterConsumerNames) : null,
null
],
[
'pactffi_verifier_add_custom_header',
$this->handle,
'name-1',
$customHeaders['name-1'],
null,
],
[
'pactffi_verifier_add_custom_header',
$this->handle,
'name-2',
$customHeaders['name-2'],
null,
],
['pactffi_init_with_log_level', strtoupper($logLevel), null],
];
}
Expand Down
Loading