Doubles
6 days ago
Providers
6 days ago
BulkRearmOnGrowthTest.php
6 days ago
BulkReviewsUpdateStuckStateTest.php
6 days ago
ClearCacheRelayResetTest.php
6 days ago
DeleteSourceRelayFailureTest.php
6 days ago
ErrorHandlerFalsyOptionTest.php
6 days ago
FeedCacheUpdateServiceTest.php
6 days ago
FeedMalformedPayloadTest.php
6 days ago
ForceKeylessRefetchTest.php
6 days ago
LicenseDeactivateStaleStateTest.php
6 days ago
MediaFinderMemoTest.php
6 days ago
MultiSourceAggregationTest.php
6 days ago
ReconcileMigratedLicenseRoutineTest.php
6 days ago
ReconcileRemovalTest.php
6 days ago
RegisterWebsiteRoutineTest.php
6 days ago
RelaySlowEndpointsTest.php
6 days ago
RemoteRequestMemoTest.php
6 days ago
ReviewAlertHeaderTotalsTest.php
6 days ago
ReviewAlertPageTargetingTest.php
6 days ago
ReviewAlertStarFillTest.php
6 days ago
ShortcodeNeutralizationTest.php
6 days ago
SiteMigrationRecoveryTest.php
6 days ago
Smash1130UsageTrackingHardeningTest.php
6 days ago
Smash1130UsageTrackingHooksTest.php
6 days ago
Smash1583HeaderParityTest.php
6 days ago
Smash1631MultiLanguageBulkTest.php
6 days ago
Smash1631UpdateSingleLangScopeTest.php
6 days ago
Smash1706TripAdvisorPlaceIdTest.php
6 days ago
Smash1756SchemaServiceTest.php
6 days ago
Smash1785AvatarLocalUrlGuardTest.php
6 days ago
Smash1785AvatarReHealTest.php
6 days ago
Smash1795ReviewTextXssTest.php
6 days ago
Smash1835TripAdvisorKeyShapeTest.php
6 days ago
Smash1973WordpressOrgPlaceIdNullTest.php
6 days ago
Smash1987NestedSourceErrorShapeTest.php
6 days ago
Smash782BookingHeaderRatingTest.php
6 days ago
Smash782CountryFlagEmojiTest.php
6 days ago
Smash782ExternalRefreshCronTest.php
6 days ago
Smash782ExtrasTemplateTest.php
6 days ago
Smash782ReviewAlertProviderDataTest.php
6 days ago
SourceIdLookupTest.php
6 days ago
WpmlGetCurrentLanguageTest.php
6 days ago
WpmlLanguageMappingTest.php
6 days ago
RelaySlowEndpointsTest.php
108 lines
| 1 | <?php |
| 2 | |
| 3 | namespace SmashBalloon\Reviews\Tests\Unit; |
| 4 | |
| 5 | use PHPUnit\Framework\TestCase; |
| 6 | |
| 7 | /** |
| 8 | * SBRelay::$slow_endpoints raises the HTTP timeout from WP's 5s default to 120s. |
| 9 | * TripAdvisor was missing from it, which was survivable while one request meant |
| 10 | * one upstream call — and stopped being survivable when SMASH-1835 turned it into |
| 11 | * a legacy -> Terra -> RapidAPI chain. Measured on staging 2026-08-21: a chained |
| 12 | * reviews fetch died with `cURL error 28: Operation timed out after 5000 |
| 13 | * milliseconds with 0 bytes received`, while the calls that did land took 1.8s to |
| 14 | * 4.4s — already at the ceiling. |
| 15 | * |
| 16 | * Source-level assertions: the plugin unit suite runs on plain PHPUnit with no WP |
| 17 | * test framework, and SBRelay's constructor reads options, so the list is checked |
| 18 | * where it is declared. |
| 19 | */ |
| 20 | final class RelaySlowEndpointsTest extends TestCase |
| 21 | { |
| 22 | /** @return list<string> */ |
| 23 | private static function slowEndpoints(): array |
| 24 | { |
| 25 | $path = __DIR__ . '/../../class/Common/Integrations/SBRelay.php'; |
| 26 | self::assertFileExists($path, 'SBRelay.php not found at expected path'); |
| 27 | |
| 28 | $src = (string) file_get_contents($path); |
| 29 | |
| 30 | $start = strpos($src, '$this->slow_endpoints = ['); |
| 31 | self::assertNotFalse($start, 'slow_endpoints must still be declared in SBRelay'); |
| 32 | |
| 33 | $end = strpos($src, '];', $start); |
| 34 | self::assertNotFalse($end, 'slow_endpoints declaration must be terminated'); |
| 35 | |
| 36 | $block = substr($src, $start, $end - $start); |
| 37 | |
| 38 | // Strip comments first: an apostrophe in prose (`WP's`) would otherwise be |
| 39 | // read as a string delimiter and desynchronise every match after it. Block |
| 40 | // comments included, so a commented-out endpoint cannot count as present. |
| 41 | $block = (string) preg_replace('#/\*.*?\*/#s', '', $block); |
| 42 | $block = (string) preg_replace('#//[^\n]*#', '', $block); |
| 43 | |
| 44 | preg_match_all("/'([^']+)'/", $block, $matches); |
| 45 | |
| 46 | return $matches[1]; |
| 47 | } |
| 48 | |
| 49 | public function test_tripadvisor_reviews_and_sources_get_the_longer_timeout(): void |
| 50 | { |
| 51 | $endpoints = self::slowEndpoints(); |
| 52 | |
| 53 | $this->assertContains( |
| 54 | 'reviews/tripadvisor', |
| 55 | $endpoints, |
| 56 | 'The fallback chain can cost three upstream hops; 5s cuts it off mid-chain.' |
| 57 | ); |
| 58 | $this->assertContains( |
| 59 | 'sources/tripadvisor', |
| 60 | $endpoints, |
| 61 | 'Source lookups walk the same chain as reviews.' |
| 62 | ); |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * The bug was not "TripAdvisor was forgotten" so much as "nothing said the |
| 67 | * pair had to move together". Every relay-proxied provider in the list needs |
| 68 | * both halves: a source that resolves but whose reviews time out is an empty |
| 69 | * feed with no error. |
| 70 | */ |
| 71 | public function test_every_listed_provider_has_both_halves(): void |
| 72 | { |
| 73 | $endpoints = self::slowEndpoints(); |
| 74 | |
| 75 | $providers = []; |
| 76 | foreach ($endpoints as $endpoint) { |
| 77 | // booking/resolve is a third, provider-specific route; auth/license |
| 78 | // is not a provider at all. |
| 79 | if (substr_count($endpoint, '/') !== 1) { |
| 80 | continue; |
| 81 | } |
| 82 | |
| 83 | list($kind, $provider) = explode('/', $endpoint); |
| 84 | |
| 85 | if ($kind !== 'sources' && $kind !== 'reviews') { |
| 86 | continue; |
| 87 | } |
| 88 | |
| 89 | $providers[$provider][$kind] = true; |
| 90 | } |
| 91 | |
| 92 | $this->assertNotEmpty($providers, 'Parsed no providers — the parser, not the list, is wrong.'); |
| 93 | |
| 94 | foreach ($providers as $provider => $halves) { |
| 95 | $this->assertArrayHasKey( |
| 96 | 'sources', |
| 97 | $halves, |
| 98 | sprintf('%s has reviews/ in slow_endpoints but not sources/.', $provider) |
| 99 | ); |
| 100 | $this->assertArrayHasKey( |
| 101 | 'reviews', |
| 102 | $halves, |
| 103 | sprintf('%s has sources/ in slow_endpoints but not reviews/.', $provider) |
| 104 | ); |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 |