Skip to content

Commit 26dd37c

Browse files
test: add comprehensive unit test coverage across all major components
Agent-Logs-Url: https://github.com/Starisian-Technologies/sparxstar-user-environment-check/sessions/d987c0ef-b328-4c25-af26-708f3dc8cf3e Co-authored-by: MaximillianGroup <34328348+MaximillianGroup@users.noreply.github.com>
1 parent 423d7c2 commit 26dd37c

11 files changed

Lines changed: 2802 additions & 4 deletions

.phpunit.result.cache

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/bootstrap-unit.php

Lines changed: 364 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ static function (string $class): void {
7272
*/
7373
$GLOBALS['wp_options'] = $GLOBALS['wp_options'] ?? [];
7474

75+
/**
76+
* In-memory transient store used by WordPress transient shims.
77+
*
78+
* @var array<string, mixed>
79+
*/
80+
$GLOBALS['wp_transients'] = $GLOBALS['wp_transients'] ?? [];
81+
7582
/**
7683
* In-memory cache store used by the WordPress cache shims.
7784
*
@@ -619,11 +626,11 @@ public function get_var(string $query): ?int
619626
/**
620627
* Stubbed getter for a row result.
621628
*
622-
* @param string $query SQL string.
623-
* @param int $output Output type (unused).
629+
* @param string $query SQL string.
630+
* @param string|int $output Output type (unused).
624631
* @return array<string, mixed>|null Null to indicate no results.
625632
*/
626-
public function get_row(string $query, int $output = ARRAY_A): ?array
633+
public function get_row(string $query, string|int $output = ARRAY_A): ?array
627634
{
628635
unset($output);
629636
$this->queries[] = ['query' => $query];
@@ -968,3 +975,357 @@ function deactivate_plugins(string|array $plugins): void
968975
$GLOBALS['deactivated_plugins'][] = $plugins;
969976
}
970977
}
978+
979+
// ---------------------------------------------------------------------------
980+
// WordPress constants
981+
// ---------------------------------------------------------------------------
982+
983+
if (! defined('ARRAY_A')) {
984+
/**
985+
* Flag requesting an associative-array result from wpdb::get_row().
986+
*/
987+
define('ARRAY_A', 'ARRAY_A');
988+
}
989+
990+
// ---------------------------------------------------------------------------
991+
// WordPress class stubs
992+
// ---------------------------------------------------------------------------
993+
994+
if (! class_exists('WP_Error')) {
995+
/**
996+
* Minimal stand-in for WordPress' WP_Error class.
997+
*/
998+
class WP_Error
999+
{
1000+
/**
1001+
* Machine-readable error code.
1002+
*
1003+
* @var string
1004+
*/
1005+
private string $code;
1006+
1007+
/**
1008+
* Human-readable error message.
1009+
*
1010+
* @var string
1011+
*/
1012+
private string $message;
1013+
1014+
/**
1015+
* Optional structured error data.
1016+
*
1017+
* @var mixed
1018+
*/
1019+
private mixed $data;
1020+
1021+
/**
1022+
* @param string $code Machine-readable error code.
1023+
* @param string $message Human-readable message.
1024+
* @param mixed $data Optional extra data.
1025+
*/
1026+
public function __construct(string $code = '', string $message = '', mixed $data = '')
1027+
{
1028+
$this->code = $code;
1029+
$this->message = $message;
1030+
$this->data = $data;
1031+
}
1032+
1033+
/** @return string */
1034+
public function get_error_code(): string
1035+
{
1036+
return $this->code;
1037+
}
1038+
1039+
/** @return string */
1040+
public function get_error_message(): string
1041+
{
1042+
return $this->message;
1043+
}
1044+
1045+
/** @return mixed */
1046+
public function get_error_data(): mixed
1047+
{
1048+
return $this->data;
1049+
}
1050+
}
1051+
}
1052+
1053+
if (! class_exists('WP_REST_Request')) {
1054+
/**
1055+
* Minimal stand-in for WordPress' WP_REST_Request class.
1056+
*/
1057+
class WP_REST_Request
1058+
{
1059+
/**
1060+
* Decoded JSON body parameters.
1061+
*
1062+
* @var array<string, mixed>
1063+
*/
1064+
private array $json_params = [];
1065+
1066+
/**
1067+
* Normalised request headers (lowercase keys).
1068+
*
1069+
* @var array<string, string>
1070+
*/
1071+
private array $headers = [];
1072+
1073+
/**
1074+
* Raw request body.
1075+
*
1076+
* @var string
1077+
*/
1078+
private string $body = '';
1079+
1080+
/**
1081+
* @param array<string, mixed> $params Decoded JSON parameters.
1082+
* @return void
1083+
*/
1084+
public function set_json_params(array $params): void
1085+
{
1086+
$this->json_params = $params;
1087+
}
1088+
1089+
/**
1090+
* @return array<string, mixed>
1091+
*/
1092+
public function get_json_params(): array
1093+
{
1094+
return $this->json_params;
1095+
}
1096+
1097+
/**
1098+
* @param string $key Header name (case-insensitive).
1099+
* @param string $value Header value.
1100+
* @return void
1101+
*/
1102+
public function set_header(string $key, string $value): void
1103+
{
1104+
$this->headers[strtolower($key)] = $value;
1105+
}
1106+
1107+
/**
1108+
* @param string $key Header name (case-insensitive).
1109+
* @return string|null Header value or null when absent.
1110+
*/
1111+
public function get_header(string $key): ?string
1112+
{
1113+
return $this->headers[strtolower($key)] ?? null;
1114+
}
1115+
1116+
/**
1117+
* @param string $body Raw request body.
1118+
* @return void
1119+
*/
1120+
public function set_body(string $body): void
1121+
{
1122+
$this->body = $body;
1123+
}
1124+
1125+
/** @return string */
1126+
public function get_body(): string
1127+
{
1128+
return $this->body;
1129+
}
1130+
}
1131+
}
1132+
1133+
if (! class_exists('WP_REST_Response')) {
1134+
/**
1135+
* Minimal stand-in for WordPress' WP_REST_Response class.
1136+
*/
1137+
class WP_REST_Response
1138+
{
1139+
/**
1140+
* Response payload.
1141+
*
1142+
* @var mixed
1143+
*/
1144+
private mixed $data;
1145+
1146+
/**
1147+
* HTTP status code.
1148+
*
1149+
* @var int
1150+
*/
1151+
private int $status;
1152+
1153+
/**
1154+
* @param mixed $data Response payload.
1155+
* @param int $status HTTP status code.
1156+
*/
1157+
public function __construct(mixed $data = null, int $status = 200)
1158+
{
1159+
$this->data = $data;
1160+
$this->status = $status;
1161+
}
1162+
1163+
/** @return mixed */
1164+
public function get_data(): mixed
1165+
{
1166+
return $this->data;
1167+
}
1168+
1169+
/** @return int */
1170+
public function get_status(): int
1171+
{
1172+
return $this->status;
1173+
}
1174+
}
1175+
}
1176+
1177+
// ---------------------------------------------------------------------------
1178+
// Additional WordPress function stubs
1179+
// ---------------------------------------------------------------------------
1180+
1181+
if (! function_exists('is_wp_error')) {
1182+
/**
1183+
* Determine whether the supplied value is a WP_Error instance.
1184+
*
1185+
* @param mixed $thing Value to inspect.
1186+
* @return bool True when the value is a WP_Error.
1187+
*/
1188+
function is_wp_error(mixed $thing): bool
1189+
{
1190+
return $thing instanceof WP_Error;
1191+
}
1192+
}
1193+
1194+
if (! function_exists('wp_verify_nonce')) {
1195+
/**
1196+
* Verify a nonce value.
1197+
* In tests the only accepted value is the literal string 'valid_nonce'.
1198+
*
1199+
* @param string|null $nonce Nonce to verify.
1200+
* @param string $action Nonce action (unused in stub).
1201+
* @return bool True when the nonce is the expected test value.
1202+
*/
1203+
function wp_verify_nonce(?string $nonce, string $action = ''): bool
1204+
{
1205+
unset($action);
1206+
return $nonce === 'valid_nonce';
1207+
}
1208+
}
1209+
1210+
if (! function_exists('wp_unslash')) {
1211+
/**
1212+
* Strip slashes from a string or array mirroring WordPress' helper.
1213+
*
1214+
* @param mixed $value String or array to unslash.
1215+
* @return mixed Unslashed value.
1216+
*/
1217+
function wp_unslash(mixed $value): mixed
1218+
{
1219+
if (is_string($value)) {
1220+
return stripslashes($value);
1221+
}
1222+
1223+
if (is_array($value)) {
1224+
return array_map('wp_unslash', $value);
1225+
}
1226+
1227+
return $value;
1228+
}
1229+
}
1230+
1231+
if (! function_exists('get_locale')) {
1232+
/**
1233+
* Return the current WordPress locale.
1234+
* Always returns 'en_US' in the test environment.
1235+
*
1236+
* @return string Locale string.
1237+
*/
1238+
function get_locale(): string
1239+
{
1240+
return 'en_US';
1241+
}
1242+
}
1243+
1244+
if (! function_exists('get_transient')) {
1245+
/**
1246+
* Retrieve a transient value from the in-memory store.
1247+
*
1248+
* @param string $transient Transient name.
1249+
* @return mixed Stored value or false when absent.
1250+
*/
1251+
function get_transient(string $transient): mixed
1252+
{
1253+
return $GLOBALS['wp_transients'][$transient] ?? false;
1254+
}
1255+
}
1256+
1257+
if (! function_exists('set_transient')) {
1258+
/**
1259+
* Store a transient value in the in-memory store.
1260+
*
1261+
* @param string $transient Transient name.
1262+
* @param mixed $value Value to store.
1263+
* @param int $expiration Ignored in the stub.
1264+
* @return bool Always true.
1265+
*/
1266+
function set_transient(string $transient, mixed $value, int $expiration = 0): bool
1267+
{
1268+
unset($expiration);
1269+
$GLOBALS['wp_transients'][$transient] = $value;
1270+
return true;
1271+
}
1272+
}
1273+
1274+
if (! function_exists('wp_get_schedules')) {
1275+
/**
1276+
* Return the standard WordPress cron schedule definitions.
1277+
*
1278+
* @return array<string, array{interval: int, display: string}>
1279+
*/
1280+
function wp_get_schedules(): array
1281+
{
1282+
return [
1283+
'hourly' => ['interval' => 3600, 'display' => 'Once Hourly'],
1284+
'twicedaily' => ['interval' => 43200, 'display' => 'Twice Daily'],
1285+
'daily' => ['interval' => 86400, 'display' => 'Once Daily'],
1286+
'weekly' => ['interval' => 604800, 'display' => 'Once Weekly'],
1287+
];
1288+
}
1289+
}
1290+
1291+
if (! function_exists('is_ssl')) {
1292+
/**
1293+
* Determine whether the current request uses HTTPS.
1294+
* Always returns false in the test environment.
1295+
*
1296+
* @return bool False.
1297+
*/
1298+
function is_ssl(): bool
1299+
{
1300+
return false;
1301+
}
1302+
}
1303+
1304+
if (! function_exists('esc_url_raw')) {
1305+
/**
1306+
* Sanitise a URL for database storage (no HTML encoding).
1307+
*
1308+
* @param string $url Raw URL.
1309+
* @return string Sanitised URL.
1310+
*/
1311+
function esc_url_raw(string $url): string
1312+
{
1313+
return filter_var($url, FILTER_SANITIZE_URL) ?: '';
1314+
}
1315+
}
1316+
1317+
if (! function_exists('__')) {
1318+
/**
1319+
* Translate a string.
1320+
* Returns the original text unchanged in the test environment.
1321+
*
1322+
* @param string $text Text to translate.
1323+
* @param string $domain Text domain (unused in stub).
1324+
* @return string Original text.
1325+
*/
1326+
function __(string $text, string $domain = ''): string
1327+
{
1328+
unset($domain);
1329+
return $text;
1330+
}
1331+
}

0 commit comments

Comments
 (0)