PluginProbe ʕ •ᴥ•ʔ
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More / 2.6.7
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More v2.6.7
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 / bootstrap.php
reviews-feed / tests Last commit date
Unit 2 months ago bootstrap.php 2 months ago phpunit.xml 2 months ago
bootstrap.php
297 lines
1 <?php
2
3 /**
4 * PHPUnit bootstrap file for sb-reviews plugin tests.
5 *
6 * These tests are designed to run without the full WordPress environment
7 * by mocking WordPress functions and focusing on unit-testable logic.
8 */
9
10 // Define WordPress stubs for functions used in tested code
11 if (!defined('ABSPATH')) {
12 define('ABSPATH', dirname(__DIR__) . '/');
13 }
14
15 if (!defined('SBR_RELAY_BASE_URL')) {
16 define('SBR_RELAY_BASE_URL', 'https://relay.smashballoon.com/api/v1.0/');
17 }
18
19 // Plugin constants required when tests `require` the full sbr-functions.php.
20 if (!defined('SBR_PLUGIN_BASENAME')) {
21 define('SBR_PLUGIN_BASENAME', 'reviews-feed-pro/sb-reviews-pro.php');
22 }
23 if (!defined('SBR_PLUGIN_URL')) {
24 define('SBR_PLUGIN_URL', 'https://example.test/wp-content/plugins/reviews-feed-pro/');
25 }
26 if (!defined('SBRVER')) {
27 define('SBRVER', '2.5.0-test');
28 }
29 // Pro-side constants — required for silent-reactivation Pro-path tests.
30 // Pro tests will have these defined; the Free-skip path is covered by the
31 // license_key==='' early return, since Free installs never populate a key.
32 if (!defined('SBR_PLUGIN_NAME')) {
33 define('SBR_PLUGIN_NAME', 'Reviews Feed Pro Test');
34 }
35 if (!defined('SBR_PRODUCT_ID')) {
36 define('SBR_PRODUCT_ID', 9999999);
37 }
38
39 // Mock WordPress functions used in tested code
40 if (!function_exists('sanitize_text_field')) {
41 function sanitize_text_field($str)
42 {
43 return trim(strip_tags($str));
44 }
45 }
46
47 if (!function_exists('absint')) {
48 function absint($maybeint)
49 {
50 return abs((int) $maybeint);
51 }
52 }
53
54 if (!function_exists('get_option')) {
55 function get_option($option, $default = false)
56 {
57 global $wp_options_mock;
58 return $wp_options_mock[$option] ?? $default;
59 }
60 }
61
62 if (!function_exists('update_option')) {
63 // Core signature: update_option($option, $value, $autoload = null).
64 // $autoload is accepted for signature parity so other tests exercising code
65 // that passes it don't fail with "Too many arguments".
66 function update_option($option, $value, $autoload = null)
67 {
68 global $wp_options_mock;
69 if (!is_array($wp_options_mock)) {
70 $wp_options_mock = [];
71 }
72 $wp_options_mock[$option] = $value;
73 return true;
74 }
75 }
76
77 if (!function_exists('delete_option')) {
78 function delete_option($option)
79 {
80 global $wp_options_mock;
81 if (!is_array($wp_options_mock)) {
82 $wp_options_mock = [];
83 return true;
84 }
85 unset($wp_options_mock[$option]);
86 return true;
87 }
88 }
89
90 if (!function_exists('get_home_url')) {
91 // Core signature: get_home_url($blog_id = null, $path = '', $scheme = null).
92 // Accept and ignore the extra args so callers using the full form don't error.
93 function get_home_url($blog_id = null, $path = '', $scheme = null)
94 {
95 global $wp_home_url_mock;
96 return $wp_home_url_mock ?? '';
97 }
98 }
99
100 if (!function_exists('wp_json_encode')) {
101 function wp_json_encode($data, $options = 0, $depth = 512)
102 {
103 return json_encode($data, $options, $depth);
104 }
105 }
106
107 if (!function_exists('trailingslashit')) {
108 function trailingslashit($string)
109 {
110 return rtrim($string, '/\\') . '/';
111 }
112 }
113
114 if (!function_exists('wp_upload_dir')) {
115 function wp_upload_dir($time = null, $create_dir = true, $refresh_cache = false)
116 {
117 return [
118 'path' => '/tmp/uploads',
119 'url' => 'https://example.test/wp-content/uploads',
120 'subdir' => '',
121 'basedir' => '/tmp/uploads',
122 'baseurl' => 'https://example.test/wp-content/uploads',
123 'error' => false,
124 ];
125 }
126 }
127
128 // Stubs that let tests `require_once 'class/sbr-functions.php'` without
129 // triggering WordPress-only bootstrap calls at the top level.
130 if (!function_exists('register_activation_hook')) {
131 function register_activation_hook($file, $callback)
132 {
133 // no-op for tests
134 }
135 }
136 if (!function_exists('add_action')) {
137 function add_action($hook, $callback, $priority = 10, $accepted_args = 1)
138 {
139 // no-op for tests
140 }
141 }
142 if (!function_exists('add_filter')) {
143 function add_filter($hook, $callback, $priority = 10, $accepted_args = 1)
144 {
145 // no-op for tests
146 }
147 }
148 if (!function_exists('apply_filters')) {
149 function apply_filters($hook, $value, ...$args)
150 {
151 return $value;
152 }
153 }
154 if (!function_exists('do_action')) {
155 function do_action($hook, ...$args)
156 {
157 // no-op for tests
158 }
159 }
160
161 // Transient stubs for silent-reactivation rate-limit + notice-payload tests.
162 // Stored in a dedicated global ($wp_transients_mock) so tests can manipulate
163 // them independently from $wp_options_mock.
164 if (!defined('DAY_IN_SECONDS')) {
165 define('DAY_IN_SECONDS', 86400);
166 }
167 if (!defined('WEEK_IN_SECONDS')) {
168 define('WEEK_IN_SECONDS', 604800);
169 }
170 if (!defined('HOUR_IN_SECONDS')) {
171 define('HOUR_IN_SECONDS', 3600);
172 }
173 if (!defined('MINUTE_IN_SECONDS')) {
174 define('MINUTE_IN_SECONDS', 60);
175 }
176 // `wpdb::get_results()` output_type constants — production code passes ARRAY_A.
177 if (!defined('ARRAY_A')) {
178 define('ARRAY_A', 'ARRAY_A');
179 }
180 if (!defined('ARRAY_N')) {
181 define('ARRAY_N', 'ARRAY_N');
182 }
183 if (!defined('OBJECT')) {
184 define('OBJECT', 'OBJECT');
185 }
186 if (!function_exists('get_transient')) {
187 function get_transient($key)
188 {
189 global $wp_transients_mock;
190 if (!is_array($wp_transients_mock) || !isset($wp_transients_mock[$key])) {
191 return false;
192 }
193 return $wp_transients_mock[$key];
194 }
195 }
196 if (!function_exists('set_transient')) {
197 function set_transient($key, $value, $ttl = 0)
198 {
199 global $wp_transients_mock;
200 if (!is_array($wp_transients_mock)) {
201 $wp_transients_mock = [];
202 }
203 $wp_transients_mock[$key] = $value;
204 return true;
205 }
206 }
207 if (!function_exists('delete_transient')) {
208 function delete_transient($key)
209 {
210 global $wp_transients_mock;
211 if (!is_array($wp_transients_mock)) {
212 return true;
213 }
214 unset($wp_transients_mock[$key]);
215 return true;
216 }
217 }
218
219 // Stub is_plugin_active for provider-detection tests (EDD provider gate).
220 // Backed by $wp_active_plugins_mock so tests can flip plugin-presence per case
221 // without touching real wp-admin includes.
222 if (!function_exists('is_plugin_active')) {
223 function is_plugin_active($plugin_path)
224 {
225 global $wp_active_plugins_mock;
226 if (!is_array($wp_active_plugins_mock)) {
227 return false;
228 }
229 return in_array($plugin_path, $wp_active_plugins_mock, true);
230 }
231 }
232
233 // i18n stub used by translatable strings in tested code paths.
234 if (!function_exists('__')) {
235 function __($text, $domain = null)
236 {
237 return $text;
238 }
239 }
240
241 // WP HTTP helpers — never actually invoked in unit tests (SBRelay::call is
242 // mocked at the `onlyMethods(['call'])` level), but reverify_token_via_register
243 // has a `function_exists` defense-in-depth guard that bails early if these
244 // helpers aren't defined. Without these stubs the guard fires in tests and
245 // reverify never reaches the mocked `call()`.
246 if (!function_exists('wp_remote_post')) {
247 function wp_remote_post($url, $args = [])
248 {
249 return [];
250 }
251 }
252 if (!function_exists('wp_remote_get')) {
253 function wp_remote_get($url, $args = [])
254 {
255 return [];
256 }
257 }
258 if (!function_exists('is_wp_error')) {
259 function is_wp_error($thing)
260 {
261 return false;
262 }
263 }
264 if (!function_exists('wp_remote_retrieve_body')) {
265 function wp_remote_retrieve_body($response)
266 {
267 return '';
268 }
269 }
270
271 // Cron API stubs — namespace-fallback resolution requires these to live in
272 // the global namespace so callers in `SmashBalloon\Reviews\Pro\Services\BulkUpdate`
273 // (and elsewhere) can find them via PHP's fallback lookup.
274 if (!function_exists('wp_schedule_single_event')) {
275 function wp_schedule_single_event($timestamp, $hook, $args = [])
276 {
277 return true;
278 }
279 }
280
281 if (!function_exists('wp_next_scheduled')) {
282 function wp_next_scheduled($hook, $args = [])
283 {
284 return false;
285 }
286 }
287
288 if (!function_exists('wp_clear_scheduled_hook')) {
289 function wp_clear_scheduled_hook($hook, $args = [], $wp_error = false)
290 {
291 return 0;
292 }
293 }
294
295 // Autoloader
296 require_once dirname(__DIR__) . '/vendor/autoload.php';
297