log_test('开始定时任务测试'); try { // 1. 环境检查 $this->test_environment(); // 2. 创建测试数据 $this->setup_test_data(); // 3. 测试续费定时任务 $this->test_renewal_cron(); // 4. 测试过期处理定时任务 $this->test_expiry_cron(); // 5. 测试清理定时任务 $this->test_cleanup_cron(); // 6. 测试定时任务调度 $this->test_cron_scheduling(); // 7. 清理测试数据 $this->cleanup_test_data(); $this->log_test('定时任务测试完成'); } catch (Exception $e) { $this->log_test('测试失败: ' . $e->getMessage(), 'error'); $this->cleanup_test_data(); } return $this->test_results; } /** * 环境检查 */ private function test_environment() { $this->log_test('检查定时任务环境'); // 检查必要的类是否存在 $required_classes = array( 'Yoone_Cron', 'Yoone_Subscription' ); foreach ($required_classes as $class) { if (!class_exists($class)) { throw new Exception("必需的类 {$class} 不存在"); } } // 检查WordPress定时任务功能 if (!function_exists('wp_schedule_event')) { throw new Exception('WordPress定时任务功能不可用'); } $this->log_test('定时任务环境检查通过', 'success'); } /** * 创建测试数据 */ private function setup_test_data() { $this->log_test('创建定时任务测试数据'); // 创建测试客户 $this->customer_id = Yoone_Test_Config::create_test_customer(); if (!$this->customer_id) { throw new Exception('创建测试客户失败'); } // 创建不同状态的测试订阅 $subscription_scenarios = array( array( 'status' => 'active', 'next_payment' => date('Y-m-d H:i:s', strtotime('-1 day')), // 需要续费 'description' => '需要续费的订阅' ), array( 'status' => 'active', 'next_payment' => date('Y-m-d H:i:s', strtotime('+7 days')), // 正常订阅 'description' => '正常活跃订阅' ), array( 'status' => 'pending-cancel', 'next_payment' => date('Y-m-d H:i:s', strtotime('-2 days')), // 待取消 'description' => '待取消订阅' ) ); foreach ($subscription_scenarios as $scenario) { $subscription = new Yoone_Subscription(); $subscription->set_customer_id($this->customer_id); $subscription->set_status($scenario['status']); $subscription->set_billing_period('month'); $subscription->set_billing_interval(1); $subscription->set_next_payment_date($scenario['next_payment']); // 添加订阅项目 $subscription->add_item(array( 'product_id' => Yoone_Test_Config::create_test_product(), 'quantity' => 1, 'price' => 29.99 )); $subscription_id = $subscription->save(); if ($subscription_id) { $this->test_subscription_ids[] = $subscription_id; $this->log_test("创建测试订阅: {$scenario['description']} - ID: {$subscription_id}"); } } if (empty($this->test_subscription_ids)) { throw new Exception('创建测试订阅失败'); } $this->log_test("定时任务测试数据创建成功 - 订阅数量: " . count($this->test_subscription_ids), 'success'); } /** * 测试续费定时任务 */ private function test_renewal_cron() { $this->log_test('测试续费定时任务'); // 检查续费定时任务是否已注册 $cron_hooks = array( 'yoone_process_subscription_renewals', 'yoone_check_renewal_payments' ); foreach ($cron_hooks as $hook) { if (!wp_next_scheduled($hook)) { $this->log_test("续费定时任务 {$hook} 未调度", 'warning'); } else { $next_run = wp_next_scheduled($hook); $this->log_test("续费定时任务 {$hook} 下次运行: " . date('Y-m-d H:i:s', $next_run)); } } // 模拟执行续费检查 if (class_exists('Yoone_Cron')) { $cron = new Yoone_Cron(); // 获取需要续费的订阅 $due_subscriptions = $this->get_due_subscriptions(); $this->log_test("找到 " . count($due_subscriptions) . " 个需要续费的订阅"); // 模拟处理续费 foreach ($due_subscriptions as $subscription_id) { $subscription = new Yoone_Subscription($subscription_id); if ($subscription->can_be_renewed()) { $this->log_test("订阅 {$subscription_id} 可以续费"); } else { $this->log_test("订阅 {$subscription_id} 不能续费", 'warning'); } } } $this->log_test('续费定时任务测试完成', 'success'); } /** * 测试过期处理定时任务 */ private function test_expiry_cron() { $this->log_test('测试过期处理定时任务'); // 检查过期处理定时任务 $expiry_hooks = array( 'yoone_process_expired_subscriptions', 'yoone_cleanup_expired_data' ); foreach ($expiry_hooks as $hook) { if (!wp_next_scheduled($hook)) { $this->log_test("过期处理定时任务 {$hook} 未调度", 'warning'); } else { $next_run = wp_next_scheduled($hook); $this->log_test("过期处理定时任务 {$hook} 下次运行: " . date('Y-m-d H:i:s', $next_run)); } } // 模拟处理过期订阅 $expired_subscriptions = $this->get_expired_subscriptions(); $this->log_test("找到 " . count($expired_subscriptions) . " 个过期订阅"); foreach ($expired_subscriptions as $subscription_id) { $subscription = new Yoone_Subscription($subscription_id); $status = $subscription->get_status(); $this->log_test("过期订阅 {$subscription_id} 当前状态: {$status}"); } $this->log_test('过期处理定时任务测试完成', 'success'); } /** * 测试清理定时任务 */ private function test_cleanup_cron() { $this->log_test('测试清理定时任务'); // 检查清理定时任务 $cleanup_hooks = array( 'yoone_cleanup_logs', 'yoone_cleanup_expired_tokens', 'yoone_cleanup_temp_data' ); foreach ($cleanup_hooks as $hook) { if (!wp_next_scheduled($hook)) { $this->log_test("清理定时任务 {$hook} 未调度", 'warning'); } else { $next_run = wp_next_scheduled($hook); $this->log_test("清理定时任务 {$hook} 下次运行: " . date('Y-m-d H:i:s', $next_run)); } } // 测试日志清理 if (class_exists('Yoone_Logger')) { $log_count_before = $this->count_log_entries(); $this->log_test("清理前日志条目数: {$log_count_before}"); // 这里可以模拟清理过程,但不实际删除数据 $this->log_test('日志清理功能可用'); } // 测试过期令牌清理 if (class_exists('Yoone_Payment_Token')) { $expired_tokens = $this->count_expired_tokens(); $this->log_test("过期支付令牌数量: {$expired_tokens}"); } $this->log_test('清理定时任务测试完成', 'success'); } /** * 测试定时任务调度 */ private function test_cron_scheduling() { $this->log_test('测试定时任务调度'); // 获取所有已调度的定时任务 $cron_array = _get_cron_array(); $yoone_crons = array(); foreach ($cron_array as $timestamp => $cron) { foreach ($cron as $hook => $dings) { if (strpos($hook, 'yoone_') === 0) { $yoone_crons[] = array( 'hook' => $hook, 'timestamp' => $timestamp, 'next_run' => date('Y-m-d H:i:s', $timestamp) ); } } } $this->log_test("找到 " . count($yoone_crons) . " 个Yoone定时任务"); foreach ($yoone_crons as $cron) { $this->log_test("定时任务: {$cron['hook']} - 下次运行: {$cron['next_run']}"); } // 检查定时任务间隔 $this->check_cron_intervals(); $this->log_test('定时任务调度测试完成', 'success'); } /** * 获取需要续费的订阅 */ private function get_due_subscriptions() { global $wpdb; $results = $wpdb->get_col($wpdb->prepare(" SELECT id FROM {$wpdb->prefix}yoone_subscriptions WHERE status = 'active' AND next_payment_date <= %s ", current_time('mysql'))); return array_intersect($results, $this->test_subscription_ids); } /** * 获取过期订阅 */ private function get_expired_subscriptions() { global $wpdb; $results = $wpdb->get_col($wpdb->prepare(" SELECT id FROM {$wpdb->prefix}yoone_subscriptions WHERE status IN ('pending-cancel', 'expired') AND next_payment_date < %s ", date('Y-m-d H:i:s', strtotime('-7 days')))); return array_intersect($results, $this->test_subscription_ids); } /** * 统计日志条目数 */ private function count_log_entries() { global $wpdb; $count = $wpdb->get_var(" SELECT COUNT(*) FROM {$wpdb->prefix}yoone_logs WHERE created_at > DATE_SUB(NOW(), INTERVAL 30 DAY) "); return intval($count); } /** * 统计过期令牌数 */ private function count_expired_tokens() { global $wpdb; $count = $wpdb->get_var(" SELECT COUNT(*) FROM {$wpdb->prefix}yoone_payment_tokens WHERE expires_at IS NOT NULL AND expires_at < NOW() "); return intval($count); } /** * 检查定时任务间隔 */ private function check_cron_intervals() { $expected_intervals = array( 'yoone_process_subscription_renewals' => 'hourly', 'yoone_process_expired_subscriptions' => 'daily', 'yoone_cleanup_logs' => 'weekly' ); foreach ($expected_intervals as $hook => $expected_interval) { $schedules = wp_get_schedules(); $next_run = wp_next_scheduled($hook); if ($next_run) { $this->log_test("定时任务 {$hook} 调度正常"); } else { $this->log_test("定时任务 {$hook} 未正确调度", 'warning'); } } } /** * 清理测试数据 */ private function cleanup_test_data() { $this->log_test('清理定时任务测试数据'); // 删除测试订阅 foreach ($this->test_subscription_ids as $subscription_id) { $subscription = new Yoone_Subscription($subscription_id); $subscription->delete(); } // 删除测试客户 if ($this->customer_id) { wp_delete_user($this->customer_id); } $this->log_test('定时任务测试数据清理完成', 'success'); } /** * 记录测试结果 */ private function log_test($message, $type = 'info') { $this->test_results[] = array( 'timestamp' => current_time('mysql'), 'message' => $message, 'type' => $type ); // 同时记录到日志系统 Yoone_Logger::info('定时任务测试: ' . $message); } /** * 获取测试结果 */ public function get_test_results() { return $this->test_results; } }