Skip to content

Commit cda2b64

Browse files
turegjorupclaude
andcommitted
test: assert DI extension wiring and provider key normalization invariant
Mutation testing showed the extension's container wiring was executed but never verified: every replaceArgument() call could be removed, the cacheItemPool reference dropped, and the provider options array_map unwrapped without a failing test. The documented invariant that provider keys are not normalized (my-provider != my_provider) was also untested. Kills all 20 mutants in src/DependencyInjection (was 12/20). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent c826902 commit cda2b64

3 files changed

Lines changed: 67 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12+
- Dev: strengthened DependencyInjection tests based on mutation testing
13+
findings — the extension's container wiring (cache pool reference,
14+
provider options mapping, CLI login route arguments) is now asserted
15+
explicitly, and the documented invariant that provider keys are not
16+
normalized (`my-provider``my_provider`) is covered by a test. No
17+
effect on the published package.
18+
1219
- CI: bumped `codecov/codecov-action` from `v5` to `v7` (restores Codecov's
1320
GPG signing key after the `codecovsecurity` account was removed, and moves
1421
the bundled `github-script` to Node 24) and set `fail_ci_if_error: false`

tests/DependencyInjection/ConfigurationTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,24 @@ public function testHttpClientOptionsRejectsUnknownKey(): void
163163
);
164164
}
165165

166+
public function testProviderKeysAreNotNormalized(): void
167+
{
168+
$input = $this->getMinimalConfig();
169+
$input['openid_providers']['my-provider'] = $input['openid_providers']['provider1'];
170+
unset($input['openid_providers']['provider1']);
171+
172+
$config = $this->processor->processConfiguration(
173+
$this->configuration,
174+
[$input]
175+
);
176+
177+
// Provider keys are part of the public contract ('my-provider' and
178+
// 'my_provider' are distinct providers), so dashes must survive
179+
// config processing instead of being normalized to underscores.
180+
$this->assertArrayHasKey('my-provider', $config['openid_providers']);
181+
$this->assertArrayNotHasKey('my_provider', $config['openid_providers']);
182+
}
183+
166184
public function testMultipleProviders(): void
167185
{
168186
$input = $this->getMinimalConfig();

tests/DependencyInjection/ItkDevOpenIdConnectExtensionTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,48 @@ public function testLoad(): void
4848
$this->assertTrue($container->hasDefinition(CliLoginTokenAuthenticator::class));
4949
}
5050

51+
public function testLoadWiresProviderManagerConfig(): void
52+
{
53+
$extension = new ItkDevOpenIdConnectExtension();
54+
$container = new ContainerBuilder();
55+
56+
$extension->load([$this->getBaseConfig()], $container);
57+
58+
$config = $container->getDefinition(OpenIdConfigurationProviderManager::class)->getArgument('$config');
59+
$this->assertIsArray($config);
60+
61+
$defaultOptions = $config['default_providers_options'] ?? null;
62+
$this->assertIsArray($defaultOptions);
63+
$cacheItemPool = $defaultOptions['cacheItemPool'] ?? null;
64+
$this->assertInstanceOf(Reference::class, $cacheItemPool);
65+
$this->assertSame('cache.app', (string) $cacheItemPool);
66+
67+
// Provider options must be keyed by provider name with the
68+
// intermediate 'options' level stripped.
69+
$providers = $config['providers'] ?? null;
70+
$this->assertIsArray($providers);
71+
$this->assertSame(['test_provider'], array_keys($providers));
72+
$provider = $providers['test_provider'];
73+
$this->assertIsArray($provider);
74+
$this->assertArrayNotHasKey('options', $provider);
75+
$this->assertSame('test_id', $provider['client_id']);
76+
}
77+
78+
public function testLoadWiresCacheAndCliLoginRoute(): void
79+
{
80+
$extension = new ItkDevOpenIdConnectExtension();
81+
$container = new ContainerBuilder();
82+
83+
$extension->load([$this->getBaseConfig()], $container);
84+
85+
$cache = $container->getDefinition(CliLoginHelper::class)->getArgument('$cache');
86+
$this->assertInstanceOf(Reference::class, $cache);
87+
$this->assertSame('cache.app', (string) $cache);
88+
89+
$this->assertSame('test_route', $container->getDefinition(UserLoginCommand::class)->getArgument('$cliLoginRoute'));
90+
$this->assertSame('test_route', $container->getDefinition(CliLoginTokenAuthenticator::class)->getArgument('$cliLoginRoute'));
91+
}
92+
5193
public function testLoadWithUserProvider(): void
5294
{
5395
$extension = new ItkDevOpenIdConnectExtension();

0 commit comments

Comments
 (0)