PluginProbe ʕ •ᴥ•ʔ
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More / 2.8.0
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More v2.8.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 month ago Providers 1 month ago BulkRearmOnGrowthTest.php 1 month ago BulkReviewsUpdateStuckStateTest.php 1 month ago ClearCacheRelayResetTest.php 1 month ago DeleteSourceRelayFailureTest.php 1 month ago ErrorHandlerFalsyOptionTest.php 1 month ago FeedCacheUpdateServiceTest.php 1 month ago FeedMalformedPayloadTest.php 1 month ago ForceKeylessRefetchTest.php 1 month ago LicenseDeactivateStaleStateTest.php 1 month ago MediaFinderMemoTest.php 1 month ago MultiSourceAggregationTest.php 1 month ago ReconcileMigratedLicenseRoutineTest.php 1 month ago ReconcileRemovalTest.php 1 month ago RegisterWebsiteRoutineTest.php 1 month ago RemoteRequestMemoTest.php 1 month ago ReviewAlertHeaderTotalsTest.php 1 month ago ReviewAlertPageTargetingTest.php 1 month ago ReviewAlertStarFillTest.php 1 month ago ShortcodeNeutralizationTest.php 1 month ago SiteMigrationRecoveryTest.php 1 month ago Smash1583HeaderParityTest.php 1 month ago Smash1631MultiLanguageBulkTest.php 1 month ago Smash1631UpdateSingleLangScopeTest.php 1 month ago Smash782BookingHeaderRatingTest.php 1 month ago Smash782CountryFlagEmojiTest.php 1 month ago Smash782ExternalRefreshCronTest.php 1 month ago Smash782ExtrasTemplateTest.php 1 month ago Smash782ReviewAlertProviderDataTest.php 1 month ago SourceIdLookupTest.php 1 month ago WpmlGetCurrentLanguageTest.php 1 month ago WpmlLanguageMappingTest.php 1 month 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