Skip to content

Commit

Permalink
Add tests on async trait
Browse files Browse the repository at this point in the history
  • Loading branch information
Neirda24 committed Nov 16, 2024
1 parent f8a1de9 commit c461a88
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 1 deletion.
4 changes: 4 additions & 0 deletions docs/async/native.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,7 @@ $builder = $this->gotenberg->pdf()->html()
> If calling `->webhookConfiguration()` first then `->webhookUrl()` will override only the "success" part.
>
> If calling `->webhookUrl()` first then `->webhookConfiguration()` totally overrides previously set values.


> [!NOTE]
> If only success URL is set, error URL will fallback to the success one.
2 changes: 1 addition & 1 deletion src/Builder/AsyncBuilderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ trait AsyncBuilderTrait
public function generateAsync(): void
{
if (null === $this->successWebhookUrl) {
throw new MissingRequiredFieldException('->webhookUrls() was never called.');
throw new MissingRequiredFieldException('->webhookUrl() was never called.');
}

$errorWebhookUrl = $this->errorWebhookUrl ?? $this->successWebhookUrl;
Expand Down
210 changes: 210 additions & 0 deletions tests/Builder/AsyncBuilderTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
<?php

namespace Sensiolabs\GotenbergBundle\Tests\Builder;

use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;
use Sensiolabs\GotenbergBundle\Builder\AsyncBuilderTrait;
use Sensiolabs\GotenbergBundle\Builder\DefaultBuilderTrait;
use Sensiolabs\GotenbergBundle\Client\GotenbergClient;
use Sensiolabs\GotenbergBundle\Client\GotenbergResponse;
use Sensiolabs\GotenbergBundle\Exception\MissingRequiredFieldException;
use Sensiolabs\GotenbergBundle\Formatter\AssetBaseDirFormatter;
use Sensiolabs\GotenbergBundle\Webhook\WebhookConfigurationRegistryInterface;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;
use Symfony\Contracts\HttpClient\HttpClientInterface;

#[CoversClass(AsyncBuilderTrait::class)]

Check failure on line 19 in tests/Builder/AsyncBuilderTraitTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Class class@anonymous/tests/Builder/AsyncBuilderTraitTest.php:190 has an uninitialized readonly property $asset. Assign it in the constructor.
#[UsesClass(DefaultBuilderTrait::class)]
#[UsesClass(AssetBaseDirFormatter::class)]
#[UsesClass(GotenbergClient::class)]
#[UsesClass(GotenbergResponse::class)]
class AsyncBuilderTraitTest extends TestCase
{
public function testRequiresAtLeastSuccessWebhookUrl(): void
{
$builder = $this->getBuilder(new MockHttpClient([]));

$this->expectException(MissingRequiredFieldException::class);
$this->expectExceptionMessage('->webhookUrl() was never called.');

$builder->generateAsync();

Check failure on line 33 in tests/Builder/AsyncBuilderTraitTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined method object::generateAsync().
}

public function testItGenerateWithJustTheSuccessWebhookUrlSet(): void
{
$callback = function ($method, $url, $options): MockResponse {
$this->assertSame('POST', $method);
$this->assertSame('https://example.com/fake/endpoint', $url);
$this->assertContains('Gotenberg-Webhook-Url: https://webhook.local', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Error-Url: https://webhook.local', $options['headers']);
$this->assertArrayNotHasKey('gotenberg-webhook-method', $options['normalized_headers']);
$this->assertArrayNotHasKey('gotenberg-webhook-error-method', $options['normalized_headers']);

return new MockResponse('', [
'response_headers' => [
'Content-Type' => 'text/plain; charset=UTF-8',
'Gotenberg-Trace' => '{trace}',
],
]);
};

$builder = $this->getBuilder(new MockHttpClient($callback));
$builder->webhookUrl('https://webhook.local');

Check failure on line 55 in tests/Builder/AsyncBuilderTraitTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined method object::webhookUrl().

$builder->generateAsync();

Check failure on line 57 in tests/Builder/AsyncBuilderTraitTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined method object::generateAsync().
}

public function testItAlsoAcceptsADifferentErrorWebhookUrl(): void
{
$callback = function ($method, $url, $options): MockResponse {
$this->assertContains('Gotenberg-Webhook-Url: https://webhook.local', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Error-Url: https://webhook.local/error', $options['headers']);

return new MockResponse('', [
'response_headers' => [
'Content-Type' => 'text/plain; charset=UTF-8',
'Gotenberg-Trace' => '{trace}',
],
]);
};

$builder = $this->getBuilder(new MockHttpClient($callback));
$builder->webhookUrl('https://webhook.local');

Check failure on line 75 in tests/Builder/AsyncBuilderTraitTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined method object::webhookUrl().
$builder->errorWebhookUrl('https://webhook.local/error');

Check failure on line 76 in tests/Builder/AsyncBuilderTraitTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined method object::errorWebhookUrl().

$builder->generateAsync();

Check failure on line 78 in tests/Builder/AsyncBuilderTraitTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Call to an undefined method object::generateAsync().
}

public function testWebhookUrlsCanChangeTheirRespectiveHttpMethods(): void
{
$callback = function ($method, $url, $options): MockResponse {
$this->assertContains('Gotenberg-Webhook-Url: https://webhook.local', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Method: PUT', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Error-Url: https://webhook.local/error', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Error-Method: PATCH', $options['headers']);

return new MockResponse('', [
'response_headers' => [
'Content-Type' => 'text/plain; charset=UTF-8',
'Gotenberg-Trace' => '{trace}',
],
]);
};

$builder = $this->getBuilder(new MockHttpClient($callback));
$builder->webhookUrl('https://webhook.local', 'PUT');
$builder->errorWebhookUrl('https://webhook.local/error', 'PATCH');

$builder->generateAsync();
}

public function testWebhookUrlsCanSendCustomHttpHeaderToEndpoint(): void
{
$callback = function ($method, $url, $options): MockResponse {
$this->assertContains('Gotenberg-Webhook-Extra-Http-Headers: {"plop":"plop"}', $options['headers']);

return new MockResponse('', [
'response_headers' => [
'Content-Type' => 'text/plain; charset=UTF-8',
'Gotenberg-Trace' => '{trace}',
],
]);
};

$builder = $this->getBuilder(new MockHttpClient($callback));
$builder->webhookUrl('https://webhook.local');
$builder->webhookExtraHeaders(['plop' => 'plop']);

$builder->generateAsync();
}

public function testWebhookUrlsCanBeSetUsingTheRegistry(): void
{
$registry = new class($this) implements WebhookConfigurationRegistryInterface {
public function __construct(private AsyncBuilderTraitTest $assert)
{
}

public function add(string $name, array $configuration): void
{
// TODO: Implement add() method.
}

public function get(string $name): array
{
$this->assert->assertSame('fake', $name);

return [
'success' => [
'url' => 'https://webhook.local',
'method' => 'PUT',
],
'error' => [
'url' => 'https://webhook.local/error',
'method' => 'PATCH',
],
'extra_http_headers' => [
'plop' => 'plop',
],
];
}
};

$callback = function ($method, $url, $options): MockResponse {
$this->assertContains('Gotenberg-Webhook-Url: https://webhook.local', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Method: PUT', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Error-Url: https://webhook.local/error', $options['headers']);
$this->assertContains('Gotenberg-Webhook-Error-Method: PATCH', $options['headers']);

return new MockResponse('', [
'response_headers' => [
'Content-Type' => 'text/plain; charset=UTF-8',
'Gotenberg-Trace' => '{trace}',
],
]);
};

$builder = $this->getBuilder(new MockHttpClient($callback), $registry);
$builder->webhookConfiguration('fake');

$builder->generateAsync();
}

private function getBuilder(MockHttpClient $httpClient, WebhookConfigurationRegistryInterface|null $registry = null): object
{
$registry ??= new class implements WebhookConfigurationRegistryInterface {
public function add(string $name, array $configuration): void
{
// TODO: Implement add() method.
}

public function get(string $name): array
{
// TODO: Implement get() method.
}
};

return new class($httpClient, $registry) {
use AsyncBuilderTrait;

public function __construct(HttpClientInterface $httpClient, WebhookConfigurationRegistryInterface $registry)
{
$this->client = new GotenbergClient($httpClient);
$this->webhookConfigurationRegistry = $registry;
}

protected function getEndpoint(): string
{
return '/fake/endpoint';
}

public function setConfigurations(array $configurations): static
{
// TODO: Implement setConfigurations() method.
}
};
}
}

0 comments on commit c461a88

Please sign in to comment.