subscription/tests/test-cron-jobs.php

418 lines
13 KiB
PHP

<?php
/**
* 定时任务测试脚本
*
* @package Yoone_Subscriptions
* @subpackage Tests
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
/**
* 定时任务测试类
*/
class Yoone_Cron_Jobs_Test {
private $test_results = array();
private $test_subscription_ids = array();
private $customer_id;
/**
* 运行完整的定时任务测试
*/
public function run_full_test() {
$this->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;
}
}