418 lines
13 KiB
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;
|
|
}
|
|
} |