注册时自动使用链接邀请码
手机号注册提交链接中的邀请码。 系统邀请码 metadata.tags 会合并到账户标签。 更新自动兑换邀请码的前端与模块测试。
This commit is contained in:
@@ -1631,6 +1631,16 @@ mod tests {
|
||||
assert!(result.error_message.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invite_code_metadata_tags_are_user_tags() {
|
||||
let tags = profile_invite_code_metadata_user_tags(
|
||||
r#"{"tags":["系统"," beta ","系统"],"channel":"spring"}"#,
|
||||
)
|
||||
.expect("metadata tags should parse");
|
||||
|
||||
assert_eq!(tags, vec!["系统".to_string(), "beta".to_string()]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recent_public_work_play_counts_group_requested_profiles_in_window() {
|
||||
let now_micros = PUBLIC_WORK_PLAY_DAY_MICROS * 10;
|
||||
@@ -2801,6 +2811,7 @@ fn profile_invite_code_metadata_user_tags(metadata_json: &str) -> Result<Vec<Str
|
||||
let tags = metadata
|
||||
.get("userTags")
|
||||
.or_else(|| metadata.get("user_tags"))
|
||||
.or_else(|| metadata.get("tags"))
|
||||
.and_then(JsonValue::as_array)
|
||||
.map(|items| {
|
||||
items
|
||||
|
||||
@@ -636,7 +636,7 @@ test('phone login result is not overwritten by an older guest hydrate', async ()
|
||||
expect(screen.queryByRole('dialog', { name: '账号入口' })).toBeNull();
|
||||
});
|
||||
|
||||
test('auth gate hides register entry and opens invite modal for new sms account', async () => {
|
||||
test('auth gate auto redeems link invite code for new sms account', async () => {
|
||||
const user = userEvent.setup();
|
||||
window.history.replaceState(null, '', '/?inviteCode=spring-2026');
|
||||
authMocks.getAuthLoginOptions.mockResolvedValue({
|
||||
@@ -646,7 +646,14 @@ test('auth gate hides register entry and opens invite modal for new sms account'
|
||||
token: 'jwt-phone-new',
|
||||
user: mockUser,
|
||||
created: true,
|
||||
referral: null,
|
||||
referral: {
|
||||
ok: true,
|
||||
message: '邀请码已绑定',
|
||||
inviteeRewardGranted: true,
|
||||
inviterRewardGranted: false,
|
||||
inviteeBalanceAfter: 30,
|
||||
inviterBalanceAfter: 0,
|
||||
},
|
||||
});
|
||||
|
||||
render(
|
||||
@@ -674,30 +681,12 @@ test('auth gate hides register entry and opens invite modal for new sms account'
|
||||
expect(authMocks.loginWithPhoneCode).toHaveBeenCalledWith(
|
||||
'13800000000',
|
||||
'123456',
|
||||
);
|
||||
});
|
||||
|
||||
const inviteDialog = await screen.findByRole('dialog', {
|
||||
name: '请填写邀请码',
|
||||
});
|
||||
expect(inviteDialog.className).toContain('platform-auth-card');
|
||||
expect(inviteDialog.className).toContain('platform-modal-shell');
|
||||
const inviteCodeInput = within(inviteDialog).getByLabelText(
|
||||
'邀请码',
|
||||
) as HTMLInputElement;
|
||||
expect(inviteCodeInput.value).toBe('SPRING2026');
|
||||
expect(inviteCodeInput.className).toContain('platform-text-field');
|
||||
expect(
|
||||
within(inviteDialog).getByRole('button', { name: '提交' }),
|
||||
).toBeTruthy();
|
||||
|
||||
await user.click(within(inviteDialog).getByRole('button', { name: '提交' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(authMocks.redeemRegistrationInviteCode).toHaveBeenCalledWith(
|
||||
'SPRING2026',
|
||||
);
|
||||
});
|
||||
|
||||
expect(screen.queryByRole('dialog', { name: '请填写邀请码' })).toBeNull();
|
||||
expect(authMocks.redeemRegistrationInviteCode).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('registration invite modal can skip when invite code is empty', async () => {
|
||||
|
||||
@@ -966,11 +966,26 @@ export function AuthGate({ children }: AuthGateProps) {
|
||||
setLoggingIn(true);
|
||||
setError('');
|
||||
try {
|
||||
const response = await loginWithPhoneCode(phone, code);
|
||||
const registrationInviteCode =
|
||||
pendingInviteCode || readInviteCodeFromLocation();
|
||||
const response = registrationInviteCode
|
||||
? await loginWithPhoneCode(phone, code, registrationInviteCode)
|
||||
: await loginWithPhoneCode(phone, code);
|
||||
const autoRedeemedInvite = response.referral?.ok === true;
|
||||
setStoredLastLoginPhone(phone);
|
||||
setLoginCaptchaChallenge(null);
|
||||
setShowRegistrationInviteModal(response.created);
|
||||
setRegistrationInviteError('');
|
||||
setShowRegistrationInviteModal(
|
||||
response.created && !autoRedeemedInvite,
|
||||
);
|
||||
setRegistrationInviteError(
|
||||
response.referral?.ok === false
|
||||
? (response.referral.message ??
|
||||
'邀请码绑定失败,请确认后重试。')
|
||||
: '',
|
||||
);
|
||||
if (autoRedeemedInvite) {
|
||||
setPendingInviteCode('');
|
||||
}
|
||||
activateReadyUser(response.user);
|
||||
} catch (loginError) {
|
||||
setError(
|
||||
|
||||
Reference in New Issue
Block a user