feat(billing): guide parents to recharge the child account

This commit is contained in:
brother7 committed 2026-10-09 08:43:05 +08:00
1 parent fe1a3775c5
commit 281e6dc151
10 files changed
+105 -14

No files matched your search

+19 -2
View File
@@ -27,14 +27,31 @@ describe('permanent point wallet', () => {
expect(dialog).toHaveTextContent('永久有效');
expect(screen.queryByText(/重置卡|升级订阅|本周剩余/)).not.toBeInTheDocument();
});
it('shows youth own precision and shared availability without enabling recharge', async () => {
it('honors unavailable recharge without asking the user to change account identity', async () => {
api.summary.mockResolvedValue(billingSummary({ can_recharge: false, payment_configured: false, own_points: permanentBalance({ can_recharge: false }), points: permanentBalance({ total: null, used: null, reserved: null, total_remaining: null, family_shared: true, entitlement_source: 'family_owner', shared_available: false, can_recharge: false }) }));
render(<PointWallet />); await screen.findByText('75 点');
expect(screen.getByText(/AI 编程使用共享点数/)).toHaveTextContent('已用尽');
fireEvent.click(screen.getByTestId('sidebar-point-wallet-open'));
await screen.findByText(/仅家长身份可以充值/);
await screen.findByText(/当前账号暂不能充值,请在社区账户页查看原因或联系支持/);
expect(screen.queryByText(/仅家长身份可以充值/)).not.toBeInTheDocument();
expect(screen.getByRole('button', { name: /500 点\s*¥10.00/ })).toBeDisabled();
});
it('recharges the displayed child account while leaving shared funding selected', async () => {
api.summary.mockResolvedValue(billingSummary({ points: permanentBalance({ total: null, used: null, reserved: null, total_remaining: null, family_shared: true, entitlement_source: 'shared_group', shared_available: true, can_recharge: false }) }));
render(<PointWallet accountName="小麦" accountUsername="child-account" />);
await screen.findByText('75 点');
fireEvent.click(screen.getByTestId('sidebar-point-wallet-open'));
const dialog = screen.getByTestId('point-wallet-dialog');
expect(screen.getByTestId('point-recharge-recipient')).toHaveTextContent('充值到:小麦(child-account)');
expect(dialog).toHaveTextContent('请由家长登录孩子的账号完成付款');
expect(dialog).toHaveTextContent('充值不会自动切换付款来源');
const buy = within(dialog).getByRole('button', { name: /500 点\s*¥10.00/ });
await waitFor(() => expect(buy).toBeEnabled());
fireEvent.click(buy);
await screen.findByTestId('point-recharge-checkout');
expect(api.create).toHaveBeenCalledWith('recharge-10', expect.any(String));
expect(api.external).not.toHaveBeenCalled();
});
it('does not mistake the family payer’s own shared wallet for an exhausted external wallet', async () => {
api.summary.mockResolvedValue(billingSummary({ points: permanentBalance({ family_shared: true, entitlement_source: 'shared_group' }) }));
await openWallet();