Skip to content

Commit ffd60b6

Browse files
committed
Merge branch '6.4' into 7.1
* 6.4: [AssetMapper] Fix `JavaScriptImportPathCompiler` regex for non-latin characters Definition::$class may not be class-string require Cache component versions compatible with Redis 6.1 [Twitter][Notifier] Fix post INIT upload [Messenger][RateLimiter] fix additional message handled when using a rate limiter [Serializer] fixed object normalizer for a class with `cancel` method Fix bucket size reduce when previously created with bigger size
2 parents e713ac2 + 8dabfd7 commit ffd60b6

File tree

17 files changed

+263
-34
lines changed

17 files changed

+263
-34
lines changed

src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ final class JavaScriptImportPathCompiler implements AssetCompilerInterface
5050
)
5151
\s*[\'"`](\.\/[^\'"`\n]++|(\.\.\/)*+[^\'"`\n]++)[\'"`]\s*[;\)]
5252
?
53-
/mx';
53+
/mxu';
5454

5555
public function __construct(
5656
private readonly ImportMapConfigReader $importMapConfigReader,

src/Symfony/Component/AssetMapper/Tests/Compiler/JavaScriptImportPathCompilerTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,22 @@ public static function provideCompileTests(): iterable
172172
'expectedJavaScriptImports' => ['/assets/other.js' => ['lazy' => false, 'asset' => 'other.js', 'add' => true]],
173173
];
174174

175+
yield 'static_named_import_with_unicode_character' => [
176+
'input' => 'import { ɵmyFunction } from "./other.js";',
177+
'expectedJavaScriptImports' => ['/assets/other.js' => ['lazy' => false, 'asset' => 'other.js', 'add' => true]],
178+
];
179+
180+
yield 'static_multiple_named_imports' => [
181+
'input' => <<<EOF
182+
import {
183+
myFunction,
184+
helperFunction
185+
} from "./other.js";
186+
EOF
187+
,
188+
'expectedJavaScriptImports' => ['/assets/other.js' => ['lazy' => false, 'asset' => 'other.js', 'add' => true]],
189+
];
190+
175191
yield 'static_import_everything' => [
176192
'input' => 'import * as myModule from "./other.js";',
177193
'expectedJavaScriptImports' => ['/assets/other.js' => ['lazy' => false, 'asset' => 'other.js', 'add' => true]],

src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ public function setClass(?string $class): static
180180

181181
/**
182182
* Gets the service class.
183-
*
184-
* @return class-string|null
185183
*/
186184
public function getClass(): ?string
187185
{

src/Symfony/Component/HttpFoundation/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"require-dev": {
2424
"doctrine/dbal": "^3.6|^4",
2525
"predis/predis": "^1.1|^2.0",
26-
"symfony/cache": "^6.4|^7.0",
26+
"symfony/cache": "^6.4.12|^7.1.5",
2727
"symfony/dependency-injection": "^6.4|^7.0",
2828
"symfony/http-kernel": "^6.4|^7.0",
2929
"symfony/mime": "^6.4|^7.0",
@@ -32,7 +32,7 @@
3232
},
3333
"conflict": {
3434
"doctrine/dbal": "<3.6",
35-
"symfony/cache": "<6.4"
35+
"symfony/cache": "<6.4.12|>=7.0,<7.1.5"
3636
},
3737
"autoload": {
3838
"psr-4": { "Symfony\\Component\\HttpFoundation\\": "" },

src/Symfony/Component/Messenger/Tests/WorkerTest.php

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Psr\EventDispatcher\EventDispatcherInterface;
1616
use Psr\Log\LoggerInterface;
17+
use Symfony\Bridge\PhpUnit\ClockMock;
1718
use Symfony\Component\Clock\MockClock;
1819
use Symfony\Component\EventDispatcher\EventDispatcher;
1920
use Symfony\Component\HttpKernel\DependencyInjection\ServicesResetter;
@@ -47,8 +48,8 @@
4748
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
4849
use Symfony\Component\Messenger\Worker;
4950
use Symfony\Component\RateLimiter\RateLimiterFactory;
51+
use Symfony\Component\RateLimiter\Reservation;
5052
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
51-
use Symfony\Contracts\Service\ResetInterface;
5253

5354
/**
5455
* @group time-sensitive
@@ -73,7 +74,7 @@ public function testWorkerDispatchTheReceivedMessage()
7374
return $envelopes[] = $envelope;
7475
});
7576

76-
$dispatcher = new class() implements EventDispatcherInterface {
77+
$dispatcher = new class implements EventDispatcherInterface {
7778
private StopWorkerOnMessageLimitListener $listener;
7879

7980
public function __construct()
@@ -403,7 +404,7 @@ public function testWorkerLimitQueuesUnsupported()
403404

404405
$worker = new Worker(['transport1' => $receiver1, 'transport2' => $receiver2], $bus, clock: new MockClock());
405406
$this->expectException(RuntimeException::class);
406-
$this->expectExceptionMessage(sprintf('Receiver for "transport2" does not implement "%s".', QueueReceiverInterface::class));
407+
$this->expectExceptionMessage(\sprintf('Receiver for "transport2" does not implement "%s".', QueueReceiverInterface::class));
407408
$worker->run(['queues' => ['foo']]);
408409
}
409410

@@ -418,7 +419,7 @@ public function testWorkerMessageReceivedEventMutability()
418419
$eventDispatcher = new EventDispatcher();
419420
$eventDispatcher->addSubscriber(new StopWorkerOnMessageLimitListener(1));
420421

421-
$stamp = new class() implements StampInterface {
422+
$stamp = new class implements StampInterface {
422423
};
423424
$listener = function (WorkerMessageReceivedEvent $event) use ($stamp) {
424425
$event->addStamps($stamp);
@@ -438,21 +439,21 @@ public function testWorkerRateLimitMessages()
438439
$envelope = [
439440
new Envelope(new DummyMessage('message1')),
440441
new Envelope(new DummyMessage('message2')),
442+
new Envelope(new DummyMessage('message3')),
443+
new Envelope(new DummyMessage('message4')),
441444
];
442445
$receiver = new DummyReceiver([$envelope]);
443446

444447
$bus = $this->createMock(MessageBusInterface::class);
445448
$bus->method('dispatch')->willReturnArgument(0);
446449

447450
$eventDispatcher = new EventDispatcher();
448-
$eventDispatcher->addSubscriber(new StopWorkerOnMessageLimitListener(2));
451+
$eventDispatcher->addSubscriber(new StopWorkerOnMessageLimitListener(4));
449452

450453
$rateLimitCount = 0;
451-
$listener = function (WorkerRateLimitedEvent $event) use (&$rateLimitCount) {
454+
$eventDispatcher->addListener(WorkerRateLimitedEvent::class, static function () use (&$rateLimitCount) {
452455
++$rateLimitCount;
453-
$event->getLimiter()->reset(); // Reset limiter to continue test
454-
};
455-
$eventDispatcher->addListener(WorkerRateLimitedEvent::class, $listener);
456+
});
456457

457458
$rateLimitFactory = new RateLimiterFactory([
458459
'id' => 'bus',
@@ -461,11 +462,14 @@ public function testWorkerRateLimitMessages()
461462
'interval' => '1 minute',
462463
], new InMemoryStorage());
463464

465+
ClockMock::register(Reservation::class);
466+
ClockMock::register(InMemoryStorage::class);
467+
464468
$worker = new Worker(['bus' => $receiver], $bus, $eventDispatcher, null, ['bus' => $rateLimitFactory], new MockClock());
465469
$worker->run();
466470

467-
$this->assertCount(2, $receiver->getAcknowledgedEnvelopes());
468-
$this->assertEquals(1, $rateLimitCount);
471+
$this->assertSame(4, $receiver->getAcknowledgeCount());
472+
$this->assertSame(3, $rateLimitCount);
469473
}
470474

471475
public function testWorkerShouldLogOnStop()

src/Symfony/Component/Messenger/Worker.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public function run(array $options = []): void
8787
// if queue names are specified, all receivers must implement the QueueReceiverInterface
8888
foreach ($this->receivers as $transportName => $receiver) {
8989
if (!$receiver instanceof QueueReceiverInterface) {
90-
throw new RuntimeException(sprintf('Receiver for "%s" does not implement "%s".', $transportName, QueueReceiverInterface::class));
90+
throw new RuntimeException(\sprintf('Receiver for "%s" does not implement "%s".', $transportName, QueueReceiverInterface::class));
9191
}
9292
}
9393
}
@@ -244,6 +244,7 @@ private function rateLimit(string $transportName): void
244244

245245
$this->eventDispatcher?->dispatch(new WorkerRateLimitedEvent($rateLimiter, $transportName));
246246
$rateLimiter->reserve()->wait();
247+
$rateLimiter->consume();
247248
}
248249

249250
private function flush(bool $force): bool

src/Symfony/Component/Notifier/Bridge/Twitter/Tests/TwitterTransportTest.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ public function testTweetImage()
6666
$transport = $this->createTransport(new MockHttpClient((function () {
6767
yield function (string $method, string $url, array $options) {
6868
$this->assertSame('POST', $method);
69-
$this->assertSame('https://upload.twitter.com/1.1/media/upload.json?command=INIT&total_bytes=185&media_type=image/gif&media_category=tweet_image', $url);
69+
$this->assertSame('https://upload.twitter.com/1.1/media/upload.json', $url);
70+
$this->assertArrayHasKey('body', $options);
71+
$this->assertSame($options['body'], 'command=INIT&total_bytes=185&media_type=image%2Fgif&media_category=tweet_image');
7072
$this->assertArrayHasKey('authorization', $options['normalized_headers']);
7173

7274
return new MockResponse('{"media_id_string":"gif123"}');
@@ -127,15 +129,19 @@ public function testTweetVideo()
127129
$transport = $this->createTransport(new MockHttpClient((function () {
128130
yield function (string $method, string $url, array $options) {
129131
$this->assertSame('POST', $method);
130-
$this->assertSame('https://upload.twitter.com/1.1/media/upload.json?command=INIT&total_bytes=185&media_type=image/gif&media_category=tweet_video', $url);
132+
$this->assertSame('https://upload.twitter.com/1.1/media/upload.json', $url);
133+
$this->assertArrayHasKey('body', $options);
134+
$this->assertSame($options['body'], 'command=INIT&total_bytes=185&media_type=image%2Fgif&media_category=tweet_video');
131135
$this->assertArrayHasKey('authorization', $options['normalized_headers']);
132136

133137
return new MockResponse('{"media_id_string":"gif123"}');
134138
};
135139

136140
yield function (string $method, string $url, array $options) {
137141
$this->assertSame('POST', $method);
138-
$this->assertSame('https://upload.twitter.com/1.1/media/upload.json?command=INIT&total_bytes=185&media_type=image/gif&media_category=subtitles', $url);
142+
$this->assertSame('https://upload.twitter.com/1.1/media/upload.json', $url);
143+
$this->assertArrayHasKey('body', $options);
144+
$this->assertSame($options['body'], 'command=INIT&total_bytes=185&media_type=image%2Fgif&media_category=subtitles');
139145
$this->assertArrayHasKey('authorization', $options['normalized_headers']);
140146

141147
return new MockResponse('{"media_id_string":"sub234"}');

src/Symfony/Component/Notifier/Bridge/Twitter/TwitterTransport.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,32 +156,32 @@ private function uploadMedia(array $media): array
156156
'category' => $category,
157157
'owners' => $extraOwners,
158158
]) {
159-
$query = [
159+
$body = [
160160
'command' => 'INIT',
161161
'total_bytes' => $file->getSize(),
162162
'media_type' => $file->getContentType(),
163163
];
164164

165165
if ($category) {
166-
$query['media_category'] = $category;
166+
$body['media_category'] = $category;
167167
}
168168

169169
if ($extraOwners) {
170-
$query['additional_owners'] = implode(',', $extraOwners);
170+
$body['additional_owners'] = implode(',', $extraOwners);
171171
}
172172

173173
$pool[++$i] = $this->request('POST', '/1.1/media/upload.json', [
174-
'query' => $query,
174+
'body' => $body,
175175
'user_data' => [$i, null, 0, fopen($file->getPath(), 'r'), $alt, $subtitles],
176176
]);
177177

178178
if ($subtitles) {
179-
$query['total_bytes'] = $subtitles->getSize();
180-
$query['media_type'] = $subtitles->getContentType();
181-
$query['media_category'] = 'subtitles';
179+
$body['total_bytes'] = $subtitles->getSize();
180+
$body['media_type'] = $subtitles->getContentType();
181+
$body['media_category'] = 'subtitles';
182182

183183
$pool[++$i] = $this->request('POST', '/1.1/media/upload.json', [
184-
'query' => $query,
184+
'body' => $body,
185185
'user_data' => [$i, null, 0, fopen($subtitles->getPath(), 'r'), null, $subtitles],
186186
]);
187187
}

src/Symfony/Component/RateLimiter/Policy/TokenBucketLimiter.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ public function reserve(int $tokens = 1, ?float $maxTime = null): Reservation
6767
$now = microtime(true);
6868
$availableTokens = $bucket->getAvailableTokens($now);
6969

70+
if ($availableTokens > $this->maxBurst) {
71+
$availableTokens = $this->maxBurst;
72+
}
73+
7074
if ($availableTokens >= $tokens) {
7175
// tokens are now available, update bucket
7276
$bucket->setTokens($availableTokens - $tokens);

src/Symfony/Component/RateLimiter/Tests/Policy/TokenBucketLimiterTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ public function testReserveMoreTokensThanBucketSize()
5757
$limiter->reserve(15);
5858
}
5959

60+
public function testReduceBucketSizeWhenAlreadyExistInStorageWithBiggerBucketSize()
61+
{
62+
$limiter = $this->createLimiter(100);
63+
64+
$limiter->consume();
65+
66+
$limiter2 = $this->createLimiter(1);
67+
$limiter2->consume();
68+
69+
$this->assertFalse($limiter2->consume()->isAccepted());
70+
}
71+
6072
public function testReserveMaxWaitingTime()
6173
{
6274
$limiter = $this->createLimiter(10, Rate::perMinute());

0 commit comments

Comments
 (0)