155 lines
7.6 KiB
PHP
155 lines
7.6 KiB
PHP
<?php
|
|
/**
|
|
* Exercise the event adapter with a recording sender and minimal WordPress hooks.
|
|
*/
|
|
|
|
namespace {
|
|
define('ABSPATH', __DIR__ . '/');
|
|
$GLOBALS['wechat_event_hooks'] = [];
|
|
|
|
class WP_User {
|
|
public function __construct(public int $ID, public string $display_name) {}
|
|
}
|
|
|
|
class WP_Comment {
|
|
public function __construct(
|
|
public int $comment_ID,
|
|
public int $comment_post_ID,
|
|
public string $comment_date,
|
|
public string $comment_content
|
|
) {}
|
|
}
|
|
|
|
function add_action(string $name, callable $callback, int $priority = 10, int $accepted_args = 1): void {
|
|
$GLOBALS['wechat_event_hooks'][$name][] = [$callback, $accepted_args];
|
|
}
|
|
|
|
function do_action(string $name, ...$args): void {
|
|
foreach ($GLOBALS['wechat_event_hooks'][$name] ?? [] as [$callback, $accepted_args]) {
|
|
$callback(...array_slice($args, 0, $accepted_args));
|
|
}
|
|
}
|
|
|
|
function __($message, $domain = ''): string { return (string) $message; }
|
|
function current_time(string $format): string { return '2026-11-10 10:00:00'; }
|
|
function home_url(string $path = '/'): string { return 'https://site.test' . $path; }
|
|
function admin_url(string $path): string { return 'https://site.test/wp-admin/' . $path; }
|
|
function jio_get_user_center_url(string $tab): string { return 'https://site.test/user/' . $tab . '/'; }
|
|
function jio_get_user_center_tab_url(string $tab): string { return 'https://site.test/user/' . $tab . '/'; }
|
|
function jio_get_messages_page_url(string $view): string { return 'https://site.test/messages/' . $view . '/'; }
|
|
function get_users(array $args): array { return [2, 3]; }
|
|
function get_userdata(int $id) { return new WP_User($id, 'User ' . $id); }
|
|
function get_the_title(int $id): string { return 'Product ' . $id; }
|
|
function get_comment_author(WP_Comment $comment): string { return 'Commenter ' . $comment->comment_ID; }
|
|
function get_comment_link(WP_Comment $comment): string { return 'https://site.test/post/#comment-' . $comment->comment_ID; }
|
|
$GLOBALS['wpdb'] = new class {
|
|
public function prepare(string $query, int $id): string { return str_replace('%d', (string) $id, $query); }
|
|
public function get_var(string $query): string { return str_contains($query, 'wp_revenue') ? 'O-3' : 'O-4'; }
|
|
};
|
|
|
|
require_once dirname(__DIR__, 2) . '/src/Ledger/AssetType.php';
|
|
require_once dirname(__DIR__, 2) . '/src/Ledger/AssetAmount.php';
|
|
require_once dirname(__DIR__, 2) . '/src/Ledger/LedgerCommand.php';
|
|
require_once dirname(__DIR__, 2) . '/src/Ledger/LedgerResult.php';
|
|
require_once dirname(__DIR__, 2) . '/src/Payment/Withdrawal.php';
|
|
require_once dirname(__DIR__, 2) . '/src/Payment/WeChatNotifyEvents.php';
|
|
}
|
|
|
|
namespace Jio\Core {
|
|
final class DBMigrator {
|
|
public static function table(string $name): string { return 'wp_' . $name; }
|
|
}
|
|
}
|
|
|
|
namespace Jio\Payment {
|
|
final class RecordingWechatSender {
|
|
use WeChatNotifyEvents;
|
|
|
|
public array $messages = [];
|
|
|
|
public function init(): void {
|
|
$this->register_event_hooks();
|
|
}
|
|
|
|
public function send_event(int $user_id, string $type, array $values, string $url = ''): bool {
|
|
$this->messages[] = compact('user_id', 'type', 'values', 'url');
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
$check = static function (bool $condition, string $message): void {
|
|
if (!$condition) {
|
|
fwrite(STDERR, $message . "\n");
|
|
exit(1);
|
|
}
|
|
};
|
|
$sender = new \Jio\Payment\RecordingWechatSender();
|
|
$sender->init();
|
|
$sender->init();
|
|
$check(count($GLOBALS['wechat_event_hooks']['jio_order_paid'] ?? []) === 1, 'order hook registered twice');
|
|
$check(count($GLOBALS['wechat_event_hooks']['jio_wechat_comment_parent'] ?? []) === 1, 'comment hook registered twice');
|
|
|
|
do_action('jio_order_paid', 'O-1', [
|
|
'user_id' => 1,
|
|
'product_id' => 9,
|
|
'amount' => '12.50',
|
|
'currency' => 'CNY',
|
|
'paid_at' => '2026-11-09 09:00:00',
|
|
]);
|
|
$check(count($sender->messages) === 3, 'order should notify buyer and two admins once');
|
|
$check($sender->messages[0]['type'] === 'payment_order', 'buyer order type');
|
|
$check($sender->messages[0]['values'] === [
|
|
'name' => 'Product 9', 'price' => '12.50 CNY', 'time' => '2026-11-09 09:00:00', 'num' => 'O-1',
|
|
], 'buyer order fields');
|
|
$check($sender->messages[0]['url'] === 'https://site.test/user/orders/', 'buyer order URL');
|
|
$check($sender->messages[1]['type'] === 'payment_order_admin', 'admin order type');
|
|
$check($sender->messages[1]['values']['user'] === 'User 1', 'admin buyer field');
|
|
$check($sender->messages[1]['url'] === 'https://site.test/wp-admin/admin.php?page=jio_orders&order=O-1', 'admin order URL');
|
|
|
|
$sender->messages = [];
|
|
$row = ['gross_amount' => '20.00', 'amount' => '19.00', 'created_at' => '2026-11-08 08:00:00'];
|
|
do_action('jio_withdrawal_submitted', 1, $row);
|
|
$check(count($sender->messages) === 2, 'withdraw request should notify admins');
|
|
$check($sender->messages[0]['type'] === 'apply_withdraw_admin', 'withdraw request type');
|
|
$check($sender->messages[0]['values']['price'] === '20.00 CNY', 'withdraw request amount');
|
|
$check(str_contains($sender->messages[0]['url'], 'page=jio_withdraw'), 'withdraw admin URL');
|
|
$sender->messages = [];
|
|
do_action('jio_withdrawal_status_changed', 1, $row, \Jio\Payment\Withdrawal::STATUS_PROCESSING, '');
|
|
$check($sender->messages === [], 'intermediate withdrawal status should not send');
|
|
do_action('jio_withdrawal_status_changed', 1, $row, \Jio\Payment\Withdrawal::STATUS_COMPLETED, '');
|
|
$check(count($sender->messages) === 1, 'processed withdrawal should send once');
|
|
$check($sender->messages[0]['type'] === 'withdraw_process', 'processed withdrawal type');
|
|
$check($sender->messages[0]['values']['service_price'] === '1.00 CNY', 'withdraw fee field');
|
|
$check($sender->messages[0]['values']['received_price'] === '19.00 CNY', 'withdraw received field');
|
|
|
|
$sender->messages = [];
|
|
$comment = new WP_Comment(11, 9, '2026-11-10 09:00:00', 'Hello');
|
|
do_action('jio_wechat_comment_postauthor', 1, $comment);
|
|
do_action('jio_wechat_comment_parent', 2, $comment);
|
|
$check(count($sender->messages) === 2, 'comment should produce two distinct event types');
|
|
$check($sender->messages[0]['type'] === 'comment_to_postauthor', 'post author comment type');
|
|
$check($sender->messages[0]['values']['post'] === 'Product 9', 'post title field');
|
|
$check($sender->messages[1]['type'] === 'comment_to_parent', 'parent comment type');
|
|
$check($sender->messages[1]['values']['content'] === 'Hello', 'reply content field');
|
|
$check($sender->messages[1]['url'] === 'https://site.test/post/#comment-11', 'comment URL');
|
|
|
|
$sender->messages = [];
|
|
$command = new \Jio\Ledger\LedgerCommand('income-1', 'creator_income', [], 'revenue', '12', 0, ['order_number' => 'O-2']);
|
|
$entry = ['user_id' => 1, 'asset' => 'balance', 'delta_minor' => 250, 'entry_type' => 'credit'];
|
|
do_action('jio_asset_transaction_committed', new \Jio\Ledger\LedgerResult(1, true, [$entry], []), $command);
|
|
$check($sender->messages === [], 'replayed ledger result should not send');
|
|
do_action('jio_asset_transaction_committed', new \Jio\Ledger\LedgerResult(2, false, [$entry], []), $command);
|
|
$check(count($sender->messages) === 1, 'committed income should send once');
|
|
$check($sender->messages[0]['type'] === 'payment_order_to_income', 'income type');
|
|
$check($sender->messages[0]['values']['price'] === '2.50 CNY', 'income amount');
|
|
$check($sender->messages[0]['values']['num'] === 'O-2', 'income order number');
|
|
$sender->messages = [];
|
|
$command = new \Jio\Ledger\LedgerCommand('income-2', 'creator_income', [], 'revenue', '12', 0, ['order_number' => '12']);
|
|
do_action('jio_asset_transaction_committed', new \Jio\Ledger\LedgerResult(3, false, [$entry], []), $command);
|
|
$check(count($sender->messages) === 1 && $sender->messages[0]['values']['num'] === 'O-3', 'ledger record id resolved to order number');
|
|
|
|
echo "WeChat events harness passed\n";
|
|
}
|