Doubles
3 weeks ago
Providers
3 weeks ago
BulkRearmOnGrowthTest.php
3 weeks ago
BulkReviewsUpdateStuckStateTest.php
3 weeks ago
ClearCacheRelayResetTest.php
3 weeks ago
DeleteSourceRelayFailureTest.php
3 weeks ago
ErrorHandlerFalsyOptionTest.php
3 weeks ago
FeedCacheUpdateServiceTest.php
3 weeks ago
FeedMalformedPayloadTest.php
3 weeks ago
ForceKeylessRefetchTest.php
3 weeks ago
LicenseDeactivateStaleStateTest.php
3 weeks ago
MediaFinderMemoTest.php
3 weeks ago
MultiSourceAggregationTest.php
3 weeks ago
ReconcileMigratedLicenseRoutineTest.php
3 weeks ago
ReconcileRemovalTest.php
3 weeks ago
RegisterWebsiteRoutineTest.php
3 weeks ago
RemoteRequestMemoTest.php
3 weeks ago
ReviewAlertHeaderTotalsTest.php
3 weeks ago
ReviewAlertPageTargetingTest.php
3 weeks ago
ReviewAlertStarFillTest.php
3 weeks ago
ShortcodeNeutralizationTest.php
3 weeks ago
SiteMigrationRecoveryTest.php
3 weeks ago
Smash1583HeaderParityTest.php
3 weeks ago
Smash1631MultiLanguageBulkTest.php
3 weeks ago
Smash1631UpdateSingleLangScopeTest.php
3 weeks ago
Smash1706TripAdvisorPlaceIdTest.php
3 weeks ago
Smash1756SchemaServiceTest.php
3 weeks ago
Smash1785AvatarLocalUrlGuardTest.php
3 weeks ago
Smash1785AvatarReHealTest.php
3 weeks ago
Smash1795ReviewTextXssTest.php
3 weeks ago
Smash782BookingHeaderRatingTest.php
3 weeks ago
Smash782CountryFlagEmojiTest.php
3 weeks ago
Smash782ExternalRefreshCronTest.php
3 weeks ago
Smash782ExtrasTemplateTest.php
3 weeks ago
Smash782ReviewAlertProviderDataTest.php
3 weeks ago
SourceIdLookupTest.php
3 weeks ago
WpmlGetCurrentLanguageTest.php
3 weeks ago
WpmlLanguageMappingTest.php
3 weeks ago
Smash1583HeaderParityTest.php
94 lines
| 1 | <?php |
| 2 | |
| 3 | namespace SmashBalloon\Reviews\Tests\Unit; |
| 4 | |
| 5 | use PHPUnit\Framework\TestCase; |
| 6 | |
| 7 | /** |
| 8 | * SMASH-1583 front-end parity guard. |
| 9 | * |
| 10 | * The multi-source feed header must report the COMBINED review count across all |
| 11 | * sources on the front-end, matching the Feed Builder (admin) preview. A bug |
| 12 | * surfaced where a source whose fresh remote fetch was skipped by a rate limit |
| 13 | * — `check_api_limit()` (API-key cap) or `limit_provider_api_calls()` (free-tier |
| 14 | * per-provider call cap, e.g. a keyless Google source that already fetched) — |
| 15 | * was dropped from the header entirely, because `Feed::api_request()`'s two |
| 16 | * limit-skip `continue` paths did NOT fall back to the source's stored `info` |
| 17 | * (unlike the no-data / error paths, which do). Result: the front-end header |
| 18 | * under-counted (e.g. showed one source's 4342 instead of the combined 6091), |
| 19 | * while the admin preview — which always aggregates every source's stored info |
| 20 | * — was correct. The fix routes both limit-skip paths through |
| 21 | * `push_stored_source_info()` so a rate-limited source is still counted. |
| 22 | * |
| 23 | * The plugin unit suite runs on plain PHPUnit (no WP / no full class tree), so |
| 24 | * these are source-level guards that fail if the fallback is removed. |
| 25 | */ |
| 26 | final class Smash1583HeaderParityTest extends TestCase |
| 27 | { |
| 28 | private static function feedSource(): string |
| 29 | { |
| 30 | $path = __DIR__ . '/../../class/Common/Feed.php'; |
| 31 | self::assertFileExists($path, 'Feed.php not found at expected path'); |
| 32 | |
| 33 | return (string) file_get_contents($path); |
| 34 | } |
| 35 | |
| 36 | /** Body of api_request(), so the skip-path assertions are scoped to it. */ |
| 37 | private static function apiRequestBody(): string |
| 38 | { |
| 39 | $src = self::feedSource(); |
| 40 | $start = strpos($src, 'function api_request'); |
| 41 | self::assertNotFalse($start, 'api_request() must exist'); |
| 42 | |
| 43 | return substr($src, $start, 4000); |
| 44 | } |
| 45 | |
| 46 | public function test_helper_exists(): void |
| 47 | { |
| 48 | $this->assertStringContainsString( |
| 49 | 'function push_stored_source_info', |
| 50 | self::feedSource(), |
| 51 | 'The stored-info fallback helper must exist.' |
| 52 | ); |
| 53 | } |
| 54 | |
| 55 | public function test_helper_is_scoped_to_sources_with_info(): void |
| 56 | { |
| 57 | $src = self::feedSource(); |
| 58 | $start = strpos($src, 'function push_stored_source_info'); |
| 59 | $this->assertNotFalse($start); |
| 60 | $body = substr($src, $start, 500); |
| 61 | |
| 62 | $this->assertStringContainsString("\$type !== 'sources'", $body, 'Helper must no-op for review requests.'); |
| 63 | $this->assertStringContainsString("empty(\$request['info'])", $body, 'Helper must no-op when there is no stored info.'); |
| 64 | $this->assertStringContainsString("\$data[] = ['info' => \$info]", $body, 'Helper must push the stored info into the results.'); |
| 65 | } |
| 66 | |
| 67 | public function test_api_key_limit_skip_keeps_the_source(): void |
| 68 | { |
| 69 | $body = self::apiRequestBody(); |
| 70 | $pos = strpos($body, 'check_api_limit('); |
| 71 | $this->assertNotFalse($pos, 'check_api_limit skip must exist'); |
| 72 | // The stored-info fallback must appear within the skip block (before its continue). |
| 73 | $block = substr($body, $pos, 200); |
| 74 | $this->assertStringContainsString( |
| 75 | 'push_stored_source_info', |
| 76 | $block, |
| 77 | 'A source skipped by check_api_limit must still be counted via stored info.' |
| 78 | ); |
| 79 | } |
| 80 | |
| 81 | public function test_provider_call_limit_skip_keeps_the_source(): void |
| 82 | { |
| 83 | $body = self::apiRequestBody(); |
| 84 | $pos = strpos($body, 'limit_provider_api_calls('); |
| 85 | $this->assertNotFalse($pos, 'limit_provider_api_calls skip must exist'); |
| 86 | $block = substr($body, $pos, 200); |
| 87 | $this->assertStringContainsString( |
| 88 | 'push_stored_source_info', |
| 89 | $block, |
| 90 | 'A source skipped by the provider call limit must still be counted via stored info (the SMASH-1583 front-end drop).' |
| 91 | ); |
| 92 | } |
| 93 | } |
| 94 |