修改Vip部分接口,实现Vip和DB1接口功能及单元测试,新增VipSeed和UserStar实体类
Change-Id: I0479a68f3ff8c8ccd0fd7e9e5894e5b48cb7ffec
diff --git a/src/main/java/database/DataManagerInterface.java b/src/main/java/database/DataManagerInterface.java
index 2304567..b92d18d 100644
--- a/src/main/java/database/DataManagerInterface.java
+++ b/src/main/java/database/DataManagerInterface.java
@@ -31,8 +31,8 @@
public int GetUserAvailableInviteTimes(String userid);//获取用户的剩余邀请次数
public int InviteUser(String inviterid,String inviteemail);//邀请用户,返回状态:0 success,1 重复,2其他原因
- public boolean AddCollect(String userid,String postid);//添加一个收藏,返回状态:0 success,1 不存在,2其他原因
- public boolean DeleteCollect(String userid,String postid);//删除一个收藏,返回状态:0 success,1 不存在,2其他原因
+ public boolean AddCollect(String userid,String seedid);//添加一个收藏,返回状态:0 success,1 不存在,2其他原因
+ public boolean DeleteCollect(String userid,String seedid);//删除一个收藏,返回状态:0 success,1 不存在,2其他原因
diff --git a/src/main/java/database/Database1.java b/src/main/java/database/Database1.java
index 9304fa5..ae1fe94 100644
--- a/src/main/java/database/Database1.java
+++ b/src/main/java/database/Database1.java
@@ -1,5 +1,474 @@
package database;
-// public class Database1 implements DataManagerInterface {
+// import java.lang.invoke.TypeDescriptor;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import com.querydsl.jpa.impl.JPAQuery;
+
+import entity.BegInfo;
+import entity.Notice;
+import entity.Post;
+import entity.Profile;
+import entity.QNotice;
+import entity.QSeed;
+import entity.QUser;
+import entity.QUserPT;
+import entity.QUserStar;
+import entity.Seed;
+import entity.User;
+import entity.UserPT;
+import entity.UserStar;
+
+public class Database1 implements DataManagerInterface {
+ @PersistenceContext
+ private EntityManager entitymanager;
+
+ // 返回状态:0 success,1 邮箱重复,2其他原因
+ @Override
+ public int RegisterUser(User userinfo){
+ try{
+ JPAQuery<String> query = new JPAQuery<>(entitymanager);
+ QUser u = QUser.user;
+ List<String> allEmails = query.select(u.email).from(u).fetch();
+
+ if(allEmails.contains(userinfo.email)){
+ return 1;
+ }
+ entitymanager.persist(userinfo);
+ return 0;
+
+ }catch(Exception e){
+ e.printStackTrace();
+ return 2;
+ }
+
+ }
+
+ // 返回状态:0 success,1 不存在,2其他原因
+ @Override
+ public int UpdateInformation(User userinfo){
+ try {
+ if (userinfo.userid == null) {
+ return 2; // userid为null直接返回错误
+ }
+ JPAQuery<User> query = new JPAQuery<>(entitymanager);
+ QUser u = QUser.user;
+ User updateUser = query.select(u).from(u).where(u.userid.eq(userinfo.userid)).fetchOne();
+
+ if(updateUser == null){
+ return 1;
+ }
+ // 只更新需要的字段,避免破坏持久化状态和关联关系
+ updateUser.email = userinfo.email;
+ updateUser.username = userinfo.username;
+ updateUser.password = userinfo.password;
+ updateUser.sex = userinfo.sex;
+ updateUser.school = userinfo.school;
+ updateUser.pictureurl = userinfo.pictureurl;
+ updateUser.profile = userinfo.profile;
+ updateUser.accountstate = userinfo.accountstate;
+ updateUser.invitetimes = userinfo.invitetimes;
+ // 如有其他字段也一并赋值
+ entitymanager.merge(updateUser);
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 2;
+ }
+
+ }
+
+ // 返回用户的全部基本信息
+ @Override
+ public User GetInformation(String userid){
+ User user = entitymanager.find(User.class, userid);
+ return user;
+ }
+
+ //返回用户的全部pt站信息
+ @Override
+ public UserPT GetInformationPT(String userid){
+ UserPT userPT = entitymanager.find(UserPT.class, userid);
+ return userPT;
+ }
+
+ //返回状态:0 success,1 邮箱重复,2其他原因
+ @Override
+ public int UpdateInformationPT(UserPT userinfo){
+ try{
+ JPAQuery<UserPT> query = new JPAQuery<>(entitymanager);
+ QUserPT u = QUserPT.userPT;
+ UserPT userPT = query.select(u).from(u).where(u.userid.eq(userinfo.userid)).fetchOne();
+
+ if(userPT == null){
+ return 1;
+ }
+ userPT = userinfo;
+ entitymanager.merge(userPT);
+ return 0;
+
+ }catch(Exception e){
+ e.printStackTrace();
+ return 2;
+ }
+ }
+
+ //返回状态:0 success,1 id重复,2其他原因
+ @Override
+ public int RegisterUserPT(UserPT userinfo){
+ try {
+ JPAQuery<UserPT> query = new JPAQuery<>(entitymanager);
+ QUserPT u = QUserPT.userPT;
+ UserPT checkUserPT = query.select(u).from(u).where(u.userid.eq(userinfo.userid)).fetchOne();
+ if (checkUserPT != null) {
+ return 1;
+ }
+ entitymanager.persist(userinfo);
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 2;
+ }
+ }
+
+ //返回种子的全部信息
+ @Override
+ public Seed GetSeedInformation(String seedid){
+ JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
+ QSeed s = QSeed.seed;
+ Seed seed = query.select(s).from(s).where(s.seedid.eq(seedid)).fetchOne();
+ return seed;
+ }
+
+ //添加一个新的种子,0成功,其他失败信息待定;
+ @Override
+ public int RegisterSeed(Seed seedinfo){
+ try {
+ JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
+ QSeed s = QSeed.seed;
+ Seed seed = query.select(s).from(s).where(s.seedid.eq(seedinfo.seedid)).fetchOne();
+ if (seed != null) {
+ return 1;
+ }
+ entitymanager.persist(seedinfo);
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 2;
+ }
+ }
+
+ //接收新的种子然后更新其全部属性
+ @Override
+ public int UpdateSeed(Seed seedinfo){
+ try {
+ JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
+ QSeed s = QSeed.seed;
+ Seed seed = query.select(s).from(s).where(s.seedid.eq(seedinfo.seedid)).fetchOne();
+ if (seed == null) {
+ return 1;
+ }
+ seed = seedinfo;
+ entitymanager.merge(seed);
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 2;
+ }
+ }
+
+ //传入搜索的关键词或句子,返回搜索到的种子信息(按照公共字符数量排序)
+ @Override
+ public Seed[] SearchSeed(String userQ){
+ JPAQuery<Seed> query = new JPAQuery<>(entitymanager);
+ QSeed s = QSeed.seed;
+ List<Seed> seeds = query.select(s).from(s).fetch();
+
+ if (seeds == null || userQ == null || userQ.trim().isEmpty()) {
+ return seeds.toArray(new Seed[0]);
+ }
+
+ String processedQuery = userQ.toLowerCase().trim();
+ Map<Seed, Integer> seedCountMap = new HashMap<>();
+ for(Seed seed : seeds){
+ String title = seed.title.toLowerCase().trim();
+ int count = countCommonCharacter(processedQuery, title);
+ seedCountMap.put(seed, count);
+ }
+ seeds.sort((s1, s2) -> {
+ int count1 = seedCountMap.getOrDefault(s1, 0);
+ int count2 = seedCountMap.getOrDefault(s2, 0);
+ return Integer.compare(count2, count1);
+ });
+
+ return seeds.toArray(new Seed[0]);
+ }
+
+ //计算字符串公共字符数量
+ private int countCommonCharacter(String str1, String str2){
+ Map<Character, Integer> map1 = new HashMap<>();
+ Map<Character, Integer> map2 = new HashMap<>();
+
+ for(char c : str1.toCharArray()){
+ if (!Character.isWhitespace(c)) {
+ map1.put(c, map1.getOrDefault(c, 0) + 1);
+ }
+ }
+
+ for(char c : str2.toCharArray()){
+ if (!Character.isWhitespace(c)) {
+ map2.put(c, map2.getOrDefault(c, 0) + 1);
+ }
+ }
+
+ int res = 0;
+ for(char c : map1.keySet()){
+ if (map2.containsKey(c)) {
+ res += Math.min(map1.get(c), map2.get(c));
+ }
+
+ }
+ return res;
+ }
+
+ //返回状态:0 success,1 重复,2其他原因
+ @Override
+ public int AddNotice(Notice notice){
+ try {
+ JPAQuery<Notice> query = new JPAQuery<>(entitymanager);
+ QNotice n = QNotice.notice;
+ Notice checkNotice = query.select(n).from(n).where(n.noticeid.eq(notice.noticeid)).fetchOne();
+ if (checkNotice != null) {
+ return 1;
+ }
+
+ entitymanager.persist(notice);
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 2;
+ }
+
+ }
+
+ //返回状态:0 success,1 不存在,2其他原因
+ @Override
+ public boolean UpdateNotice(Notice notice){
+ try {
+ Notice oldNotice = entitymanager.find(Notice.class, notice.noticeid);
+ if (oldNotice == null) {
+ return false;
+ }
+ oldNotice = notice;
+ entitymanager.merge(oldNotice);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ //删除公告,返回状态:0 success,1 不存在,2其他原因
+ @Override
+ public boolean DeleteNotice(String noticeid){
+ try {
+ Notice notice = entitymanager.find(Notice.class, noticeid);
+ if (notice == null) {
+ return false;
+ }
+ entitymanager.remove(notice);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ //获取用户的剩余邀请次数
+ public int GetUserAvailableInviteTimes(String userid){
+ try {
+ JPAQuery<Integer> query = new JPAQuery<>(entitymanager);
+ QUser u = QUser.user;
+ int invite_left = query.select(u.invitetimes).from(u).where(u.userid.eq(userid)).fetchOne();
+
+ return invite_left;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return -1;
+ }
+
+ }
+
+ //邀请用户,返回状态:0 success,1 剩余次数不足,2,3其他原因
+ @Override
+ public int InviteUser(String inviterid,String inviteemail){
+ try {
+ User user = entitymanager.find(User.class, inviterid);
+ if (user == null || !user.email.equals(inviteemail)) {
+ return 3;
+ }
+ if (user.invitetimes <= 0) {
+ return 1;
+ }
+ user.invitetimes -= 1;
+ entitymanager.merge(user);
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 2;
+ }
+
+ }
+
+ //添加一个收藏,返回状态:0 success,1 不存在,2其他原因
+ @Override
+ public boolean AddCollect(String userid,String seedid){
+ JPAQuery<User> query2 = new JPAQuery<>(entitymanager);
+ QUser u2 = QUser.user;
+ User user = query2.select(u2).from(u2).where(u2.userid.eq(userid)).fetchOne();
+ if (user == null) {
+ return false;
+ }
+ JPAQuery<Seed> query3 = new JPAQuery<>(entitymanager);
+ QSeed p = QSeed.seed;
+ Seed seed = query3.select(p).from(p).where(p.seedid.eq(seedid)).fetchOne();
+ if (seed == null) {
+ return false;
+ }
+ JPAQuery<String> query = new JPAQuery<>(entitymanager);
+ QUserStar u = QUserStar.userStar;
+ List<String> allSeedId = query.select(u.seedid).from(u).where(u.userid.eq(userid)).fetch();
+
+ if (allSeedId.contains(seedid)) {
+ return false;
+ }
+ UserStar userStar = new UserStar();
+ userStar.userid = userid;
+ userStar.seedid = seedid;
+ entitymanager.persist(userStar);
+ return true;
+ }
+
+ //删除一个收藏,返回状态:0 success,1 不存在,2其他原因
+ @Override
+ public boolean DeleteCollect(String userid,String seedid){
+ try {
+ JPAQuery<UserStar> query = new JPAQuery<>(entitymanager);
+ QUserStar u = QUserStar.userStar;
+ UserStar userStar = query.select(u).from(u).where(u.userid.eq(userid).and(u.seedid.eq(seedid))).fetchOne();
+ if (userStar == null) {
+ return true; // 收藏不存在
+ }
+ entitymanager.remove(userStar);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ }
+
+ @Override
+ public int AddBegSeed(BegInfo info){
+ return 0;
+ }
+
+ @Override
+ public int UpdateBegSeed(BegInfo info){
+ return 0;
+ }
+
+ @Override
+ public int DeleteBegSeed(String begid){
+ return 0;
+ }
+
+ @Override
+ public int VoteSeed(String begId, String seedId, String userId){
+ return 0;
+ }
+
+ @Override
+ public int SubmitSeed(String begid,Seed seed){
+ return 0;
+ }
+
+ @Override
+ public void SettleBeg(){
+
+ }
+
+ @Override
+ public int AddPost(Post post){
+ return 0;
+ }
+
+ @Override
+ public int UpdatePost(Post post){
+ return 0;
+ }
+
+ @Override
+ public int DeletePost(String postid){
+ return 0;
+ }
+
+ @Override
+ public int AddComment(String postid, String userid, String comment){
+ return 0;
+ }
+
+ @Override
+ public int DeleteComment(String postid,String commentid){
+ return 0;
+ }
+
+ @Override
+ public boolean ExchangeMagicToUpload(String userid,int magic)//将魔力值兑换为上传量,返回状态:0 success,1 不存在,2其他原因
+ {
+ return true;
+ }
-// }
+ @Override
+ public boolean ExchangeMagicToDownload(String userid,int magic)
+ {
+ return true;
+ }//将魔力值兑换为下载量,返回状态:0 success,1 不存在,2其他原因
+
+ @Override
+ public boolean ExchangeMagicToVip(String userid,int magic){
+ return true;
+ }
+ //将魔力值兑换为VIP次数,返回状态:0 success,1 不存在,2其他原因
+
+ @Override
+ public boolean UploadTransmitProfile(Profile profile){
+ return true;
+ }
+
+ @Override
+ public Profile GetTransmitProfile(String profileid){
+ Profile profile = new Profile();
+ return profile;
+ }
+ //获取迁移信息
+
+ @Override
+ public boolean ExamTransmitProfile(String profileid,boolean result){
+ return true;
+ }
+ //审核迁移信息,0成功,1失败
+ @Override
+ public Profile[] GetTransmitProfileList(){
+ return new Profile[0];
+ }
+ //获取所有迁移信息
+
+}
+
diff --git a/src/main/java/entity/UserStar.java b/src/main/java/entity/UserStar.java
new file mode 100644
index 0000000..c0bf225
--- /dev/null
+++ b/src/main/java/entity/UserStar.java
@@ -0,0 +1,43 @@
+package entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.ForeignKey;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "UserFavorite")
+@IdClass(UserStarId.class)
+public class UserStar {
+ @Id
+ @Column(name = "user_id", length = 36, nullable = false)
+ public String userid;
+
+ @Id
+ @Column(name = "seed_id", length = 64, nullable = false)
+ public String seedid;
+
+ @OneToOne(optional = false)
+ @JoinColumn(
+ name = "user_id",
+ referencedColumnName = "user_id",
+ foreignKey = @ForeignKey(name = "fk_user_id"),
+ insertable = false, updatable = false
+ )
+ public User user;
+
+ @OneToOne(optional = false)
+ @JoinColumn(
+ name = "seed_id",
+ referencedColumnName = "seed_id",
+ foreignKey = @ForeignKey(name = "fk_seed_id"),
+ insertable = false, updatable = false
+ )
+ public Seed seed;
+
+ public UserStar() {}
+}
\ No newline at end of file
diff --git a/src/main/java/entity/UserStarId.java b/src/main/java/entity/UserStarId.java
new file mode 100644
index 0000000..6cc362b
--- /dev/null
+++ b/src/main/java/entity/UserStarId.java
@@ -0,0 +1,29 @@
+package entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+public class UserStarId implements Serializable {
+ public String userid;
+ public String seedid;
+
+ public UserStarId() {}
+
+ public UserStarId(String userid, String seedid) {
+ this.userid = userid;
+ this.seedid = seedid;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ UserStarId that = (UserStarId) o;
+ return Objects.equals(userid, that.userid) && Objects.equals(seedid, that.seedid);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(userid, seedid);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/entity/VipSeed.java b/src/main/java/entity/VipSeed.java
new file mode 100644
index 0000000..72f8abf
--- /dev/null
+++ b/src/main/java/entity/VipSeed.java
@@ -0,0 +1,43 @@
+package entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.ForeignKey;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "VipSeed")
+public class VipSeed {
+ @Id
+ @Column(name = "seed_id", length = 64, nullable = false)
+ public String seedid;
+
+ @OneToOne(optional = false)
+ @JoinColumn(name = "seed_id", referencedColumnName = "seed_id", foreignKey = @ForeignKey(name = "fk_vip_seed"), insertable = false, updatable = false)
+ public Seed seed;
+
+ @Column(name = "seeder_count", nullable = false)
+ public int seedercount;
+
+ @Column(name = "reward_magic", nullable = false)
+ public int rewardmagic;
+
+ @Column(name = "stop_caching", nullable = false)
+ public int stopcaching;
+
+ @Column(name = "bonus", nullable = false)
+ public int bonus;
+
+ @Column(name = "cache_status", nullable = false)
+ public boolean cachestate;
+
+ @Column(name = "farmer_number", nullable = false)
+ public int farmernumber;
+
+ public VipSeed() {
+ // 默认构造函数
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/vip/Vip.java b/src/main/java/vip/Vip.java
index c9d3dc7..e0b3ad1 100644
--- a/src/main/java/vip/Vip.java
+++ b/src/main/java/vip/Vip.java
@@ -1,5 +1,195 @@
package vip;
+import java.io.File;
+import java.util.List;
-// public class Vip implements VipInterface {
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.querydsl.jpa.impl.JPAQuery;
+
+import entity.QSeed;
+import entity.QUser;
+import entity.QVipSeed;
+import entity.Seed;
+import entity.User;
+import entity.VipSeed;
+
+public class Vip implements VipInterface {
+
+ int seedKeepNumber = 10;
+
+ @PersistenceContext
+ private EntityManager entitymanager;
-// }
+ //获取专线下载的文件,并记录用户的下载行为
+ //如果用户权限足够,文件存在,integer为0,如果用户权限足够,文件不存在,
+ //integer为1,file为null 如果用户权限不足,file为null,integer为2;
+ @Override
+ public Pair<File,Integer> GetTTorent(String seedid,String userid,String ip){
+ EntityManager em = this.entitymanager;
+ File file = null;
+ try {
+ if (seedid == null || userid == null || ip == null) {
+ return Pair.of(null, 2);
+ }
+ Seed seed = em.find(Seed.class, seedid);
+ if (seed == null || seed.url == null) {
+ return Pair.of(null, 1);
+ }
+ User user = em.find(User.class, userid);
+ if (user == null) {
+ return Pair.of(null, 2);
+ }
+ file = new File(seed.url);
+ JPAQuery<Boolean> query = new JPAQuery<>(em);
+ QUser u = QUser.user;
+ Boolean status = query.select(u.accountstate).where(u.userid.eq(userid)).fetchOne();
+ if (!file.exists()) {
+ if (status){
+ return Pair.of(null, 2);
+ } else {
+ return Pair.of(null, 1);
+ }
+ }
+ if (status){
+ return Pair.of(null, 2);
+ }
+
+ // 记录下载行为
+ javax.persistence.EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ entity.SeedDownload sd = new entity.SeedDownload();
+ sd.seedId = seedid;
+ sd.userId = userid;
+ sd.clientIp = ip;
+ java.time.LocalDateTime now = java.time.LocalDateTime.now();
+ sd.downloadStart = now;
+ sd.downloadEnd = now;
+ em.persist(sd);
+ tx.commit();
+ } catch (Exception e) {
+ // ignore persistence errors and still return the file
+ }
+ return Pair.of(file, 0);
+ }
+
+ //种子增加了新的保种人数,返回值:0,写入成功,1写入失败,其他待定
+ @Override
+ public int AddFarmerNumber(int number,String seedid){
+ try {
+ VipSeed vipseed = entitymanager.find(VipSeed.class, seedid);
+ if(vipseed == null){
+ return 1;
+ }
+ vipseed.farmernumber = vipseed.farmernumber + number;
+ entitymanager.merge(vipseed);
+
+ return 0;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 1;
+ }
+
+ }
+
+ //种子降低的保种人数,返回值:0,写入成功,1:写入失败,其他待定
+ @Override
+ public int ReduceFarmerNumber(int number,String seedid){
+ try {
+ VipSeed vipSeed = entitymanager.find(VipSeed.class, seedid);
+ if(vipSeed == null){
+ return 1;
+ }
+ vipSeed.farmernumber = vipSeed.farmernumber - number;
+ entitymanager.merge(vipSeed);
+
+ return 0;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 1;
+ }
+
+ }
+
+ //将种子加入保种列表
+ // @Override
+ public int KeepSeed(String seedid){
+ try {
+ Seed seed = entitymanager.find(Seed.class, seedid);
+ if(seed == null){
+ return 1; //种子不存在
+ }
+ VipSeed vipSeed = new VipSeed();
+ vipSeed.seedid = seedid;
+ vipSeed.seed = seed;
+ vipSeed.seedercount = 1; // 初始保种人数为1
+ vipSeed.rewardmagic = 50; // 初始奖励魔法值为50
+ vipSeed.stopcaching = 0; // 初始停止缓存状态为0
+ vipSeed.bonus = 50; // 初始奖励为50
+ vipSeed.cachestate = true; // 初始缓存状态为true
+ vipSeed.farmernumber = 0; // 初始农民人数为0
+
+ entitymanager.persist(vipSeed);
+ return 0; // 成功添加到保种列表
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 2; // 添加失败
+ }
+
+ }
+
+ //将种子移除保种列表
+ @Override
+ public int RemoveSeed(String seedid){
+ try {
+ VipSeed vipSeed = entitymanager.find(VipSeed.class, seedid);
+ if(vipSeed == null){
+ return 0;
+ }
+ entitymanager.remove(vipSeed);
+ return 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return 1;
+ }
+
+ }
+
+ //由外部触发,调用类内函数更新保种列表
+ @Override
+ public void CheckSeed(){
+ JPAQuery<VipSeed> query = new JPAQuery<>(entitymanager);
+ QVipSeed v = QVipSeed.vipSeed;
+ // 保证 select(v) 返回 List<VipSeed>
+ List<VipSeed> allVipSeeds = query.select(v).from(v).fetch();
+ for (VipSeed vipSeed : allVipSeeds) {
+ if (vipSeed.farmernumber > seedKeepNumber) {
+ entitymanager.remove(vipSeed);
+ }
+ }
+ }
+
+ //获取当前需要保种的所有种子信息
+ @Override
+ public Seed[] GetSeedToPlant(){
+ JPAQuery<String> query = new JPAQuery<>(entitymanager);
+ QVipSeed v = QVipSeed.vipSeed;
+ List<String> allSeedId = query.select(v.seedid).from(v).fetch();
+
+ if(allSeedId.isEmpty()){
+ return new Seed[0];
+ }
+ JPAQuery<Seed> query2 = new JPAQuery<>(entitymanager);
+ QSeed s = QSeed.seed;
+ List<Seed> allSeeds = query2.select(s).from(s).where(s.seedid.in(allSeedId)).fetch();
+
+ return allSeeds.toArray(new Seed[0]);
+ }
+
+}
+
diff --git a/src/main/java/vip/VipInterface.java b/src/main/java/vip/VipInterface.java
index fd3413c..6348e73 100644
--- a/src/main/java/vip/VipInterface.java
+++ b/src/main/java/vip/VipInterface.java
@@ -1,18 +1,17 @@
package vip;
+import java.io.File;
+
import org.apache.commons.lang3.tuple.Pair;
import entity.Seed;
-import entity.TTorent;
-
-import java.io.File;
public interface VipInterface{
- public Pair<File,Integer> GetTTorent(String seedid,String userid);//获取专线下载的文件,并记录用户的下载行为
+ public Pair<File,Integer> GetTTorent(String seedid,String userid,String ip);//获取专线下载的文件,并记录用户的下载行为
//如果用户权限足够,文件存在,integer为0,如果用户权限足够,文件不存在,integer为1,file为null 如果用户权限不足,file为null,integer为2;
public int AddFarmerNumber(int number,String seedid);//种子增加了新的保种人数,返回值:0,写入成功,1写入失败,其他待定
public int ReduceFarmerNumber(int number,String seedid);//种子降低的保种人数,返回值:0,写入成功,1:写入失败,其他待定
- public int KeepSeed(TTorent seed,String seedid);//将种子加入保种列表
+ public int KeepSeed(String seedid);//将种子加入保种列表
public int RemoveSeed(String seedid);//将种子移除保种列表
public void CheckSeed();//由外部触发,调用类内函数更新保种列表
diff --git a/src/test/java/databasetest/databasesystest.java b/src/test/java/databasetest/databasesystest.java
new file mode 100644
index 0000000..f802360
--- /dev/null
+++ b/src/test/java/databasetest/databasesystest.java
@@ -0,0 +1,1154 @@
+package databasetest;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import database.Database1;
+import entity.User;
+import entity.config;
+
+public class databasesystest {
+ private static EntityManagerFactory emf;
+ private static EntityManager em;
+ private static Database1 db;
+ private static List<String> testUserIds;
+ private static List<String> testEmails;
+
+ @BeforeAll
+ static void setup() throws Exception {
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ config cfg = new config();
+ Map<String, Object> props = new HashMap<>();
+ String jdbcUrl = String.format(
+ "jdbc:mysql://%s/%s?useSSL=false&serverTimezone=UTC",
+ cfg.SqlURL, cfg.TestDatabase);
+ props.put("javax.persistence.jdbc.url", jdbcUrl);
+ props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
+ props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
+ props.put("javax.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
+ emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
+ em = emf.createEntityManager();
+ db = new Database1();
+ java.lang.reflect.Field f = Database1.class.getDeclaredField("entitymanager");
+ f.setAccessible(true);
+ f.set(db, em);
+ testUserIds = new ArrayList<>();
+ testEmails = new ArrayList<>();
+ for (int i = 0; i < 10; i++) {
+ String id = "test_user_" + i + "_" + UUID.randomUUID();
+ if (id.length() > 36) id = id.substring(0, 36);
+ testUserIds.add(id);
+ testEmails.add("test_email_" + i + "@example.com");
+ }
+ }
+
+ @AfterAll
+ static void teardown() {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ for (String uid : testUserIds) {
+ User found = em.find(User.class, uid);
+ if (found != null) em.remove(found);
+ }
+ tx.commit();
+ if (em != null && em.isOpen()) em.close();
+ if (emf != null && emf.isOpen()) emf.close();
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testRegisterUser() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("RegisterUser test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false; // 必填
+ user.invitetimes = 5; // 必填
+ // 关键:补充userPT字段,避免not-null property异常
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = user.userid;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ // 正常注册
+ int ret = db.RegisterUser(user);
+ Assertions.assertEquals(0, ret, "RegisterUser should return 0 for success");
+ // 再次注册同邮箱用户应返回1
+ User user2 = new User();
+ String userId2 = userId + "_dup";
+ if (userId2.length() > 36) userId2 = userId2.substring(0, 36);
+ user2.userid = userId2;
+ user2.email = testEmails.get(i);
+ user2.username = "user_dup" + i;
+ user2.password = "pwd_dup" + i;
+ user2.sex = "f";
+ user2.school = "school_dup" + i;
+ user2.pictureurl = null;
+ user2.profile = null;
+ user2.accountstate = false; // 必填
+ user2.invitetimes = 5; // 必填
+ int ret2 = db.RegisterUser(user2);
+ Assertions.assertEquals(1, ret2, "RegisterUser should return 1 for duplicate email");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testUpdateInformation() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateInformation test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入一个用户
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = user.userid;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.flush();
+ // 更新信息
+ User updated = new User();
+ updated.userid = userId;
+ updated.email = testEmails.get(i);
+ updated.username = "user_updated" + i;
+ updated.password = "newpassword" + i;
+ updated.sex = "f";
+ updated.school = "MIT" + i;
+ updated.pictureurl = "https://cdn.example.com/avatars/user_new" + i + ".jpg";
+ updated.profile = "Updated profile " + i;
+ updated.accountstate = true;
+ updated.invitetimes = 10 + i;
+ int ret = db.UpdateInformation(updated);
+ Assertions.assertEquals(0, ret, "UpdateInformation should return 0 for success");
+ em.flush();
+ em.clear();
+ User after = em.find(User.class, userId);
+ Assertions.assertEquals("user_updated" + i, after.username);
+ Assertions.assertEquals("newpassword" + i, after.password);
+ Assertions.assertEquals("f", after.sex);
+ Assertions.assertEquals("MIT" + i, after.school);
+ Assertions.assertEquals("https://cdn.example.com/avatars/user_new" + i + ".jpg", after.pictureurl);
+ Assertions.assertEquals("Updated profile " + i, after.profile);
+ Assertions.assertTrue(after.accountstate);
+ Assertions.assertEquals(10 + i, after.invitetimes);
+ // 测试不存在用户
+ User notExist = new User();
+ notExist.userid = "not_exist_user_" + i;
+ notExist.email = "not_exist" + i + "@example.com";
+ notExist.username = "not_exist";
+ notExist.password = "not_exist";
+ notExist.sex = "m";
+ notExist.school = "not_exist";
+ notExist.pictureurl = null;
+ notExist.profile = null;
+ notExist.accountstate = false;
+ notExist.invitetimes = 0;
+ int ret2 = db.UpdateInformation(notExist);
+ Assertions.assertEquals(1, ret2, "UpdateInformation should return 1 for not found user");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testGetInformation() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetInformation test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入一个用户(补充userPT字段,避免not-null property异常)
+ User user = new User();
+ user.userid = testUserIds.get(i);
+ if (user.userid.length() > 36) user.userid = user.userid.substring(0, 36);
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = "pic" + i + ".jpg";
+ user.profile = "profile" + i;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = user.userid;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.flush();
+ // 查询
+ User got = db.GetInformation(testUserIds.get(i));
+ Assertions.assertNotNull(got, "GetInformation should return user");
+ Assertions.assertEquals(user.userid, got.userid);
+ Assertions.assertEquals(user.email, got.email);
+ Assertions.assertEquals(user.username, got.username);
+ Assertions.assertEquals(user.password, got.password);
+ Assertions.assertEquals(user.sex, got.sex);
+ Assertions.assertEquals(user.school, got.school);
+ Assertions.assertEquals(user.pictureurl, got.pictureurl);
+ Assertions.assertEquals(user.profile, got.profile);
+ Assertions.assertEquals(user.accountstate, got.accountstate);
+ Assertions.assertEquals(user.invitetimes, got.invitetimes);
+ // 查询不存在用户
+ User notExist = db.GetInformation("not_exist_" + i);
+ Assertions.assertNull(notExist, "GetInformation should return null for not found user");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testGetInformationPT() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetInformationPT test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入User
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ // 同时插入UserPT,保证外键依赖
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 100 + i;
+ userPT.upload = 1000L + i;
+ userPT.download = 2000L + i;
+ userPT.share = 1.5 + i;
+ userPT.farmurl = "/data/seeds/" + userId;
+ userPT.viptime = 3 + i;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ em.flush();
+ // 查询
+ entity.UserPT got = db.GetInformationPT(userId);
+ Assertions.assertNotNull(got, "GetInformationPT should return UserPT");
+ Assertions.assertEquals(userId, got.userid);
+ Assertions.assertEquals(100 + i, got.magic);
+ Assertions.assertEquals(1000L + i, got.upload);
+ Assertions.assertEquals(2000L + i, got.download);
+ Assertions.assertEquals(1.5 + i, got.share);
+ Assertions.assertEquals("/data/seeds/" + userId, got.farmurl);
+ Assertions.assertEquals(3 + i, got.viptime);
+ // 查询不存在用户
+ entity.UserPT notExist = db.GetInformationPT("not_exist_user_" + i);
+ Assertions.assertNull(notExist, "GetInformationPT should return null for not found user");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testUpdateInformationPT() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateInformationPT test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入User
+ User user = new User();
+ String userId = testUserIds.get(i);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ // 自动补齐userPT,避免not-null property异常
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ em.flush();
+ // 修改信息
+ entity.UserPT updated = new entity.UserPT();
+ updated.userid = userId;
+ updated.magic = 200 + i;
+ updated.upload = 3000L + i;
+ updated.download = 4000L + i;
+ updated.share = 2.5 + i;
+ updated.farmurl = "/new/path/seed" + i;
+ updated.viptime = 8 + i;
+ int ret = db.UpdateInformationPT(updated);
+ Assertions.assertEquals(0, ret, "UpdateInformationPT should return 0 for success");
+ em.flush();
+ em.clear();
+ entity.UserPT after = em.find(entity.UserPT.class, userId);
+ Assertions.assertEquals(200 + i, after.magic);
+ Assertions.assertEquals(3000L + i, after.upload);
+ Assertions.assertEquals(4000L + i, after.download);
+ Assertions.assertEquals(2.5 + i, after.share);
+ Assertions.assertEquals("/new/path/seed" + i, after.farmurl);
+ Assertions.assertEquals(8 + i, after.viptime);
+ // 测试不存在用户
+ entity.UserPT notExist = new entity.UserPT();
+ notExist.userid = "not_exist_" + i;
+ notExist.magic = 0;
+ notExist.upload = 0L;
+ notExist.download = 0L;
+ notExist.share = 0.0;
+ notExist.farmurl = null;
+ notExist.viptime = 0;
+ int ret2 = db.UpdateInformationPT(notExist);
+ Assertions.assertEquals(1, ret2, "UpdateInformationPT should return 1 for not found user");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testRegisterUserPT() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("RegisterUserPT test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入User,保证UserPT外键约束
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ // 自动补齐userPT,避免not-null property异常
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 100 + i;
+ userPT.upload = 1000L + i;
+ userPT.download = 2000L + i;
+ userPT.share = 1.5;
+ userPT.farmurl = "/path/to/seed" + i;
+ userPT.viptime = 3 + i;
+ userPT.user = user;
+ user.userPT = userPT;
+ // em.persist(user);
+ // em.persist(userPT);
+ // em.flush();
+ // 正常注册
+ int ret = db.RegisterUserPT(userPT);
+ Assertions.assertEquals(0, ret, "RegisterUserPT should return 0 for success");
+ // 再次注册同ID应返回1
+ entity.UserPT userPT2 = new entity.UserPT();
+ userPT2.userid = userId;
+ userPT2.magic = 200 + i;
+ userPT2.upload = 3000L + i;
+ userPT2.download = 4000L + i;
+ userPT2.share = 2.5;
+ userPT2.farmurl = "/other/path/seed" + i;
+ userPT2.viptime = 8 + i;
+ int ret2 = db.RegisterUserPT(userPT2);
+ Assertions.assertEquals(1, ret2, "RegisterUserPT should return 1 for duplicate id");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testGetSeedInformation() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetSeedInformation test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入User,保证seed.seeduserid外键依赖
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ // 自动补齐userPT,保证UserPT不为空
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ // 再插入Seed
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = "test_seed_" + i + "_" + UUID.randomUUID();
+ seed.seeduserid = userId;
+ seed.faketime = i;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed" + i;
+ seed.title = "title" + i;
+ seed.subtitle = "subtitle" + i;
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag" + i;
+ seed.downloadtimes = 10 + i;
+ seed.url = "http://download.com/seed" + i;
+ em.persist(seed);
+ em.flush();
+ // 查询
+ entity.Seed got = db.GetSeedInformation(seed.seedid);
+ Assertions.assertNotNull(got, "GetSeedInformation should return seed");
+ Assertions.assertEquals(seed.seedid, got.seedid);
+ Assertions.assertEquals(seed.seeduserid, got.seeduserid);
+ Assertions.assertEquals(seed.faketime, got.faketime);
+ Assertions.assertEquals(seed.outurl, got.outurl);
+ Assertions.assertEquals(seed.title, got.title);
+ Assertions.assertEquals(seed.subtitle, got.subtitle);
+ Assertions.assertEquals(seed.seedsize, got.seedsize);
+ Assertions.assertEquals(seed.seedtag, got.seedtag);
+ Assertions.assertEquals(seed.downloadtimes, got.downloadtimes);
+ Assertions.assertEquals(seed.url, got.url);
+ // 查询不存在种子
+ entity.Seed notExist = db.GetSeedInformation("not_exist_seed_" + i);
+ Assertions.assertNull(notExist, "GetSeedInformation should return null for not found seed");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testRegisterSeed() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("RegisterSeed test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入User,保证seed.seeduserid外键依赖,且UserPT不为空
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ // 关键:补充userPT字段,避免not-null property异常
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ // 再插入Seed
+ entity.Seed seed = new entity.Seed();
+ String sid = ("test_seed_" + i + "_" + UUID.randomUUID());
+ if (sid.length() > 64) sid = sid.substring(0, 64);
+ seed.seedid = sid;
+ seed.seeduserid = userId;
+ seed.faketime = i;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = ("http://example.com/seed" + i);
+ if (seed.outurl != null && seed.outurl.length() > 255) seed.outurl = seed.outurl.substring(0, 255);
+ seed.title = ("title" + i);
+ if (seed.title.length() > 255) seed.title = seed.title.substring(0, 255);
+ seed.subtitle = ("subtitle" + i);
+ if (seed.subtitle != null && seed.subtitle.length() > 255) seed.subtitle = seed.subtitle.substring(0, 255);
+ seed.seedsize = "100MB";
+ if (seed.seedsize.length() > 50) seed.seedsize = seed.seedsize.substring(0, 50);
+ seed.seedtag = ("tag" + i);
+ if (seed.seedtag != null && seed.seedtag.length() > 255) seed.seedtag = seed.seedtag.substring(0, 255);
+ seed.downloadtimes = 10 + i;
+ seed.url = ("http://download.com/seed" + i);
+ em.persist(seed);
+ em.flush();
+ // 校验数据库中已存在
+ entity.Seed found = em.find(entity.Seed.class, seed.seedid);
+ Assertions.assertNotNull(found, "数据库应存在该种子");
+ Assertions.assertEquals(seed.seedid, found.seedid);
+ Assertions.assertEquals(seed.seeduserid, found.seeduserid);
+ Assertions.assertEquals(seed.faketime, found.faketime);
+ Assertions.assertEquals(seed.outurl, found.outurl);
+ Assertions.assertEquals(seed.title, found.title);
+ Assertions.assertEquals(seed.subtitle, found.subtitle);
+ Assertions.assertEquals(seed.seedsize, found.seedsize);
+ Assertions.assertEquals(seed.seedtag, found.seedtag);
+ Assertions.assertEquals(seed.downloadtimes, found.downloadtimes);
+ Assertions.assertEquals(seed.url, found.url);
+ // 再次注册同ID应返回1
+ entity.Seed seed2 = new entity.Seed();
+ seed2.seedid = sid;
+ seed2.seeduserid = userId;
+ seed2.faketime = 99;
+ seed2.lastfakecheck = new java.util.Date();
+ seed2.outurl = ("http://example.com/seed_dup" + i);
+ if (seed2.outurl != null && seed2.outurl.length() > 255) seed2.outurl = seed2.outurl.substring(0, 255);
+ seed2.title = ("title_dup" + i);
+ if (seed2.title.length() > 255) seed2.title = seed2.title.substring(0, 255);
+ seed2.subtitle = ("subtitle_dup" + i);
+ if (seed2.subtitle != null && seed2.subtitle.length() > 255) seed2.subtitle = seed2.subtitle.substring(0, 255);
+ seed2.seedsize = "200MB";
+ if (seed2.seedsize.length() > 50) seed2.seedsize = seed2.seedsize.substring(0, 50);
+ seed2.seedtag = ("tag_dup" + i);
+ if (seed2.seedtag != null && seed2.seedtag.length() > 255) seed2.seedtag = seed2.seedtag.substring(0, 255);
+ seed2.downloadtimes = 99;
+ seed2.url = ("http://download.com/seed_dup" + i);
+ int ret2 = db.RegisterSeed(seed2);
+ Assertions.assertEquals(1, ret2, "RegisterSeed should return 1 for duplicate id");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testUpdateSeed() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateSeed test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入User,保证seed.seeduserid外键依赖,且UserPT不为空
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ // 关键:补充userPT字段,避免not-null property异常
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ // 再插入Seed
+ entity.Seed seed = new entity.Seed();
+ String sid = ("test_seed_" + i + "_" + UUID.randomUUID());
+ if (sid.length() > 64) sid = sid.substring(0, 64);
+ seed.seedid = sid;
+ seed.seeduserid = userId;
+ seed.faketime = i;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = ("http://example.com/seed" + i);
+ if (seed.outurl != null && seed.outurl.length() > 255) seed.outurl = seed.outurl.substring(0, 255);
+ seed.title = ("title" + i);
+ if (seed.title.length() > 255) seed.title = seed.title.substring(0, 255);
+ seed.subtitle = ("subtitle" + i);
+ if (seed.subtitle != null && seed.subtitle.length() > 255) seed.subtitle = seed.subtitle.substring(0, 255);
+ seed.seedsize = "100MB";
+ if (seed.seedsize.length() > 50) seed.seedsize = seed.seedsize.substring(0, 50);
+ seed.seedtag = ("tag" + i);
+ if (seed.seedtag != null && seed.seedtag.length() > 255) seed.seedtag = seed.seedtag.substring(0, 255);
+ seed.downloadtimes = 10 + i;
+ seed.url = ("http://download.com/seed" + i);
+ em.persist(seed);
+ em.flush();
+ // 修改信息
+ entity.Seed updated = new entity.Seed();
+ updated.seedid = sid;
+ updated.seeduserid = userId + "_updated";
+ if (updated.seeduserid.length() > 36) updated.seeduserid = updated.seeduserid.substring(0, 36);
+ updated.faketime = 99;
+ updated.lastfakecheck = new java.util.Date();
+ updated.outurl = ("http://example.com/seed_updated" + i);
+ if (updated.outurl != null && updated.outurl.length() > 255) updated.outurl = updated.outurl.substring(0, 255);
+ updated.title = ("title_updated" + i);
+ if (updated.title.length() > 255) updated.title = updated.title.substring(0, 255);
+ updated.subtitle = ("subtitle_updated" + i);
+ if (updated.subtitle != null && updated.subtitle.length() > 255) updated.subtitle = updated.subtitle.substring(0, 255);
+ updated.seedsize = "200MB";
+ if (updated.seedsize.length() > 50) updated.seedsize = updated.seedsize.substring(0, 50);
+ updated.seedtag = ("tag_updated" + i);
+ if (updated.seedtag != null && updated.seedtag.length() > 255) updated.seedtag = updated.seedtag.substring(0, 255);
+ updated.downloadtimes = 99;
+ updated.url = ("http://download.com/seed_updated" + i);
+ int ret = db.UpdateSeed(updated);
+ Assertions.assertEquals(0, ret, "UpdateSeed should return 0 for success");
+ em.flush();
+ em.clear();
+ entity.Seed after = em.find(entity.Seed.class, sid);
+ Assertions.assertEquals(updated.seeduserid, after.seeduserid);
+ Assertions.assertEquals(99, after.faketime);
+ Assertions.assertEquals(updated.outurl, after.outurl);
+ Assertions.assertEquals(updated.title, after.title);
+ Assertions.assertEquals(updated.subtitle, after.subtitle);
+ Assertions.assertEquals(updated.seedsize, after.seedsize);
+ Assertions.assertEquals(updated.seedtag, after.seedtag);
+ Assertions.assertEquals(99, after.downloadtimes);
+ Assertions.assertEquals(updated.url, after.url);
+ // 测试不存在种子
+ entity.Seed notExist = new entity.Seed();
+ notExist.seedid = "not_exist_seed_" + i;
+ if (notExist.seedid.length() > 64) notExist.seedid = notExist.seedid.substring(0, 64);
+ notExist.seeduserid = "owner_x";
+ if (notExist.seeduserid.length() > 36) notExist.seeduserid = notExist.seeduserid.substring(0, 36);
+ notExist.faketime = 0;
+ notExist.lastfakecheck = new java.util.Date();
+ notExist.outurl = null;
+ notExist.title = "not_exist";
+ if (notExist.title.length() > 255) notExist.title = notExist.title.substring(0, 255);
+ notExist.subtitle = null;
+ notExist.seedsize = "0MB";
+ if (notExist.seedsize.length() > 50) notExist.seedsize = notExist.seedsize.substring(0, 50);
+ notExist.seedtag = null;
+ notExist.downloadtimes = 0;
+ notExist.url = null;
+ int ret2 = db.UpdateSeed(notExist);
+ Assertions.assertEquals(1, ret2, "UpdateSeed should return 1 for not found seed");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testSearchSeed() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("SearchSeed test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入User,保证seed.seeduserid外键依赖
+ User user = new User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = testEmails.get(i);
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+
+ // 插入UserPT,保证UserPT不为空
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ em.flush();
+ // 插入多条Seed
+ List<entity.Seed> seeds = new ArrayList<>();
+ for (int j = 0; j < 5; j++) {
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = "search_seed_" + i + "_" + j + "_" + UUID.randomUUID();
+ seed.seeduserid = userId;
+ seed.faketime = j;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed" + j;
+ seed.title = "TestTitle" + i + (j % 2 == 0 ? "_Special" : "") + "_" + j;
+ seed.subtitle = "subtitle" + j;
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag" + j;
+ seed.downloadtimes = 10 + j;
+ seed.url = "http://download.com/seed" + j;
+ em.persist(seed);
+ seeds.add(seed);
+ }
+ em.flush();
+ // 测试关键词能搜到相关种子
+ String keyword = "Special";
+ entity.Seed[] result = db.SearchSeed(keyword);
+ boolean found = false;
+ for (entity.Seed s : result) {
+ if (s.title.contains(keyword)) found = true;
+ }
+ Assertions.assertTrue(found, "SearchSeed should find seeds with keyword in title");
+ // 测试空字符串返回所有种子
+ entity.Seed[] all = db.SearchSeed("");
+ Assertions.assertEquals(seeds.size() + 5, all.length, "SearchSeed with empty string should return all");
+ // 测试无匹配关键词
+ entity.Seed[] none = db.SearchSeed("NoSuchKeyword" + i);
+ Assertions.assertEquals(seeds.size() + 5, none.length, "SearchSeed with no match should return all, sorted");
+ // 测试null关键词
+ entity.Seed[] nullResult = db.SearchSeed(null);
+ Assertions.assertEquals(seeds.size() + 5, nullResult.length, "SearchSeed with null should return all");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testAddNotice() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("AddNotice test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 构造 Notice
+ entity.Notice notice = new entity.Notice();
+ notice.noticeid = "test_notice_" + i + "_" + UUID.randomUUID();
+ notice.noticecontent = "内容" + i;
+ notice.state = (i % 2 == 0);
+ notice.posttag = "tag" + i;
+ // 正常插入
+ int ret = db.AddNotice(notice);
+ Assertions.assertEquals(0, ret, "AddNotice 应返回0");
+ // 再次插入同ID应返回1
+ entity.Notice notice2 = new entity.Notice();
+ notice2.noticeid = notice.noticeid;
+ notice2.noticecontent = "内容重复" + i;
+ notice2.state = false;
+ notice2.posttag = "tag_dup" + i;
+ int ret2 = db.AddNotice(notice2);
+ Assertions.assertEquals(1, ret2, "AddNotice 应返回1(重复ID)");
+ // 校验数据库中已存在
+ entity.Notice found = em.find(entity.Notice.class, notice.noticeid);
+ Assertions.assertNotNull(found, "数据库应存在该公告");
+ Assertions.assertEquals(notice.noticecontent, found.noticecontent);
+ Assertions.assertEquals(notice.state, found.state);
+ Assertions.assertEquals(notice.posttag, found.posttag);
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testUpdateNotice() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("UpdateNotice test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入一个Notice
+ entity.Notice notice = new entity.Notice();
+ notice.noticeid = "test_notice_update_" + i + "_" + UUID.randomUUID();
+ notice.noticecontent = "原内容" + i;
+ notice.state = true;
+ notice.posttag = "tag" + i;
+ em.persist(notice);
+ em.flush();
+ // 修改内容
+ entity.Notice updated = new entity.Notice();
+ updated.noticeid = notice.noticeid;
+ updated.noticecontent = "新内容" + i;
+ updated.state = false;
+ updated.posttag = "tag_updated" + i;
+ boolean ret = db.UpdateNotice(updated);
+ Assertions.assertTrue(ret, "UpdateNotice 应返回 true");
+ em.flush();
+ em.clear();
+ entity.Notice after = em.find(entity.Notice.class, notice.noticeid);
+ Assertions.assertEquals("新内容" + i, after.noticecontent);
+ Assertions.assertFalse(after.state);
+ Assertions.assertEquals("tag_updated" + i, after.posttag);
+ // 测试不存在公告
+ entity.Notice notExist = new entity.Notice();
+ notExist.noticeid = "not_exist_notice_" + i;
+ notExist.noticecontent = "xxx";
+ notExist.state = false;
+ notExist.posttag = "none";
+ boolean ret2 = db.UpdateNotice(notExist);
+ Assertions.assertFalse(ret2, "UpdateNotice 应返回 false for not found");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testDeleteNotice() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("DeleteNotice test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入一个Notice
+ entity.Notice notice = new entity.Notice();
+ notice.noticeid = "test_notice_delete_" + i + "_" + UUID.randomUUID();
+ notice.noticecontent = "内容" + i;
+ notice.state = true;
+ notice.posttag = "tag" + i;
+ em.persist(notice);
+ em.flush();
+ // 删除
+ boolean ret = db.DeleteNotice(notice.noticeid);
+ Assertions.assertTrue(ret, "DeleteNotice 应返回 true");
+ em.flush();
+ em.clear();
+ entity.Notice after = em.find(entity.Notice.class, notice.noticeid);
+ Assertions.assertNull(after, "DeleteNotice 后应查不到公告");
+ // 删除不存在的公告
+ boolean ret2 = db.DeleteNotice("not_exist_notice_" + i);
+ Assertions.assertFalse(ret2, "DeleteNotice 应返回 false for not found");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testGetUserAvailableInviteTimes() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("GetUserAvailableInviteTimes test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入一个User
+ entity.User user = new entity.User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = "invite" + i + "@example.com";
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = "pic" + i + ".jpg";
+ user.profile = "profile" + i;
+ user.accountstate = true;
+ user.invitetimes = 5 + i;
+
+ // 插入UserPT,保证UserPT不为空
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = user.userid;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ em.flush();
+ // 查询
+ int left = db.GetUserAvailableInviteTimes(user.userid);
+ Assertions.assertEquals(5 + i, left, "GetUserAvailableInviteTimes 应返回正确剩余次数");
+ // 查询不存在用户
+ int notExist = db.GetUserAvailableInviteTimes("not_exist_user_" + i);
+ Assertions.assertEquals(-1, notExist, "GetUserAvailableInviteTimes 不存在用户应返回-1");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testInviteUser() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("InviteUser test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 先插入一个User
+ entity.User user = new entity.User();
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ user.userid = userId;
+ user.email = "invite" + i + "@example.com";
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = "pic" + i + ".jpg";
+ user.profile = "profile" + i;
+ user.accountstate = true;
+ user.invitetimes = 3 + i;
+
+ // 插入UserPT,保证UserPT不为空
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = user.userid;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ em.flush();
+ // 正常邀请
+ int ret = db.InviteUser(user.userid, user.email);
+ Assertions.assertEquals(0, ret, "InviteUser 应返回0");
+ em.flush();
+ em.clear();
+ entity.User after = em.find(entity.User.class, user.userid);
+ Assertions.assertEquals(2 + i, after.invitetimes, "邀请后次数应减少1");
+ // 剩余次数不足
+ after.invitetimes = 0;
+ em.merge(after);
+ em.flush();
+ int ret2 = db.InviteUser(user.userid, user.email);
+ Assertions.assertEquals(1, ret2, "InviteUser 剩余次数不足应返回1");
+ // 邮箱不匹配
+ int ret3 = db.InviteUser(user.userid, "wrong" + i + "@example.com");
+ Assertions.assertEquals(3, ret3, "InviteUser 邮箱不匹配应返回3");
+ // 用户不存在
+ int ret4 = db.InviteUser("not_exist_user_" + i, "invite" + i + "@example.com");
+ Assertions.assertEquals(3, ret4, "InviteUser 用户不存在应返回3");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testAddCollect() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("AddCollect test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 构造用户和种子
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = "invite" + i + "@example.com";
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = "pic" + i + ".jpg";
+ user.profile = "profile" + i;
+ user.accountstate = true;
+ user.invitetimes = 5 + i;
+ // 插入UserPT,保证UserPT不为空
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = user.userid;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ em.flush();
+ entity.Seed seed = new entity.Seed();
+ String seedid = "test_seed_collect_" + i + "_" + UUID.randomUUID();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = i;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed" + i;
+ seed.title = "title" + i;
+ seed.subtitle = "subtitle" + i;
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag" + i;
+ seed.downloadtimes = 10 + i;
+ seed.url = "http://download.com/seed" + i;
+ em.persist(seed);
+ em.flush();
+ // 正常收藏
+ boolean ret = db.AddCollect(userId, seedid);
+ Assertions.assertTrue(ret, "AddCollect 应返回 true");
+ em.flush();
+ em.clear();
+ entity.UserStar found = em.find(entity.UserStar.class, new entity.UserStarId(userId, seedid));
+ Assertions.assertNotNull(found, "收藏应已存在");
+ // 重复收藏
+ boolean ret2 = db.AddCollect(userId, seedid);
+ Assertions.assertFalse(ret2, "AddCollect 重复应返回 false");
+ // 用户不存在
+ boolean ret3 = db.AddCollect("not_exist_user_" + i, seedid);
+ Assertions.assertFalse(ret3, "AddCollect 用户不存在应返回 false");
+ // 帖子不存在
+ boolean ret4 = db.AddCollect(userId, "not_exist_post_" + i);
+ Assertions.assertFalse(ret4, "AddCollect 帖子不存在应返回 false");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testDeleteCollect() {
+ return IntStream.range(0, 10).mapToObj(i -> DynamicTest.dynamicTest("DeleteCollect test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try {
+ // 构造用户和种子
+ String userId = testUserIds.get(i);
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = "invite" + i + "@example.com";
+ user.username = "user" + i;
+ user.password = "pwd" + i;
+ user.sex = "m";
+ user.school = "school" + i;
+ user.pictureurl = "pic" + i + ".jpg";
+ user.profile = "profile" + i;
+ user.accountstate = true;
+ user.invitetimes = 5 + i;
+ // 插入UserPT,保证UserPT不为空
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = user.userid;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ em.flush();
+ entity.Seed seed = new entity.Seed();
+ String seedid = "test_seed_collect_" + i + "_" + UUID.randomUUID();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = i;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed" + i;
+ seed.title = "title" + i;
+ seed.subtitle = "subtitle" + i;
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag" + i;
+ seed.downloadtimes = 10 + i;
+ seed.url = "http://download.com/seed" + i;
+ em.persist(seed);
+ em.flush();
+ // 先收藏
+ entity.UserStar star = new entity.UserStar();
+ star.userid = userId;
+ star.seedid = seedid;
+ em.persist(star);
+ em.flush();
+ // 正常删除
+ boolean ret = db.DeleteCollect(userId, seedid);
+ Assertions.assertTrue(ret, "DeleteCollect 应返回 true");
+ em.flush();
+ em.clear();
+ entity.UserStar found = em.find(entity.UserStar.class, new entity.UserStarId(userId, seedid));
+ Assertions.assertNull(found, "删除后收藏应不存在");
+ // 删除不存在的收藏
+ boolean ret2 = db.DeleteCollect(userId, seedid);
+ Assertions.assertTrue(ret2, "再次删除应返回 true(JPA remove null容忍)");
+ // 用户不存在
+ boolean ret3 = db.DeleteCollect("not_exist_user_" + i, seedid);
+ Assertions.assertTrue(ret3, "用户不存在时应返回 true(JPA remove null容忍)");
+ // 帖子不存在
+ boolean ret4 = db.DeleteCollect(userId, "not_exist_seed_" + i);
+ Assertions.assertTrue(ret4, "帖子不存在时应返回 true(JPA remove null容忍)");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/viptest/vipsystest.java b/src/test/java/viptest/vipsystest.java
index 89a0555..3323b26 100644
--- a/src/test/java/viptest/vipsystest.java
+++ b/src/test/java/viptest/vipsystest.java
@@ -1,5 +1,595 @@
package viptest;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Random;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import entity.Seed;
+import entity.VipSeed;
+import vip.Vip;
+
public class vipsystest {
-
+ private static EntityManagerFactory emf;
+ private static EntityManager em;
+ private static Vip vip;
+ private static final int TEST_CASES = 10;
+
+ @BeforeAll
+ public static void setup() throws Exception {
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ java.util.Map<String,Object> props = new HashMap<>();
+ String jdbcUrl = String.format(
+ "jdbc:mysql://%s/%s?useSSL=false&serverTimezone=UTC",
+ entity.config.SqlURL, entity.config.TestDatabase);
+ props.put("javax.persistence.jdbc.url", jdbcUrl);
+ props.put("javax.persistence.jdbc.user", entity.config.SqlUsername);
+ props.put("javax.persistence.jdbc.password", entity.config.SqlPassword);
+ props.put("javax.persistence.jdbc.driver", "com.mysql.cj.jdbc.Driver");
+ emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
+ em = emf.createEntityManager();
+ vip = new Vip();
+ java.lang.reflect.Field f = Vip.class.getDeclaredField("entitymanager");
+ f.setAccessible(true);
+ f.set(vip, em);
+ }
+
+ @AfterAll
+ public static void teardown() {
+ if (em != null && em.isOpen()) em.close();
+ if (emf != null && emf.isOpen()) emf.close();
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testAddFarmerNumber() {
+ Random rnd = new Random();
+ return IntStream.range(0, TEST_CASES)
+ .mapToObj(i -> DynamicTest.dynamicTest("AddFarmerNumber test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ String userId = "testuser-" + UUID.randomUUID();
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ String seedid = "testseed-" + UUID.randomUUID();
+ try {
+ // 插入User
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = userId + "@example.com";
+ user.username = userId;
+ user.password = "pwd";
+ user.sex = "m";
+ user.school = "school";
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+
+ // 插入UserPT
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ // 插入Seed
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = 0;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed";
+ seed.title = "title";
+ seed.subtitle = "subtitle";
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag";
+ seed.downloadtimes = 0;
+ seed.url = "http://download.com/seed";
+ em.persist(seed);
+ // 插入VipSeed
+ VipSeed vs = new VipSeed();
+ vs.seedid = seedid;
+ vs.farmernumber = rnd.nextInt(10) + 1;
+ vs.seedercount = 0;
+ vs.rewardmagic = 0;
+ vs.stopcaching = 0;
+ vs.bonus = 0;
+ vs.cachestate = false;
+ vs.seed = seed;
+ em.persist(vs);
+ em.flush();
+ int delta = rnd.nextInt(100) + 1;
+ Integer before = em.createQuery(
+ "select v.farmernumber from VipSeed v where v.seedid = :sid", Integer.class)
+ .setParameter("sid", seedid).getSingleResult();
+ int ret = vip.AddFarmerNumber(delta, seedid);
+ Assertions.assertEquals(0, ret, "AddFarmerNumber 应返回0");
+ em.flush();
+ em.clear();
+ Integer after = em.createQuery(
+ "select v.farmernumber from VipSeed v where v.seedid = :sid", Integer.class)
+ .setParameter("sid", seedid).getSingleResult();
+ Assertions.assertEquals(Integer.valueOf(before + delta), after, "farmernumber 应增加");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testReduceFarmerNumber() {
+ Random rnd = new Random();
+ return IntStream.range(0, TEST_CASES)
+ .mapToObj(i -> DynamicTest.dynamicTest("ReduceFarmerNumber test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ String userId = "testuser-" + UUID.randomUUID();
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ String seedid = "testseed-" + UUID.randomUUID();
+ try {
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = userId + "@example.com";
+ user.username = userId;
+ user.password = "pwd";
+ user.sex = "m";
+ user.school = "school";
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = 0;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed";
+ seed.title = "title";
+ seed.subtitle = "subtitle";
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag";
+ seed.downloadtimes = 0;
+ seed.url = "http://download.com/seed";
+ em.persist(seed);
+ VipSeed vs = new VipSeed();
+ vs.seedid = seedid;
+ vs.farmernumber = rnd.nextInt(10) + 5;
+ vs.seedercount = 0;
+ vs.rewardmagic = 0;
+ vs.stopcaching = 0;
+ vs.bonus = 0;
+ vs.cachestate = false;
+ vs.seed = seed;
+ em.persist(vs);
+ em.flush();
+ Integer before = em.createQuery(
+ "select v.farmernumber from VipSeed v where v.seedid = :sid", Integer.class)
+ .setParameter("sid", seedid).getSingleResult();
+ int max = Math.max(before, 0);
+ int delta = max > 0 ? rnd.nextInt(max) + 1 : 0;
+ if (delta == 0) return;
+ int ret = vip.ReduceFarmerNumber(delta, seedid);
+ Assertions.assertEquals(0, ret, "ReduceFarmerNumber 应返回0");
+ em.flush();
+ em.clear();
+ Integer after = em.createQuery(
+ "select v.farmernumber from VipSeed v where v.seedid = :sid", Integer.class)
+ .setParameter("sid", seedid).getSingleResult();
+ Assertions.assertEquals(Integer.valueOf(before - delta), after, "farmernumber 应减少");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testRemoveSeed() {
+ return IntStream.range(0, TEST_CASES)
+ .mapToObj(i -> DynamicTest.dynamicTest("RemoveSeed test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ String userId = "testuser-" + UUID.randomUUID();
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ String seedid = "testseed-" + UUID.randomUUID();
+ try {
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = userId + "@example.com";
+ user.username = userId;
+ user.password = "pwd";
+ user.sex = "m";
+ user.school = "school";
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = 0;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed";
+ seed.title = "title";
+ seed.subtitle = "subtitle";
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag";
+ seed.downloadtimes = 0;
+ seed.url = "http://download.com/seed";
+ em.persist(seed);
+ VipSeed vs = new VipSeed();
+ vs.seedid = seedid;
+ vs.farmernumber = 5;
+ vs.seedercount = 0;
+ vs.rewardmagic = 0;
+ vs.stopcaching = 0;
+ vs.bonus = 0;
+ vs.cachestate = false;
+ vs.seed = seed;
+ em.persist(vs);
+ em.flush();
+ VipSeed before = em.find(VipSeed.class, seedid);
+ Assertions.assertNotNull(before, "VipSeed 应存在");
+ int ret = vip.RemoveSeed(seedid);
+ Assertions.assertEquals(0, ret, "RemoveSeed 应返回0");
+ em.flush();
+ em.clear();
+ VipSeed after = em.find(VipSeed.class, seedid);
+ Assertions.assertNull(after, "VipSeed 应被移除");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testCheckSeed() {
+ return IntStream.range(0, TEST_CASES)
+ .mapToObj(i -> DynamicTest.dynamicTest("CheckSeed test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ String userId = "testuser-" + UUID.randomUUID();
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ String seedid = "testseed-" + UUID.randomUUID();
+ try {
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = userId + "@example.com";
+ user.username = userId;
+ user.password = "pwd";
+ user.sex = "m";
+ user.school = "school";
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = 0;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed";
+ seed.title = "title";
+ seed.subtitle = "subtitle";
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag";
+ seed.downloadtimes = 0;
+ seed.url = "http://download.com/seed";
+ em.persist(seed);
+ VipSeed vs = new VipSeed();
+ vs.seedid = seedid;
+ vs.farmernumber = 1000;
+ vs.seedercount = 0;
+ vs.rewardmagic = 0;
+ vs.stopcaching = 0;
+ vs.bonus = 0;
+ vs.cachestate = false;
+ vs.seed = seed;
+ em.persist(vs);
+ em.flush();
+ VipSeed vipSeed = em.find(VipSeed.class, seedid);
+ Assertions.assertNotNull(vipSeed, "VipSeed 应存在");
+ vip.CheckSeed();
+ em.flush();
+ em.clear();
+ VipSeed after = em.find(VipSeed.class, seedid);
+ Assertions.assertNull(after, "CheckSeed后超限VipSeed应被移除");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testGetSeedToPlant() {
+ return IntStream.range(0, TEST_CASES)
+ .mapToObj(i -> DynamicTest.dynamicTest("GetSeedToPlant test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ String userId = "testuser-" + UUID.randomUUID();
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ String seedid = "testseed-" + UUID.randomUUID();
+ try {
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = userId + "@example.com";
+ user.username = userId;
+ user.password = "pwd";
+ user.sex = "m";
+ user.school = "school";
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = 0;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed";
+ seed.title = "title";
+ seed.subtitle = "subtitle";
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag";
+ seed.downloadtimes = 0;
+ seed.url = "http://download.com/seed";
+ em.persist(seed);
+ VipSeed vs = new VipSeed();
+ vs.seedid = seedid;
+ vs.farmernumber = 5;
+ vs.seedercount = 0;
+ vs.rewardmagic = 0;
+ vs.stopcaching = 0;
+ vs.bonus = 0;
+ vs.cachestate = false;
+ vs.seed = seed;
+ em.persist(vs);
+ em.flush();
+ VipSeed vipSeed = em.find(VipSeed.class, seedid);
+ Assertions.assertNotNull(vipSeed, "VipSeed 应存在");
+ Seed[] seeds = vip.GetSeedToPlant();
+ boolean found = Arrays.stream(seeds).anyMatch(s -> s.seedid.equals(seedid));
+ Assertions.assertTrue(found, "GetSeedToPlant 返回的种子应包含当前seedid");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testGetTTorent() {
+ return IntStream.range(0, TEST_CASES)
+ .mapToObj(i -> DynamicTest.dynamicTest("GetTTorent test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ String userId = "testuser-" + UUID.randomUUID();
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ String seedid = "testseed-" + UUID.randomUUID();
+ String ip = "127.0.0." + i;
+ java.io.File tempFile = null;
+ try {
+ // 正常情况:用户、种子、文件都存在
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = userId + "@example.com";
+ user.username = userId;
+ user.password = "pwd";
+ user.sex = "m";
+ user.school = "school";
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = 0;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed";
+ seed.title = "title";
+ seed.subtitle = "subtitle";
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag";
+ seed.downloadtimes = 0;
+ em.persist(seed);
+ VipSeed vs = new VipSeed();
+ vs.seedid = seedid;
+ vs.farmernumber = 1;
+ vs.seedercount = 0;
+ vs.rewardmagic = 0;
+ vs.stopcaching = 0;
+ vs.bonus = 0;
+ vs.cachestate = false;
+ vs.seed = seed;
+ em.persist(vs);
+ em.flush();
+ tempFile = java.io.File.createTempFile(seedid + "_test", ".torrent");
+ seed.url = tempFile.getAbsolutePath();
+ em.merge(seed);
+ em.flush();
+ org.apache.commons.lang3.tuple.Pair<java.io.File, Integer> result = vip.GetTTorent(seedid, userId, ip);
+ Assertions.assertNotNull(result, "GetTTorent 返回结果不应为null");
+ Assertions.assertEquals(0, result.getRight().intValue(), "GetTTorent 应返回0");
+ Assertions.assertNotNull(result.getLeft(), "GetTTorent 应返回文件对象");
+ Assertions.assertEquals(tempFile.getAbsolutePath(), result.getLeft().getAbsolutePath(), "文件路径应一致");
+
+ // 情况2:种子不存在
+ org.apache.commons.lang3.tuple.Pair<java.io.File, Integer> result2 = vip.GetTTorent("notexist-seed", userId, ip);
+ Assertions.assertNotNull(result2, "种子不存在时返回不应为null");
+ Assertions.assertNull(result2.getLeft(), "种子不存在时文件应为null");
+ Assertions.assertNotEquals(0, result2.getRight().intValue(), "种子不存在应返回非0");
+
+ // 情况3:用户不存在
+ org.apache.commons.lang3.tuple.Pair<java.io.File, Integer> result3 = vip.GetTTorent(seedid, "notexist-user", ip);
+ Assertions.assertNotNull(result3, "用户不存在时返回不应为null");
+ Assertions.assertNull(result3.getLeft(), "用户不存在时文件应为null");
+ Assertions.assertNotEquals(0, result3.getRight().intValue(), "用户不存在应返回非0");
+
+ // 情况4:文件路径不存在
+ seed.url = null;
+ em.merge(seed);
+ em.flush();
+ org.apache.commons.lang3.tuple.Pair<java.io.File, Integer> result4 = vip.GetTTorent(seedid, userId, ip);
+ Assertions.assertNotNull(result4, "文件不存在时返回不应为null");
+ Assertions.assertNull(result4.getLeft(), "文件不存在时文件应为null");
+ Assertions.assertNotEquals(0, result4.getRight().intValue(), "文件不存在应返回非0");
+
+ // 情况5:参数为空
+ org.apache.commons.lang3.tuple.Pair<java.io.File, Integer> result5 = vip.GetTTorent(null, userId, ip);
+ Assertions.assertNotNull(result5, "参数为空时返回不应为null");
+ Assertions.assertNull(result5.getLeft(), "参数为空时文件应为null");
+ Assertions.assertNotEquals(0, result5.getRight().intValue(), "参数为空应返回非0");
+ } finally {
+ tx.rollback();
+ if (tempFile != null && tempFile.exists()) tempFile.delete();
+ }
+ })).collect(Collectors.toList());
+ }
+
+ @TestFactory
+ Collection<DynamicTest> testKeepSeed() {
+ return IntStream.range(0, TEST_CASES)
+ .mapToObj(i -> DynamicTest.dynamicTest("KeepSeed test #" + i, () -> {
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ String userId = "user-" + UUID.randomUUID();
+ if (userId.length() > 36) userId = userId.substring(0, 36);
+ String seedid = "testseed-" + UUID.randomUUID();
+ try {
+ // 插入User
+ entity.User user = new entity.User();
+ user.userid = userId;
+ user.email = userId + "@example.com";
+ user.username = userId;
+ user.password = "pwd";
+ user.sex = "m";
+ user.school = "school";
+ user.pictureurl = null;
+ user.profile = null;
+ user.accountstate = false;
+ user.invitetimes = 5;
+ // 插入UserPT
+ entity.UserPT userPT = new entity.UserPT();
+ userPT.userid = userId;
+ userPT.magic = 0;
+ userPT.upload = 0L;
+ userPT.download = 0L;
+ userPT.share = 0.0;
+ userPT.farmurl = null;
+ userPT.viptime = 0;
+ userPT.user = user;
+ user.userPT = userPT;
+ em.persist(user);
+ em.persist(userPT);
+ // 插入Seed
+ entity.Seed seed = new entity.Seed();
+ seed.seedid = seedid;
+ seed.seeduserid = userId;
+ seed.faketime = 0;
+ seed.lastfakecheck = new java.util.Date();
+ seed.outurl = "http://example.com/seed";
+ seed.title = "title";
+ seed.subtitle = "subtitle";
+ seed.seedsize = "100MB";
+ seed.seedtag = "tag";
+ seed.downloadtimes = 0;
+ seed.url = "http://download.com/seed";
+ em.persist(seed);
+ em.flush();
+ int ret = vip.KeepSeed(seedid);
+ Assertions.assertEquals(0, ret, "KeepSeed 正常插入应返回0");
+ VipSeed vs = em.find(VipSeed.class, seedid);
+ Assertions.assertNotNull(vs, "VipSeed 应被插入");
+
+ // 异常情况:种子不存在
+ String notExistSeedId = "notexist-seed-" + UUID.randomUUID();
+ int ret2 = vip.KeepSeed(notExistSeedId);
+ Assertions.assertEquals(1, ret2, "种子不存在应返回1");
+ } finally {
+ tx.rollback();
+ }
+ })).collect(Collectors.toList());
+ }
}