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

🩹 fix workflow file oops #4

Merged
merged 6 commits into from
Oct 12, 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
18 changes: 10 additions & 8 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Tests

on:
push:
branches: [ master ]
branches: [ main ]
pull_request:
branches: [ master ]
branches: [ main ]
schedule:
- cron: '0 0 * * *'

Expand All @@ -26,11 +26,13 @@ jobs:
- name: Install dependencies
run: composer install

- name: Start server
run: php bin/drumkit --tls-cert=ssl/mercure-router.local.pem --tls-key=ssl/mercure-router.local-key.pem --dev --active-subscriptions &

- name: Wait for server to be ready
run: sleep 2

- name: Run PHPUnit tests
run: vendor/bin/phpunit

- name: Logs of the server by test
if: always()
uses: actions/upload-artifact@v4
with:
name: server-logs
path: |
logs
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ vendor/
/ssl/mercure-router.local.pem
.phpunit.result.cache
composer.lock
logs
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"amphp/http-client-cookies": "^2.0.0",
"amphp/phpunit-util": "^3.0.0",
"phpspec/prophecy-phpunit": "^2.2.0",
"dg/bypass-finals": "dev-master"
"dg/bypass-finals": "dev-master",
"symfony/process": "^7.1"
}
}
2 changes: 2 additions & 0 deletions lib/amphp/http-server-router/src/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public function handleRequest(Request $request): Response
$method = $request->getMethod();
$path = $request->getUri()->getPath();

$this->logger->debug('[Router] Matching path: "' . $path . '" with method '.$method);

$toMatch = "{$method}\0{$path}";

if (null === $match = $this->cache->get($toMatch)) {
Expand Down
25 changes: 22 additions & 3 deletions src/Command/RunCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class RunCommand extends Command
private const OPTION_SECURITY_PUBLISHER_KEY = 'security-publisher-key';
private const OPTION_SECURITY_SUBSCRIBER_ALG = 'security-subscriber-algorithm';
private const OPTION_SECURITY_SUBSCRIBER_KEY = 'security-subscriber-key';
private const OPTION_CORS_ORIGIN_KEY = 'corsOrigin';
private const OPTION_PORT_HTTP = 'http-port';
private const OPTION_PORT_HTTPS = 'https-port';
protected static $defaultDescription = 'Start Drumkit (run a Mercure server)';

public function __construct(
Expand Down Expand Up @@ -124,12 +127,26 @@ function (CompletionInput $input): array {
'Run the server in dev mode (shows more explicit errors, logs & run with xdebug)'
)
->addOption(
'corsOrigin',
self::OPTION_CORS_ORIGIN_KEY,
null,
InputOption::VALUE_IS_ARRAY|InputOption::VALUE_REQUIRED,
'Specified authorised cors domain',
[]
)
->addOption(
self::OPTION_PORT_HTTP,
null,
InputOption::VALUE_REQUIRED,
'Port number for HTTP',
80
)
->addOption(
self::OPTION_PORT_HTTPS,
null,
InputOption::VALUE_REQUIRED,
'Port number for HTTPS',
443
)
;
}

Expand Down Expand Up @@ -158,13 +175,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$options = OptionsFactory::fromCommandOptions(
$tlsCert,
$tlsKey,
$input->getOption('corsOrigin'),
$input->getOption(self::OPTION_CORS_ORIGIN_KEY),
$input->getOption(self::OPTION_SECURITY_SUBSCRIBER_KEY),
$input->getOption(self::OPTION_SECURITY_SUBSCRIBER_ALG),
$input->getOption(self::OPTION_SECURITY_PUBLISHER_KEY),
$input->getOption(self::OPTION_SECURITY_PUBLISHER_ALG),
$input->getOption(self::OPTION_FEATURE_SUBSCRIPTIONS),
devMode: $devMode
devMode: $devMode,
httpPort: (int) $input->getOption(self::OPTION_PORT_HTTP),
httpsPort: (int) $input->getOption(self::OPTION_PORT_HTTPS),
);
} else {
$output->writeln('<error>You need to provide at least TLS certificates to run the server. Run command `drumkit --help` to learn more.</error>');
Expand Down
6 changes: 5 additions & 1 deletion src/Configuration/OptionsFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ public static function fromCommandOptions(
?string $pubKey,
?string $pubAlg,
bool $activeSubscriptions,
bool $devMode
bool $devMode,
int $httpPort,
int $httpsPort,
): Options {
$tlsKey = self::resolvePath($tlsKey);
$tlsCert = self::resolvePath($tlsCert);
Expand Down Expand Up @@ -85,6 +87,8 @@ public static function fromCommandOptions(
$tlsCert,
$tlsKey,
new CorsConfiguration($corsOrigin),
tlsPort: $httpsPort,
unsecuredPort: $httpPort,
activeSubscriptionEnabled: $activeSubscriptions,
devMode: $devMode,
subscriberSecurity: $subscriberSecurity,
Expand Down
13 changes: 9 additions & 4 deletions src/Controller/Subscription/GetSubscriptionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
use Amp\Http\Server\RequestHandler;
use Amp\Http\Server\Response;
use Amp\Http\Server\Router;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use SwagIndustries\MercureRouter\Controller\NotFoundController;
use SwagIndustries\MercureRouter\Mercure\Hub;
use SwagIndustries\MercureRouter\Security\Security;
Expand All @@ -24,10 +26,15 @@ class GetSubscriptionController implements RequestHandler
{
use SubscriptionNormalizerTrait;
use SubscriptionApiResponseTrait;
public function __construct(private Hub $mercure, private NotFoundController $notFound) {}
public function __construct(
private Hub $mercure,
private NotFoundController $notFound,
private LoggerInterface $logger = new NullLogger()
) {}
public function handleRequest(Request $request): Response
{
['topic' => $topicQuery, 'subscriber' => $subscriberId] = $request->getAttribute(Router::class);
$this->logger->debug('[API] Get subscriptions for topic "' . $topicQuery . '" and subscriber "' . $subscriberId . '"');

/** @var array{subscribe: array|string|null, payload?: array} $jwtContent */
$jwtContent = $request->getAttribute(Security::ATTRIBUTE_JWT_PAYLOAD)['mercure'] ?? [];
Expand All @@ -36,9 +43,7 @@ public function handleRequest(Request $request): Response
$validPaths = [
Hub::MERCURE_PATH . '/subscriptions{/topic}{/subscriber}',
];
dump($allowedTopics);
dump($validPaths);
dump(array_intersect($validPaths, $allowedTopics));

if (empty(array_intersect($validPaths, $allowedTopics))) {
return $this->forbiddenApiResponse();
}
Expand Down
9 changes: 8 additions & 1 deletion src/Controller/Subscription/GetSubscriptionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Amp\Http\Server\Request;
use Amp\Http\Server\RequestHandler;
use Amp\Http\Server\Response;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use SwagIndustries\MercureRouter\Controller\NotFoundController;
use SwagIndustries\MercureRouter\Mercure\Hub;
use SwagIndustries\MercureRouter\Security\Security;
Expand All @@ -23,9 +25,14 @@ class GetSubscriptionsController implements RequestHandler
{
use SubscriptionNormalizerTrait;
use SubscriptionApiResponseTrait;
public function __construct(private Hub $mercure, private NotFoundController $notFound) {}
public function __construct(
private Hub $mercure,
private NotFoundController $notFound,
private LoggerInterface $logger = new NullLogger()
) {}
public function handleRequest(Request $request): Response
{
$this->logger->debug('[API] Get all subscriptions');
/** @var array{subscribe: array|string|null, payload?: array} $jwtContent */
$jwtContent = $request->getAttribute(Security::ATTRIBUTE_JWT_PAYLOAD)['mercure'] ?? [];
$allowedTopics = (array) ($jwtContent['subscribe'] ?? []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
use Amp\Http\Server\RequestHandler;
use Amp\Http\Server\Response;
use Amp\Http\Server\Router;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use SwagIndustries\MercureRouter\Controller\NotFoundController;
use SwagIndustries\MercureRouter\Mercure\Hub;
use SwagIndustries\MercureRouter\Security\Security;
Expand All @@ -24,10 +26,15 @@ class GetTopicSubscriptionsController implements RequestHandler
{
use SubscriptionNormalizerTrait;
use SubscriptionApiResponseTrait;
public function __construct(private Hub $mercure, private NotFoundController $notFound) {}
public function __construct(
private Hub $mercure,
private NotFoundController $notFound,
private LoggerInterface $logger = new NullLogger()
) {}
public function handleRequest(Request $request): Response
{
['topic' => $topicQuery] = $request->getAttribute(Router::class);
$this->logger->debug('[API] Get topic subscriptions for topic "' . $topicQuery . '"');

/** @var array{subscribe: array|string|null, payload?: array} $jwtContent */
$jwtContent = $request->getAttribute(Security::ATTRIBUTE_JWT_PAYLOAD)['mercure'] ?? [];
Expand Down
45 changes: 45 additions & 0 deletions tests/Functional/AbstractFunctionalTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace SwagIndustries\MercureRouter\Test\Functional;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;

abstract class AbstractFunctionalTest extends TestCase
{
public const UNSECURED_PORT = 8080;
public const TLS_PORT = 4443;
private Process $process;
protected function setUp(): void
{
$this->process = new Process(
[
'bin/drumkit',
'--tls-cert=ssl/ci.mercure-router.local.pem',
'--tls-key=ssl/ci.mercure-router.local-key.pem',
'--dev',
'--active-subscriptions',
'--http-port='.self::UNSECURED_PORT,
'--https-port='.self::TLS_PORT,
]
);

$this->process->start();
$this->process->waitUntil(function ($type, $buffer) {
return str_contains($buffer, 'Listening on');
});
}

protected function tearDown(): void
{
$outputDir = __DIR__.'/../../logs';
if (!is_dir($outputDir)) {
mkdir($outputDir);
}

$file = $this->getName();
file_put_contents($outputDir.'/'.$file.'.out',$this->process->getOutput());
file_put_contents($outputDir.'/'.$file.'.err',$this->process->getErrorOutput());
$this->process->stop();
}
}
14 changes: 12 additions & 2 deletions tests/Functional/RecoveryTest.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
<?php

namespace Functional;
/**
* This file is a part of mercure-router-php package.
*
* (c) Swag Industries <[email protected]>
*
* For the full license, take a look to the LICENSE file
* on the root directory of this project
*/

namespace SwagIndustries\MercureRouter\Test\Functional;

use PHPUnit\Framework\TestCase;

use SwagIndustries\MercureRouter\Test\Functional\AbstractFunctionalTest;
use SwagIndustries\MercureRouter\Test\Functional\Tool\TestClient;
use SwagIndustries\MercureRouter\Test\Functional\Tool\TestSubscriber;
use function Amp\async;
use function Amp\Future\await;

class RecoveryTest extends TestCase
class RecoveryTest extends AbstractFunctionalTest
{
public function testItCanRecoverySomeMessagesBefore(): void
{
Expand Down
3 changes: 1 addition & 2 deletions tests/Functional/SendUpdateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
namespace SwagIndustries\MercureRouter\Test\Functional;

use SwagIndustries\MercureRouter\Test\Functional\Tool\TestClient;
use PHPUnit\Framework\TestCase;
use SwagIndustries\MercureRouter\Test\Functional\Tool\TestSubscriber;
use function Amp\async;
use function Amp\Future\await;

class SendUpdateTest extends TestCase
class SendUpdateTest extends AbstractFunctionalTest
{
public function testSendUpdate(): void
{
Expand Down
14 changes: 11 additions & 3 deletions tests/Functional/SendUpdateUsingSymfonyClientTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
<?php

/**
* This file is a part of mercure-router-php package.
*
* (c) Swag Industries <[email protected]>
*
* For the full license, take a look to the LICENSE file
* on the root directory of this project
*/

namespace SwagIndustries\MercureRouter\Test\Functional;

use PHPUnit\Framework\TestCase;
use SwagIndustries\MercureRouter\Test\Functional\Tool\TestClient;
use SwagIndustries\MercureRouter\Test\Functional\Tool\TestSubscriber;
use Symfony\Component\HttpClient\HttpClient;
Expand All @@ -14,7 +22,7 @@
use function Amp\delay;
use function Amp\Future\await;

class SendUpdateUsingSymfonyClientTest extends TestCase
class SendUpdateUsingSymfonyClientTest extends AbstractFunctionalTest
{
public function testSendUpdateUsingSymfonyHttpClient(): void
{
Expand All @@ -27,7 +35,7 @@ public function testSendUpdateUsingSymfonyHttpClient(): void
$httpClient = HttpClient::create(['verify_peer' => false, 'verify_host'=> false]);
$token = (new LcobucciFactory(TestClient::PASSPHRASE_JWT))->create();
$hub = new Hub(
'https://127.0.0.1/.well-known/mercure',
'https://127.0.0.1:'.self::TLS_PORT.'/.well-known/mercure',
jwtProvider: new StaticTokenProvider($token),
httpClient: $httpClient,
);
Expand Down
16 changes: 13 additions & 3 deletions tests/Functional/SubscriptionsApiTest.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
<?php

namespace Functional;
/**
* This file is a part of mercure-router-php package.
*
* (c) Swag Industries <[email protected]>
*
* For the full license, take a look to the LICENSE file
* on the root directory of this project
*/

namespace SwagIndustries\MercureRouter\Test\Functional;

use Amp\Http\Client\Response;
use PHPUnit\Framework\TestCase;
use SwagIndustries\MercureRouter\Test\Functional\Tool\TestClient;
use SwagIndustries\MercureRouter\Test\Functional\Tool\TestSubscriber;
use Symfony\Component\Mercure\Jwt\LcobucciFactory;
use function Amp\async;
use function Amp\delay;
use function Amp\Future\await;

class SubscriptionsApiTest extends TestCase
class SubscriptionsApiTest extends AbstractFunctionalTest
{
public const PASSPHRASE_JWT = '!ChangeThisMercureHubJWTSecretKey!';
public function testSubscriptionsList(): void
Expand Down Expand Up @@ -103,6 +111,7 @@ public function testGetASpecificSubscription(): void
[,[$response, $content]] = await([
$subscriber1->subscribe(),
async(function () use ($client, $subscriber1) {
delay(1);
$topic = urlencode('https://example.com/my-topic');
// Let some time pass for the subscription to be established
$res = $client->get(
Expand Down Expand Up @@ -136,6 +145,7 @@ function (string $content) {
]);

$content = json_decode($content, true, flags: JSON_THROW_ON_ERROR);

$this->assertEquals($response->getRequest()->getUri()->getPath(), $content['id']);
$this->assertTrue($content['active']);
$this->assertEquals('https://example.com/my-topic', $content['topic']);
Expand Down
Loading
Loading