blob: 22a9b1ebaa4eb116fd64e28d72ac92754186c98b [file] [log] [blame]
root0dbc9812025-05-19 04:41:57 +00001package databasetest;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Map;
8import java.util.UUID;
9import java.util.stream.Collectors;
10import java.util.stream.IntStream;
11
12import javax.persistence.EntityManager;
13import javax.persistence.EntityManagerFactory;
14import javax.persistence.EntityTransaction;
15import javax.persistence.Persistence;
16
17import org.junit.jupiter.api.AfterAll;
18import org.junit.jupiter.api.Assertions;
19import org.junit.jupiter.api.BeforeAll;
20import org.junit.jupiter.api.DynamicTest;
21import org.junit.jupiter.api.TestFactory;
22
TRM-codingcdfe5482025-06-06 17:31:01 +080023import entity.UserInvite;
24import entity.QUserInvite;
root0dbc9812025-05-19 04:41:57 +000025import database.Database1;
26import entity.User;
27import entity.config;
28
29public class databasesystest {
30 private static EntityManagerFactory emf;
31 private static EntityManager em;
32 private static Database1 db;
33 private static List<String> testUserIds;
34 private static List<String> testEmails;
35
36 @BeforeAll
37 static void setup() throws Exception {
38 Class.forName("com.mysql.cj.jdbc.Driver");
39 config cfg = new config();
40 Map<String, Object> props = new HashMap<>();
41 String jdbcUrl = String.format(
42 "jdbc:mysql://%s/%s?useSSL=false&serverTimezone=UTC",
43 cfg.SqlURL, cfg.TestDatabase);
44 props.put("javax.persistence.jdbc.url", jdbcUrl);
45 props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
46 props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
47 props.put("javax.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
48 emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
49 em = emf.createEntityManager();
Raverf79fdb62025-06-03 06:02:49 +000050 db = new Database1();
51 java.lang.reflect.Field f = Database1.class.getDeclaredField("entitymanager");
52 f.setAccessible(true);
53 f.set(db, em);
root0dbc9812025-05-19 04:41:57 +000054 testUserIds = new ArrayList<>();
55 testEmails = new ArrayList<>();
56 for (int i = 0; i < 10; i++) {
57 String id = "test_user_" + i + "_" + UUID.randomUUID();
58 if (id.length() > 36) id = id.substring(0, 36);
59 testUserIds.add(id);
60 testEmails.add("test_email_" + i + "@example.com");
61 }
62 }
63
64 @AfterAll
65 static void teardown() {
66 EntityTransaction tx = em.getTransaction();
67 tx.begin();
68 for (String uid : testUserIds) {
69 User found = em.find(User.class, uid);
70 if (found != null) em.remove(found);
71 }
72 tx.commit();
73 if (em != null && em.isOpen()) em.close();
74 if (emf != null && emf.isOpen()) emf.close();
75 }
76
77 @TestFactory
78 Collection<DynamicTest> testRegisterUser() {
79 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("RegisterUser test #" + i, () -> {
80 EntityTransaction tx = em.getTransaction();
81 tx.begin();
82 try {
TRM-codingcdfe5482025-06-06 17:31:01 +080083 // 1. 创建一些用户并将其保存到数据库中
84 List<User> existingUsers = new ArrayList<>();
85 for (int j = 0; j < 3; j++) {
86 User existingUser = new User();
87 String userId = "existing_user_" + i + "_" + j;
88 if (userId.length() > 36) userId = userId.substring(0, 36);
89 existingUser.userid = userId;
90 existingUser.email = "existing_email_" + i + "_" + j + "@example.com";
91 existingUser.username = "existing_user" + i + "_" + j;
92 existingUser.password = "pwd" + i;
93 existingUser.sex = "m";
94 existingUser.school = "school" + i;
95 existingUser.pictureurl = null;
96 existingUser.profile = null;
97 existingUser.accountstate = false;
98 existingUser.invitetimes = 5;
99
100 entity.UserPT existingUserPT = new entity.UserPT();
101 existingUserPT.userid = existingUser.userid;
102 existingUserPT.magic = 0;
103 existingUserPT.upload = 0L;
104 existingUserPT.download = 0L;
105 existingUserPT.share = 0.0;
106 existingUserPT.farmurl = null;
107 existingUserPT.viptime = 0;
108 existingUserPT.user = existingUser;
109 existingUser.userPT = existingUserPT;
110
111 em.persist(existingUser);
112 existingUsers.add(existingUser);
113 }
114 em.flush();
115
116 // 2. 创建邀请记录 - 一些被邀请的邮箱和一些未被邀请的邮箱
117 // 被邀请的邮箱列表
118 List<String> invitedEmails = new ArrayList<>();
119 for (int j = 0; j < 3; j++) {
120 // 生成邀请记录
121 String invitedEmail = "invited_" + i + "_" + j + "@example.com";
122 invitedEmails.add(invitedEmail);
123
124 UserInvite invite = new UserInvite();
125 invite.userId = existingUsers.get(j % existingUsers.size()).userid; // 使用现有用户作为邀请人
126 invite.inviterEmail = invitedEmail;
127 invite.inviterRegistered = false;
128 em.persist(invite);
129 }
130 em.flush();
131
132 // 非邀请邮箱
133 List<String> uninvitedEmails = new ArrayList<>();
134 for (int j = 0; j < 2; j++) {
135 uninvitedEmails.add("uninvited_" + i + "_" + j + "@example.com");
136 }
137
138 // 3. 测试被邀请且首次注册的用户 - 应该成功 (返回0)
139 User invitedUser = new User();
140 String invitedUserId = testUserIds.get(i);
141 if (invitedUserId.length() > 36) invitedUserId = invitedUserId.substring(0, 36);
142 invitedUser.userid = invitedUserId;
143 invitedUser.email = invitedEmails.get(0); // 使用被邀请的邮箱
144 invitedUser.username = "invited_user" + i;
145 invitedUser.password = "pwd" + i;
146 invitedUser.sex = "m";
147 invitedUser.school = "school" + i;
148 invitedUser.pictureurl = null;
149 invitedUser.profile = null;
150 invitedUser.accountstate = false;
151 invitedUser.invitetimes = 5;
152
153 entity.UserPT invitedUserPT = new entity.UserPT();
154 invitedUserPT.userid = invitedUser.userid;
155 invitedUserPT.magic = 0;
156 invitedUserPT.upload = 0L;
157 invitedUserPT.download = 0L;
158 invitedUserPT.share = 0.0;
159 invitedUserPT.farmurl = null;
160 invitedUserPT.viptime = 0;
161 invitedUserPT.user = invitedUser;
162 invitedUser.userPT = invitedUserPT;
163
164 int ret1 = db.RegisterUser(invitedUser);
165 Assertions.assertEquals(0, ret1, "RegisterUser should return 0 for invited user's first registration");
166
167 // 检查用户是否已保存到数据库
168 User checkUser = em.find(User.class, invitedUserId);
169 Assertions.assertNotNull(checkUser, "User should be saved to database when registration succeeds");
170 Assertions.assertEquals(invitedUser.email, checkUser.email);
171
172 // 4. 测试被邀请但重复注册的用户 - 应该失败 (返回1)
173 User duplicateUser = new User();
174 String duplicateUserId = "duplicate_" + i;
175 if (duplicateUserId.length() > 36) duplicateUserId = duplicateUserId.substring(0, 36);
176 duplicateUser.userid = duplicateUserId;
177 duplicateUser.email = invitedEmails.get(0); // 重复使用同一个邮箱
178 duplicateUser.username = "duplicate_user" + i;
179 duplicateUser.password = "pwd_dup" + i;
180 duplicateUser.sex = "f";
181 duplicateUser.school = "school_dup" + i;
182 duplicateUser.pictureurl = null;
183 duplicateUser.profile = null;
184 duplicateUser.accountstate = false;
185 duplicateUser.invitetimes = 5;
186
187 int ret2 = db.RegisterUser(duplicateUser);
root0dbc9812025-05-19 04:41:57 +0000188 Assertions.assertEquals(1, ret2, "RegisterUser should return 1 for duplicate email");
TRM-codingcdfe5482025-06-06 17:31:01 +0800189
190 // 5. 测试未被邀请的用户 - 应该失败 (返回2)
191 User uninvitedUser = new User();
192 String uninvitedUserId = "uninvited_" + i;
193 if (uninvitedUserId.length() > 36) uninvitedUserId = uninvitedUserId.substring(0, 36);
194 uninvitedUser.userid = uninvitedUserId;
195 uninvitedUser.email = uninvitedEmails.get(0); // 使用未被邀请的邮箱
196 uninvitedUser.username = "uninvited_user" + i;
197 uninvitedUser.password = "pwd_uninv" + i;
198 uninvitedUser.sex = "m";
199 uninvitedUser.school = "school_uninv" + i;
200 uninvitedUser.pictureurl = null;
201 uninvitedUser.profile = null;
202 uninvitedUser.accountstate = false;
203 uninvitedUser.invitetimes = 5;
204
205 int ret3 = db.RegisterUser(uninvitedUser);
206 Assertions.assertEquals(2, ret3, "RegisterUser should return 2 for uninvited email");
207
root0dbc9812025-05-19 04:41:57 +0000208 } finally {
TRM-codingcdfe5482025-06-06 17:31:01 +0800209 // 确保回滚所有更改,不影响真实数据库
root0dbc9812025-05-19 04:41:57 +0000210 tx.rollback();
211 }
212 })).collect(Collectors.toList());
213 }
214
215 @TestFactory
216 Collection<DynamicTest> testUpdateInformation() {
217 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateInformation test #" + i, () -> {
218 EntityTransaction tx = em.getTransaction();
219 tx.begin();
220 try {
221 // 先插入一个用户
222 User user = new User();
223 String userId = testUserIds.get(i);
224 if (userId.length() > 36) userId = userId.substring(0, 36);
225 user.userid = userId;
226 user.email = testEmails.get(i);
227 user.username = "user" + i;
228 user.password = "pwd" + i;
229 user.sex = "m";
230 user.school = "school" + i;
231 user.pictureurl = null;
232 user.profile = null;
233 user.accountstate = false;
234 user.invitetimes = 5;
235 entity.UserPT userPT = new entity.UserPT();
236 userPT.userid = user.userid;
237 userPT.magic = 0;
238 userPT.upload = 0L;
239 userPT.download = 0L;
240 userPT.share = 0.0;
241 userPT.farmurl = null;
242 userPT.viptime = 0;
243 userPT.user = user;
244 user.userPT = userPT;
245 em.persist(user);
246 em.flush();
247 // 更新信息
248 User updated = new User();
249 updated.userid = userId;
250 updated.email = testEmails.get(i);
251 updated.username = "user_updated" + i;
252 updated.password = "newpassword" + i;
253 updated.sex = "f";
254 updated.school = "MIT" + i;
255 updated.pictureurl = "https://cdn.example.com/avatars/user_new" + i + ".jpg";
256 updated.profile = "Updated profile " + i;
257 updated.accountstate = true;
258 updated.invitetimes = 10 + i;
259 int ret = db.UpdateInformation(updated);
260 Assertions.assertEquals(0, ret, "UpdateInformation should return 0 for success");
261 em.flush();
262 em.clear();
263 User after = em.find(User.class, userId);
264 Assertions.assertEquals("user_updated" + i, after.username);
265 Assertions.assertEquals("newpassword" + i, after.password);
266 Assertions.assertEquals("f", after.sex);
267 Assertions.assertEquals("MIT" + i, after.school);
268 Assertions.assertEquals("https://cdn.example.com/avatars/user_new" + i + ".jpg", after.pictureurl);
269 Assertions.assertEquals("Updated profile " + i, after.profile);
270 Assertions.assertTrue(after.accountstate);
271 Assertions.assertEquals(10 + i, after.invitetimes);
272 // 测试不存在用户
273 User notExist = new User();
274 notExist.userid = "not_exist_user_" + i;
275 notExist.email = "not_exist" + i + "@example.com";
276 notExist.username = "not_exist";
277 notExist.password = "not_exist";
278 notExist.sex = "m";
279 notExist.school = "not_exist";
280 notExist.pictureurl = null;
281 notExist.profile = null;
282 notExist.accountstate = false;
283 notExist.invitetimes = 0;
284 int ret2 = db.UpdateInformation(notExist);
285 Assertions.assertEquals(1, ret2, "UpdateInformation should return 1 for not found user");
286 } finally {
287 tx.rollback();
288 }
289 })).collect(Collectors.toList());
290 }
291
292 @TestFactory
293 Collection<DynamicTest> testGetInformation() {
294 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetInformation test #" + i, () -> {
295 EntityTransaction tx = em.getTransaction();
296 tx.begin();
297 try {
298 // 先插入一个用户(补充userPT字段,避免not-null property异常)
299 User user = new User();
300 user.userid = testUserIds.get(i);
301 if (user.userid.length() > 36) user.userid = user.userid.substring(0, 36);
302 user.email = testEmails.get(i);
303 user.username = "user" + i;
304 user.password = "pwd" + i;
305 user.sex = "m";
306 user.school = "school" + i;
307 user.pictureurl = "pic" + i + ".jpg";
308 user.profile = "profile" + i;
309 user.accountstate = false;
310 user.invitetimes = 5;
311 entity.UserPT userPT = new entity.UserPT();
312 userPT.userid = user.userid;
313 userPT.magic = 0;
314 userPT.upload = 0L;
315 userPT.download = 0L;
316 userPT.share = 0.0;
317 userPT.farmurl = null;
318 userPT.viptime = 0;
319 userPT.user = user;
320 user.userPT = userPT;
321 em.persist(user);
322 em.flush();
323 // 查询
324 User got = db.GetInformation(testUserIds.get(i));
325 Assertions.assertNotNull(got, "GetInformation should return user");
326 Assertions.assertEquals(user.userid, got.userid);
327 Assertions.assertEquals(user.email, got.email);
328 Assertions.assertEquals(user.username, got.username);
329 Assertions.assertEquals(user.password, got.password);
330 Assertions.assertEquals(user.sex, got.sex);
331 Assertions.assertEquals(user.school, got.school);
332 Assertions.assertEquals(user.pictureurl, got.pictureurl);
333 Assertions.assertEquals(user.profile, got.profile);
334 Assertions.assertEquals(user.accountstate, got.accountstate);
335 Assertions.assertEquals(user.invitetimes, got.invitetimes);
336 // 查询不存在用户
337 User notExist = db.GetInformation("not_exist_" + i);
338 Assertions.assertNull(notExist, "GetInformation should return null for not found user");
339 } finally {
340 tx.rollback();
341 }
342 })).collect(Collectors.toList());
343 }
344
345 @TestFactory
346 Collection<DynamicTest> testGetInformationPT() {
347 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetInformationPT test #" + i, () -> {
348 EntityTransaction tx = em.getTransaction();
349 tx.begin();
350 try {
351 // 先插入User
352 User user = new User();
353 String userId = testUserIds.get(i);
354 if (userId.length() > 36) userId = userId.substring(0, 36);
355 user.userid = userId;
356 user.email = testEmails.get(i);
357 user.username = "user" + i;
358 user.password = "pwd" + i;
359 user.sex = "m";
360 user.school = "school" + i;
361 user.pictureurl = null;
362 user.profile = null;
363 user.accountstate = false;
364 user.invitetimes = 5;
365 // 同时插入UserPT,保证外键依赖
366 entity.UserPT userPT = new entity.UserPT();
367 userPT.userid = userId;
368 userPT.magic = 100 + i;
369 userPT.upload = 1000L + i;
370 userPT.download = 2000L + i;
371 userPT.share = 1.5 + i;
372 userPT.farmurl = "/data/seeds/" + userId;
373 userPT.viptime = 3 + i;
374 userPT.user = user;
375 user.userPT = userPT;
376 em.persist(user);
377 em.persist(userPT);
378 em.flush();
379 // 查询
380 entity.UserPT got = db.GetInformationPT(userId);
381 Assertions.assertNotNull(got, "GetInformationPT should return UserPT");
382 Assertions.assertEquals(userId, got.userid);
383 Assertions.assertEquals(100 + i, got.magic);
384 Assertions.assertEquals(1000L + i, got.upload);
385 Assertions.assertEquals(2000L + i, got.download);
386 Assertions.assertEquals(1.5 + i, got.share);
387 Assertions.assertEquals("/data/seeds/" + userId, got.farmurl);
388 Assertions.assertEquals(3 + i, got.viptime);
389 // 查询不存在用户
390 entity.UserPT notExist = db.GetInformationPT("not_exist_user_" + i);
391 Assertions.assertNull(notExist, "GetInformationPT should return null for not found user");
392 } finally {
393 tx.rollback();
394 }
395 })).collect(Collectors.toList());
396 }
397
398 @TestFactory
399 Collection<DynamicTest> testUpdateInformationPT() {
400 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateInformationPT test #" + i, () -> {
401 EntityTransaction tx = em.getTransaction();
402 tx.begin();
403 try {
404 // 先插入User
405 User user = new User();
406 String userId = testUserIds.get(i);
407 user.userid = userId;
408 user.email = testEmails.get(i);
409 user.username = "user" + i;
410 user.password = "pwd" + i;
411 user.sex = "m";
412 user.school = "school" + i;
413 user.pictureurl = null;
414 user.profile = null;
415 user.accountstate = false;
416 user.invitetimes = 5;
417 // 自动补齐userPT,避免not-null property异常
418 entity.UserPT userPT = new entity.UserPT();
419 userPT.userid = userId;
420 userPT.magic = 0;
421 userPT.upload = 0L;
422 userPT.download = 0L;
423 userPT.share = 0.0;
424 userPT.farmurl = null;
425 userPT.viptime = 0;
426 userPT.user = user;
427 user.userPT = userPT;
428 em.persist(user);
429 em.persist(userPT);
430 em.flush();
431 // 修改信息
432 entity.UserPT updated = new entity.UserPT();
433 updated.userid = userId;
434 updated.magic = 200 + i;
435 updated.upload = 3000L + i;
436 updated.download = 4000L + i;
437 updated.share = 2.5 + i;
438 updated.farmurl = "/new/path/seed" + i;
439 updated.viptime = 8 + i;
440 int ret = db.UpdateInformationPT(updated);
441 Assertions.assertEquals(0, ret, "UpdateInformationPT should return 0 for success");
442 em.flush();
443 em.clear();
444 entity.UserPT after = em.find(entity.UserPT.class, userId);
445 Assertions.assertEquals(200 + i, after.magic);
446 Assertions.assertEquals(3000L + i, after.upload);
447 Assertions.assertEquals(4000L + i, after.download);
448 Assertions.assertEquals(2.5 + i, after.share);
449 Assertions.assertEquals("/new/path/seed" + i, after.farmurl);
450 Assertions.assertEquals(8 + i, after.viptime);
451 // 测试不存在用户
452 entity.UserPT notExist = new entity.UserPT();
453 notExist.userid = "not_exist_" + i;
454 notExist.magic = 0;
455 notExist.upload = 0L;
456 notExist.download = 0L;
457 notExist.share = 0.0;
458 notExist.farmurl = null;
459 notExist.viptime = 0;
460 int ret2 = db.UpdateInformationPT(notExist);
461 Assertions.assertEquals(1, ret2, "UpdateInformationPT should return 1 for not found user");
462 } finally {
463 tx.rollback();
464 }
465 })).collect(Collectors.toList());
466 }
467
468 @TestFactory
469 Collection<DynamicTest> testRegisterUserPT() {
470 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("RegisterUserPT test #" + i, () -> {
471 EntityTransaction tx = em.getTransaction();
472 tx.begin();
473 try {
474 // 先插入User,保证UserPT外键约束
475 User user = new User();
476 String userId = testUserIds.get(i);
477 if (userId.length() > 36) userId = userId.substring(0, 36);
478 user.userid = userId;
479 user.email = testEmails.get(i);
480 user.username = "user" + i;
481 user.password = "pwd" + i;
482 user.sex = "m";
483 user.school = "school" + i;
484 user.pictureurl = null;
485 user.profile = null;
486 user.accountstate = false;
487 user.invitetimes = 5;
488 // 自动补齐userPT,避免not-null property异常
489 entity.UserPT userPT = new entity.UserPT();
490 userPT.userid = userId;
491 userPT.magic = 100 + i;
492 userPT.upload = 1000L + i;
493 userPT.download = 2000L + i;
494 userPT.share = 1.5;
495 userPT.farmurl = "/path/to/seed" + i;
496 userPT.viptime = 3 + i;
497 userPT.user = user;
498 user.userPT = userPT;
499 // em.persist(user);
500 // em.persist(userPT);
501 // em.flush();
502 // 正常注册
503 int ret = db.RegisterUserPT(userPT);
504 Assertions.assertEquals(0, ret, "RegisterUserPT should return 0 for success");
505 // 再次注册同ID应返回1
506 entity.UserPT userPT2 = new entity.UserPT();
507 userPT2.userid = userId;
508 userPT2.magic = 200 + i;
509 userPT2.upload = 3000L + i;
510 userPT2.download = 4000L + i;
511 userPT2.share = 2.5;
512 userPT2.farmurl = "/other/path/seed" + i;
513 userPT2.viptime = 8 + i;
514 int ret2 = db.RegisterUserPT(userPT2);
515 Assertions.assertEquals(1, ret2, "RegisterUserPT should return 1 for duplicate id");
516 } finally {
517 tx.rollback();
518 }
519 })).collect(Collectors.toList());
520 }
521
522 @TestFactory
523 Collection<DynamicTest> testGetSeedInformation() {
524 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetSeedInformation test #" + i, () -> {
525 EntityTransaction tx = em.getTransaction();
526 tx.begin();
527 try {
528 // 先插入User,保证seed.seeduserid外键依赖
529 User user = new User();
530 String userId = testUserIds.get(i);
531 if (userId.length() > 36) userId = userId.substring(0, 36);
532 user.userid = userId;
533 user.email = testEmails.get(i);
534 user.username = "user" + i;
535 user.password = "pwd" + i;
536 user.sex = "m";
537 user.school = "school" + i;
538 user.pictureurl = null;
539 user.profile = null;
540 user.accountstate = false;
541 user.invitetimes = 5;
542 // 自动补齐userPT,保证UserPT不为空
543 entity.UserPT userPT = new entity.UserPT();
544 userPT.userid = userId;
545 userPT.magic = 0;
546 userPT.upload = 0L;
547 userPT.download = 0L;
548 userPT.share = 0.0;
549 userPT.farmurl = null;
550 userPT.viptime = 0;
551 userPT.user = user;
552 user.userPT = userPT;
553 em.persist(user);
554 em.persist(userPT);
555 // 再插入Seed
556 entity.Seed seed = new entity.Seed();
557 seed.seedid = "test_seed_" + i + "_" + UUID.randomUUID();
558 seed.seeduserid = userId;
559 seed.faketime = i;
560 seed.lastfakecheck = new java.util.Date();
561 seed.outurl = "http://example.com/seed" + i;
562 seed.title = "title" + i;
563 seed.subtitle = "subtitle" + i;
564 seed.seedsize = "100MB";
565 seed.seedtag = "tag" + i;
566 seed.downloadtimes = 10 + i;
567 seed.url = "http://download.com/seed" + i;
568 em.persist(seed);
569 em.flush();
570 // 查询
571 entity.Seed got = db.GetSeedInformation(seed.seedid);
572 Assertions.assertNotNull(got, "GetSeedInformation should return seed");
573 Assertions.assertEquals(seed.seedid, got.seedid);
574 Assertions.assertEquals(seed.seeduserid, got.seeduserid);
575 Assertions.assertEquals(seed.faketime, got.faketime);
576 Assertions.assertEquals(seed.outurl, got.outurl);
577 Assertions.assertEquals(seed.title, got.title);
578 Assertions.assertEquals(seed.subtitle, got.subtitle);
579 Assertions.assertEquals(seed.seedsize, got.seedsize);
580 Assertions.assertEquals(seed.seedtag, got.seedtag);
581 Assertions.assertEquals(seed.downloadtimes, got.downloadtimes);
582 Assertions.assertEquals(seed.url, got.url);
583 // 查询不存在种子
584 entity.Seed notExist = db.GetSeedInformation("not_exist_seed_" + i);
585 Assertions.assertNull(notExist, "GetSeedInformation should return null for not found seed");
586 } finally {
587 tx.rollback();
588 }
589 })).collect(Collectors.toList());
590 }
591
592 @TestFactory
593 Collection<DynamicTest> testRegisterSeed() {
594 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("RegisterSeed test #" + i, () -> {
595 EntityTransaction tx = em.getTransaction();
596 tx.begin();
597 try {
598 // 先插入User,保证seed.seeduserid外键依赖,且UserPT不为空
599 User user = new User();
600 String userId = testUserIds.get(i);
601 if (userId.length() > 36) userId = userId.substring(0, 36);
602 user.userid = userId;
603 user.email = testEmails.get(i);
604 user.username = "user" + i;
605 user.password = "pwd" + i;
606 user.sex = "m";
607 user.school = "school" + i;
608 user.pictureurl = null;
609 user.profile = null;
610 user.accountstate = false;
611 user.invitetimes = 5;
612 // 关键:补充userPT字段,避免not-null property异常
613 entity.UserPT userPT = new entity.UserPT();
614 userPT.userid = userId;
615 userPT.magic = 0;
616 userPT.upload = 0L;
617 userPT.download = 0L;
618 userPT.share = 0.0;
619 userPT.farmurl = null;
620 userPT.viptime = 0;
621 userPT.user = user;
622 user.userPT = userPT;
623 em.persist(user);
624 em.persist(userPT);
625 // 再插入Seed
626 entity.Seed seed = new entity.Seed();
627 String sid = ("test_seed_" + i + "_" + UUID.randomUUID());
628 if (sid.length() > 64) sid = sid.substring(0, 64);
629 seed.seedid = sid;
630 seed.seeduserid = userId;
631 seed.faketime = i;
632 seed.lastfakecheck = new java.util.Date();
633 seed.outurl = ("http://example.com/seed" + i);
634 if (seed.outurl != null && seed.outurl.length() > 255) seed.outurl = seed.outurl.substring(0, 255);
635 seed.title = ("title" + i);
636 if (seed.title.length() > 255) seed.title = seed.title.substring(0, 255);
637 seed.subtitle = ("subtitle" + i);
638 if (seed.subtitle != null && seed.subtitle.length() > 255) seed.subtitle = seed.subtitle.substring(0, 255);
639 seed.seedsize = "100MB";
640 if (seed.seedsize.length() > 50) seed.seedsize = seed.seedsize.substring(0, 50);
641 seed.seedtag = ("tag" + i);
642 if (seed.seedtag != null && seed.seedtag.length() > 255) seed.seedtag = seed.seedtag.substring(0, 255);
643 seed.downloadtimes = 10 + i;
644 seed.url = ("http://download.com/seed" + i);
645 em.persist(seed);
646 em.flush();
647 // 校验数据库中已存在
648 entity.Seed found = em.find(entity.Seed.class, seed.seedid);
649 Assertions.assertNotNull(found, "数据库应存在该种子");
650 Assertions.assertEquals(seed.seedid, found.seedid);
651 Assertions.assertEquals(seed.seeduserid, found.seeduserid);
652 Assertions.assertEquals(seed.faketime, found.faketime);
653 Assertions.assertEquals(seed.outurl, found.outurl);
654 Assertions.assertEquals(seed.title, found.title);
655 Assertions.assertEquals(seed.subtitle, found.subtitle);
656 Assertions.assertEquals(seed.seedsize, found.seedsize);
657 Assertions.assertEquals(seed.seedtag, found.seedtag);
658 Assertions.assertEquals(seed.downloadtimes, found.downloadtimes);
659 Assertions.assertEquals(seed.url, found.url);
660 // 再次注册同ID应返回1
661 entity.Seed seed2 = new entity.Seed();
662 seed2.seedid = sid;
663 seed2.seeduserid = userId;
664 seed2.faketime = 99;
665 seed2.lastfakecheck = new java.util.Date();
666 seed2.outurl = ("http://example.com/seed_dup" + i);
667 if (seed2.outurl != null && seed2.outurl.length() > 255) seed2.outurl = seed2.outurl.substring(0, 255);
668 seed2.title = ("title_dup" + i);
669 if (seed2.title.length() > 255) seed2.title = seed2.title.substring(0, 255);
670 seed2.subtitle = ("subtitle_dup" + i);
671 if (seed2.subtitle != null && seed2.subtitle.length() > 255) seed2.subtitle = seed2.subtitle.substring(0, 255);
672 seed2.seedsize = "200MB";
673 if (seed2.seedsize.length() > 50) seed2.seedsize = seed2.seedsize.substring(0, 50);
674 seed2.seedtag = ("tag_dup" + i);
675 if (seed2.seedtag != null && seed2.seedtag.length() > 255) seed2.seedtag = seed2.seedtag.substring(0, 255);
676 seed2.downloadtimes = 99;
677 seed2.url = ("http://download.com/seed_dup" + i);
678 int ret2 = db.RegisterSeed(seed2);
679 Assertions.assertEquals(1, ret2, "RegisterSeed should return 1 for duplicate id");
680 } finally {
681 tx.rollback();
682 }
683 })).collect(Collectors.toList());
684 }
685
686 @TestFactory
687 Collection<DynamicTest> testUpdateSeed() {
688 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateSeed test #" + i, () -> {
689 EntityTransaction tx = em.getTransaction();
690 tx.begin();
691 try {
692 // 先插入User,保证seed.seeduserid外键依赖,且UserPT不为空
693 User user = new User();
694 String userId = testUserIds.get(i);
695 if (userId.length() > 36) userId = userId.substring(0, 36);
696 user.userid = userId;
697 user.email = testEmails.get(i);
698 user.username = "user" + i;
699 user.password = "pwd" + i;
700 user.sex = "m";
701 user.school = "school" + i;
702 user.pictureurl = null;
703 user.profile = null;
704 user.accountstate = false;
705 user.invitetimes = 5;
706 // 关键:补充userPT字段,避免not-null property异常
707 entity.UserPT userPT = new entity.UserPT();
708 userPT.userid = userId;
709 userPT.magic = 0;
710 userPT.upload = 0L;
711 userPT.download = 0L;
712 userPT.share = 0.0;
713 userPT.farmurl = null;
714 userPT.viptime = 0;
715 userPT.user = user;
716 user.userPT = userPT;
717 em.persist(user);
718 em.persist(userPT);
719 // 再插入Seed
720 entity.Seed seed = new entity.Seed();
721 String sid = ("test_seed_" + i + "_" + UUID.randomUUID());
722 if (sid.length() > 64) sid = sid.substring(0, 64);
723 seed.seedid = sid;
724 seed.seeduserid = userId;
725 seed.faketime = i;
726 seed.lastfakecheck = new java.util.Date();
727 seed.outurl = ("http://example.com/seed" + i);
728 if (seed.outurl != null && seed.outurl.length() > 255) seed.outurl = seed.outurl.substring(0, 255);
729 seed.title = ("title" + i);
730 if (seed.title.length() > 255) seed.title = seed.title.substring(0, 255);
731 seed.subtitle = ("subtitle" + i);
732 if (seed.subtitle != null && seed.subtitle.length() > 255) seed.subtitle = seed.subtitle.substring(0, 255);
733 seed.seedsize = "100MB";
734 if (seed.seedsize.length() > 50) seed.seedsize = seed.seedsize.substring(0, 50);
735 seed.seedtag = ("tag" + i);
736 if (seed.seedtag != null && seed.seedtag.length() > 255) seed.seedtag = seed.seedtag.substring(0, 255);
737 seed.downloadtimes = 10 + i;
738 seed.url = ("http://download.com/seed" + i);
739 em.persist(seed);
740 em.flush();
741 // 修改信息
742 entity.Seed updated = new entity.Seed();
743 updated.seedid = sid;
744 updated.seeduserid = userId + "_updated";
745 if (updated.seeduserid.length() > 36) updated.seeduserid = updated.seeduserid.substring(0, 36);
746 updated.faketime = 99;
747 updated.lastfakecheck = new java.util.Date();
748 updated.outurl = ("http://example.com/seed_updated" + i);
749 if (updated.outurl != null && updated.outurl.length() > 255) updated.outurl = updated.outurl.substring(0, 255);
750 updated.title = ("title_updated" + i);
751 if (updated.title.length() > 255) updated.title = updated.title.substring(0, 255);
752 updated.subtitle = ("subtitle_updated" + i);
753 if (updated.subtitle != null && updated.subtitle.length() > 255) updated.subtitle = updated.subtitle.substring(0, 255);
754 updated.seedsize = "200MB";
755 if (updated.seedsize.length() > 50) updated.seedsize = updated.seedsize.substring(0, 50);
756 updated.seedtag = ("tag_updated" + i);
757 if (updated.seedtag != null && updated.seedtag.length() > 255) updated.seedtag = updated.seedtag.substring(0, 255);
758 updated.downloadtimes = 99;
759 updated.url = ("http://download.com/seed_updated" + i);
760 int ret = db.UpdateSeed(updated);
761 Assertions.assertEquals(0, ret, "UpdateSeed should return 0 for success");
762 em.flush();
763 em.clear();
764 entity.Seed after = em.find(entity.Seed.class, sid);
765 Assertions.assertEquals(updated.seeduserid, after.seeduserid);
766 Assertions.assertEquals(99, after.faketime);
767 Assertions.assertEquals(updated.outurl, after.outurl);
768 Assertions.assertEquals(updated.title, after.title);
769 Assertions.assertEquals(updated.subtitle, after.subtitle);
770 Assertions.assertEquals(updated.seedsize, after.seedsize);
771 Assertions.assertEquals(updated.seedtag, after.seedtag);
772 Assertions.assertEquals(99, after.downloadtimes);
773 Assertions.assertEquals(updated.url, after.url);
774 // 测试不存在种子
775 entity.Seed notExist = new entity.Seed();
776 notExist.seedid = "not_exist_seed_" + i;
777 if (notExist.seedid.length() > 64) notExist.seedid = notExist.seedid.substring(0, 64);
778 notExist.seeduserid = "owner_x";
779 if (notExist.seeduserid.length() > 36) notExist.seeduserid = notExist.seeduserid.substring(0, 36);
780 notExist.faketime = 0;
781 notExist.lastfakecheck = new java.util.Date();
782 notExist.outurl = null;
783 notExist.title = "not_exist";
784 if (notExist.title.length() > 255) notExist.title = notExist.title.substring(0, 255);
785 notExist.subtitle = null;
786 notExist.seedsize = "0MB";
787 if (notExist.seedsize.length() > 50) notExist.seedsize = notExist.seedsize.substring(0, 50);
788 notExist.seedtag = null;
789 notExist.downloadtimes = 0;
790 notExist.url = null;
791 int ret2 = db.UpdateSeed(notExist);
792 Assertions.assertEquals(1, ret2, "UpdateSeed should return 1 for not found seed");
793 } finally {
794 tx.rollback();
795 }
796 })).collect(Collectors.toList());
797 }
798
799 @TestFactory
800 Collection<DynamicTest> testSearchSeed() {
801 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("SearchSeed test #" + i, () -> {
802 EntityTransaction tx = em.getTransaction();
803 tx.begin();
804 try {
805 // 先插入User,保证seed.seeduserid外键依赖
806 User user = new User();
807 String userId = testUserIds.get(i);
808 if (userId.length() > 36) userId = userId.substring(0, 36);
809 user.userid = userId;
810 user.email = testEmails.get(i);
811 user.username = "user" + i;
812 user.password = "pwd" + i;
813 user.sex = "m";
814 user.school = "school" + i;
815 user.pictureurl = null;
816 user.profile = null;
817 user.accountstate = false;
818 user.invitetimes = 5;
819
820 // 插入UserPT,保证UserPT不为空
821 entity.UserPT userPT = new entity.UserPT();
822 userPT.userid = userId;
823 userPT.magic = 0;
824 userPT.upload = 0L;
825 userPT.download = 0L;
826 userPT.share = 0.0;
827 userPT.farmurl = null;
828 userPT.viptime = 0;
829 userPT.user = user;
830 user.userPT = userPT;
831 em.persist(user);
832 em.persist(userPT);
833 em.flush();
834 // 插入多条Seed
835 List<entity.Seed> seeds = new ArrayList<>();
836 for (int j = 0; j < 5; j++) {
837 entity.Seed seed = new entity.Seed();
838 seed.seedid = "search_seed_" + i + "_" + j + "_" + UUID.randomUUID();
839 seed.seeduserid = userId;
840 seed.faketime = j;
841 seed.lastfakecheck = new java.util.Date();
842 seed.outurl = "http://example.com/seed" + j;
843 seed.title = "TestTitle" + i + (j % 2 == 0 ? "_Special" : "") + "_" + j;
844 seed.subtitle = "subtitle" + j;
845 seed.seedsize = "100MB";
846 seed.seedtag = "tag" + j;
847 seed.downloadtimes = 10 + j;
848 seed.url = "http://download.com/seed" + j;
849 em.persist(seed);
850 seeds.add(seed);
851 }
852 em.flush();
853 // 测试关键词能搜到相关种子
854 String keyword = "Special";
855 entity.Seed[] result = db.SearchSeed(keyword);
856 boolean found = false;
857 for (entity.Seed s : result) {
858 if (s.title.contains(keyword)) found = true;
859 }
860 Assertions.assertTrue(found, "SearchSeed should find seeds with keyword in title");
861 // 测试空字符串返回所有种子
862 entity.Seed[] all = db.SearchSeed("");
863 Assertions.assertEquals(seeds.size() + 5, all.length, "SearchSeed with empty string should return all");
864 // 测试无匹配关键词
865 entity.Seed[] none = db.SearchSeed("NoSuchKeyword" + i);
866 Assertions.assertEquals(seeds.size() + 5, none.length, "SearchSeed with no match should return all, sorted");
867 // 测试null关键词
868 entity.Seed[] nullResult = db.SearchSeed(null);
869 Assertions.assertEquals(seeds.size() + 5, nullResult.length, "SearchSeed with null should return all");
870 } finally {
871 tx.rollback();
872 }
873 })).collect(Collectors.toList());
874 }
875
876 @TestFactory
877 Collection<DynamicTest> testAddNotice() {
878 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("AddNotice test #" + i, () -> {
879 EntityTransaction tx = em.getTransaction();
880 tx.begin();
881 try {
882 // 构造 Notice
883 entity.Notice notice = new entity.Notice();
884 notice.noticeid = "test_notice_" + i + "_" + UUID.randomUUID();
885 notice.noticecontent = "内容" + i;
886 notice.state = (i % 2 == 0);
887 notice.posttag = "tag" + i;
888 // 正常插入
889 int ret = db.AddNotice(notice);
890 Assertions.assertEquals(0, ret, "AddNotice 应返回0");
891 // 再次插入同ID应返回1
892 entity.Notice notice2 = new entity.Notice();
893 notice2.noticeid = notice.noticeid;
894 notice2.noticecontent = "内容重复" + i;
895 notice2.state = false;
896 notice2.posttag = "tag_dup" + i;
897 int ret2 = db.AddNotice(notice2);
898 Assertions.assertEquals(1, ret2, "AddNotice 应返回1(重复ID)");
899 // 校验数据库中已存在
900 entity.Notice found = em.find(entity.Notice.class, notice.noticeid);
901 Assertions.assertNotNull(found, "数据库应存在该公告");
902 Assertions.assertEquals(notice.noticecontent, found.noticecontent);
903 Assertions.assertEquals(notice.state, found.state);
904 Assertions.assertEquals(notice.posttag, found.posttag);
905 } finally {
906 tx.rollback();
907 }
908 })).collect(Collectors.toList());
909 }
910
911 @TestFactory
912 Collection<DynamicTest> testUpdateNotice() {
913 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateNotice test #" + i, () -> {
914 EntityTransaction tx = em.getTransaction();
915 tx.begin();
916 try {
917 // 先插入一个Notice
918 entity.Notice notice = new entity.Notice();
919 notice.noticeid = "test_notice_update_" + i + "_" + UUID.randomUUID();
920 notice.noticecontent = "原内容" + i;
921 notice.state = true;
922 notice.posttag = "tag" + i;
923 em.persist(notice);
924 em.flush();
925 // 修改内容
926 entity.Notice updated = new entity.Notice();
927 updated.noticeid = notice.noticeid;
928 updated.noticecontent = "新内容" + i;
929 updated.state = false;
930 updated.posttag = "tag_updated" + i;
931 boolean ret = db.UpdateNotice(updated);
932 Assertions.assertTrue(ret, "UpdateNotice 应返回 true");
933 em.flush();
934 em.clear();
935 entity.Notice after = em.find(entity.Notice.class, notice.noticeid);
936 Assertions.assertEquals("新内容" + i, after.noticecontent);
937 Assertions.assertFalse(after.state);
938 Assertions.assertEquals("tag_updated" + i, after.posttag);
939 // 测试不存在公告
940 entity.Notice notExist = new entity.Notice();
941 notExist.noticeid = "not_exist_notice_" + i;
942 notExist.noticecontent = "xxx";
943 notExist.state = false;
944 notExist.posttag = "none";
945 boolean ret2 = db.UpdateNotice(notExist);
946 Assertions.assertFalse(ret2, "UpdateNotice 应返回 false for not found");
947 } finally {
948 tx.rollback();
949 }
950 })).collect(Collectors.toList());
951 }
952
953 @TestFactory
954 Collection<DynamicTest> testDeleteNotice() {
955 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("DeleteNotice test #" + i, () -> {
956 EntityTransaction tx = em.getTransaction();
957 tx.begin();
958 try {
959 // 先插入一个Notice
960 entity.Notice notice = new entity.Notice();
961 notice.noticeid = "test_notice_delete_" + i + "_" + UUID.randomUUID();
962 notice.noticecontent = "内容" + i;
963 notice.state = true;
964 notice.posttag = "tag" + i;
965 em.persist(notice);
966 em.flush();
967 // 删除
968 boolean ret = db.DeleteNotice(notice.noticeid);
969 Assertions.assertTrue(ret, "DeleteNotice 应返回 true");
970 em.flush();
971 em.clear();
972 entity.Notice after = em.find(entity.Notice.class, notice.noticeid);
973 Assertions.assertNull(after, "DeleteNotice 后应查不到公告");
974 // 删除不存在的公告
975 boolean ret2 = db.DeleteNotice("not_exist_notice_" + i);
976 Assertions.assertFalse(ret2, "DeleteNotice 应返回 false for not found");
977 } finally {
978 tx.rollback();
979 }
980 })).collect(Collectors.toList());
981 }
982
983 @TestFactory
984 Collection<DynamicTest> testGetUserAvailableInviteTimes() {
985 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetUserAvailableInviteTimes test #" + i, () -> {
986 EntityTransaction tx = em.getTransaction();
987 tx.begin();
988 try {
989 // 先插入一个User
990 entity.User user = new entity.User();
991 String userId = testUserIds.get(i);
992 if (userId.length() > 36) userId = userId.substring(0, 36);
993 user.userid = userId;
994 user.email = "invite" + i + "@example.com";
995 user.username = "user" + i;
996 user.password = "pwd" + i;
997 user.sex = "m";
998 user.school = "school" + i;
999 user.pictureurl = "pic" + i + ".jpg";
1000 user.profile = "profile" + i;
1001 user.accountstate = true;
1002 user.invitetimes = 5 + i;
1003
1004 // 插入UserPT,保证UserPT不为空
1005 entity.UserPT userPT = new entity.UserPT();
1006 userPT.userid = user.userid;
1007 userPT.magic = 0;
1008 userPT.upload = 0L;
1009 userPT.download = 0L;
1010 userPT.share = 0.0;
1011 userPT.farmurl = null;
1012 userPT.viptime = 0;
1013 userPT.user = user;
1014 user.userPT = userPT;
1015 em.persist(user);
1016 em.persist(userPT);
1017 em.flush();
1018 // 查询
1019 int left = db.GetUserAvailableInviteTimes(user.userid);
1020 Assertions.assertEquals(5 + i, left, "GetUserAvailableInviteTimes 应返回正确剩余次数");
1021 // 查询不存在用户
1022 int notExist = db.GetUserAvailableInviteTimes("not_exist_user_" + i);
1023 Assertions.assertEquals(-1, notExist, "GetUserAvailableInviteTimes 不存在用户应返回-1");
1024 } finally {
1025 tx.rollback();
1026 }
1027 })).collect(Collectors.toList());
1028 }
1029
1030 @TestFactory
1031 Collection<DynamicTest> testInviteUser() {
1032 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("InviteUser test #" + i, () -> {
1033 EntityTransaction tx = em.getTransaction();
1034 tx.begin();
1035 try {
1036 // 先插入一个User
1037 entity.User user = new entity.User();
1038 String userId = testUserIds.get(i);
1039 if (userId.length() > 36) userId = userId.substring(0, 36);
1040 user.userid = userId;
1041 user.email = "invite" + i + "@example.com";
1042 user.username = "user" + i;
1043 user.password = "pwd" + i;
1044 user.sex = "m";
1045 user.school = "school" + i;
1046 user.pictureurl = "pic" + i + ".jpg";
1047 user.profile = "profile" + i;
1048 user.accountstate = true;
1049 user.invitetimes = 3 + i;
1050
1051 // 插入UserPT,保证UserPT不为空
1052 entity.UserPT userPT = new entity.UserPT();
1053 userPT.userid = user.userid;
1054 userPT.magic = 0;
1055 userPT.upload = 0L;
1056 userPT.download = 0L;
1057 userPT.share = 0.0;
1058 userPT.farmurl = null;
1059 userPT.viptime = 0;
1060 userPT.user = user;
1061 user.userPT = userPT;
1062 em.persist(user);
1063 em.persist(userPT);
1064 em.flush();
1065 // 正常邀请
1066 int ret = db.InviteUser(user.userid, user.email);
1067 Assertions.assertEquals(0, ret, "InviteUser 应返回0");
1068 em.flush();
1069 em.clear();
1070 entity.User after = em.find(entity.User.class, user.userid);
1071 Assertions.assertEquals(2 + i, after.invitetimes, "邀请后次数应减少1");
1072 // 剩余次数不足
1073 after.invitetimes = 0;
1074 em.merge(after);
1075 em.flush();
1076 int ret2 = db.InviteUser(user.userid, user.email);
1077 Assertions.assertEquals(1, ret2, "InviteUser 剩余次数不足应返回1");
1078 // 邮箱不匹配
1079 int ret3 = db.InviteUser(user.userid, "wrong" + i + "@example.com");
1080 Assertions.assertEquals(3, ret3, "InviteUser 邮箱不匹配应返回3");
1081 // 用户不存在
1082 int ret4 = db.InviteUser("not_exist_user_" + i, "invite" + i + "@example.com");
1083 Assertions.assertEquals(3, ret4, "InviteUser 用户不存在应返回3");
1084 } finally {
1085 tx.rollback();
1086 }
1087 })).collect(Collectors.toList());
1088 }
1089
1090 @TestFactory
1091 Collection<DynamicTest> testAddCollect() {
1092 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("AddCollect test #" + i, () -> {
1093 EntityTransaction tx = em.getTransaction();
1094 tx.begin();
1095 try {
1096 // 构造用户和种子
1097 String userId = testUserIds.get(i);
1098 if (userId.length() > 36) userId = userId.substring(0, 36);
1099
1100 entity.User user = new entity.User();
1101 user.userid = userId;
1102 user.email = "invite" + i + "@example.com";
1103 user.username = "user" + i;
1104 user.password = "pwd" + i;
1105 user.sex = "m";
1106 user.school = "school" + i;
1107 user.pictureurl = "pic" + i + ".jpg";
1108 user.profile = "profile" + i;
1109 user.accountstate = true;
1110 user.invitetimes = 5 + i;
1111 // 插入UserPT,保证UserPT不为空
1112 entity.UserPT userPT = new entity.UserPT();
1113 userPT.userid = user.userid;
1114 userPT.magic = 0;
1115 userPT.upload = 0L;
1116 userPT.download = 0L;
1117 userPT.share = 0.0;
1118 userPT.farmurl = null;
1119 userPT.viptime = 0;
1120 userPT.user = user;
1121 user.userPT = userPT;
1122 em.persist(user);
1123 em.persist(userPT);
1124 em.flush();
1125 entity.Seed seed = new entity.Seed();
1126 String seedid = "test_seed_collect_" + i + "_" + UUID.randomUUID();
1127 seed.seedid = seedid;
1128 seed.seeduserid = userId;
1129 seed.faketime = i;
1130 seed.lastfakecheck = new java.util.Date();
1131 seed.outurl = "http://example.com/seed" + i;
1132 seed.title = "title" + i;
1133 seed.subtitle = "subtitle" + i;
1134 seed.seedsize = "100MB";
1135 seed.seedtag = "tag" + i;
1136 seed.downloadtimes = 10 + i;
1137 seed.url = "http://download.com/seed" + i;
1138 em.persist(seed);
1139 em.flush();
1140 // 正常收藏
1141 boolean ret = db.AddCollect(userId, seedid);
1142 Assertions.assertTrue(ret, "AddCollect 应返回 true");
1143 em.flush();
1144 em.clear();
1145 entity.UserStar found = em.find(entity.UserStar.class, new entity.UserStarId(userId, seedid));
1146 Assertions.assertNotNull(found, "收藏应已存在");
1147 // 重复收藏
1148 boolean ret2 = db.AddCollect(userId, seedid);
1149 Assertions.assertFalse(ret2, "AddCollect 重复应返回 false");
1150 // 用户不存在
1151 boolean ret3 = db.AddCollect("not_exist_user_" + i, seedid);
1152 Assertions.assertFalse(ret3, "AddCollect 用户不存在应返回 false");
1153 // 帖子不存在
1154 boolean ret4 = db.AddCollect(userId, "not_exist_post_" + i);
1155 Assertions.assertFalse(ret4, "AddCollect 帖子不存在应返回 false");
1156 } finally {
1157 tx.rollback();
1158 }
1159 })).collect(Collectors.toList());
1160 }
1161
1162 @TestFactory
1163 Collection<DynamicTest> testDeleteCollect() {
1164 return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("DeleteCollect test #" + i, () -> {
1165 EntityTransaction tx = em.getTransaction();
1166 tx.begin();
1167 try {
1168 // 构造用户和种子
1169 String userId = testUserIds.get(i);
1170 if (userId.length() > 36) userId = userId.substring(0, 36);
1171
1172 entity.User user = new entity.User();
1173 user.userid = userId;
1174 user.email = "invite" + i + "@example.com";
1175 user.username = "user" + i;
1176 user.password = "pwd" + i;
1177 user.sex = "m";
1178 user.school = "school" + i;
1179 user.pictureurl = "pic" + i + ".jpg";
1180 user.profile = "profile" + i;
1181 user.accountstate = true;
1182 user.invitetimes = 5 + i;
1183 // 插入UserPT,保证UserPT不为空
1184 entity.UserPT userPT = new entity.UserPT();
1185 userPT.userid = user.userid;
1186 userPT.magic = 0;
1187 userPT.upload = 0L;
1188 userPT.download = 0L;
1189 userPT.share = 0.0;
1190 userPT.farmurl = null;
1191 userPT.viptime = 0;
1192 userPT.user = user;
1193 user.userPT = userPT;
1194 em.persist(user);
1195 em.persist(userPT);
1196 em.flush();
1197 entity.Seed seed = new entity.Seed();
1198 String seedid = "test_seed_collect_" + i + "_" + UUID.randomUUID();
1199 seed.seedid = seedid;
1200 seed.seeduserid = userId;
1201 seed.faketime = i;
1202 seed.lastfakecheck = new java.util.Date();
1203 seed.outurl = "http://example.com/seed" + i;
1204 seed.title = "title" + i;
1205 seed.subtitle = "subtitle" + i;
1206 seed.seedsize = "100MB";
1207 seed.seedtag = "tag" + i;
1208 seed.downloadtimes = 10 + i;
1209 seed.url = "http://download.com/seed" + i;
1210 em.persist(seed);
1211 em.flush();
1212 // 先收藏
1213 entity.UserStar star = new entity.UserStar();
1214 star.userid = userId;
1215 star.seedid = seedid;
1216 em.persist(star);
1217 em.flush();
1218 // 正常删除
1219 boolean ret = db.DeleteCollect(userId, seedid);
1220 Assertions.assertTrue(ret, "DeleteCollect 应返回 true");
1221 em.flush();
1222 em.clear();
1223 entity.UserStar found = em.find(entity.UserStar.class, new entity.UserStarId(userId, seedid));
1224 Assertions.assertNull(found, "删除后收藏应不存在");
1225 // 删除不存在的收藏
1226 boolean ret2 = db.DeleteCollect(userId, seedid);
1227 Assertions.assertTrue(ret2, "再次删除应返回 true(JPA remove null容忍)");
1228 // 用户不存在
1229 boolean ret3 = db.DeleteCollect("not_exist_user_" + i, seedid);
1230 Assertions.assertTrue(ret3, "用户不存在时应返回 true(JPA remove null容忍)");
1231 // 帖子不存在
1232 boolean ret4 = db.DeleteCollect(userId, "not_exist_seed_" + i);
1233 Assertions.assertTrue(ret4, "帖子不存在时应返回 true(JPA remove null容忍)");
1234 } finally {
1235 tx.rollback();
1236 }
1237 })).collect(Collectors.toList());
1238 }
TRM-codingcdfe5482025-06-06 17:31:01 +08001239
1240 @TestFactory
1241 Collection<DynamicTest> testLoginUser() {
1242 // 查询所有现有用户
1243 List<User> allUsers = em.createQuery("SELECT u FROM User u", User.class).getResultList();
1244
1245 // 为每个用户创建测试
1246 return allUsers.stream().map(existingUser ->
1247 DynamicTest.dynamicTest("LoginUser test for user: " + existingUser.username, () -> {
1248 EntityTransaction tx = em.getTransaction();
1249 tx.begin();
1250 try {
1251 // 测试1:使用用户名登录(成功)
1252 User loginWithUsername = new User();
1253 loginWithUsername.username = existingUser.username;
1254 loginWithUsername.password = existingUser.password;
1255 String loginResult1 = db.LoginUser(loginWithUsername);
1256 Assertions.assertEquals(existingUser.userid, loginResult1,
1257 "Should successfully login with username and correct password for user: " + existingUser.username);
1258
1259 // 测试2:使用邮箱登录(成功)
1260 User loginWithEmail = new User();
1261 loginWithEmail.email = existingUser.email;
1262 loginWithEmail.password = existingUser.password;
1263 String loginResult2 = db.LoginUser(loginWithEmail);
1264 Assertions.assertEquals(existingUser.userid, loginResult2,
1265 "Should successfully login with email and correct password for user: " + existingUser.email);
1266
1267 // 测试3:密码错误(失败)
1268 User wrongPassword = new User();
1269 wrongPassword.username = existingUser.username;
1270 wrongPassword.password = "wrong_password_" + UUID.randomUUID();
1271 String loginResult3 = db.LoginUser(wrongPassword);
1272 Assertions.assertNull(loginResult3,
1273 "Should fail with wrong password for user: " + existingUser.username);
1274
1275 // 测试4:同时提供用户名和邮箱(失败)
1276 User bothFields = new User();
1277 bothFields.username = existingUser.username;
1278 bothFields.email = existingUser.email;
1279 bothFields.password = existingUser.password;
1280 String loginResult5 = db.LoginUser(bothFields);
1281 Assertions.assertNull(loginResult5,
1282 "Should fail when both username and email are provided for user: " + existingUser.username);
1283
1284 } finally {
1285 tx.rollback();
1286 }
1287 })
1288 ).collect(Collectors.toList());
1289 }
1290
1291 @TestFactory
1292 Collection<DynamicTest> testLoginUserAdditionalCases() {
1293 return IntStream.range(0, 3).mapToObj(i -> DynamicTest.dynamicTest("LoginUser additional test #" + i, () -> {
1294 EntityTransaction tx = em.getTransaction();
1295 tx.begin();
1296 try {
1297 // 测试1:用户名不存在(失败)
1298 User nonExistentUser = new User();
1299 nonExistentUser.username = "non_existent_user_" + UUID.randomUUID();
1300 nonExistentUser.password = "any_password";
1301 String loginResult1 = db.LoginUser(nonExistentUser);
1302 Assertions.assertNull(loginResult1, "Should fail with non-existent username");
1303
1304 // 测试2:邮箱不存在(失败)
1305 User nonExistentEmail = new User();
1306 nonExistentEmail.email = "non_existent_" + UUID.randomUUID() + "@example.com";
1307 nonExistentEmail.password = "any_password";
1308 String loginResult2 = db.LoginUser(nonExistentEmail);
1309 Assertions.assertNull(loginResult2, "Should fail with non-existent email");
1310
1311 // 测试3:缺少密码(失败)
1312 User noPassword = new User();
1313 noPassword.username = "some_username";
1314 noPassword.password = null;
1315 String loginResult3 = db.LoginUser(noPassword);
1316 Assertions.assertNull(loginResult3, "Should fail when password is null");
1317
1318 // 测试4:null userinfo(失败)
1319 String loginResult4 = db.LoginUser(null);
1320 Assertions.assertNull(loginResult4, "Should fail when userinfo is null");
1321
1322 } finally {
1323 tx.rollback();
1324 }
1325 })).collect(Collectors.toList());
1326 }
root0dbc9812025-05-19 04:41:57 +00001327}