PluginProbe ʕ •ᴥ•ʔ
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More / 2.11.0
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More v2.11.0
2.11.0 2.10.0 2.9.0 2.8.0 2.7.0 2.6.7 2.6.8 2.6.5 2.6.4 2.6.3 2.6.2 2.6.0 2.5.5 2.5.4 2.5.3 2.5.2 trunk 1.0 1.0.1 1.0.2 1.0.3 1.1 1.1.1 1.1.2 1.2.0 2.0 2.1.0 2.1.1 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5.0 2.5.1
reviews-feed / tests / Unit / Smash782ExternalRefreshCronTest.php
reviews-feed / tests / Unit Last commit date
Doubles 1 week ago Providers 1 week ago BulkRearmOnGrowthTest.php 1 week ago BulkReviewsUpdateStuckStateTest.php 1 week ago ClearCacheRelayResetTest.php 1 week ago DeleteSourceRelayFailureTest.php 1 week ago ErrorHandlerFalsyOptionTest.php 1 week ago FeedCacheUpdateServiceTest.php 1 week ago FeedMalformedPayloadTest.php 1 week ago ForceKeylessRefetchTest.php 1 week ago LicenseDeactivateStaleStateTest.php 1 week ago MediaFinderMemoTest.php 1 week ago MultiSourceAggregationTest.php 1 week ago ReconcileMigratedLicenseRoutineTest.php 1 week ago ReconcileRemovalTest.php 1 week ago RegisterWebsiteRoutineTest.php 1 week ago RelaySlowEndpointsTest.php 1 week ago RemoteRequestMemoTest.php 1 week ago ReviewAlertHeaderTotalsTest.php 1 week ago ReviewAlertPageTargetingTest.php 1 week ago ReviewAlertStarFillTest.php 1 week ago ShortcodeNeutralizationTest.php 1 week ago SiteMigrationRecoveryTest.php 1 week ago Smash1130UsageTrackingHardeningTest.php 1 week ago Smash1130UsageTrackingHooksTest.php 1 week ago Smash1583HeaderParityTest.php 1 week ago Smash1631MultiLanguageBulkTest.php 1 week ago Smash1631UpdateSingleLangScopeTest.php 1 week ago Smash1706TripAdvisorPlaceIdTest.php 1 week ago Smash1756SchemaServiceTest.php 1 week ago Smash1785AvatarLocalUrlGuardTest.php 1 week ago Smash1785AvatarReHealTest.php 1 week ago Smash1795ReviewTextXssTest.php 1 week ago Smash1835TripAdvisorKeyShapeTest.php 1 week ago Smash1973WordpressOrgPlaceIdNullTest.php 1 week ago Smash1987NestedSourceErrorShapeTest.php 1 week ago Smash782BookingHeaderRatingTest.php 1 week ago Smash782CountryFlagEmojiTest.php 1 week ago Smash782ExternalRefreshCronTest.php 1 week ago Smash782ExtrasTemplateTest.php 1 week ago Smash782ReviewAlertProviderDataTest.php 1 week ago SourceIdLookupTest.php 1 week ago WpmlGetCurrentLanguageTest.php 1 week ago WpmlLanguageMappingTest.php 1 week ago
Smash782ExternalRefreshCronTest.php
137 lines
1 <?php
2
3 namespace SmashBalloon\Reviews\Tests\Unit;
4
5 use PHPUnit\Framework\TestCase;
6 use SmashBalloon\Reviews\Pro\Services\BulkUpdate\Bulk_External_Reviews_Update;
7
8 /**
9 * SMASH-782 — recurring "grow the feed" refresh for external providers.
10 *
11 * External providers (Airbnb, Booking, AliExpress) store reviews in the DB via a
12 * ONE-SHOT bulk cron and were then frozen until a manual Clear Cache — unlike keyed
13 * providers, which pick up new reviews through the hourly sbr_feed_update ->
14 * Feed::get_set_cache() API re-fetch. This recurring event periodically re-arms the
15 * bulk fetch so new reviews keep flowing in.
16 *
17 * These pin the scheduling contract (weekly default, idempotency, filterable
18 * cadence, safe fallback) and that the handler re-arms sources without deleting
19 * reviews.
20 *
21 * @group cron
22 * @group smash-782
23 */
24 class Smash782ExternalRefreshCronTest extends TestCase
25 {
26 protected function setUp(): void
27 {
28 parent::setUp();
29 global $wp_options_mock, $wp_scheduled_events_mock, $wp_filter_mock;
30 $wp_options_mock = [];
31 $wp_scheduled_events_mock = [];
32 $wp_filter_mock = [];
33 }
34
35 private function scheduled(): ?array
36 {
37 global $wp_scheduled_events_mock;
38 return $wp_scheduled_events_mock[Bulk_External_Reviews_Update::REFRESH_CRON_NAME] ?? null;
39 }
40
41 private function setTier(int $tier): void
42 {
43 global $wp_options_mock;
44 $wp_options_mock['sbr_statuses'] = ['license_tier' => $tier];
45 }
46
47 // --- scheduling ---------------------------------------------------------------
48
49 public function test_default_cadence_is_daily_below_elite(): void
50 {
51 // Manage Caching UI promises "daily" for non-Elite tiers.
52 $this->setTier(2);
53 $this->assertFalse(wp_next_scheduled(Bulk_External_Reviews_Update::REFRESH_CRON_NAME));
54
55 Bulk_External_Reviews_Update::schedule_refresh_cron();
56
57 $event = $this->scheduled();
58 $this->assertIsArray($event, 'A recurring event must be scheduled.');
59 $this->assertSame('daily', $event['recurrence']);
60 // First run staggered ~1 hour out so it never piles onto the add-source bulk.
61 $this->assertGreaterThanOrEqual(time() + HOUR_IN_SECONDS - 5, $event['timestamp']);
62 $this->assertLessThanOrEqual(time() + HOUR_IN_SECONDS + 5, $event['timestamp']);
63 }
64
65 public function test_default_cadence_is_twicedaily_on_elite(): void
66 {
67 // Manage Caching UI promises "twice daily for external sources" on Elite (tier 3).
68 $this->setTier(3);
69
70 Bulk_External_Reviews_Update::schedule_refresh_cron();
71
72 $this->assertSame('twicedaily', $this->scheduled()['recurrence']);
73 }
74
75 public function test_scheduling_is_idempotent(): void
76 {
77 Bulk_External_Reviews_Update::schedule_refresh_cron();
78 $first = $this->scheduled();
79
80 // A second admin_init hit must NOT enqueue a duplicate / reschedule.
81 Bulk_External_Reviews_Update::schedule_refresh_cron();
82 $second = $this->scheduled();
83
84 $this->assertSame($first['timestamp'], $second['timestamp']);
85 }
86
87 public function test_recurrence_is_filterable(): void
88 {
89 global $wp_filter_mock;
90 // Override to a value distinct from either tier default to prove the filter wins.
91 $wp_filter_mock['sbr_external_reviews_refresh_recurrence'] = 'weekly';
92
93 Bulk_External_Reviews_Update::schedule_refresh_cron();
94
95 $this->assertSame('weekly', $this->scheduled()['recurrence']);
96 }
97
98 public function test_invalid_filter_value_falls_back_to_tier_default(): void
99 {
100 global $wp_filter_mock;
101 // Tier default (non-Elite) is 'daily'; a misconfigured filter returning an
102 // empty / non-string value must not schedule a garbage recurrence.
103 $this->setTier(0);
104 $wp_filter_mock['sbr_external_reviews_refresh_recurrence'] = '';
105
106 Bulk_External_Reviews_Update::schedule_refresh_cron();
107
108 $this->assertSame('daily', $this->scheduled()['recurrence']);
109 }
110
111 // --- handler re-arms sources --------------------------------------------------
112
113 public function test_periodic_refresh_rearms_completed_sources(): void
114 {
115 global $wp_options_mock;
116 $wp_options_mock['sbr_bulk_external'] = [
117 'booking_15321869' => [
118 'source_id' => '15321869',
119 'provider' => 'booking',
120 'page' => 3,
121 'is_done' => true,
122 'retry' => true,
123 'reviews_fetched' => 50,
124 ],
125 ];
126
127 (new Bulk_External_Reviews_Update())->run_periodic_refresh();
128
129 $state = $wp_options_mock['sbr_bulk_external']['booking_15321869'];
130 $this->assertFalse($state['is_done'], 'Refresh must re-open the completed source.');
131 $this->assertSame(1, $state['page'], 'Refresh must re-fetch from the first page.');
132 $this->assertFalse($state['retry'], 'Retry flag must be cleared on re-arm.');
133 // Re-arm must never wipe the already-fetched tally (reviews are not deleted).
134 $this->assertSame(50, $state['reviews_fetched']);
135 }
136 }
137