Merge pull request #3 from codex/coin-consume
# Conflicts: # packages/shared/src/contracts/runtime.ts # server-rs/crates/module-runtime/src/lib.rs # server-rs/crates/shared-contracts/src/runtime.rs # server-rs/crates/spacetime-client/src/module_bindings/runtime_profile_wallet_ledger_source_type_type.rs # src/components/rpg-entry/RpgEntryHomeView.tsx
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { afterEach, expect, test, vi } from 'vitest';
|
||||
|
||||
@@ -11,7 +11,29 @@ import {
|
||||
} from './RpgEntryHomeView';
|
||||
import type { PlatformPublicGalleryCard } from './rpgEntryWorldPresentation';
|
||||
|
||||
const { mockGetRpgProfileWalletLedger } = vi.hoisted(() => ({
|
||||
mockGetRpgProfileWalletLedger: vi.fn(async () => ({
|
||||
entries: [
|
||||
{
|
||||
id: 'ledger-1',
|
||||
amountDelta: -1,
|
||||
balanceAfter: 29,
|
||||
sourceType: 'asset_operation_consume',
|
||||
createdAt: '2026-04-28T10:00:00Z',
|
||||
},
|
||||
{
|
||||
id: 'ledger-2',
|
||||
amountDelta: 30,
|
||||
balanceAfter: 30,
|
||||
sourceType: 'invite_invitee_reward',
|
||||
createdAt: '2026-04-28T09:00:00Z',
|
||||
},
|
||||
],
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock('../../services/rpg-entry/rpgProfileClient', () => ({
|
||||
getRpgProfileWalletLedger: mockGetRpgProfileWalletLedger,
|
||||
getRpgProfileRechargeCenter: vi.fn(async () => ({
|
||||
walletBalance: 0,
|
||||
membership: {
|
||||
@@ -269,20 +291,34 @@ afterEach(() => {
|
||||
});
|
||||
});
|
||||
|
||||
test('opens recharge modal and submits points product', async () => {
|
||||
test('opens wallet ledger modal from narrative coin card', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onRechargeSuccess = vi.fn();
|
||||
|
||||
renderProfileView(onRechargeSuccess);
|
||||
await user.click(screen.getByText('会员充值'));
|
||||
renderProfileView();
|
||||
await user.click(screen.getByText('剩余叙世币'));
|
||||
|
||||
expect(await screen.findByText('账户充值')).toBeTruthy();
|
||||
expect(await screen.findByText('叙世币充值')).toBeTruthy();
|
||||
expect(await screen.findByText('60叙世币')).toBeTruthy();
|
||||
expect(await screen.findByText('叙世币账单')).toBeTruthy();
|
||||
expect(mockGetRpgProfileWalletLedger).toHaveBeenCalledTimes(1);
|
||||
expect(screen.getByText('资产操作消耗')).toBeTruthy();
|
||||
expect(screen.getByText('-1')).toBeTruthy();
|
||||
expect(screen.getByText('填写邀请码奖励')).toBeTruthy();
|
||||
expect(screen.getByText('+30')).toBeTruthy();
|
||||
});
|
||||
|
||||
await user.click(screen.getByText('首充送60叙世币'));
|
||||
test('wallet ledger modal shows empty and error states', async () => {
|
||||
const user = userEvent.setup();
|
||||
mockGetRpgProfileWalletLedger.mockResolvedValueOnce({ entries: [] });
|
||||
|
||||
await waitFor(() => expect(onRechargeSuccess).toHaveBeenCalledTimes(1));
|
||||
renderProfileView();
|
||||
await user.click(screen.getByText('剩余叙世币'));
|
||||
expect(await screen.findByText('暂无账单记录')).toBeTruthy();
|
||||
|
||||
await user.click(screen.getByLabelText('关闭叙世币账单'));
|
||||
mockGetRpgProfileWalletLedger.mockRejectedValueOnce(new Error('加载失败'));
|
||||
await user.click(screen.getByText('剩余叙世币'));
|
||||
|
||||
expect(await screen.findByText('加载失败')).toBeTruthy();
|
||||
expect(screen.getByText('重新加载')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('shows a reachable login entry in logged out mobile shell', async () => {
|
||||
|
||||
Reference in New Issue
Block a user