Skip to content

Commit 657f5a9

Browse files
committed
Merge branch '6.4' into 7.0
* 6.4: (43 commits) [AssetMapper] Fix entrypoint scripts are not preloaded Fix typo in method resolvePackages Make FormPerformanceTestCase compatible with PHPUnit 10 Avoid calling getInvocationCount() [AssetMapper] Always downloading vendor files [Security] Fix resetting traceable listeners [HttpClient] Fix type error with http_version 1.1 [DependencyInjection] Add tests for `AutowireLocator`/`AutowireIterator` [DependencyInjection] Add `#[AutowireIterator]` attribute and improve `#[AutowireLocator]` Update documentation link Fix typo that causes unit test to fail Fix CS [AssetMapper] Add audit command [Mailer] Use idn encoded address otherwise Brevo throws an error [Messenger] Resend failed retries back to failure transport [FrameworkBundle] Fix call to invalid method in NotificationAssertionsTrait [Validator] Add missing italian translations [Notifier] Fix failing testcase Fix order array sum normalizedData and nestedData Add test for 0 and '0' in PeriodicalTrigger Fix '0' case error and remove duplicate code ...
2 parents 4633b15 + 21a2f61 commit 657f5a9

22 files changed

+327
-59
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ CHANGELOG
2828
6.4
2929
---
3030

31+
* Add `HttpClientAssertionsTrait`
3132
* Add `AbstractController::renderBlock()` and `renderBlockView()`
3233
* Add native return type to `Translator` and to `Application::reset()`
3334
* Deprecate the integration of Doctrine annotations, either uninstall the `doctrine/annotations` package or disable the integration by setting `framework.annotations` to `false`
@@ -49,8 +50,9 @@ CHANGELOG
4950
* Deprecate `framework.validation.enable_annotations`, use `framework.validation.enable_attributes` instead
5051
* Deprecate `framework.serializer.enable_annotations`, use `framework.serializer.enable_attributes` instead
5152
* Add `array $tokenAttributes = []` optional parameter to `KernelBrowser::loginUser()`
52-
* Add support for relative URLs in BrowserKit's redirect assertion.
53+
* Add support for relative URLs in BrowserKit's redirect assertion
5354
* Change BrowserKitAssertionsTrait::getClient() to be protected
55+
* Deprecate the `framework.asset_mapper.provider` config option
5456

5557
6.3
5658
---

DependencyInjection/Compiler/UnusedTagsPass.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class UnusedTagsPass implements CompilerPassInterface
2323
{
2424
private const KNOWN_TAGS = [
2525
'asset_mapper.compiler',
26-
'asset_mapper.importmap.resolver',
2726
'assets.package',
2827
'auto_alias',
2928
'cache.pool',

DependencyInjection/Configuration.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Symfony\Bundle\FullStack;
1818
use Symfony\Component\Asset\Package;
1919
use Symfony\Component\AssetMapper\AssetMapper;
20-
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
2120
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
2221
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
2322
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
@@ -901,8 +900,7 @@ private function addAssetMapperSection(ArrayNodeDefinition $rootNode, callable $
901900
->defaultValue('%kernel.project_dir%/assets/vendor')
902901
->end()
903902
->scalarNode('provider')
904-
->info('The provider (CDN) to use'.(class_exists(ImportMapManager::class) ? sprintf(' (e.g.: "%s").', implode('", "', ImportMapManager::PROVIDERS)) : '.'))
905-
->defaultValue('jsdelivr.esm')
903+
->setDeprecated('symfony/framework-bundle', '6.4', 'Option "%node%" at "%path%" is deprecated and does nothing. Remove it.')
906904
->end()
907905
->end()
908906
->end()

DependencyInjection/FrameworkExtension.php

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
use Symfony\Component\AssetMapper\AssetMapper;
3434
use Symfony\Component\AssetMapper\Compiler\AssetCompilerInterface;
3535
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
36-
use Symfony\Component\AssetMapper\ImportMap\Resolver\PackageResolverInterface;
3736
use Symfony\Component\BrowserKit\AbstractBrowser;
3837
use Symfony\Component\Cache\Adapter\AdapterInterface;
3938
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -1346,28 +1345,24 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
13461345
->setArgument(1, $config['missing_import_mode']);
13471346

13481347
$container
1349-
->getDefinition('asset_mapper.importmap.manager')
1350-
->replaceArgument(3, $config['vendor_dir'])
1348+
->getDefinition('asset_mapper.importmap.remote_package_downloader')
1349+
->replaceArgument(2, $config['vendor_dir'])
13511350
;
1352-
13531351
$container
1354-
->getDefinition('asset_mapper.importmap.config_reader')
1355-
->replaceArgument(0, $config['importmap_path'])
1352+
->getDefinition('asset_mapper.mapped_asset_factory')
1353+
->replaceArgument(2, $config['vendor_dir'])
13561354
;
13571355

13581356
$container
1359-
->getDefinition('asset_mapper.importmap.resolver')
1360-
->replaceArgument(0, $config['provider'])
1357+
->getDefinition('asset_mapper.importmap.config_reader')
1358+
->replaceArgument(0, $config['importmap_path'])
13611359
;
13621360

13631361
$container
13641362
->getDefinition('asset_mapper.importmap.renderer')
13651363
->replaceArgument(3, $config['importmap_polyfill'] ?? ImportMapManager::POLYFILL_URL)
13661364
->replaceArgument(4, $config['importmap_script_attributes'])
13671365
;
1368-
1369-
$container->registerForAutoconfiguration(PackageResolverInterface::class)
1370-
->addTag('asset_mapper.importmap.resolver');
13711366
}
13721367

13731368
/**
@@ -1669,9 +1664,8 @@ private function registerValidationConfiguration(array $config, ContainerBuilder
16691664

16701665
if (!class_exists(ExpressionLanguage::class)) {
16711666
$container->removeDefinition('validator.expression_language');
1672-
}
1673-
1674-
if (!class_exists(ExpressionLanguageProvider::class)) {
1667+
$container->removeDefinition('validator.expression_language_provider');
1668+
} elseif (!class_exists(ExpressionLanguageProvider::class)) {
16751669
$container->removeDefinition('validator.expression_language_provider');
16761670
}
16771671
}

Resources/config/asset_mapper.php

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\AssetMapper\AssetMapperRepository;
1919
use Symfony\Component\AssetMapper\Command\AssetMapperCompileCommand;
2020
use Symfony\Component\AssetMapper\Command\DebugAssetMapperCommand;
21+
use Symfony\Component\AssetMapper\Command\ImportMapAuditCommand;
2122
use Symfony\Component\AssetMapper\Command\ImportMapInstallCommand;
2223
use Symfony\Component\AssetMapper\Command\ImportMapRemoveCommand;
2324
use Symfony\Component\AssetMapper\Command\ImportMapRequireCommand;
@@ -27,12 +28,12 @@
2728
use Symfony\Component\AssetMapper\Compiler\SourceMappingUrlsCompiler;
2829
use Symfony\Component\AssetMapper\Factory\CachedMappedAssetFactory;
2930
use Symfony\Component\AssetMapper\Factory\MappedAssetFactory;
31+
use Symfony\Component\AssetMapper\ImportMap\ImportMapAuditor;
3032
use Symfony\Component\AssetMapper\ImportMap\ImportMapConfigReader;
3133
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
3234
use Symfony\Component\AssetMapper\ImportMap\ImportMapRenderer;
35+
use Symfony\Component\AssetMapper\ImportMap\RemotePackageDownloader;
3336
use Symfony\Component\AssetMapper\ImportMap\Resolver\JsDelivrEsmResolver;
34-
use Symfony\Component\AssetMapper\ImportMap\Resolver\JspmResolver;
35-
use Symfony\Component\AssetMapper\ImportMap\Resolver\PackageResolver;
3637
use Symfony\Component\AssetMapper\MapperAwareAssetPackage;
3738
use Symfony\Component\AssetMapper\Path\PublicAssetsPathResolver;
3839
use Symfony\Component\HttpKernel\Event\RequestEvent;
@@ -51,6 +52,7 @@
5152
->args([
5253
service('asset_mapper.public_assets_path_resolver'),
5354
service('asset_mapper_compiler'),
55+
abstract_arg('vendor directory'),
5456
])
5557

5658
->set('asset_mapper.cached_mapped_asset_factory', CachedMappedAssetFactory::class)
@@ -148,41 +150,20 @@
148150
service('asset_mapper'),
149151
service('asset_mapper.public_assets_path_resolver'),
150152
service('asset_mapper.importmap.config_reader'),
151-
abstract_arg('vendor directory'),
153+
service('asset_mapper.importmap.remote_package_downloader'),
152154
service('asset_mapper.importmap.resolver'),
153-
service('http_client'),
154155
])
155156
->alias(ImportMapManager::class, 'asset_mapper.importmap.manager')
156157

157-
->set('asset_mapper.importmap.resolver', PackageResolver::class)
158+
->set('asset_mapper.importmap.remote_package_downloader', RemotePackageDownloader::class)
158159
->args([
159-
abstract_arg('provider'),
160-
tagged_locator('asset_mapper.importmap.resolver'),
160+
service('asset_mapper.importmap.config_reader'),
161+
service('asset_mapper.importmap.resolver'),
162+
abstract_arg('vendor directory'),
161163
])
162164

163-
->set('asset_mapper.importmap.resolver.jsdelivr_esm', JsDelivrEsmResolver::class)
165+
->set('asset_mapper.importmap.resolver', JsDelivrEsmResolver::class)
164166
->args([service('http_client')])
165-
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSDELIVR_ESM])
166-
167-
->set('asset_mapper.importmap.resolver.jspm', JspmResolver::class)
168-
->args([service('http_client'), ImportMapManager::PROVIDER_JSPM])
169-
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSPM])
170-
171-
->set('asset_mapper.importmap.resolver.jspm_system', JspmResolver::class)
172-
->args([service('http_client'), ImportMapManager::PROVIDER_JSPM_SYSTEM])
173-
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSPM_SYSTEM])
174-
175-
->set('asset_mapper.importmap.resolver.skypack', JspmResolver::class)
176-
->args([service('http_client'), ImportMapManager::PROVIDER_SKYPACK])
177-
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_SKYPACK])
178-
179-
->set('asset_mapper.importmap.resolver.jsdelivr', JspmResolver::class)
180-
->args([service('http_client'), ImportMapManager::PROVIDER_JSDELIVR])
181-
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSDELIVR])
182-
183-
->set('asset_mapper.importmap.resolver.unpkg', JspmResolver::class)
184-
->args([service('http_client'), ImportMapManager::PROVIDER_UNPKG])
185-
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_UNPKG])
186167

187168
->set('asset_mapper.importmap.renderer', ImportMapRenderer::class)
188169
->args([
@@ -193,10 +174,15 @@
193174
abstract_arg('script HTML attributes'),
194175
])
195176

177+
->set('asset_mapper.importmap.auditor', ImportMapAuditor::class)
178+
->args([
179+
service('asset_mapper.importmap.config_reader'),
180+
service('http_client'),
181+
])
182+
196183
->set('asset_mapper.importmap.command.require', ImportMapRequireCommand::class)
197184
->args([
198185
service('asset_mapper.importmap.manager'),
199-
service('asset_mapper'),
200186
param('kernel.project_dir'),
201187
])
202188
->tag('console.command')
@@ -210,7 +196,14 @@
210196
->tag('console.command')
211197

212198
->set('asset_mapper.importmap.command.install', ImportMapInstallCommand::class)
213-
->args([service('asset_mapper.importmap.manager')])
199+
->args([
200+
service('asset_mapper.importmap.remote_package_downloader'),
201+
param('kernel.project_dir'),
202+
])
203+
->tag('console.command')
204+
205+
->set('asset_mapper.importmap.command.audit', ImportMapAuditCommand::class)
206+
->args([service('asset_mapper.importmap.auditor')])
214207
->tag('console.command')
215208
;
216209
};

Resources/config/services.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use Symfony\Component\HttpFoundation\RequestStack;
3636
use Symfony\Component\HttpFoundation\Response;
3737
use Symfony\Component\HttpFoundation\Session\SessionInterface;
38+
use Symfony\Component\HttpFoundation\UriSigner;
3839
use Symfony\Component\HttpFoundation\UrlHelper;
3940
use Symfony\Component\HttpKernel\CacheClearer\ChainCacheClearer;
4041
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate;
@@ -47,7 +48,7 @@
4748
use Symfony\Component\HttpKernel\HttpKernelInterface;
4849
use Symfony\Component\HttpKernel\KernelEvents;
4950
use Symfony\Component\HttpKernel\KernelInterface;
50-
use Symfony\Component\HttpKernel\UriSigner;
51+
use Symfony\Component\HttpKernel\UriSigner as HttpKernelUriSigner;
5152
use Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner;
5253
use Symfony\Component\Runtime\Runner\Symfony\ResponseRunner;
5354
use Symfony\Component\Runtime\SymfonyRuntime;
@@ -157,6 +158,8 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : []
157158
param('kernel.secret'),
158159
])
159160
->alias(UriSigner::class, 'uri_signer')
161+
->alias(HttpKernelUriSigner::class, 'uri_signer')
162+
->deprecate('symfony/framework-bundle', '6.4', 'The "%alias_id%" alias is deprecated, use "'.UriSigner::class.'" instead.')
160163

161164
->set('config_cache_factory', ResourceCheckerConfigCacheFactory::class)
162165
->args([

Test/HttpClientAssertionsTrait.php

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\Test;
13+
14+
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
15+
use Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector;
16+
17+
/*
18+
* @author Mathieu Santostefano <[email protected]>
19+
*/
20+
21+
trait HttpClientAssertionsTrait
22+
{
23+
public static function assertHttpClientRequest(string $expectedUrl, string $expectedMethod = 'GET', string|array $expectedBody = null, array $expectedHeaders = [], string $httpClientId = 'http_client'): void
24+
{
25+
/** @var KernelBrowser $client */
26+
$client = static::getClient();
27+
28+
if (!($profile = $client->getProfile())) {
29+
static::fail('The Profiler must be enabled for the current request. Please ensure to call "$client->enableProfiler()" before making the request.');
30+
}
31+
32+
/** @var HttpClientDataCollector $httpClientDataCollector */
33+
$httpClientDataCollector = $profile->getCollector('http_client');
34+
$expectedRequestHasBeenFound = false;
35+
36+
if (!\array_key_exists($httpClientId, $httpClientDataCollector->getClients())) {
37+
static::fail(sprintf('HttpClient "%s" is not registered.', $httpClientId));
38+
}
39+
40+
foreach ($httpClientDataCollector->getClients()[$httpClientId]['traces'] as $trace) {
41+
if (($expectedUrl !== $trace['info']['url'] && $expectedUrl !== $trace['url'])
42+
|| $expectedMethod !== $trace['method']
43+
) {
44+
continue;
45+
}
46+
47+
if (null !== $expectedBody) {
48+
$actualBody = null;
49+
50+
if (null !== $trace['options']['body'] && null === $trace['options']['json']) {
51+
$actualBody = \is_string($trace['options']['body']) ? $trace['options']['body'] : $trace['options']['body']->getValue(true);
52+
}
53+
54+
if (null === $trace['options']['body'] && null !== $trace['options']['json']) {
55+
$actualBody = $trace['options']['json']->getValue(true);
56+
}
57+
58+
if (!$actualBody) {
59+
continue;
60+
}
61+
62+
if ($expectedBody === $actualBody) {
63+
$expectedRequestHasBeenFound = true;
64+
65+
if (!$expectedHeaders) {
66+
break;
67+
}
68+
}
69+
}
70+
71+
if ($expectedHeaders) {
72+
$actualHeaders = $trace['options']['headers'] ?? [];
73+
74+
foreach ($actualHeaders as $headerKey => $actualHeader) {
75+
if (\array_key_exists($headerKey, $expectedHeaders)
76+
&& $expectedHeaders[$headerKey] === $actualHeader->getValue(true)
77+
) {
78+
$expectedRequestHasBeenFound = true;
79+
break 2;
80+
}
81+
}
82+
}
83+
84+
$expectedRequestHasBeenFound = true;
85+
break;
86+
}
87+
88+
self::assertTrue($expectedRequestHasBeenFound, 'The expected request has not been called: "'.$expectedMethod.'" - "'.$expectedUrl.'"');
89+
}
90+
91+
public function assertNotHttpClientRequest(string $unexpectedUrl, string $expectedMethod = 'GET', string $httpClientId = 'http_client'): void
92+
{
93+
/** @var KernelBrowser $client */
94+
$client = static::getClient();
95+
96+
if (!$profile = $client->getProfile()) {
97+
static::fail('The Profiler must be enabled for the current request. Please ensure to call "$client->enableProfiler()" before making the request.');
98+
}
99+
100+
/** @var HttpClientDataCollector $httpClientDataCollector */
101+
$httpClientDataCollector = $profile->getCollector('http_client');
102+
$unexpectedUrlHasBeenFound = false;
103+
104+
if (!\array_key_exists($httpClientId, $httpClientDataCollector->getClients())) {
105+
static::fail(sprintf('HttpClient "%s" is not registered.', $httpClientId));
106+
}
107+
108+
foreach ($httpClientDataCollector->getClients()[$httpClientId]['traces'] as $trace) {
109+
if (($unexpectedUrl === $trace['info']['url'] || $unexpectedUrl === $trace['url'])
110+
&& $expectedMethod === $trace['method']
111+
) {
112+
$unexpectedUrlHasBeenFound = true;
113+
break;
114+
}
115+
}
116+
117+
self::assertFalse($unexpectedUrlHasBeenFound, sprintf('Unexpected URL called: "%s" - "%s"', $expectedMethod, $unexpectedUrl));
118+
}
119+
120+
public static function assertHttpClientRequestCount(int $count, string $httpClientId = 'http_client'): void
121+
{
122+
/** @var KernelBrowser $client */
123+
$client = static::getClient();
124+
125+
if (!($profile = $client->getProfile())) {
126+
static::fail('The Profiler must be enabled for the current request. Please ensure to call "$client->enableProfiler()" before making the request.');
127+
}
128+
129+
/** @var HttpClientDataCollector $httpClientDataCollector */
130+
$httpClientDataCollector = $profile->getCollector('http_client');
131+
132+
self::assertCount($count, $httpClientDataCollector->getClients()[$httpClientId]['traces']);
133+
}
134+
}

Test/NotificationAssertionsTrait.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static function assertNotificationCount(int $count, string $transportName
2929

3030
public static function assertQueuedNotificationCount(int $count, string $transportName = null, string $message = ''): void
3131
{
32-
self::assertThat(self::getMessageMailerEvents(), new NotifierConstraint\NotificationCount($count, $transportName, true), $message);
32+
self::assertThat(self::getNotificationEvents(), new NotifierConstraint\NotificationCount($count, $transportName, true), $message);
3333
}
3434

3535
public static function assertNotificationIsQueued(MessageEvent $event, string $message = ''): void
@@ -52,12 +52,12 @@ public static function assertNotificationSubjectNotContains(MessageInterface $no
5252
self::assertThat($notification, new LogicalNot(new NotifierConstraint\NotificationSubjectContains($text)), $message);
5353
}
5454

55-
public static function assertNotificationTransportIsEqual(MessageInterface $notification, string $transportName, string $message = ''): void
55+
public static function assertNotificationTransportIsEqual(MessageInterface $notification, string $transportName = null, string $message = ''): void
5656
{
5757
self::assertThat($notification, new NotifierConstraint\NotificationTransportIsEqual($transportName), $message);
5858
}
5959

60-
public static function assertNotificationTransportIsNotEqual(MessageInterface $notification, string $transportName, string $message = ''): void
60+
public static function assertNotificationTransportIsNotEqual(MessageInterface $notification, string $transportName = null, string $message = ''): void
6161
{
6262
self::assertThat($notification, new LogicalNot(new NotifierConstraint\NotificationTransportIsEqual($transportName)), $message);
6363
}

0 commit comments

Comments
 (0)