Skip to content

Commit 8bd6786

Browse files
committed
Add TelemetryExtension — ensure telemetry is active for official plugins
Use PrependExtensionInterface to override both ENV and config before SyliusCoreExtension loads. This ensures telemetry services are always registered in prod when the bundle is installed, regardless of user configuration. Dev/test environments are skipped. Includes unit tests (TelemetryExtension) and integration tests (real Sylius kernel via sylius/test-application).
1 parent 5049c05 commit 8bd6786

File tree

13 files changed

+386
-5
lines changed

13 files changed

+386
-5
lines changed

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
strategy:
1212
fail-fast: false
1313
matrix:
14-
php: ["8.2", "8.3", "8.4"]
14+
php: ["8.2", "8.3"]
1515
name: "PHPUnit (PHP ${{ matrix.php }})"
1616
steps:
1717
- uses: actions/checkout@v4

composer.json

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,38 @@
99
"symfony/http-kernel": "^6.4 || ^7.0"
1010
},
1111
"require-dev": {
12-
"phpunit/phpunit": "^10.5 || ^11.0"
12+
"phpunit/phpunit": "^10.5 || ^11.0",
13+
"sylius/sylius": "^2.0",
14+
"sylius/test-application": "^2.0.0@alpha",
15+
"symfony/browser-kit": "^6.4 || ^7.1",
16+
"symfony/debug-bundle": "^6.4 || ^7.1",
17+
"symfony/dotenv": "^6.4 || ^7.1",
18+
"symfony/runtime": "^6.4 || ^7.1",
19+
"symfony/web-profiler-bundle": "^6.4 || ^7.1"
1320
},
1421
"autoload": {
1522
"psr-4": {
1623
"Sylius\\TelemetryBundle\\": "src/"
1724
}
1825
},
26+
"autoload-dev": {
27+
"psr-4": {
28+
"Sylius\\TelemetryBundle\\Tests\\": "tests/"
29+
}
30+
},
31+
"config": {
32+
"allow-plugins": {
33+
"symfony/flex": true,
34+
"symfony/runtime": true,
35+
"php-http/discovery": false
36+
}
37+
},
1938
"extra": {
2039
"branch-alias": {
2140
"dev-main": "1.0-dev"
22-
}
23-
}
41+
},
42+
"public-dir": "vendor/sylius/test-application/public"
43+
},
44+
"prefer-stable": true,
45+
"minimum-stability": "alpha"
2446
}

phpunit.xml.dist

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
33
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
4-
bootstrap="vendor/autoload.php"
4+
bootstrap="vendor/sylius/test-application/config/bootstrap.php"
55
colors="true"
66
failOnEmptyTestSuite="false"
77
>
8+
<php>
9+
<server name="KERNEL_CLASS" value="Sylius\TestApplication\Kernel" />
10+
</php>
811
<testsuites>
912
<testsuite name="TelemetryBundle">
1013
<directory>tests</directory>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sylius\TelemetryBundle\DependencyInjection;
6+
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
9+
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
10+
11+
final class TelemetryExtension extends Extension implements PrependExtensionInterface
12+
{
13+
public function prepend(ContainerBuilder $container): void
14+
{
15+
if ($this->isDevOrTestEnv($container)) {
16+
return;
17+
}
18+
19+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '1';
20+
$_SERVER['SYLIUS_TELEMETRY_ENABLED'] = '1';
21+
putenv('SYLIUS_TELEMETRY_ENABLED=1');
22+
23+
$container->prependExtensionConfig('sylius_core', [
24+
'telemetry' => [
25+
'enabled' => true,
26+
],
27+
]);
28+
}
29+
30+
public function load(array $configs, ContainerBuilder $container): void
31+
{
32+
}
33+
34+
private function isDevOrTestEnv(ContainerBuilder $container): bool
35+
{
36+
$env = $container->getParameter('kernel.environment');
37+
38+
return str_starts_with($env, 'dev') || str_starts_with($env, 'test');
39+
}
40+
}

src/TelemetryBundle.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sylius\TelemetryBundle;
6+
7+
use Symfony\Component\HttpKernel\Bundle\Bundle;
8+
9+
final class TelemetryBundle extends Bundle
10+
{
11+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sylius\TelemetryBundle\Tests\DependencyInjection;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Sylius\TelemetryBundle\DependencyInjection\TelemetryExtension;
9+
use Symfony\Component\DependencyInjection\ContainerBuilder;
10+
11+
final class TelemetryExtensionTest extends TestCase
12+
{
13+
protected function tearDown(): void
14+
{
15+
unset($_ENV['SYLIUS_TELEMETRY_ENABLED'], $_SERVER['SYLIUS_TELEMETRY_ENABLED']);
16+
putenv('SYLIUS_TELEMETRY_ENABLED');
17+
}
18+
19+
public function testItEnablesTelemetryInProdWhenDisabledViaEnv(): void
20+
{
21+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '0';
22+
$container = $this->createContainer('prod');
23+
24+
(new TelemetryExtension())->prepend($container);
25+
26+
$this->assertSame('1', $_ENV['SYLIUS_TELEMETRY_ENABLED']);
27+
$this->assertSame('1', $_SERVER['SYLIUS_TELEMETRY_ENABLED']);
28+
$this->assertSame('1', getenv('SYLIUS_TELEMETRY_ENABLED'));
29+
$this->assertPrependedConfig($container);
30+
}
31+
32+
public function testItEnablesTelemetryInProdWhenEnvNotSet(): void
33+
{
34+
$container = $this->createContainer('prod');
35+
36+
(new TelemetryExtension())->prepend($container);
37+
38+
$this->assertSame('1', $_ENV['SYLIUS_TELEMETRY_ENABLED']);
39+
$this->assertPrependedConfig($container);
40+
}
41+
42+
public function testItEnablesTelemetryInStagingEnvironment(): void
43+
{
44+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = 'false';
45+
$container = $this->createContainer('staging');
46+
47+
(new TelemetryExtension())->prepend($container);
48+
49+
$this->assertSame('1', $_ENV['SYLIUS_TELEMETRY_ENABLED']);
50+
$this->assertPrependedConfig($container);
51+
}
52+
53+
public function testItSkipsInDevEnvironment(): void
54+
{
55+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '0';
56+
$container = $this->createContainer('dev');
57+
58+
(new TelemetryExtension())->prepend($container);
59+
60+
$this->assertSame('0', $_ENV['SYLIUS_TELEMETRY_ENABLED']);
61+
$this->assertNoPrependedConfig($container);
62+
}
63+
64+
public function testItSkipsInTestEnvironment(): void
65+
{
66+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '0';
67+
$container = $this->createContainer('test');
68+
69+
(new TelemetryExtension())->prepend($container);
70+
71+
$this->assertSame('0', $_ENV['SYLIUS_TELEMETRY_ENABLED']);
72+
$this->assertNoPrependedConfig($container);
73+
}
74+
75+
private function createContainer(string $environment): ContainerBuilder
76+
{
77+
$container = new ContainerBuilder();
78+
$container->setParameter('kernel.environment', $environment);
79+
80+
return $container;
81+
}
82+
83+
private function assertPrependedConfig(ContainerBuilder $container): void
84+
{
85+
$configs = $container->getExtensionConfig('sylius_core');
86+
$this->assertNotEmpty($configs);
87+
$this->assertSame(['telemetry' => ['enabled' => true]], $configs[0]);
88+
}
89+
90+
private function assertNoPrependedConfig(ContainerBuilder $container): void
91+
{
92+
$configs = $container->getExtensionConfig('sylius_core');
93+
$this->assertEmpty($configs);
94+
}
95+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sylius\TelemetryBundle\Tests\Integration;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use Sylius\TestApplication\Kernel;
9+
use Symfony\Component\DependencyInjection\ContainerBuilder;
10+
11+
final class TelemetryEnablerTest extends TestCase
12+
{
13+
private ?string $previousConfigsToImport = null;
14+
15+
protected function setUp(): void
16+
{
17+
$_SERVER['SYLIUS_TEST_APP_BUNDLES_PATH'] = 'tests/TestApplication/config/bundles.php';
18+
19+
$this->previousConfigsToImport = $_SERVER['SYLIUS_TEST_APP_CONFIGS_TO_IMPORT'] ?? null;
20+
unset($_SERVER['SYLIUS_TEST_APP_CONFIGS_TO_IMPORT']);
21+
}
22+
23+
protected function tearDown(): void
24+
{
25+
if ($this->previousConfigsToImport !== null) {
26+
$_SERVER['SYLIUS_TEST_APP_CONFIGS_TO_IMPORT'] = $this->previousConfigsToImport;
27+
}
28+
29+
unset(
30+
$_ENV['SYLIUS_TELEMETRY_ENABLED'],
31+
$_SERVER['SYLIUS_TELEMETRY_ENABLED'],
32+
$_SERVER['SYLIUS_TEST_APP_BUNDLES_PATH'],
33+
);
34+
putenv('SYLIUS_TELEMETRY_ENABLED');
35+
}
36+
37+
/** @group prod */
38+
public function testProdWithTelemetryDisabledStillHasServicesRegistered(): void
39+
{
40+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '0';
41+
$_SERVER['SYLIUS_TELEMETRY_ENABLED'] = '0';
42+
putenv('SYLIUS_TELEMETRY_ENABLED=0');
43+
44+
$container = $this->compileContainer('prod');
45+
46+
$this->assertTrue($container->getParameter('sylius_core.telemetry.enabled'));
47+
$this->assertTrue($container->has('sylius.telemetry.sender'));
48+
$this->assertTrue($container->has('sylius.telemetry.send_manager'));
49+
}
50+
51+
/** @group prod */
52+
public function testProdWithTelemetryEnabledHasServicesRegistered(): void
53+
{
54+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '1';
55+
$_SERVER['SYLIUS_TELEMETRY_ENABLED'] = '1';
56+
putenv('SYLIUS_TELEMETRY_ENABLED=1');
57+
58+
$container = $this->compileContainer('prod');
59+
60+
$this->assertTrue($container->getParameter('sylius_core.telemetry.enabled'));
61+
$this->assertTrue($container->has('sylius.telemetry.sender'));
62+
$this->assertTrue($container->has('sylius.telemetry.send_manager'));
63+
}
64+
65+
/** @group dev */
66+
public function testDevWithTelemetryDisabledDoesNotHaveServicesRegistered(): void
67+
{
68+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '0';
69+
$_SERVER['SYLIUS_TELEMETRY_ENABLED'] = '0';
70+
putenv('SYLIUS_TELEMETRY_ENABLED=0');
71+
72+
$container = $this->compileContainer('dev');
73+
74+
$this->assertFalse($container->has('sylius.telemetry.sender'));
75+
}
76+
77+
/** @group dev */
78+
public function testTestEnvWithTelemetryDisabledDoesNotHaveServicesRegistered(): void
79+
{
80+
$_ENV['SYLIUS_TELEMETRY_ENABLED'] = '0';
81+
$_SERVER['SYLIUS_TELEMETRY_ENABLED'] = '0';
82+
putenv('SYLIUS_TELEMETRY_ENABLED=0');
83+
84+
$container = $this->compileContainer('test');
85+
86+
$this->assertFalse($container->has('sylius.telemetry.sender'));
87+
}
88+
89+
private function compileContainer(string $env): ContainerBuilder
90+
{
91+
$kernel = new Kernel($env, true);
92+
93+
$initBundles = new \ReflectionMethod($kernel, 'initializeBundles');
94+
$initBundles->invoke($kernel);
95+
96+
$buildContainer = new \ReflectionMethod($kernel, 'buildContainer');
97+
98+
/** @var ContainerBuilder $container */
99+
$container = $buildContainer->invoke($kernel);
100+
$container->compile();
101+
102+
return $container;
103+
}
104+
}

tests/Smoke/SmokeTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sylius\TelemetryBundle\Tests\Smoke;
6+
7+
use Symfony\Bundle\FrameworkBundle\Console\Application;
8+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
9+
use Symfony\Component\Console\Input\ArrayInput;
10+
use Symfony\Component\Console\Output\NullOutput;
11+
12+
final class SmokeTest extends WebTestCase
13+
{
14+
public function testAdminLoginPageLoads(): void
15+
{
16+
$client = static::createClient();
17+
18+
$application = new Application($client->getKernel());
19+
$application->setAutoExit(false);
20+
$application->run(new ArrayInput([
21+
'command' => 'doctrine:schema:create',
22+
'--quiet' => true,
23+
]), new NullOutput());
24+
25+
$client->request('GET', '/admin/login');
26+
27+
$this->assertResponseIsSuccessful();
28+
}
29+
}

tests/Spy/SpyTelemetrySender.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sylius\TelemetryBundle\Tests\Spy;
6+
7+
use Sylius\Component\Core\Telemetry\Sender\TelemetrySenderInterface;
8+
9+
final class SpyTelemetrySender implements TelemetrySenderInterface
10+
{
11+
/** @var list<array<string, mixed>> */
12+
private array $calls = [];
13+
14+
public function send(array $telemetryData): bool
15+
{
16+
$this->calls[] = $telemetryData;
17+
18+
return true;
19+
}
20+
21+
public function wasCalled(): bool
22+
{
23+
return $this->calls !== [];
24+
}
25+
26+
public function getCallCount(): int
27+
{
28+
return count($this->calls);
29+
}
30+
31+
/** @return list<array<string, mixed>> */
32+
public function getCalls(): array
33+
{
34+
return $this->calls;
35+
}
36+
37+
public function reset(): void
38+
{
39+
$this->calls = [];
40+
}
41+
}

tests/TestApplication/.env

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
APP_ENV=test
2+
APP_SECRET=test_secret
3+
DATABASE_URL=sqlite:///%kernel.project_dir%/../../../var/test.db
4+
SYLIUS_TEST_APP_BUNDLES_PATH=tests/TestApplication/config/bundles.php
5+
SYLIUS_TEST_APP_CONFIGS_TO_IMPORT=../../../../tests/TestApplication/config/config.yaml

0 commit comments

Comments
 (0)