blob: beacf28cc0437ce90da4183ea3369f520ae30cee [file] [log] [blame]
Your Name292c25d2025-05-25 01:21:44 +08001package edu.bjtu.groupone.backend;
2
3import edu.bjtu.groupone.backend.mapper.UserMapper;
4import edu.bjtu.groupone.backend.utils.EmailUtil;
5import edu.bjtu.groupone.backend.service.impl.UserServImpl;
6import edu.bjtu.groupone.backend.model.User;
7import org.junit.jupiter.api.BeforeEach;
8import org.junit.jupiter.api.Test;
9import org.junit.jupiter.api.extension.ExtendWith;
10import org.mockito.InjectMocks;
11import org.mockito.Mock;
12import org.mockito.junit.jupiter.MockitoExtension;
13
14import java.lang.reflect.Field;
15
16import static org.assertj.core.api.Assertions.*;
17import static org.mockito.Mockito.*;
18
19/**
20 * 单元测试 UserServImpl 的核心逻辑:登录、发/验注册码、发/验重置码、重置密码。
21 */
22@ExtendWith(MockitoExtension.class)
23public class UserServImplTest {
24
25 @Mock
26 private UserMapper userMapper;
27
28 @Mock
29 private EmailUtil emailUtil;
30
31 @InjectMocks
32 private UserServImpl userService;
33
34 @BeforeEach
35 void clearCaches() throws Exception {
36 clearMap("emailCodes");
37 clearMap("resetCodes");
38 }
39
40 @Test
41 public void login_shouldReturnUser_whenCredentialsMatch() {
42 User in = new User();
43 in.setEmail("a@b.com");
44 in.setPassword("pwd");
45 User out = new User();
46 out.setUserId(1);
47 out.setUsername("alice");
48 out.setEmail("a@b.com");
49 when(userMapper.login(in)).thenReturn(out);
50
51 User result = userService.login(in);
52 assertThat(result).isSameAs(out);
53 verify(userMapper, times(1)).login(in);
54 }
55
56 @Test
57 public void sendVerification_and_verifyCode_workCorrectly() throws Exception {
58 String email = "test@x.com";
59 userService.sendVerificationCode(email);
60 verify(emailUtil).sendVerificationEmail(eq(email), anyString());
61
62 String stored = readMap("emailCodes", email);
63 String code = stored.split("\\|")[0];
64 assertThat(userService.verifyCode(email, code)).isTrue();
65 assertThat(userService.verifyCode(email, "000000")).isFalse();
66
67 // 模拟过期
68 patchExpiry("emailCodes", email, -1000L);
69 assertThat(userService.verifyCode(email, code)).isFalse();
70 }
71
72 @Test
73 public void sendResetCode_and_resetPassword_workCorrectly() throws Exception {
74 String email = "reset@x.com";
75 when(userMapper.selectByEmail(email)).thenReturn(null);
76 assertThatThrownBy(() -> userService.sendResetCode(email))
77 .isInstanceOf(IllegalArgumentException.class);
78
79 User u = new User();
80 u.setEmail(email);
81 when(userMapper.selectByEmail(email)).thenReturn(u);
82
83 userService.sendResetCode(email);
84 verify(emailUtil).sendVerificationEmail(eq(email), anyString());
85 String stored = readMap("resetCodes", email);
86 String code = stored.split("\\|")[0];
87
88 when(userMapper.updatePasswordByEmail(email, "newpwd")).thenReturn(1);
89 assertThat(userService.resetPassword(email, code, "newpwd")).isTrue();
90 assertThat(userService.resetPassword(email, code, "abc")).isFalse();
91
92 userService.sendResetCode(email);
93 String stored2 = readMap("resetCodes", email);
94 String code2 = stored2.split("\\|")[0];
95 patchExpiry("resetCodes", email, -2000L);
96 assertThat(userService.resetPassword(email, code2, "pw")).isFalse();
97 }
98
99 // --- 反射辅助方法 ---
100 @SuppressWarnings("unchecked")
101 private void clearMap(String fieldName) throws Exception {
102 Field f = UserServImpl.class.getDeclaredField(fieldName);
103 f.setAccessible(true);
104 ((java.util.Map<String, String>)f.get(userService)).clear();
105 }
106
107 @SuppressWarnings("unchecked")
108 private String readMap(String fieldName, String key) throws Exception {
109 Field f = UserServImpl.class.getDeclaredField(fieldName);
110 f.setAccessible(true);
111 return ((java.util.Map<String, String>)f.get(userService)).get(key);
112 }
113
114 @SuppressWarnings("unchecked")
115 private void patchExpiry(String fieldName, String key, long offsetMs) throws Exception {
116 String combined = readMap(fieldName, key);
117 String code = combined.split("\\|")[0];
118 long expire = System.currentTimeMillis() + offsetMs;
119 String updated = code + "|" + expire;
120 Field f = UserServImpl.class.getDeclaredField(fieldName);
121 f.setAccessible(true);
122 ((java.util.Map<String, String>)f.get(userService)).put(key, updated);
123 }
124}