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