From 675802e8e5dd5bf4f02a34de0fa443b9a4603ff1 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Sun, 8 Mar 2026 14:33:54 +0100 Subject: [PATCH] 25 - Move PHPStan ignores to baseline, fix HttpFetcher type --- app/Services/Http/HttpFetcher.php | 2 +- phpstan-baseline.neon | 115 ++++++++++++++++++ phpstan.neon | 1 + tests/Feature/DatabaseIntegrationTest.php | 2 +- .../Unit/Actions/CreateChannelActionTest.php | 4 +- tests/Unit/Actions/CreateFeedActionTest.php | 4 +- tests/Unit/Actions/CreateRouteActionTest.php | 2 +- tests/Unit/Enums/LogLevelEnumTest.php | 4 +- tests/Unit/Enums/PlatformEnumTest.php | 2 +- tests/Unit/Models/FeedTest.php | 6 +- tests/Unit/Models/PlatformAccountTest.php | 12 +- tests/Unit/Models/PlatformChannelTest.php | 18 +-- tests/Unit/Models/PlatformInstanceTest.php | 16 +-- tests/Unit/Models/RouteTest.php | 2 +- tests/Unit/Services/ArticleFetcherTest.php | 2 +- 15 files changed, 154 insertions(+), 38 deletions(-) create mode 100644 phpstan-baseline.neon diff --git a/app/Services/Http/HttpFetcher.php b/app/Services/Http/HttpFetcher.php index 723c138..1caa6a6 100644 --- a/app/Services/Http/HttpFetcher.php +++ b/app/Services/Http/HttpFetcher.php @@ -48,7 +48,7 @@ public static function fetchMultipleUrls(array $urls): array ->reject(fn ($response, $index) => $response instanceof Exception) ->map(function ($response, $index) use ($urls) { $url = $urls[$index]; - + /** @var \Illuminate\Http\Client\Response $response */ try { if ($response->successful()) { return [ diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..f34b7da --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,115 @@ +parameters: + ignoreErrors: + - + message: '#^Call to an undefined static method App\\Models\\Feed\:\:withTrashed\(\)\.$#' + identifier: staticMethod.notFound + count: 1 + path: tests/Feature/DatabaseIntegrationTest.php + + - + message: '#^Access to an undefined property App\\Models\\PlatformAccount\:\:\$pivot\.$#' + identifier: property.notFound + count: 1 + path: tests/Unit/Actions/CreateChannelActionTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertNull\(\) with int will always evaluate to false\.$#' + identifier: method.impossibleType + count: 1 + path: tests/Unit/Actions/CreateChannelActionTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertNull\(\) with string will always evaluate to false\.$#' + identifier: method.impossibleType + count: 2 + path: tests/Unit/Actions/CreateFeedActionTest.php + + - + message: '#^Access to an undefined property App\\Models\\Route\:\:\$id\.$#' + identifier: property.notFound + count: 2 + path: tests/Unit/Actions/CreateRouteActionTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertFalse\(\) with false will always evaluate to false\.$#' + identifier: method.impossibleType + count: 1 + path: tests/Unit/Enums/LogLevelEnumTest.php + + - + message: '#^Strict comparison using \=\=\= between App\\Enums\\LogLevelEnum\:\:DEBUG and App\\Enums\\LogLevelEnum\:\:DEBUG will always evaluate to true\.$#' + identifier: identical.alwaysTrue + count: 1 + path: tests/Unit/Enums/LogLevelEnumTest.php + + - + message: '#^Strict comparison using \=\=\= between App\\Enums\\LogLevelEnum\:\:DEBUG and App\\Enums\\LogLevelEnum\:\:INFO will always evaluate to false\.$#' + identifier: identical.alwaysFalse + count: 1 + path: tests/Unit/Enums/LogLevelEnumTest.php + + - + message: '#^Strict comparison using \=\=\= between App\\Enums\\PlatformEnum\:\:LEMMY and App\\Enums\\PlatformEnum\:\:LEMMY will always evaluate to true\.$#' + identifier: identical.alwaysTrue + count: 1 + path: tests/Unit/Enums/PlatformEnumTest.php + + - + message: '#^Access to an undefined property App\\Models\\PlatformChannel\:\:\$pivot\.$#' + identifier: property.notFound + count: 2 + path: tests/Unit/Models/FeedTest.php + + - + message: '#^Right side of \|\| is always true\.$#' + identifier: booleanOr.rightAlwaysTrue + count: 1 + path: tests/Unit/Models/FeedTest.php + + - + message: '#^Access to an undefined property App\\Models\\PlatformChannel\:\:\$pivot\.$#' + identifier: property.notFound + count: 6 + path: tests/Unit/Models/PlatformAccountTest.php + + - + message: '#^Access to an undefined property App\\Models\\Feed\:\:\$pivot\.$#' + identifier: property.notFound + count: 2 + path: tests/Unit/Models/PlatformChannelTest.php + + - + message: '#^Access to an undefined property App\\Models\\PlatformAccount\:\:\$pivot\.$#' + identifier: property.notFound + count: 6 + path: tests/Unit/Models/PlatformChannelTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertIsString\(\) with int will always evaluate to false\.$#' + identifier: method.impossibleType + count: 1 + path: tests/Unit/Models/PlatformChannelTest.php + + - + message: '#^Access to an undefined property App\\Models\\Language\:\:\$pivot\.$#' + identifier: property.notFound + count: 7 + path: tests/Unit/Models/PlatformInstanceTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertNull\(\) with string will always evaluate to false\.$#' + identifier: method.impossibleType + count: 1 + path: tests/Unit/Models/PlatformInstanceTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertNull\(\) with string will always evaluate to false\.$#' + identifier: method.impossibleType + count: 1 + path: tests/Unit/Models/RouteTest.php + + - + message: '#^Call to method PHPUnit\\Framework\\Assert\:\:assertNull\(\) with int will always evaluate to false\.$#' + identifier: method.impossibleType + count: 1 + path: tests/Unit/Services/ArticleFetcherTest.php diff --git a/phpstan.neon b/phpstan.neon index dd69d17..eb281c6 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,7 @@ includes: - vendor/larastan/larastan/extension.neon - vendor/phpstan/phpstan-mockery/extension.neon + - phpstan-baseline.neon parameters: level: 7 diff --git a/tests/Feature/DatabaseIntegrationTest.php b/tests/Feature/DatabaseIntegrationTest.php index 6b70806..e7c9a1d 100644 --- a/tests/Feature/DatabaseIntegrationTest.php +++ b/tests/Feature/DatabaseIntegrationTest.php @@ -327,7 +327,7 @@ public function test_model_soft_deletes_work_correctly(): void // Should find with withTrashed if model uses soft deletes if (method_exists($feed, 'withTrashed')) { - $this->assertNotNull(Feed::withTrashed()->find($feedId)); // @phpstan-ignore staticMethod.notFound + $this->assertNotNull(Feed::withTrashed()->find($feedId)); } } diff --git a/tests/Unit/Actions/CreateChannelActionTest.php b/tests/Unit/Actions/CreateChannelActionTest.php index 7783a89..06160f7 100644 --- a/tests/Unit/Actions/CreateChannelActionTest.php +++ b/tests/Unit/Actions/CreateChannelActionTest.php @@ -44,7 +44,7 @@ public function test_creates_channel_and_attaches_account(): void // Verify account is attached $this->assertTrue($channel->platformAccounts->contains($account)); - $this->assertEquals(1, $channel->platformAccounts->first()->pivot->priority); // @phpstan-ignore property.notFound + $this->assertEquals(1, $channel->platformAccounts->first()->pivot->priority); } public function test_creates_channel_without_language(): void @@ -57,7 +57,7 @@ public function test_creates_channel_without_language(): void $channel = $this->action->execute('test_community', $instance->id); - $this->assertNull($channel->language_id); // @phpstan-ignore method.impossibleType + $this->assertNull($channel->language_id); } public function test_fails_when_no_active_accounts(): void diff --git a/tests/Unit/Actions/CreateFeedActionTest.php b/tests/Unit/Actions/CreateFeedActionTest.php index 6649fef..3cc6013 100644 --- a/tests/Unit/Actions/CreateFeedActionTest.php +++ b/tests/Unit/Actions/CreateFeedActionTest.php @@ -45,7 +45,7 @@ public function test_creates_belga_feed_with_correct_url(): void $this->assertEquals('https://www.belganewsagency.eu/', $feed->url); $this->assertEquals('website', $feed->type); $this->assertEquals('belga', $feed->provider); - $this->assertNull($feed->description); // @phpstan-ignore method.impossibleType + $this->assertNull($feed->description); } public function test_creates_guardian_feed_with_correct_url(): void @@ -57,7 +57,7 @@ public function test_creates_guardian_feed_with_correct_url(): void $this->assertEquals('https://www.theguardian.com/international/rss', $feed->url); $this->assertEquals('rss', $feed->type); $this->assertEquals('guardian', $feed->provider); - $this->assertNull($feed->description); // @phpstan-ignore method.impossibleType + $this->assertNull($feed->description); } public function test_creates_vrt_feed_with_dutch_language(): void diff --git a/tests/Unit/Actions/CreateRouteActionTest.php b/tests/Unit/Actions/CreateRouteActionTest.php index 4b3a7e2..2bfa248 100644 --- a/tests/Unit/Actions/CreateRouteActionTest.php +++ b/tests/Unit/Actions/CreateRouteActionTest.php @@ -69,7 +69,7 @@ public function test_returns_existing_route_for_duplicate_feed_channel_pair(): v $first = $this->action->execute($feed->id, $channel->id, 10); $second = $this->action->execute($feed->id, $channel->id, 99); - $this->assertEquals($first->id, $second->id); // @phpstan-ignore property.notFound, property.notFound + $this->assertEquals($first->id, $second->id); $this->assertEquals(10, $second->priority); $this->assertDatabaseCount('routes', 1); } diff --git a/tests/Unit/Enums/LogLevelEnumTest.php b/tests/Unit/Enums/LogLevelEnumTest.php index fb35642..bb127a1 100644 --- a/tests/Unit/Enums/LogLevelEnumTest.php +++ b/tests/Unit/Enums/LogLevelEnumTest.php @@ -83,8 +83,8 @@ public function test_enum_can_be_compared(): void $debug2 = LogLevelEnum::DEBUG; $info = LogLevelEnum::INFO; - $this->assertTrue($debug1 === $debug2); // @phpstan-ignore identical.alwaysTrue - $this->assertFalse($debug1 === $info); // @phpstan-ignore identical.alwaysFalse, method.impossibleType + $this->assertTrue($debug1 === $debug2); + $this->assertFalse($debug1 === $info); } public function test_enum_can_be_used_in_match_expression(): void diff --git a/tests/Unit/Enums/PlatformEnumTest.php b/tests/Unit/Enums/PlatformEnumTest.php index 61e0047..9825453 100644 --- a/tests/Unit/Enums/PlatformEnumTest.php +++ b/tests/Unit/Enums/PlatformEnumTest.php @@ -54,7 +54,7 @@ public function test_enum_can_be_compared(): void $lemmy1 = PlatformEnum::LEMMY; $lemmy2 = PlatformEnum::LEMMY; - $this->assertTrue($lemmy1 === $lemmy2); // @phpstan-ignore identical.alwaysTrue + $this->assertTrue($lemmy1 === $lemmy2); } public function test_enum_can_be_used_in_match_expression(): void diff --git a/tests/Unit/Models/FeedTest.php b/tests/Unit/Models/FeedTest.php index 039713d..da959f8 100644 --- a/tests/Unit/Models/FeedTest.php +++ b/tests/Unit/Models/FeedTest.php @@ -171,8 +171,8 @@ public function test_belongs_to_many_channels_relationship(): void // Test pivot data $channel1FromRelation = $channels->find($channel1->id); - $this->assertEquals(1, $channel1FromRelation->pivot->is_active); // @phpstan-ignore property.notFound - $this->assertEquals(100, $channel1FromRelation->pivot->priority); // @phpstan-ignore property.notFound + $this->assertEquals(1, $channel1FromRelation->pivot->is_active); + $this->assertEquals(100, $channel1FromRelation->pivot->priority); } public function test_active_channels_relationship(): void @@ -226,7 +226,7 @@ public function test_feed_creation_with_factory(): void $this->assertIsString($feed->url); $this->assertIsString($feed->type); // Language ID may be null as it's nullable in the database - $this->assertTrue($feed->language_id === null || is_int($feed->language_id)); // @phpstan-ignore booleanOr.rightAlwaysTrue + $this->assertTrue($feed->language_id === null || is_int($feed->language_id)); $this->assertIsBool($feed->is_active); $this->assertIsArray($feed->settings); } diff --git a/tests/Unit/Models/PlatformAccountTest.php b/tests/Unit/Models/PlatformAccountTest.php index d74f1a8..c3e351e 100644 --- a/tests/Unit/Models/PlatformAccountTest.php +++ b/tests/Unit/Models/PlatformAccountTest.php @@ -196,12 +196,12 @@ public function test_belongs_to_many_channels_relationship(): void // Test pivot data $channel1FromRelation = $channels->find($channel1->id); - $this->assertEquals(1, $channel1FromRelation->pivot->is_active); // @phpstan-ignore property.notFound - $this->assertEquals(100, $channel1FromRelation->pivot->priority); // @phpstan-ignore property.notFound + $this->assertEquals(1, $channel1FromRelation->pivot->is_active); + $this->assertEquals(100, $channel1FromRelation->pivot->priority); $channel2FromRelation = $channels->find($channel2->id); - $this->assertEquals(0, $channel2FromRelation->pivot->is_active); // @phpstan-ignore property.notFound - $this->assertEquals(50, $channel2FromRelation->pivot->priority); // @phpstan-ignore property.notFound + $this->assertEquals(0, $channel2FromRelation->pivot->is_active); + $this->assertEquals(50, $channel2FromRelation->pivot->priority); } public function test_active_channels_relationship(): void @@ -392,8 +392,8 @@ public function test_account_can_have_multiple_channels_with_different_prioritie // Test that we can access pivot data foreach ($allChannels as $channel) { - $this->assertNotNull($channel->pivot->priority); // @phpstan-ignore property.notFound - $this->assertIsInt($channel->pivot->is_active); // @phpstan-ignore property.notFound + $this->assertNotNull($channel->pivot->priority); + $this->assertIsInt($channel->pivot->is_active); } } diff --git a/tests/Unit/Models/PlatformChannelTest.php b/tests/Unit/Models/PlatformChannelTest.php index 2c83f7f..9d08a2e 100644 --- a/tests/Unit/Models/PlatformChannelTest.php +++ b/tests/Unit/Models/PlatformChannelTest.php @@ -89,12 +89,12 @@ public function test_belongs_to_many_platform_accounts_relationship(): void // Test pivot data $account1FromRelation = $accounts->find($account1->id); - $this->assertEquals(1, $account1FromRelation->pivot->is_active); // @phpstan-ignore property.notFound - $this->assertEquals(100, $account1FromRelation->pivot->priority); // @phpstan-ignore property.notFound + $this->assertEquals(1, $account1FromRelation->pivot->is_active); + $this->assertEquals(100, $account1FromRelation->pivot->priority); $account2FromRelation = $accounts->find($account2->id); - $this->assertEquals(0, $account2FromRelation->pivot->is_active); // @phpstan-ignore property.notFound - $this->assertEquals(50, $account2FromRelation->pivot->priority); // @phpstan-ignore property.notFound + $this->assertEquals(0, $account2FromRelation->pivot->is_active); + $this->assertEquals(50, $account2FromRelation->pivot->priority); } public function test_active_platform_accounts_relationship(): void @@ -168,8 +168,8 @@ public function test_belongs_to_many_feeds_relationship(): void // Test pivot data $feed1FromRelation = $feeds->find($feed1->id); - $this->assertEquals(1, $feed1FromRelation->pivot->is_active); // @phpstan-ignore property.notFound - $this->assertEquals(100, $feed1FromRelation->pivot->priority); // @phpstan-ignore property.notFound + $this->assertEquals(1, $feed1FromRelation->pivot->is_active); + $this->assertEquals(100, $feed1FromRelation->pivot->priority); } public function test_active_feeds_relationship(): void @@ -221,7 +221,7 @@ public function test_channel_creation_with_factory(): void $this->assertInstanceOf(PlatformChannel::class, $channel); $this->assertNotNull($channel->platform_instance_id); $this->assertIsString($channel->name); - $this->assertIsString($channel->channel_id); // @phpstan-ignore method.impossibleType + $this->assertIsString($channel->channel_id); $this->assertIsBool($channel->is_active); } @@ -331,8 +331,8 @@ public function test_channel_can_have_multiple_accounts_with_different_prioritie // Test that we can access pivot data foreach ($allAccounts as $account) { - $this->assertNotNull($account->pivot->priority); // @phpstan-ignore property.notFound - $this->assertIsInt($account->pivot->is_active); // @phpstan-ignore property.notFound + $this->assertNotNull($account->pivot->priority); + $this->assertIsInt($account->pivot->is_active); } } } diff --git a/tests/Unit/Models/PlatformInstanceTest.php b/tests/Unit/Models/PlatformInstanceTest.php index 7d55a42..296515f 100644 --- a/tests/Unit/Models/PlatformInstanceTest.php +++ b/tests/Unit/Models/PlatformInstanceTest.php @@ -95,12 +95,12 @@ public function test_belongs_to_many_languages_relationship(): void // Test pivot data $language1FromRelation = $languages->find($language1->id); - $this->assertEquals(1, $language1FromRelation->pivot->platform_language_id); // @phpstan-ignore property.notFound - $this->assertEquals(1, $language1FromRelation->pivot->is_default); // @phpstan-ignore property.notFound + $this->assertEquals(1, $language1FromRelation->pivot->platform_language_id); + $this->assertEquals(1, $language1FromRelation->pivot->is_default); $language2FromRelation = $languages->find($language2->id); - $this->assertEquals(2, $language2FromRelation->pivot->platform_language_id); // @phpstan-ignore property.notFound - $this->assertEquals(0, $language2FromRelation->pivot->is_default); // @phpstan-ignore property.notFound + $this->assertEquals(2, $language2FromRelation->pivot->platform_language_id); + $this->assertEquals(0, $language2FromRelation->pivot->is_default); } public function test_find_by_url_static_method(): void @@ -219,7 +219,7 @@ public function test_instance_can_have_null_description(): void { $instance = PlatformInstance::factory()->create(['description' => null]); - $this->assertNull($instance->description); // @phpstan-ignore method.impossibleType + $this->assertNull($instance->description); } public function test_instance_can_have_empty_description(): void @@ -274,12 +274,12 @@ public function test_instance_can_have_multiple_languages(): void // Test that we can access pivot data foreach ($languages as $language) { - $this->assertNotNull($language->pivot->platform_language_id); // @phpstan-ignore property.notFound - $this->assertContains($language->pivot->is_default, [0, 1, true, false]); // @phpstan-ignore property.notFound + $this->assertNotNull($language->pivot->platform_language_id); + $this->assertContains($language->pivot->is_default, [0, 1, true, false]); } // Only one should be default - $defaultLanguages = $languages->filter(fn ($lang) => $lang->pivot->is_default); // @phpstan-ignore property.notFound + $defaultLanguages = $languages->filter(fn ($lang) => $lang->pivot->is_default); $this->assertCount(1, $defaultLanguages); } diff --git a/tests/Unit/Models/RouteTest.php b/tests/Unit/Models/RouteTest.php index 43e81a5..1903e43 100644 --- a/tests/Unit/Models/RouteTest.php +++ b/tests/Unit/Models/RouteTest.php @@ -47,7 +47,7 @@ public function test_primary_key_configuration(): void { $route = new Route; - $this->assertNull($route->getKeyName()); // @phpstan-ignore method.impossibleType + $this->assertNull($route->getKeyName()); $this->assertFalse($route->getIncrementing()); } diff --git a/tests/Unit/Services/ArticleFetcherTest.php b/tests/Unit/Services/ArticleFetcherTest.php index 100aa5b..180b099 100644 --- a/tests/Unit/Services/ArticleFetcherTest.php +++ b/tests/Unit/Services/ArticleFetcherTest.php @@ -261,7 +261,7 @@ public function test_save_article_without_feed_id(): void $this->assertInstanceOf(Article::class, $article); $this->assertEquals($url, $article->url); - $this->assertNull($article->feed_id); // @phpstan-ignore method.impossibleType + $this->assertNull($article->feed_id); $this->assertDatabaseHas('articles', ['url' => $url, 'feed_id' => null]); }