276 lines
22 KiB
PHP
276 lines
22 KiB
PHP
<?php
|
|
|
|
$_SERVER['HTTP_HOST'] = 'localhost:9081';
|
|
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
|
if (($argv[1] ?? '') === 'install') {
|
|
define('WP_INSTALLING', true);
|
|
}
|
|
require '/var/www/html/wp-load.php';
|
|
|
|
if (($argv[1] ?? '') === 'set-browser-password') {
|
|
$password = (string) getenv('JIO_FORUM_TEST_PASSWORD');
|
|
$admin = get_user_by('login', 'forum_admin');
|
|
if (strlen($password) < 16 || !$admin instanceof WP_User) {
|
|
throw new RuntimeException('browser login configuration missing');
|
|
}
|
|
wp_set_password($password, (int) $admin->ID);
|
|
echo "browser login ready\n";
|
|
exit;
|
|
}
|
|
|
|
if (($argv[1] ?? '') === 'install') {
|
|
if (!is_blog_installed()) {
|
|
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
|
wp_install('Forum check', 'forum_admin', 'forum@example.test', false, '', wp_generate_password(24));
|
|
}
|
|
update_option('home', 'http://localhost:9081');
|
|
update_option('siteurl', 'http://localhost:9081');
|
|
switch_theme('jio');
|
|
echo "installed\n";
|
|
exit;
|
|
}
|
|
|
|
function forum_check(bool $condition, string $label): void {
|
|
if (!$condition) {
|
|
throw new RuntimeException($label);
|
|
}
|
|
echo "OK: {$label}\n";
|
|
}
|
|
|
|
function forum_request(string $method, string $route, int $user_id, array $params = [], string $key = ''): WP_REST_Response {
|
|
wp_set_current_user($user_id);
|
|
$request = new WP_REST_Request($method, '/jio/v1/forum/' . ltrim($route, '/'));
|
|
$request->set_header('X-WP-Nonce', wp_create_nonce('wp_rest'));
|
|
if ($key !== '') $request->set_header('Idempotency-Key', $key);
|
|
$request->set_body_params($params);
|
|
$response = rest_do_request($request);
|
|
forum_check($response instanceof WP_REST_Response, "REST response {$route}");
|
|
return $response;
|
|
}
|
|
|
|
forum_check(post_type_exists(\Jio\Forum\Core::PLATE), 'plate registered');
|
|
forum_check(post_type_exists(\Jio\Forum\Core::POST), 'post registered');
|
|
forum_check(taxonomy_exists(\Jio\Forum\Core::TOPIC), 'topic registered');
|
|
forum_check(get_page_by_path('forums') instanceof WP_Post, 'forum home created');
|
|
|
|
$schema = \Jio\Admin\SchemaProvider::get_instance()->get_schema('forum');
|
|
forum_check(is_array($schema) && count($schema['sections'] ?? []) === 7, 'forum settings schema');
|
|
$invalid_urls = \Jio\Admin\SchemaProvider::get_instance()->validate('forum', ['jio_forum_slug_plate' => 'forum-post'], 'urls');
|
|
forum_check(!$invalid_urls['valid'], 'duplicate URL slugs rejected');
|
|
|
|
$admin = get_user_by('login', 'forum_admin');
|
|
forum_check($admin instanceof WP_User, 'admin exists');
|
|
wp_set_current_user((int) $admin->ID);
|
|
$admin_schema_request = new WP_REST_Request('GET', '/jio/v1/settings/schema/forum/general');
|
|
$admin_schema_request->set_header('X-WP-Nonce', wp_create_nonce('wp_rest'));
|
|
$admin_schema_response = rest_do_request($admin_schema_request);
|
|
forum_check($admin_schema_response->get_status() === 200, 'admin forum settings route');
|
|
$member_login = 'forum_member_' . substr(str_replace('-', '', wp_generate_uuid4()), 0, 8);
|
|
$member_id = wp_create_user($member_login, wp_generate_password(24), $member_login . '@example.test');
|
|
forum_check(!is_wp_error($member_id), 'member created');
|
|
$member = get_userdata((int) $member_id);
|
|
|
|
wp_set_current_user((int) $admin->ID);
|
|
$plate = wp_insert_post(['post_type' => \Jio\Forum\Core::PLATE, 'post_status' => 'publish', 'post_title' => '测试版块', 'post_author' => (int) $admin->ID], true);
|
|
forum_check(!is_wp_error($plate) && $plate > 0, 'plate created');
|
|
|
|
$guest = forum_request('POST', 'posts', 0, ['title' => '测试帖子', 'content' => '正文内容', 'plate_id' => $plate]);
|
|
forum_check($guest->get_status() === 401, 'guest cannot publish');
|
|
|
|
$created = forum_request('POST', 'posts', (int) $member->ID, ['title' => '测试帖子', 'content' => '正文内容', 'plate_id' => $plate, 'type' => 'question']);
|
|
forum_check($created->get_status() === 200, 'member can submit');
|
|
$post_id = (int) ($created->get_data()['data']['id'] ?? 0);
|
|
forum_check($post_id > 0 && get_post_status($post_id) === 'pending', 'post awaits review');
|
|
|
|
$blocked = forum_request('POST', "posts/{$post_id}/audit", (int) $member->ID);
|
|
forum_check($blocked->get_status() === 403, 'member cannot audit');
|
|
$approved = forum_request('POST', "posts/{$post_id}/audit", (int) $admin->ID);
|
|
forum_check($approved->get_status() === 200 && get_post_status($post_id) === 'publish', 'moderator approves post');
|
|
|
|
$follow = forum_request('POST', "plates/{$plate}/follow", (int) $member->ID);
|
|
forum_check($follow->get_status() === 200 && \Jio\Forum\Access::follows((int) $member->ID, $plate), 'plate follow');
|
|
|
|
$reply = forum_request('POST', "posts/{$post_id}/replies", (int) $admin->ID, ['content' => '这是测试回复']);
|
|
forum_check($reply->get_status() === 200, 'reply submitted');
|
|
$comment_id = (int) ($reply->get_data()['data']['id'] ?? 0);
|
|
$adopt = forum_request('POST', "posts/{$post_id}/adopt", (int) $member->ID, ['comment_id' => $comment_id]);
|
|
forum_check($adopt->get_status() === 200, 'answer adopted');
|
|
$hot_reply = forum_request('POST', "replies/{$comment_id}/hot", (int) $admin->ID);
|
|
forum_check($hot_reply->get_status() === 200 && get_comment_meta($comment_id, '_jio_forum_hot', true), 'reply marked hot');
|
|
$reply_deleted = forum_request('POST', "replies/{$comment_id}/delete", (int) $member->ID);
|
|
forum_check($reply_deleted->get_status() === 403, 'other member cannot delete reply');
|
|
$reply_deleted = forum_request('POST', "replies/{$comment_id}/delete", (int) $admin->ID);
|
|
forum_check($reply_deleted->get_status() === 200 && get_comment($comment_id)->comment_approved === 'trash', 'moderator deletes reply');
|
|
forum_check(!get_post_meta($post_id, '_jio_forum_adopted_comment', true), 'deleted answer clears adoption');
|
|
$reply_restored = forum_request('POST', "replies/{$comment_id}/restore", (int) $admin->ID);
|
|
forum_check($reply_restored->get_status() === 200 && get_comment($comment_id)->comment_approved === '1', 'moderator restores reply');
|
|
$readopt = forum_request('POST', "posts/{$post_id}/adopt", (int) $member->ID, ['comment_id' => $comment_id]);
|
|
forum_check($readopt->get_status() === 200, 'restored answer may be adopted again');
|
|
$article_id = wp_insert_post(['post_type' => 'post', 'post_status' => 'publish', 'post_title' => '普通文章', 'post_author' => (int) $admin->ID]);
|
|
$article_comment = wp_insert_comment(['comment_post_ID' => $article_id, 'comment_content' => '普通文章评论', 'user_id' => (int) $member->ID, 'comment_approved' => 1]);
|
|
$wrong_comment_delete = forum_request('POST', "replies/{$article_comment}/delete", (int) $member->ID);
|
|
forum_check($wrong_comment_delete->get_status() === 403 && get_comment($article_comment)->comment_approved === '1', 'forum route cannot delete article comment');
|
|
|
|
$term_created = forum_request('POST', 'terms', (int) $admin->ID, ['type' => 'topic', 'name' => '测试话题']);
|
|
forum_check($term_created->get_status() === 200, 'forum topic created');
|
|
$term_id = (int) ($term_created->get_data()['data']['id'] ?? 0);
|
|
$term_updated = forum_request('PATCH', "terms/{$term_id}", (int) $admin->ID, ['name' => '新测试话题']);
|
|
forum_check($term_updated->get_status() === 200 && get_term($term_id)->name === '新测试话题', 'forum topic edited');
|
|
$term_deleted = forum_request('DELETE', "terms/{$term_id}", (int) $admin->ID);
|
|
forum_check($term_deleted->get_status() === 200, 'forum topic deleted');
|
|
|
|
$vote = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '测试投票', 'content' => '请选择选项', 'plate_id' => $plate, 'type' => 'vote', 'vote_options' => "选项一\n选项二"]);
|
|
forum_check($vote->get_status() === 200, 'vote post created');
|
|
$vote_id = (int) ($vote->get_data()['data']['id'] ?? 0);
|
|
$cast = forum_request('POST', "posts/{$vote_id}/vote", (int) $member->ID, ['option' => 0]);
|
|
forum_check($cast->get_status() === 200, 'vote cast');
|
|
$repeat = forum_request('POST', "posts/{$vote_id}/vote", (int) $member->ID, ['option' => 1]);
|
|
forum_check($repeat->get_status() === 200 && (int) get_post_meta($vote_id, '_jio_forum_vote_total', true) === 1, 'vote idempotent');
|
|
$multi = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '多选投票', 'content' => '选择多个选项', 'plate_id' => $plate, 'type' => 'vote', 'vote_type' => 'multiple', 'vote_title' => '你喜欢什么', 'vote_options' => "一\n二\n三"]);
|
|
forum_check($multi->get_status() === 200, 'multiple vote created');
|
|
$multi_id = (int) ($multi->get_data()['data']['id'] ?? 0);
|
|
$multi_cast = forum_request('POST', "posts/{$multi_id}/vote", (int) $member->ID, ['options' => [0, 2]]);
|
|
$multi_counts = (array) get_post_meta($multi_id, '_jio_forum_vote_counts', true);
|
|
forum_check($multi_cast->get_status() === 200 && (int) get_post_meta($multi_id, '_jio_forum_vote_total', true) === 1 && (int) ($multi_counts[0] ?? 0) === 1 && (int) ($multi_counts[2] ?? 0) === 1, 'multiple vote counts one voter');
|
|
$expired_vote = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '过期投票', 'content' => '已过期', 'plate_id' => $plate, 'type' => 'vote', 'vote_days' => 1, 'vote_options' => "甲\n乙"]);
|
|
forum_check($expired_vote->get_status() === 200, 'limited vote created');
|
|
$expired_id = (int) ($expired_vote->get_data()['data']['id'] ?? 0);
|
|
update_post_meta($expired_id, '_jio_forum_vote_deadline', current_time('timestamp') - 10);
|
|
$late_cast = forum_request('POST', "posts/{$expired_id}/vote", (int) $member->ID, ['option' => 0]);
|
|
forum_check($late_cast->get_status() === 409, 'expired vote rejects ballot');
|
|
$locked_vote = \Jio\Forum\Lock::acquire('vote', (int) $admin->ID, $vote_id);
|
|
forum_check($locked_vote !== '', 'vote lock acquired');
|
|
$overlap_vote = forum_request('POST', "posts/{$vote_id}/vote", (int) $admin->ID, ['option' => 0]);
|
|
forum_check($overlap_vote->get_status() === 409 && (int) get_post_meta($vote_id, '_jio_forum_vote_total', true) === 1, 'overlapping vote rejected');
|
|
\Jio\Forum\Lock::release('vote', (int) $admin->ID, $vote_id, $locked_vote);
|
|
$object_lock = \Jio\Forum\Lock::acquire('vote-object', 0, $vote_id);
|
|
forum_check($object_lock !== '', 'vote object lock acquired');
|
|
$cross_user_vote = forum_request('POST', "posts/{$vote_id}/vote", (int) $admin->ID, ['option' => 0]);
|
|
forum_check($cross_user_vote->get_status() === 409 && (int) get_post_meta($vote_id, '_jio_forum_vote_total', true) === 1, 'cross-user overlapping vote rejected');
|
|
\Jio\Forum\Lock::release('vote-object', 0, $vote_id, $object_lock);
|
|
$pinned = forum_request('POST', "posts/{$vote_id}/pin", (int) $admin->ID);
|
|
forum_check($pinned->get_status() === 200, 'post pinned');
|
|
$ordered = new WP_Query(['post_type' => \Jio\Forum\Core::POST, 'post_status' => 'publish', 'posts_per_page' => 1, 'jio_forum_list' => 'latest']);
|
|
forum_check((int) ($ordered->posts[0]->ID ?? 0) === $vote_id, 'pinned post leads list');
|
|
$favorite = forum_request('POST', "posts/{$vote_id}/favorite", (int) $member->ID);
|
|
forum_check($favorite->get_status() === 200 && (int) get_post_meta($vote_id, '_jio_forum_favorite_count', true) === 1, 'favorite count updated');
|
|
$scored = forum_request('POST', "posts/{$vote_id}/score", (int) $member->ID, ['direction' => 'up']);
|
|
forum_check($scored->get_status() === 200 && (int) get_post_meta($vote_id, '_jio_forum_score', true) === 1, 'score count updated');
|
|
|
|
$apply = forum_request('POST', "plates/{$plate}/apply", (int) $member->ID, ['reason' => '愿意维护版块']);
|
|
forum_check($apply->get_status() === 200, 'moderator application submitted');
|
|
$process = forum_request('POST', "plates/{$plate}/applications/{$member->ID}", (int) $admin->ID, ['status' => 'approved']);
|
|
forum_check($process->get_status() === 200 && \Jio\Forum\Access::is_moderator((int) $member->ID, $plate), 'moderator application approved');
|
|
|
|
$member_plate = forum_request('POST', 'plates', (int) $member->ID, ['title' => '用户创建版块']);
|
|
forum_check($member_plate->get_status() === 200, 'member plate submitted');
|
|
$member_plate_id = (int) ($member_plate->get_data()['data']['id'] ?? 0);
|
|
forum_check(get_post_status($member_plate_id) === 'pending', 'member plate awaits review');
|
|
$member_plate_approved = forum_request('POST', "plates/{$member_plate_id}/audit", (int) $admin->ID);
|
|
forum_check($member_plate_approved->get_status() === 200, 'member plate approved');
|
|
$member_plate_post = forum_request('POST', 'posts', (int) $member->ID, ['title' => '用户版块帖子', 'content' => '删除版块后应该一起入回收站', 'plate_id' => $member_plate_id]);
|
|
forum_check($member_plate_post->get_status() === 200, 'member plate post created');
|
|
$member_plate_post_id = (int) ($member_plate_post->get_data()['data']['id'] ?? 0);
|
|
$deleted_plate = forum_request('POST', "plates/{$member_plate_id}/delete", (int) $member->ID, ['posts_action' => 'trash']);
|
|
forum_check($deleted_plate->get_status() === 200 && get_post_status($member_plate_post_id) === 'trash', 'plate deletion cascades to posts');
|
|
$restored_plate = forum_request('POST', "plates/{$member_plate_id}/restore", (int) $member->ID);
|
|
forum_check($restored_plate->get_status() === 200 && get_post_status($member_plate_post_id) === 'publish', 'plate restore recovers posts (' . get_post_status($member_plate_post_id) . ')');
|
|
|
|
wp_set_current_user((int) $admin->ID);
|
|
$pay_test_plate = wp_insert_post(['post_type' => \Jio\Forum\Core::PLATE, 'post_status' => 'publish', 'post_title' => '付费测试版块', 'post_author' => (int) $admin->ID], true);
|
|
forum_check(!is_wp_error($pay_test_plate) && $pay_test_plate > 0, 'payment test plate created');
|
|
$pending_post = forum_request('POST', 'posts', (int) $member->ID, ['title' => '待审核恢复测试', 'content' => '恢复后不能绕过审核', 'plate_id' => $pay_test_plate]);
|
|
$pending_id = (int) ($pending_post->get_data()['data']['id'] ?? 0);
|
|
forum_check($pending_post->get_status() === 200 && get_post_status($pending_id) === 'pending', 'pending post created');
|
|
$pending_deleted = forum_request('POST', "posts/{$pending_id}/delete", (int) $member->ID);
|
|
forum_check($pending_deleted->get_status() === 200 && get_post_status($pending_id) === 'trash', 'pending post trashed');
|
|
$pending_restored = forum_request('POST', "posts/{$pending_id}/restore", (int) $member->ID);
|
|
forum_check($pending_restored->get_status() === 200 && get_post_status($pending_id) === 'pending', 'pending status preserved on restore');
|
|
|
|
\Jio\Core\DBMigrator::maybe_migrate();
|
|
$ledger = \Jio\Ledger\LedgerService::get_instance();
|
|
$credit = $ledger->credit((int) $member->ID, \Jio\Ledger\AssetType::POINTS, 30, \Jio\Ledger\OperationKey::unique('forum-smoke-credit'), 'forum_test_credit');
|
|
forum_check(!is_wp_error($credit), 'points credited');
|
|
$before = $ledger->balance((int) $member->ID, \Jio\Ledger\AssetType::POINTS);
|
|
$locked = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '积分帖子', 'content' => '需要积分查看的正文', 'plate_id' => $pay_test_plate, 'view_limit' => 'points', 'price' => '5']);
|
|
forum_check($locked->get_status() === 200, 'paid post created');
|
|
$locked_id = (int) ($locked->get_data()['data']['id'] ?? 0);
|
|
forum_check(!\Jio\Forum\Access::can_view((int) $member->ID, $locked_id), 'unpaid content locked');
|
|
$preview = forum_request('GET', "posts/{$locked_id}/checkout", (int) $member->ID);
|
|
forum_check($preview->get_status() === 200 && (string) ($preview->get_data()['data']['price'] ?? '') === '5', 'points preview');
|
|
$checkout_key = wp_generate_uuid4();
|
|
$checkout = forum_request('POST', "posts/{$locked_id}/checkout", (int) $member->ID, ['payment_method' => 'points'], $checkout_key);
|
|
forum_check($checkout->get_status() === 200, 'points checkout');
|
|
forum_check(\Jio\Forum\Access::can_view((int) $member->ID, $locked_id), 'paid content unlocked');
|
|
$after = $ledger->balance((int) $member->ID, \Jio\Ledger\AssetType::POINTS);
|
|
forum_check($after === $before - 5, 'points debited once');
|
|
$checkout_repeat = forum_request('POST', "posts/{$locked_id}/checkout", (int) $member->ID, ['payment_method' => 'points'], $checkout_key);
|
|
forum_check($checkout_repeat->get_status() === 200 && $ledger->balance((int) $member->ID, \Jio\Ledger\AssetType::POINTS) === $after, 'checkout idempotent');
|
|
|
|
$paid_plate = forum_request('POST', 'plates', (int) $admin->ID, ['title' => '积分版块', 'follow_mode' => 'points', 'follow_price' => '3', 'view_limit' => 'points']);
|
|
forum_check($paid_plate->get_status() === 200, 'paid plate created');
|
|
$paid_plate_id = (int) ($paid_plate->get_data()['data']['id'] ?? 0);
|
|
$plate_post = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '版块内帖子', 'content' => '付费版块内的内容', 'plate_id' => $paid_plate_id]);
|
|
forum_check($plate_post->get_status() === 200, 'paid plate post created');
|
|
$plate_post_id = (int) ($plate_post->get_data()['data']['id'] ?? 0);
|
|
forum_check(!\Jio\Forum\Access::can_view((int) $member->ID, $plate_post_id), 'paid plate content locked');
|
|
$nested_post = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '双层解锁帖子', 'content' => '双层付费正文', 'plate_id' => $paid_plate_id, 'view_limit' => 'points', 'price' => '1']);
|
|
forum_check($nested_post->get_status() === 200, 'nested paid post created');
|
|
$nested_post_id = (int) ($nested_post->get_data()['data']['id'] ?? 0);
|
|
$premature_checkout = forum_request('POST', "posts/{$nested_post_id}/checkout", (int) $member->ID, ['payment_method' => 'points'], wp_generate_uuid4());
|
|
forum_check($premature_checkout->get_status() === 402, 'post checkout requires parent plate access');
|
|
$denied_follow = forum_request('POST', "plates/{$paid_plate_id}/follow", (int) $member->ID);
|
|
forum_check($denied_follow->get_status() === 402, 'paid plate follow requires payment');
|
|
$follow_paid = forum_request('POST', "plates/{$paid_plate_id}/checkout", (int) $member->ID, ['payment_method' => 'points'], wp_generate_uuid4());
|
|
forum_check($follow_paid->get_status() === 200 && \Jio\Forum\Commerce::has_plate_entitlement((int) $member->ID, $paid_plate_id), 'paid plate entitlement');
|
|
forum_check(\Jio\Forum\Access::can_view((int) $member->ID, $plate_post_id), 'paid plate content unlocked');
|
|
$unfollow = forum_request('POST', "plates/{$paid_plate_id}/follow", (int) $member->ID);
|
|
forum_check($unfollow->get_status() === 200 && !\Jio\Forum\Commerce::has_plate_entitlement((int) $member->ID, $paid_plate_id), 'unfollow revokes entitlement');
|
|
forum_check(!\Jio\Forum\Access::can_view((int) $member->ID, $plate_post_id), 'unfollow relocks content');
|
|
$points_before_refollow = $ledger->balance((int) $member->ID, \Jio\Ledger\AssetType::POINTS);
|
|
$repurchase = forum_request('POST', "plates/{$paid_plate_id}/checkout", (int) $member->ID, ['payment_method' => 'points'], wp_generate_uuid4());
|
|
forum_check($repurchase->get_status() === 200 && \Jio\Forum\Commerce::has_plate_entitlement((int) $member->ID, $paid_plate_id), 'paid follow can be purchased again');
|
|
forum_check($ledger->balance((int) $member->ID, \Jio\Ledger\AssetType::POINTS) === $points_before_refollow - 3, 'second follow charged once');
|
|
|
|
$cash_credit = $ledger->credit((int) $member->ID, \Jio\Ledger\AssetType::BALANCE, 500, \Jio\Ledger\OperationKey::unique('forum-smoke-balance'), 'forum_test_credit');
|
|
forum_check(!is_wp_error($cash_credit), 'balance credited');
|
|
$cash_before = $ledger->balance((int) $member->ID, \Jio\Ledger\AssetType::BALANCE);
|
|
$cash_post = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '余额帖子', 'content' => '需要余额查看的正文', 'plate_id' => $pay_test_plate, 'view_limit' => 'pay', 'price' => '2.00']);
|
|
forum_check($cash_post->get_status() === 200, 'cash post created');
|
|
$cash_post_id = (int) ($cash_post->get_data()['data']['id'] ?? 0);
|
|
$cash_paid = forum_request('POST', "posts/{$cash_post_id}/checkout", (int) $member->ID, ['payment_method' => 'balance'], wp_generate_uuid4());
|
|
forum_check($cash_paid->get_status() === 200, 'balance checkout');
|
|
forum_check(\Jio\Forum\Access::can_view((int) $member->ID, $cash_post_id), 'balance content unlocked');
|
|
forum_check($ledger->balance((int) $member->ID, \Jio\Ledger\AssetType::BALANCE) === $cash_before - 200, 'balance debited once');
|
|
|
|
$lock = \Jio\Forum\Lock::acquire('checkout-forum_post', (int) $member->ID, $vote_id);
|
|
forum_check($lock !== '' && \Jio\Forum\Lock::acquire('checkout-forum_post', (int) $member->ID, $vote_id) === '', 'checkout lock excludes overlap');
|
|
\Jio\Forum\Lock::release('checkout-forum_post', (int) $member->ID, $vote_id, $lock);
|
|
$expensive = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '余额不足测试', 'content' => '订单复用正文', 'plate_id' => $pay_test_plate, 'view_limit' => 'pay', 'price' => '1000.00']);
|
|
$expensive_id = (int) ($expensive->get_data()['data']['id'] ?? 0);
|
|
forum_check($expensive->get_status() === 200, 'expensive post created');
|
|
$first_attempt = forum_request('POST', "posts/{$expensive_id}/checkout", (int) $member->ID, ['payment_method' => 'balance'], wp_generate_uuid4());
|
|
forum_check($first_attempt->get_status() === 402, 'insufficient balance rejected');
|
|
$second_attempt = forum_request('POST', "posts/{$expensive_id}/checkout", (int) $member->ID, ['payment_method' => 'balance'], wp_generate_uuid4());
|
|
forum_check($second_attempt->get_status() === 402, 'retry still insufficient (' . $second_attempt->get_status() . ': ' . wp_json_encode($second_attempt->get_data()) . ')');
|
|
$pending_orders = array_filter(\Jio\Payment\OrderRepository::get_instance()->get_user_orders((int) $member->ID, ['product_type' => 'forum_post', 'status' => 'pending', 'limit' => 100]), static fn(array $order): bool => (int) $order['product_id'] === $expensive_id);
|
|
forum_check(count($pending_orders) === 1, 'checkout retry reuses pending order');
|
|
$too_large = forum_request('POST', 'posts', (int) $admin->ID, ['title' => '无效价格测试', 'content' => '异常金额不应入库', 'plate_id' => $pay_test_plate, 'view_limit' => 'pay', 'price' => '9999999999999999999999999999999.00']);
|
|
forum_check($too_large->get_status() === 400, 'oversized price rejected before save');
|
|
update_post_meta($expensive_id, '_jio_forum_price', '9999999999999999999999999999999.00');
|
|
$invalid_preview = forum_request('GET', "posts/{$expensive_id}/checkout", (int) $member->ID);
|
|
forum_check($invalid_preview->get_status() === 400, 'invalid stored price cannot become free');
|
|
update_post_meta($expensive_id, '_jio_forum_price', '1000.00');
|
|
|
|
$settings = get_option('jio_settings', []);
|
|
$settings['jio_forum_enabled'] = false;
|
|
update_option('jio_settings', $settings);
|
|
\Jio\Settings\Settings::flush_settings_cache();
|
|
$disabled = forum_request('POST', 'posts', (int) $member->ID, ['title' => '已关闭论坛', 'content' => '不能发帖', 'plate_id' => $plate]);
|
|
forum_check($disabled->get_status() === 404, 'disabled forum rejects writes');
|
|
$settings['jio_forum_enabled'] = true;
|
|
update_option('jio_settings', $settings);
|
|
\Jio\Settings\Settings::flush_settings_cache();
|
|
|
|
echo "forum smoke passed\n";
|