e4d570e5d1
修复 legacy 余额回退与编辑器加载态 保留任务列表局部成功结果并持续钱包轮询 隔离邀请码异步状态并防止重复下单 补齐支付响应快照时序与定向回归测试 同步钱包与支付生命周期文档
120 lines
3.9 KiB
TypeScript
120 lines
3.9 KiB
TypeScript
/* @vitest-environment jsdom */
|
|
|
|
import { act } from '@testing-library/react';
|
|
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
|
import { usePlatformWalletStore } from '../../stores/usePlatformWalletStore';
|
|
import {
|
|
profileClientMocks,
|
|
renderController,
|
|
userA,
|
|
userB,
|
|
} from './usePlatformProfileCenterController.testSupport';
|
|
|
|
describe('usePlatformProfileCenterController redemption lifecycle', () => {
|
|
beforeEach(() => {
|
|
window.history.replaceState(null, '', '/profile');
|
|
usePlatformWalletStore.getState().resetWalletBalance();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
test('ignores a reward-code response after the account changes', async () => {
|
|
let resolveReward!: (value: {
|
|
walletBalance: number;
|
|
amountGranted: number;
|
|
ledgerEntry: never;
|
|
}) => void;
|
|
profileClientMocks.redeemPlatformProfileRewardCode.mockImplementation(
|
|
() =>
|
|
new Promise((resolve) => {
|
|
resolveReward = resolve;
|
|
}),
|
|
);
|
|
const onRechargeSuccess = vi.fn();
|
|
const { result, rerender } = renderController(userA, onRechargeSuccess);
|
|
act(() => result.current.setRewardCodeInput('reward-code'));
|
|
act(() => result.current.submitRewardCode());
|
|
|
|
rerender({ user: userB });
|
|
await act(async () => {
|
|
resolveReward({
|
|
walletBalance: 100,
|
|
amountGranted: 20,
|
|
ledgerEntry: undefined as never,
|
|
});
|
|
});
|
|
|
|
expect(result.current.rewardCodeSuccess).toBeNull();
|
|
expect(result.current.isSubmittingRewardCode).toBe(false);
|
|
expect(onRechargeSuccess).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('ignores an invite-code response after the account changes', async () => {
|
|
let resolveReferral!: (value: {
|
|
center: never;
|
|
inviteeRewardGranted: boolean;
|
|
inviterRewardGranted: boolean;
|
|
inviteeBalanceAfter: number;
|
|
inviterBalanceAfter: number;
|
|
}) => void;
|
|
profileClientMocks.redeemPlatformProfileReferralInviteCode.mockImplementation(
|
|
() =>
|
|
new Promise((resolve) => {
|
|
resolveReferral = resolve;
|
|
}),
|
|
);
|
|
const onRechargeSuccess = vi.fn();
|
|
const { result, rerender } = renderController(userA, onRechargeSuccess);
|
|
act(() => result.current.setReferralRedeemCode('invite-code'));
|
|
act(() => result.current.submitReferralRedeemCode());
|
|
|
|
rerender({ user: userB });
|
|
await act(async () => {
|
|
resolveReferral({
|
|
center: undefined as never,
|
|
inviteeRewardGranted: true,
|
|
inviterRewardGranted: false,
|
|
inviteeBalanceAfter: 100,
|
|
inviterBalanceAfter: 0,
|
|
});
|
|
});
|
|
|
|
expect(result.current.referralSuccess).toBeNull();
|
|
expect(result.current.isSubmittingReferralRedeem).toBe(false);
|
|
expect(onRechargeSuccess).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('clears referral UI and ignores a late referral-center read after account change', async () => {
|
|
let resolveReferralCenter!: (value: never) => void;
|
|
profileClientMocks.getPlatformProfileReferralInviteCenter.mockImplementation(
|
|
() =>
|
|
new Promise((resolve) => {
|
|
resolveReferralCenter = resolve;
|
|
}),
|
|
);
|
|
const { result, rerender } = renderController(userA);
|
|
act(() => {
|
|
result.current.openProfilePopupPanel('redeem');
|
|
result.current.setReferralRedeemCode('USER-A-CODE');
|
|
result.current.loadReferralCenter();
|
|
});
|
|
expect(result.current.profilePopupPanel).toBe('redeem');
|
|
expect(result.current.isLoadingReferral).toBe(true);
|
|
|
|
rerender({ user: userB });
|
|
|
|
expect(result.current.profilePopupPanel).toBeNull();
|
|
expect(result.current.referralRedeemCode).toBe('');
|
|
expect(result.current.referralCenter).toBeNull();
|
|
expect(result.current.isLoadingReferral).toBe(false);
|
|
await act(async () => {
|
|
resolveReferralCenter({
|
|
inviteCode: 'USER-A',
|
|
inviteLinkPath: '/?inviteCode=USER-A',
|
|
} as never);
|
|
});
|
|
expect(result.current.referralCenter).toBeNull();
|
|
expect(result.current.isLoadingReferral).toBe(false);
|
|
});
|
|
});
|