Doubles
2 months ago
Providers
2 months ago
BulkReviewsUpdateStuckStateTest.php
2 months ago
ClearCacheRelayResetTest.php
2 months ago
DeleteSourceRelayFailureTest.php
2 months ago
ErrorHandlerFalsyOptionTest.php
2 months ago
FeedCacheUpdateServiceTest.php
2 months ago
FeedMalformedPayloadTest.php
2 months ago
ForceKeylessRefetchTest.php
2 months ago
LicenseDeactivateStaleStateTest.php
2 months ago
MediaFinderMemoTest.php
2 months ago
MultiSourceAggregationTest.php
2 months ago
ReconcileMigratedLicenseRoutineTest.php
2 months ago
ReconcileRemovalTest.php
2 months ago
RegisterWebsiteRoutineTest.php
2 months ago
RemoteRequestMemoTest.php
2 months ago
ReviewAlertHeaderTotalsTest.php
2 months ago
ReviewAlertPageTargetingTest.php
2 months ago
ReviewAlertStarFillTest.php
2 months ago
ShortcodeNeutralizationTest.php
2 months ago
SiteMigrationRecoveryTest.php
2 months ago
Smash1583HeaderParityTest.php
2 months ago
SourceIdLookupTest.php
2 months ago
WpmlGetCurrentLanguageTest.php
2 months ago
WpmlLanguageMappingTest.php
2 months ago
ClearCacheRelayResetTest.php
96 lines
| 1 | <?php |
| 2 | |
| 3 | namespace SmashBalloon\Reviews\Tests\Unit; |
| 4 | |
| 5 | use PHPUnit\Framework\TestCase; |
| 6 | |
| 7 | /** |
| 8 | * Pins the SMASH-1614 follow-up: a user-initiated "Clear All Caches" tells the |
| 9 | * relay to clear the per-source weekly fetch window, so the immediate refresh |
| 10 | * that follows can actually refetch instead of being blocked by the once-per-week |
| 11 | * Pro update cap (which would otherwise leave the feed empty for up to 7 days |
| 12 | * after the local cache is wiped). |
| 13 | * |
| 14 | * These are source-level guards (the plugin unit suite runs on plain PHPUnit |
| 15 | * without the WP test framework, so clear_all_caches() — which calls wp_die / |
| 16 | * ajax / relay — can't be invoked directly). They protect the wiring, |
| 17 | * ordering, endpoint, filter gate, and best-effort safety from regression. |
| 18 | */ |
| 19 | final class ClearCacheRelayResetTest extends TestCase |
| 20 | { |
| 21 | private static function saverSource(): string |
| 22 | { |
| 23 | $path = __DIR__ . '/../../class/Common/Builder/SBR_Feed_Saver_Manager.php'; |
| 24 | self::assertFileExists($path, 'SBR_Feed_Saver_Manager.php not found at expected path'); |
| 25 | |
| 26 | return (string) file_get_contents($path); |
| 27 | } |
| 28 | |
| 29 | /** Just the body of clear_all_caches(), so ordering assertions are scoped. */ |
| 30 | private static function clearAllCachesBody(): string |
| 31 | { |
| 32 | $src = self::saverSource(); |
| 33 | $start = strpos($src, 'function clear_all_caches'); |
| 34 | self::assertNotFalse($start, 'clear_all_caches() must exist'); |
| 35 | // Slice a generous window that covers the method body. |
| 36 | return substr($src, $start, 1600); |
| 37 | } |
| 38 | |
| 39 | public function test_clear_all_caches_calls_relay_fetch_window_reset(): void |
| 40 | { |
| 41 | $this->assertStringContainsString( |
| 42 | 'self::reset_relay_fetch_window()', |
| 43 | self::clearAllCachesBody(), |
| 44 | 'Clear All Caches must trigger the relay fetch-window reset.' |
| 45 | ); |
| 46 | } |
| 47 | |
| 48 | public function test_reset_is_gated_by_a_filter(): void |
| 49 | { |
| 50 | $this->assertStringContainsString( |
| 51 | "apply_filters('sbr_reset_relay_fetch_window_on_clear', true)", |
| 52 | self::clearAllCachesBody(), |
| 53 | 'The relay reset must be filterable so support can disable it without a redeploy.' |
| 54 | ); |
| 55 | } |
| 56 | |
| 57 | public function test_reset_runs_before_the_immediate_refresh(): void |
| 58 | { |
| 59 | // Compare the unique call sites in the full source (window-independent): |
| 60 | // the reset must be invoked before the refresh, or the cron fetches the |
| 61 | // refresh schedules still hit the weekly wall. |
| 62 | $src = self::saverSource(); |
| 63 | $resetPos = strpos($src, 'self::reset_relay_fetch_window()'); |
| 64 | $refreshPos = strpos($src, 'self::trigger_immediate_refresh()'); |
| 65 | |
| 66 | $this->assertNotFalse($resetPos, 'reset_relay_fetch_window() must be called'); |
| 67 | $this->assertNotFalse($refreshPos, 'trigger_immediate_refresh() must be called'); |
| 68 | $this->assertLessThan( |
| 69 | $refreshPos, |
| 70 | $resetPos, |
| 71 | 'The relay window reset must run BEFORE the immediate refresh.' |
| 72 | ); |
| 73 | } |
| 74 | |
| 75 | public function test_helper_posts_to_the_correct_relay_endpoint(): void |
| 76 | { |
| 77 | $src = self::saverSource(); |
| 78 | $this->assertStringContainsString( |
| 79 | "->call('source/reset-fetch-window', [], 'POST', true)", |
| 80 | $src, |
| 81 | 'The reset must POST to source/reset-fetch-window with auth.' |
| 82 | ); |
| 83 | } |
| 84 | |
| 85 | public function test_helper_is_best_effort_and_cannot_block_clear(): void |
| 86 | { |
| 87 | $src = self::saverSource(); |
| 88 | $start = strpos($src, 'function reset_relay_fetch_window'); |
| 89 | $this->assertNotFalse($start, 'reset_relay_fetch_window() helper must exist'); |
| 90 | $body = substr($src, $start, 500); |
| 91 | |
| 92 | $this->assertStringContainsString('try {', $body, 'The relay call must be wrapped in try/catch.'); |
| 93 | $this->assertStringContainsString('catch (\Throwable', $body, 'A relay failure must never block Clear All Caches.'); |
| 94 | } |
| 95 | } |
| 96 |