@@ -1026,4 +1026,132 @@ static function ( $storage ) use ( &$filter_called ) {
10261026
10271027 $ this ->assertTrue ( $ filter_called , 'The wp_sync_storage filter should be applied during route registration. ' );
10281028 }
1029+
1030+ /*
1031+ * Cron cleanup tests.
1032+ */
1033+
1034+ /**
1035+ * Inserts a row directly into the sync_updates table with a given age.
1036+ *
1037+ * @param int $age_in_seconds How old the row should be.
1038+ * @param string $label A label stored in the update_value for identification.
1039+ */
1040+ private function insert_sync_row ( $ age_in_seconds , $ label = 'test ' ) {
1041+ global $ wpdb ;
1042+
1043+ $ wpdb ->insert (
1044+ $ wpdb ->sync_updates ,
1045+ array (
1046+ 'room ' => $ this ->get_post_room (),
1047+ 'update_value ' => wp_json_encode ( array ( 'type ' => 'update ' , 'data ' => $ label ) ),
1048+ 'created_at ' => gmdate ( 'Y-m-d H:i:s ' , time () - $ age_in_seconds ),
1049+ ),
1050+ array ( '%s ' , '%s ' , '%s ' )
1051+ );
1052+ }
1053+
1054+ /**
1055+ * Returns the number of rows in the sync_updates table.
1056+ *
1057+ * @return int Row count.
1058+ */
1059+ private function get_sync_row_count () {
1060+ global $ wpdb ;
1061+
1062+ return (int ) $ wpdb ->get_var ( "SELECT COUNT(*) FROM {$ wpdb ->sync_updates }" );
1063+ }
1064+
1065+ /**
1066+ * @ticket 64696
1067+ */
1068+ public function test_cron_cleanup_deletes_old_rows () {
1069+ $ this ->insert_sync_row ( 8 * DAY_IN_SECONDS );
1070+
1071+ $ this ->assertSame ( 1 , $ this ->get_sync_row_count () );
1072+
1073+ wp_delete_old_sync_updates ();
1074+
1075+ $ this ->assertSame ( 0 , $ this ->get_sync_row_count () );
1076+ }
1077+
1078+ /**
1079+ * @ticket 64696
1080+ */
1081+ public function test_cron_cleanup_preserves_recent_rows () {
1082+ $ this ->insert_sync_row ( DAY_IN_SECONDS );
1083+
1084+ wp_delete_old_sync_updates ();
1085+
1086+ $ this ->assertSame ( 1 , $ this ->get_sync_row_count () );
1087+ }
1088+
1089+ /**
1090+ * @ticket 64696
1091+ */
1092+ public function test_cron_cleanup_boundary_at_exactly_seven_days () {
1093+ $ this ->insert_sync_row ( WEEK_IN_SECONDS + 1 , 'expired ' );
1094+ $ this ->insert_sync_row ( WEEK_IN_SECONDS - 1 , 'just-inside ' );
1095+
1096+ wp_delete_old_sync_updates ();
1097+
1098+ global $ wpdb ;
1099+ $ remaining = $ wpdb ->get_col ( "SELECT update_value FROM {$ wpdb ->sync_updates }" );
1100+
1101+ $ this ->assertCount ( 1 , $ remaining , 'Only the row within the 7-day window should remain. ' );
1102+ $ this ->assertStringContainsString ( 'just-inside ' , $ remaining [0 ], 'The surviving row should be the one inside the window. ' );
1103+ }
1104+
1105+ /**
1106+ * @ticket 64696
1107+ */
1108+ public function test_cron_cleanup_selectively_deletes_mixed_rows () {
1109+ // 3 expired rows.
1110+ $ this ->insert_sync_row ( 10 * DAY_IN_SECONDS );
1111+ $ this ->insert_sync_row ( 10 * DAY_IN_SECONDS );
1112+ $ this ->insert_sync_row ( 10 * DAY_IN_SECONDS );
1113+
1114+ // 2 recent rows.
1115+ $ this ->insert_sync_row ( HOUR_IN_SECONDS );
1116+ $ this ->insert_sync_row ( HOUR_IN_SECONDS );
1117+
1118+ $ this ->assertSame ( 5 , $ this ->get_sync_row_count () );
1119+
1120+ wp_delete_old_sync_updates ();
1121+
1122+ $ this ->assertSame ( 2 , $ this ->get_sync_row_count (), 'Only the 2 recent rows should survive cleanup. ' );
1123+ }
1124+
1125+ /**
1126+ * @ticket 64696
1127+ */
1128+ public function test_cron_cleanup_hook_is_registered () {
1129+ $ this ->assertSame (
1130+ 10 ,
1131+ has_action ( 'wp_delete_old_sync_updates ' , 'wp_delete_old_sync_updates ' ),
1132+ 'The wp_delete_old_sync_updates action should be hooked in default-filters.php. '
1133+ );
1134+ }
1135+
1136+ /*
1137+ * Route registration guard tests.
1138+ */
1139+
1140+ /**
1141+ * @ticket 64696
1142+ */
1143+ public function test_sync_routes_not_registered_when_db_version_is_old () {
1144+ update_option ( 'db_version ' , 61697 );
1145+
1146+ // Reset the global REST server so rest_get_server() builds a fresh instance.
1147+ $ GLOBALS ['wp_rest_server ' ] = null ;
1148+
1149+ $ server = rest_get_server ();
1150+ $ routes = $ server ->get_routes ();
1151+
1152+ $ this ->assertArrayNotHasKey ( '/wp-sync/v1/updates ' , $ routes , 'Sync routes should not be registered when db_version is below 61698. ' );
1153+
1154+ // Reset again so subsequent tests get a server with the correct db_version.
1155+ $ GLOBALS ['wp_rest_server ' ] = null ;
1156+ }
10291157}
0 commit comments