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 / ErrorHandlerFalsyOptionTest.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
ErrorHandlerFalsyOptionTest.php
132 lines
1 <?php
2
3 namespace SmashBalloon\Reviews\Tests\Unit;
4
5 use PHPUnit\Framework\TestCase;
6 use SmashBalloon\Reviews\Common\Helpers\SBR_Error_Handler;
7
8 /**
9 * Regression tests for SMASH-1544.
10 *
11 * On PHP 8, when the `sbr_errors` option row EXISTS in the DB but holds a
12 * falsy value (boolean false / '' — corrupted, legacy or third-party write),
13 * get_option('sbr_errors', []) returns that falsy value, NOT the [] default
14 * (the default only fires when the row is absent — see
15 * wp-includes/option.php). The handler then passed that bool to foreach()
16 * and array_push(), producing:
17 *
18 * PHP Warning: foreach() argument must be of type array|object, false given
19 * PHP Fatal error: Uncaught TypeError: array_push(): Argument #1 ($array)
20 * must be of type array, false given
21 *
22 * which took down the feed builder admin page and the WP-Cron cache update.
23 *
24 * These tests drive the falsy-stored-value path. failOnWarning="true" in
25 * phpunit.xml means even the foreach() warning fails the suite pre-fix.
26 *
27 * @group SMASH-1544
28 * @covers \SmashBalloon\Reviews\Common\Helpers\SBR_Error_Handler
29 */
30 class ErrorHandlerFalsyOptionTest extends TestCase
31 {
32 protected function setUp(): void
33 {
34 parent::setUp();
35 global $wp_options_mock;
36 $wp_options_mock = [];
37 }
38
39 protected function tearDown(): void
40 {
41 global $wp_options_mock;
42 $wp_options_mock = [];
43 parent::tearDown();
44 }
45
46 private function sampleError(): array
47 {
48 return [
49 'type' => 'connection',
50 'id' => 'feed_1',
51 'provider' => 'google',
52 'message' => 'API key missing',
53 ];
54 }
55
56 /**
57 * The exact customer condition: option row present, value === false.
58 * Pre-fix this fataled at array_push(false, ...). Post-fix it logs cleanly.
59 */
60 public function test_log_error_does_not_fatal_when_option_stored_as_false(): void
61 {
62 global $wp_options_mock;
63 $wp_options_mock['sbr_errors'] = false;
64
65 SBR_Error_Handler::log_error($this->sampleError());
66
67 $stored = SBR_Error_Handler::get_errors();
68 $this->assertIsArray($stored);
69 $this->assertCount(1, $stored);
70 // @phpstan-ignore-next-line — assertCount above guarantees offset 0; get_errors() returns an untyped array.
71 $this->assertSame('feed_1', $stored[0]['id']);
72 }
73
74 /** Empty-string is the other falsy shape a corrupted option row can take. */
75 public function test_log_error_does_not_fatal_when_option_stored_as_empty_string(): void
76 {
77 global $wp_options_mock;
78 $wp_options_mock['sbr_errors'] = '';
79
80 SBR_Error_Handler::log_error($this->sampleError());
81
82 $this->assertCount(1, SBR_Error_Handler::get_errors());
83 }
84
85 /** get_errors() must always hand back an array, whatever the stored shape. */
86 public function test_get_errors_always_returns_array(): void
87 {
88 // `null` is deliberately omitted: the bootstrap get_option() stub uses
89 // `$wp_options_mock[$option] ?? $default`, so a stored null collapses to
90 // the [] default (same as "option not set") and would not exercise the
91 // is_array() coercion. The remaining falsy/non-array shapes do. SMASH-1544.
92 global $wp_options_mock;
93 foreach ([false, '', 0, 'not-an-array', 42] as $bad) {
94 $wp_options_mock['sbr_errors'] = $bad;
95 $this->assertIsArray(
96 SBR_Error_Handler::get_errors(),
97 'get_errors() must coerce non-array stored value to []'
98 );
99 }
100 }
101
102 /** check_error() must not trip foreach() on a falsy stored value. */
103 public function test_check_error_handles_falsy_option(): void
104 {
105 global $wp_options_mock;
106 $wp_options_mock['sbr_errors'] = false;
107
108 $this->assertSame('not_defined', SBR_Error_Handler::check_error($this->sampleError()));
109 }
110
111 /**
112 * BC: the normal path (option absent, then a real array) is unchanged.
113 * An existing caller relying on append-then-read still works.
114 */
115 public function test_existing_array_path_is_preserved(): void
116 {
117 // Option absent -> [] default -> first log creates the array.
118 SBR_Error_Handler::log_error($this->sampleError());
119
120 $second = $this->sampleError();
121 $second['id'] = 'feed_2';
122 SBR_Error_Handler::log_error($second);
123
124 $stored = SBR_Error_Handler::get_errors();
125 $this->assertCount(2, $stored);
126 // @phpstan-ignore-next-line — assertCount above guarantees offset 0; get_errors() returns an untyped array.
127 $this->assertSame('feed_1', $stored[0]['id']);
128 // @phpstan-ignore-next-line — assertCount above guarantees offset 1.
129 $this->assertSame('feed_2', $stored[1]['id']);
130 }
131 }
132