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