• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

DataBiosphere / consent / #5971

28 May 2025 01:45PM UTC coverage: 78.503% (-0.06%) from 78.558%
#5971

push

web-flow
DT-1662: Ensure single Library Card per User (#2536)

83 of 86 new or added lines in 9 files covered. (96.51%)

4 existing lines in 3 files now uncovered.

10028 of 12774 relevant lines covered (78.5%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.0
/src/main/java/org/broadinstitute/consent/http/service/LibraryCardService.java
1
package org.broadinstitute.consent.http.service;
2

3
import com.google.inject.Inject;
4
import jakarta.ws.rs.BadRequestException;
5
import jakarta.ws.rs.NotFoundException;
6
import java.util.Date;
7
import java.util.List;
8
import java.util.Objects;
9
import org.broadinstitute.consent.http.db.InstitutionDAO;
10
import org.broadinstitute.consent.http.db.LibraryCardDAO;
11
import org.broadinstitute.consent.http.db.UserDAO;
12
import org.broadinstitute.consent.http.enumeration.UserRoles;
13
import org.broadinstitute.consent.http.exceptions.ConsentConflictException;
14
import org.broadinstitute.consent.http.models.Institution;
15
import org.broadinstitute.consent.http.models.LibraryCard;
16
import org.broadinstitute.consent.http.models.User;
17

18
public class LibraryCardService {
19

20
  private final LibraryCardDAO libraryCardDAO;
21
  private final InstitutionDAO institutionDAO;
22
  private final InstitutionService institutionService;
23
  private final UserDAO userDAO;
24

25
  @Inject
26
  public LibraryCardService(LibraryCardDAO libraryCardDAO, InstitutionDAO institutionDAO,
27
      InstitutionService institutionService,
28
      UserDAO userDAO) {
1✔
29
    this.libraryCardDAO = libraryCardDAO;
1✔
30
    this.institutionDAO = institutionDAO;
1✔
31
    this.institutionService = institutionService;
1✔
32
    this.userDAO = userDAO;
1✔
33
  }
1✔
34

35
  public LibraryCard createLibraryCard(LibraryCard libraryCard, User user) {
36
    throwIfNull(libraryCard);
1✔
37
    boolean isAdmin = checkIsAdmin(user);
1✔
38
    checkIfCardExists(libraryCard);
1✔
39
    processUserOnNewLC(libraryCard);
1✔
40
    if (!isAdmin) {
1✔
41
      checkForValidInstitution(user.getInstitutionId(), libraryCard.getUserEmail());
1✔
42
    }
43
    Date createDate = new Date();
1✔
44
    Integer id = libraryCardDAO.insertLibraryCard(
1✔
45
        libraryCard.getUserId(),
1✔
46
        libraryCard.getUserName(),
1✔
47
        libraryCard.getUserEmail(),
1✔
48
        libraryCard.getCreateUserId(),
1✔
49
        createDate);
50
    return libraryCardDAO.findLibraryCardById(id);
1✔
51
  }
52

53
  public void deleteLibraryCardById(Integer id) {
54
    LibraryCard card = findLibraryCardById(id);
×
55
    throwIfNull(card);
×
56
    libraryCardDAO.deleteLibraryCardById(id);
×
57
  }
×
58

59
  public List<LibraryCard> findAllLibraryCards() {
60
    return libraryCardDAO.findAllLibraryCards();
×
61
  }
62

63
  public LibraryCard findLibraryCardByUserId(Integer userId) {
64
    return libraryCardDAO.findLibraryCardByUserId(userId);
1✔
65
  }
66

67
  public List<LibraryCard> findLibraryCardsByInstitutionId(Integer institutionId) {
68
    return libraryCardDAO.findLibraryCardsByInstitutionId(institutionId);
×
69
  }
70

71
  public LibraryCard findLibraryCardById(Integer libraryCardId) {
72
    LibraryCard libraryCard = libraryCardDAO.findLibraryCardById(libraryCardId);
1✔
73
    throwIfNull(libraryCard);
1✔
74
    return libraryCard;
1✔
75
  }
76

77
  public LibraryCard findLibraryCardWithDaasById(Integer libraryCardId) {
78
    LibraryCard libraryCard = libraryCardDAO.findLibraryCardDaaById(libraryCardId);
1✔
79
    throwIfNull(libraryCard);
1✔
80
    return libraryCard;
1✔
81
  }
82

83
  public void addDaaToLibraryCard(Integer libraryCardId, Integer daaId) {
84
    libraryCardDAO.createLibraryCardDaaRelation(libraryCardId, daaId);
1✔
85
  }
1✔
86

87
  public void removeDaaFromLibraryCard(Integer libraryCardId, Integer daaId) {
88
    libraryCardDAO.deleteLibraryCardDaaRelation(libraryCardId, daaId);
1✔
89
  }
1✔
90

91
  public LibraryCard addDaaToUserLibraryCard(User user, User signingOfficial, Integer daaId) {
92
    if (signingOfficial.getInstitutionId() == null) {
1✔
UNCOV
93
      throw new BadRequestException("This signing official does not have an institution.");
×
94
    }
95
    LibraryCard libraryCard = libraryCardDAO.findLibraryCardByUserId(user.getUserId());
1✔
96
    if (libraryCard == null) {
1✔
97
      libraryCard = createLibraryCardForSigningOfficial(user, signingOfficial);
1✔
98
    }
99
    addDaaToLibraryCard(libraryCard.getId(), daaId);
1✔
100
    return libraryCardDAO.findLibraryCardByUserId(user.getUserId());
1✔
101
  }
102

103
  public LibraryCard removeDaaFromUserLibraryCard(User user, Integer daaId) {
104
    LibraryCard libraryCard = findLibraryCardByUserId(user.getUserId());
1✔
105
    // typically there should be one library card per user
106
    if (libraryCard != null) {
1✔
107
      removeDaaFromLibraryCard(libraryCard.getId(), daaId);
1✔
108
    }
109
    return findLibraryCardByUserId(user.getUserId());
1✔
110
  }
111

112
  public LibraryCard createLibraryCardForSigningOfficial(User user, User signingOfficial) {
113
    LibraryCard lc = new LibraryCard();
1✔
114
    lc.setUserId(user.getUserId());
1✔
115
    lc.setUserName(user.getDisplayName());
1✔
116
    lc.setUserEmail(user.getEmail());
1✔
117
    lc.setCreateUserId(signingOfficial.getUserId());
1✔
118
    LibraryCard createdLc = createLibraryCard(lc, user);
1✔
119
    return createdLc;
1✔
120
  }
121

122
  private void checkForValidInstitution(Integer institutionId, String userEmail) {
123
    checkInstitutionId(institutionId);
1✔
124
    Institution institution = institutionDAO.findInstitutionById(institutionId);
1✔
125

126
    if (Objects.isNull(institution)) {
1✔
127
      throw new IllegalArgumentException("Invalid Institution Id");
×
128
    }
129

130
    var userInstitution = institutionService.findInstitutionForEmail(userEmail);
1✔
131
    if (userInstitution == null || !userInstitution.getId().equals(institutionId)) {
1✔
132
      throw new BadRequestException(
1✔
133
          "User email %s does not match institution %s".formatted(userEmail, institution.getName()));
1✔
134
    }
135
  }
1✔
136

137
  private void checkInstitutionId(Integer institutionId) {
138
    if (Objects.isNull(institutionId)) {
1✔
139
      throw new IllegalArgumentException("Institution ID is a required parameter");
×
140
    }
141
  }
1✔
142

143
  private void throwIfNull(LibraryCard libraryCard) {
144
    if (Objects.isNull(libraryCard)) {
1✔
145
      throw new NotFoundException("LibraryCard not found.");
1✔
146
    }
147
  }
1✔
148

149
  //helper method for create method, checks to see if card already exists
150
  private void checkIfCardExists(LibraryCard payload) {
151
    LibraryCard result = null;
1✔
152

153
    if (payload.getUserId() != null) {
1✔
154
      result = libraryCardDAO.findLibraryCardByUserId(payload.getUserId());
1✔
155
    } else if (payload.getUserEmail() != null) {
1✔
156
      result = libraryCardDAO.findLibraryCardByUserEmail(payload.getUserEmail());
1✔
157
    } else {
158
      throw new BadRequestException();
1✔
159
    }
160

161
    if (result != null) {
1✔
162
      Boolean sameUserId = payload.getUserId() != null && result.getUserId().equals(payload.getUserId());
1✔
163
      Boolean sameUserEmail = payload.getUserEmail() != null && result.getUserEmail().equalsIgnoreCase(payload.getUserEmail());
1✔
164
      if (sameUserId || sameUserEmail) {
1✔
165
        throw new ConsentConflictException("Library card already exists for this user.");
1✔
166
      }
167
    }
168
  }
1✔
169

170
  // Helper method to process user data on create LC payload.
171
  // Needed since CREATE has a unique situation where admins can create LCs without an active
172
  // user (save with userEmail instead).
173
  private void processUserOnNewLC(LibraryCard card) {
174
    if (card.getUserId() == null) {
1✔
175
      // No user ID is provided, email must exist in card request.
176
      if (card.getUserEmail() == null) {
1✔
177
        throw new BadRequestException();
×
178
      }
179
      // If a user is found, update the card to have the correct userId associated.
180
      User user = userDAO.findUserByEmail(card.getUserEmail());
1✔
181
      if (user != null) {
1✔
182
        card.setUserId(user.getUserId());
×
183
      }
184
    } else {
1✔
185
      // check if userId exists
186
      User user = userDAO.findUserById(card.getUserId());
1✔
187
      if (user == null) {
1✔
188
        throw new BadRequestException();
1✔
189
      }
190
      if (card.getUserEmail() == null) {
1✔
191
        // if no email is provided in the card request, use the one from the user.
192
        card.setUserEmail(user.getEmail());
1✔
193
      } else if (!(user.getEmail().equalsIgnoreCase(card.getUserEmail()))) {
1✔
194
        // Emails do not match, throw an error.
195
        throw new ConsentConflictException();
1✔
196
      }
197
      card.setUserName(user.getDisplayName());
1✔
198
    }
199
  }
1✔
200

201
  private boolean checkIsAdmin(User user) {
202
    return user.getRoles()
1✔
203
        .stream()
1✔
204
        .anyMatch(role -> role.getName().equalsIgnoreCase(UserRoles.ADMIN.getRoleName()));
1✔
205
  }
206
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc