From 500c122cf390420402162901cec11f4c1a5863b6 Mon Sep 17 00:00:00 2001 From: Pavel Rossinsky Date: Wed, 29 Jul 2026 13:18:14 +0200 Subject: [PATCH] fix: no longer report actively supported releases as end of active support (#451) The v0 API's boolean support means active support exists when true. The inverted mapping reported supported cycles as "active support ended" and would hide cycles whose support really ended. --- src/Components/Security/EndOfLifeService.php | 2 +- .../Security/EndOfLifeServiceTest.php | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tests/Components/Security/EndOfLifeServiceTest.php diff --git a/src/Components/Security/EndOfLifeService.php b/src/Components/Security/EndOfLifeService.php index e57dc658..a2209723 100644 --- a/src/Components/Security/EndOfLifeService.php +++ b/src/Components/Security/EndOfLifeService.php @@ -129,7 +129,7 @@ private function normalizeEntry(array $entry): array $support = $entry['support'] ?? null; $supportEnded = false; - if ($support === true) { + if ($support === false) { $supportEnded = true; } elseif (\is_string($support) && $support !== '') { try { diff --git a/tests/Components/Security/EndOfLifeServiceTest.php b/tests/Components/Security/EndOfLifeServiceTest.php new file mode 100644 index 00000000..f69dda3d --- /dev/null +++ b/tests/Components/Security/EndOfLifeServiceTest.php @@ -0,0 +1,67 @@ + '9.7', 'eol' => '2034-04-21', 'latest' => '9.7.2']; + if ($support !== null) { + $entry['support'] = $support; + } + + $cycle = $this->getCycle($entry); + + static::assertNotNull($cycle); + static::assertSame($expectedSupportEnded, $cycle['supportEnded']); + } + + public function testApiErrorYieldsNull(): void + { + $client = new MockHttpClient([new MockResponse('', ['http_code' => 500])]); + $service = new EndOfLifeService($client, new ArrayAdapter()); + + static::assertNull($service->getCycle('mysql', '9.7.2')); + } + + public function testUnknownCycleYieldsNull(): void + { + static::assertNull($this->getCycle(['cycle' => '8.0', 'eol' => '2026-04-30']), 'requested cycle 9.7 is not in the payload'); + } + + public static function supportProvider(): iterable + { + yield 'boolean true means active support' => [true, false]; + yield 'boolean false means active support has ended' => [false, true]; + yield 'past date means active support has ended' => ['2020-01-01', true]; + yield 'future date means active support' => ['2099-01-01', false]; + yield 'unparseable date stays not ended' => ['not-a-date', false]; + yield 'absent field stays not ended' => [null, false]; + } + + /** + * @param array $entry + * + * @return array{cycle: string, eol: \DateTimeImmutable|null, eolUnknown: bool, supportEnded: bool, latest: string|null}|null + */ + private function getCycle(array $entry): ?array + { + $client = new MockHttpClient([new MockResponse(json_encode([$entry], \JSON_THROW_ON_ERROR))]); + $service = new EndOfLifeService($client, new ArrayAdapter()); + + return $service->getCycle('mysql', '9.7.2'); + } +}