claimResolver) {
+ final Claims claims = extractAllClaims(token);
+ return claimResolver.apply(claims);
+ }
+
+ /**
+ * Parses the JWT token and returns all claims contained in its payload.
+ *
+ * The method verifies the token signature using the secret key.
+ *
+ * @param token JWT token string
+ * @return Claims object containing all claims from the token payload
+ * @throws JwtException if the token is invalid or the signature does not match
+ */
+ private Claims extractAllClaims(String token) {
+ return Jwts.parser()
+ .verifyWith(decodeSecretKey())
+ .build()
+ .parseSignedClaims(token)
+ .getPayload();
+ }
}
diff --git a/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java b/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java
deleted file mode 100644
index 3e39b00..0000000
--- a/src/main/java/org/pkwmtt/security/token/JwtServiceImpl.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package org.pkwmtt.security.token;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.JwtException;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.security.Keys;
-import lombok.RequiredArgsConstructor;
-import org.pkwmtt.examCalendar.entity.User;
-import org.pkwmtt.exceptions.InvalidRefreshTokenException;
-import org.pkwmtt.security.token.dto.UserDTO;
-import org.pkwmtt.security.token.entity.RefreshToken;
-import org.pkwmtt.security.token.utils.JwtUtils;
-import org.springframework.stereotype.Service;
-
-import javax.crypto.SecretKey;
-import java.security.SecureRandom;
-import java.time.LocalDateTime;
-import java.util.Base64;
-import java.util.Date;
-import java.util.UUID;
-import java.util.function.Function;
-
-@Service
-@RequiredArgsConstructor
-public class JwtServiceImpl implements JwtService {
-
- private final JwtUtils jwtUtils;
-
- /**
- * Generates a JWT token for a given user.
- * The token contains user's email, group, and role as claims,
- * and is signed with a secret key.
- *
- * @param user - required user data to include in token claims
- * @return signed JWT token as a String
- */
- @Override
- public String generateAccessToken(UserDTO user) {
- return Jwts.builder()
- .subject(user.getEmail())
- .claim("group", user.getGroup())
- .claim("role", user.getRole())
- .issuedAt(new Date())
- .expiration((new Date(System.currentTimeMillis() + jwtUtils.getExpirationMs())))
- .signWith(decodeSecretKey())
- .compact();
- }
-
- @Override
- public String generateAccessToken(UUID uuid) {
- return Jwts.builder()
- .subject(uuid.toString())
- .claim("role", "MODERATOR")
- .issuedAt(new Date())
- .expiration((new Date(System.currentTimeMillis() + jwtUtils.getExpirationMs())))
- .signWith(decodeSecretKey())
- .compact();
- }
-
- public static String generateRefreshToken() {
- SecureRandom random = new SecureRandom();
- byte[] randomBytes = new byte[32];
- random.nextBytes(randomBytes);
- return Base64.getUrlEncoder().withoutPadding().encodeToString(randomBytes);
- }
-
-
- public static void validateRefreshToken(RefreshToken rt) throws InvalidRefreshTokenException {
- if (rt.getExpires().isBefore(LocalDateTime.now()))
- throw new InvalidRefreshTokenException();
- }
-
-
- /**
- * Decode a secret key for signing JWT.
- * The key is decoded from Base64 stored in JwtUtils configuration.
- *
- * @return secret key for JWT signing
- */
- SecretKey decodeSecretKey(){
- byte[] decodedKey = Base64.getDecoder().decode(jwtUtils.getSecret());
- return Keys.hmacShaKeyFor(decodedKey);
- }
-
- /**
- * Validate a JWT token.
- * Attempts to parse the token; if parsing fails, the token is considered invalid.
- *
- * @param token JWT token string to validate
- * @return true if the token is valid, false otherwise
- */
- @Override
- public Boolean validateAccessToken(String token, User user) {
- try {
- final String userEmail = getSubject(token);
- return userEmail != null
- && userEmail.equals(user.getEmail())
- && !isTokenExpired(token);
- } catch (JwtException | IllegalArgumentException e) {
- return false;
- }
- }
-
- @Override
- public Boolean validateAccessToken(String token, String uuid) {
- try {
- final String userid = getSubject(token);
- return userid != null
- && userid.equals(uuid)
- && !isTokenExpired(token);
- } catch (JwtException | IllegalArgumentException e) {
- return false;
- }
- }
-
-
- /**
- * Extracts the user identifier (email) from a JWT token.
- *
- * @param token JWT token to extract user from
- * @return user email from token
- */
- @Override
- public String getSubject(String token) {
- return extractClaim(token, Claims::getSubject);
- }
-
- /**
- * Extracts the expiration date from a JWT token.
- *
- * @param token JWT token string
- * @return expiration date of the token
- */
- private Date getExpirationDateFromToken(String token) {
- return extractClaim(token, Claims::getExpiration);
- }
-
- /**
- * Checks whether a JWT token has expired.
- *
- * @param token JWT token string
- * @return true if the token is expired, false otherwise
- */
- private boolean isTokenExpired(String token){
- return getExpirationDateFromToken(token).before(new Date());
- }
-
- /**
- * Extracts a specific claim from a JWT token using a claim resolver function.
- *
- * @param type of the claim
- * @param token JWT token string
- * @param claimResolver function to extract the desired claim from Claims
- * @return the extracted claim of type T
- */
- public T extractClaim(String token, Function claimResolver) {
- final Claims claims = extractAllClaims(token);
- return claimResolver.apply(claims);
- }
-
- /**
- * Parses the JWT token and returns all claims contained in its payload.
- *
- * The method verifies the token signature using the secret key.
- *
- * @param token JWT token string
- * @return Claims object containing all claims from the token payload
- * @throws JwtException if the token is invalid or the signature does not match
- */
- private Claims extractAllClaims(String token) {
- return Jwts.parser()
- .verifyWith(decodeSecretKey())
- .build()
- .parseSignedClaims(token)
- .getPayload();
- }
-}
diff --git a/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java b/src/main/java/org/pkwmtt/security/token/dto/RepresentativeDTO.java
similarity index 52%
rename from src/main/java/org/pkwmtt/security/token/dto/UserDTO.java
rename to src/main/java/org/pkwmtt/security/token/dto/RepresentativeDTO.java
index 2c69368..a2f124d 100644
--- a/src/main/java/org/pkwmtt/security/token/dto/UserDTO.java
+++ b/src/main/java/org/pkwmtt/security/token/dto/RepresentativeDTO.java
@@ -3,8 +3,8 @@
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
-import org.pkwmtt.examCalendar.entity.GeneralGroup;
-import org.pkwmtt.examCalendar.entity.User;
+import org.pkwmtt.examCalendar.entity.SuperiorGroup;
+import org.pkwmtt.examCalendar.entity.Representative;
import org.pkwmtt.examCalendar.enums.Role;
import java.util.Optional;
@@ -12,14 +12,14 @@
@Data
@NoArgsConstructor
@Accessors(chain = true)
-public class UserDTO {
+public class RepresentativeDTO {
private String email;
private String group;
private Role role;
- public UserDTO (User user) {
+ public RepresentativeDTO (Representative user) {
this.email = user.getEmail();
- this.role = user.getRole();
- this.group = Optional.ofNullable(user.getGeneralGroup()).map(GeneralGroup::getName).orElse(null);
+ this.role = Role.REPRESENTATIVE;
+ this.group = Optional.ofNullable(user.getSuperiorGroup()).map(SuperiorGroup::getName).orElse(null);
}
}
diff --git a/src/main/java/org/pkwmtt/security/token/entity/UserRefreshToken.java b/src/main/java/org/pkwmtt/security/token/entity/UserRefreshToken.java
index 6f7f156..e5562b8 100644
--- a/src/main/java/org/pkwmtt/security/token/entity/UserRefreshToken.java
+++ b/src/main/java/org/pkwmtt/security/token/entity/UserRefreshToken.java
@@ -2,7 +2,7 @@
import jakarta.persistence.*;
import lombok.*;
-import org.pkwmtt.examCalendar.entity.User;
+import org.pkwmtt.examCalendar.entity.Representative;
import java.time.LocalDateTime;
@@ -18,16 +18,16 @@ public class UserRefreshToken implements RefreshToken {
private String token;
@ManyToOne
- @JoinColumn(name = "user_id")
- private User user;
+ @JoinColumn(name = "representative_id")
+ private Representative representative;
private LocalDateTime created;
private LocalDateTime expires;
- public UserRefreshToken(String token, User user) {
+ public UserRefreshToken(String token, Representative representative) {
this.token = token;
- this.user = user;
+ this.representative = representative;
this.created = LocalDateTime.now();
this.expires = LocalDateTime.now().plusMonths(6);
}
diff --git a/src/main/java/org/pkwmtt/security/token/filter/JwtFilter.java b/src/main/java/org/pkwmtt/security/token/filter/JwtFilter.java
index d21c271..bee765d 100644
--- a/src/main/java/org/pkwmtt/security/token/filter/JwtFilter.java
+++ b/src/main/java/org/pkwmtt/security/token/filter/JwtFilter.java
@@ -4,8 +4,10 @@
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import org.pkwmtt.examCalendar.entity.User;
-import org.pkwmtt.examCalendar.repository.UserRepository;
+import lombok.NonNull;
+import org.pkwmtt.examCalendar.entity.Representative;
+import org.pkwmtt.examCalendar.enums.Role;
+import org.pkwmtt.examCalendar.repository.RepresentativeRepository;
import org.pkwmtt.security.moderator.ModeratorRepository;
import org.pkwmtt.security.token.JwtAuthenticationToken;
import org.pkwmtt.security.token.JwtService;
@@ -23,16 +25,16 @@
@Component
public class JwtFilter extends OncePerRequestFilter {
-
+
@Autowired
JwtService jwtService;
-
+
@Autowired
- UserRepository userRepository;
-
+ RepresentativeRepository representativeRepository;
+
@Autowired
ModeratorRepository moderatorRepository;
-
+
/**
* Filters incoming HTTP requests to validate JWT tokens.
*
@@ -49,70 +51,74 @@ public class JwtFilter extends OncePerRequestFilter {
* @throws IOException if an I/O error occurs
*/
@Override
- protected void doFilterInternal(HttpServletRequest request,
- HttpServletResponse response,
- FilterChain filterChain) throws ServletException, IOException {
-
+ protected void doFilterInternal (HttpServletRequest request,
+ @NonNull HttpServletResponse response,
+ @NonNull FilterChain filterChain) throws ServletException, IOException {
+
String authHeader = request.getHeader("Authorization");
String token = null;
String subject = null;
-
+
if (authHeader != null && authHeader.startsWith("Bearer ")) {
token = authHeader.substring(7);
subject = jwtService.getSubject(token);
}
-
+
if (subject != null && SecurityContextHolder.getContext().getAuthentication() == null) {
String role = jwtService.extractClaim(token, claims -> claims.get("role", String.class));
-
-
- if (role.equals("MODERATOR"))
+
+
+ if (role.equals("MODERATOR")) {
filterModerator(request, token, subject);
- else
+ } else {
filterUser(request, token, subject);
+ }
}
-
+
filterChain.doFilter(request, response);
}
-
- private void filterModerator(HttpServletRequest request, String token, String subject) {
+
+ private void filterModerator (HttpServletRequest request, String token, String subject) {
+
+ // After
UUID uuid = UUID.fromString(subject);
- moderatorRepository.findById(uuid).orElseThrow(); //TODO: add exception type
-
+ byte[] uuidBytes = uuid.toString().getBytes(); // Convert UUID to byte[]
+ moderatorRepository.findById(uuidBytes).orElseThrow(); // TODO: add exception type
+
if (jwtService.validateAccessToken(token, subject)) {
List authorities = List.of(
- new SimpleGrantedAuthority("ROLE_" + "MODERATOR")
+ new SimpleGrantedAuthority("ROLE_" + "MODERATOR")
);
-
+
UsernamePasswordAuthenticationToken authToken =
- new UsernamePasswordAuthenticationToken(
- subject,
- null,
- authorities
- );
-
+ new UsernamePasswordAuthenticationToken(
+ subject,
+ null,
+ authorities
+ );
+
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
-
+
}
}
-
- private void filterUser(HttpServletRequest request, String token, String subject) {
-// TODO: handle invalid email
- User user = userRepository.findByEmail(subject).orElseThrow();
-
- if (jwtService.validateAccessToken(token, user)) {
+
+ private void filterUser (HttpServletRequest request, String token, String subject) {
+ // TODO: handle invalid email
+ Representative representative = representativeRepository.findByEmail(subject).orElseThrow();
+
+ if (jwtService.validateAccessToken(token, representative)) {
List authorities = List.of(
- new SimpleGrantedAuthority("ROLE_" + user.getRole())
+ new SimpleGrantedAuthority("ROLE_" + Role.REPRESENTATIVE)
);
-
+
UsernamePasswordAuthenticationToken authToken =
- new JwtAuthenticationToken(
- user.getEmail(),
- authorities,
- jwtService.extractClaim(token, claims -> claims.get("group", String.class))
- );
-
+ new JwtAuthenticationToken(
+ representative.getEmail(),
+ authorities,
+ jwtService.extractClaim(token, claims -> claims.get("group", String.class))
+ );
+
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
diff --git a/src/main/java/org/pkwmtt/otp/OTPController.java b/src/main/java/org/pkwmtt/studentCodes/StudentCodeController.java
similarity index 77%
rename from src/main/java/org/pkwmtt/otp/OTPController.java
rename to src/main/java/org/pkwmtt/studentCodes/StudentCodeController.java
index a22d2d9..4a7650c 100644
--- a/src/main/java/org/pkwmtt/otp/OTPController.java
+++ b/src/main/java/org/pkwmtt/studentCodes/StudentCodeController.java
@@ -1,10 +1,10 @@
-package org.pkwmtt.otp;
+package org.pkwmtt.studentCodes;
import com.mysql.cj.exceptions.WrongArgumentException;
import lombok.RequiredArgsConstructor;
import org.pkwmtt.exceptions.*;
-import org.pkwmtt.otp.dto.OTPRequest;
+import org.pkwmtt.studentCodes.dto.StudentCodeRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -13,11 +13,11 @@
@RestController
@RequestMapping("${apiPrefix}/representatives")
@RequiredArgsConstructor
-public class OTPController {
- private final OTPService service;
+public class StudentCodeController {
+ private final StudentCodeService service;
@PostMapping("/codes/generate")
- public ResponseEntity generateCodes (@RequestBody List request)
+ public ResponseEntity generateCodes (@RequestBody List request)
throws MailCouldNotBeSendException, WrongArgumentException, SpecifiedGeneralGroupDoesntExistsException, IllegalArgumentException {
service.sendOTPCodesForManyGroups(request);
return ResponseEntity.ok().build();
diff --git a/src/main/java/org/pkwmtt/otp/OTPExceptionHandler.java b/src/main/java/org/pkwmtt/studentCodes/StudentCodeExceptionHandler.java
similarity index 74%
rename from src/main/java/org/pkwmtt/otp/OTPExceptionHandler.java
rename to src/main/java/org/pkwmtt/studentCodes/StudentCodeExceptionHandler.java
index 6494829..02cb81f 100644
--- a/src/main/java/org/pkwmtt/otp/OTPExceptionHandler.java
+++ b/src/main/java/org/pkwmtt/studentCodes/StudentCodeExceptionHandler.java
@@ -1,4 +1,4 @@
-package org.pkwmtt.otp;
+package org.pkwmtt.studentCodes;
import com.mysql.cj.exceptions.WrongArgumentException;
@@ -12,9 +12,9 @@
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Order(2)
-@RestControllerAdvice(assignableTypes = {OTPController.class, ModeratorController.class})
-public class OTPExceptionHandler {
- @ExceptionHandler({OTPCodeNotFoundException.class, WrongOTPFormatException.class, UserNotFoundException.class, WrongArgumentException.class, SpecifiedGeneralGroupDoesntExistsException.class, IllegalArgumentException.class})
+@RestControllerAdvice(assignableTypes = {StudentCodeController.class, ModeratorController.class})
+public class StudentCodeExceptionHandler {
+ @ExceptionHandler({StudentCodeNotFoundException.class, WrongOTPFormatException.class, UserNotFoundException.class, WrongArgumentException.class, SpecifiedGeneralGroupDoesntExistsException.class, IllegalArgumentException.class})
public ResponseEntity handleBadRequests (Exception e) {
return new ResponseEntity<>(new ErrorResponseDTO(e.getMessage()), HttpStatus.BAD_REQUEST);
}
diff --git a/src/main/java/org/pkwmtt/otp/OTPService.java b/src/main/java/org/pkwmtt/studentCodes/StudentCodeService.java
similarity index 57%
rename from src/main/java/org/pkwmtt/otp/OTPService.java
rename to src/main/java/org/pkwmtt/studentCodes/StudentCodeService.java
index e37b3ce..5108b77 100644
--- a/src/main/java/org/pkwmtt/otp/OTPService.java
+++ b/src/main/java/org/pkwmtt/studentCodes/StudentCodeService.java
@@ -1,23 +1,23 @@
-package org.pkwmtt.otp;
+package org.pkwmtt.studentCodes;
import com.mysql.cj.exceptions.WrongArgumentException;
import jakarta.mail.MessagingException;
import lombok.RequiredArgsConstructor;
-import org.pkwmtt.examCalendar.entity.GeneralGroup;
-import org.pkwmtt.examCalendar.entity.OTPCode;
-import org.pkwmtt.examCalendar.entity.User;
+import org.pkwmtt.examCalendar.entity.SuperiorGroup;
+import org.pkwmtt.examCalendar.entity.StudentCode;
+import org.pkwmtt.examCalendar.entity.Representative;
import org.pkwmtt.examCalendar.enums.Role;
-import org.pkwmtt.examCalendar.repository.GeneralGroupRepository;
-import org.pkwmtt.examCalendar.repository.UserRepository;
+import org.pkwmtt.examCalendar.repository.SuperiorGroupRepository;
+import org.pkwmtt.examCalendar.repository.RepresentativeRepository;
import org.pkwmtt.exceptions.*;
import org.pkwmtt.mail.EmailService;
import org.pkwmtt.mail.dto.MailDTO;
-import org.pkwmtt.otp.dto.OTPRequest;
-import org.pkwmtt.otp.repository.OTPCodeRepository;
+import org.pkwmtt.security.token.JwtService;
+import org.pkwmtt.studentCodes.dto.StudentCodeRequest;
+import org.pkwmtt.studentCodes.repository.StudentCodeRepository;
import org.pkwmtt.security.auhentication.JwtAuthenticationService;
import org.pkwmtt.security.auhentication.dto.JwtAuthenticationDto;
-import org.pkwmtt.security.token.JwtService;
-import org.pkwmtt.security.token.dto.UserDTO;
+import org.pkwmtt.security.token.dto.RepresentativeDTO;
import org.pkwmtt.timetable.TimetableService;
import org.springframework.stereotype.Service;
@@ -31,44 +31,44 @@
@Service
@RequiredArgsConstructor
-public class OTPService {
- private final OTPCodeRepository otpRepository;
- private final UserRepository userRepository;
- private final GeneralGroupRepository generalGroupRepository;
+public class StudentCodeService {
+ private final StudentCodeRepository studentCodeRepository;
+ private final RepresentativeRepository representativeRepository;
+ private final SuperiorGroupRepository superiorGroupRepository;
private final EmailService emailService;
private final JwtService jwtService;
private final JwtAuthenticationService jwtAuthenticationService;
private final TimetableService timetableService;
public JwtAuthenticationDto generateTokenForRepresentative (String code)
- throws OTPCodeNotFoundException, WrongOTPFormatException, UserNotFoundException {
- var generalGroup = this.getGeneralGroupAssignedToCode(code);
- var user = userRepository
- .findByGeneralGroup(generalGroup)
- .orElseThrow(() -> new UserNotFoundException("No user is assigned to this code."));
-
- var userEmail = user.getEmail();
- String token = jwtService.generateAccessToken(new UserDTO()
+ throws StudentCodeNotFoundException, WrongOTPFormatException, UserNotFoundException {
+ var superiorGroup = this.getSuperiorGroupAssignedToCode(code);
+ var representative = representativeRepository
+ .findBySuperiorGroup(superiorGroup)
+ .orElseThrow(() -> new UserNotFoundException("No representative is assigned to this code."));
+
+ var userEmail = representative.getEmail();
+ String token = jwtService.generateAccessToken(new RepresentativeDTO()
.setEmail(userEmail)
.setRole(Role.REPRESENTATIVE)
- .setGroup(generalGroup.getName()));
- otpRepository.deleteByCode(code);
+ .setGroup(superiorGroup.getName()));
+ studentCodeRepository.deleteByCode(code);
return JwtAuthenticationDto.builder()
.accessToken(token)
- .refreshToken(jwtAuthenticationService.getNewUserRefreshToken(user))
+ .refreshToken(jwtAuthenticationService.getNewUserRefreshToken(representative))
.build();
}
- public void sendOTPCodesForManyGroups (List requests)
+ public void sendOTPCodesForManyGroups (List requests)
throws MailCouldNotBeSendException, WrongArgumentException, SpecifiedSubGroupDoesntExistsException, IllegalArgumentException {
requests.forEach(this::sendOtpCode);
}
- public void sendOtpCode (OTPRequest request)
+ public void sendOtpCode (StudentCodeRequest request)
throws MailCouldNotBeSendException, WrongArgumentException, SpecifiedSubGroupDoesntExistsException, IllegalArgumentException {
var code = generateNewCode();
var mail = createMail(request, code);
- var groupName = request.getGeneralGroupName();
+ var groupName = request.getSuperiorGroup();
var groupNameLength = groupName.length();
if (groupNameLength > 3 && Character.isDigit(
@@ -81,63 +81,46 @@ public void sendOtpCode (OTPRequest request)
throw new SpecifiedGeneralGroupDoesntExistsException();
}
- var generalGroup = generalGroupRepository.findByName(groupName);
-
- if (generalGroup.isPresent()) { //Check if general group is already saved in database
- if (otpRepository.existsOTPCodeByGeneralGroup(
- generalGroup.get())) { //Check if provided general group has assigned code
- otpRepository.deleteByGeneralGroup(generalGroup.get()); // Delete existing code
+ var superiorGroup = superiorGroupRepository.findByName(groupName);
+ if (superiorGroup.isPresent()) {
+ if (studentCodeRepository.existsBySuperiorGroup(
+ superiorGroup.get())) {
+ studentCodeRepository.deleteBySuperiorGroup(superiorGroup.get());
}
} else {
- //Save general group to database
- generalGroup = Optional.of(generalGroupRepository.save(new GeneralGroup(null, groupName)));
+ superiorGroup = Optional.of(superiorGroupRepository.save(new SuperiorGroup(null, groupName)));
}
-
- var userByEmail = userRepository.findByEmail(request.getEmail());
-
- //Check if user isn't already assigned to any general group
- if (userByEmail.isPresent()) {
+ var representativeByEmail = representativeRepository.findByEmail(request.getEmail());
+ if (representativeByEmail.isPresent()) {
throw new UserAlreadyAssignedException(
- "User with this email is already assigned group.");
+ "Representative with this email is already assigned group.");
}
-
try {
- emailService.send(mail); //Send email
+ emailService.send(mail);
} catch (MessagingException e) {
throw new MailCouldNotBeSendException("Couldn't send mail for group: " + groupName);
}
-
- var user = User
+ var representative = Representative
.builder()
.email(request.getEmail())
- .generalGroup(generalGroup.get())
- .role(Role.REPRESENTATIVE)
+ .superiorGroup(superiorGroup.get())
.isActive(true)
.build();
-
-
-
-
-
- userRepository
- .findByGeneralGroup(generalGroup.get())
- .ifPresent(value -> userRepository.deleteUserByEmail(value.getEmail()));
-
- userRepository.save(user);
- otpRepository.save(new OTPCode(code, generalGroup.get()));
+ representativeRepository
+ .findBySuperiorGroup(superiorGroup.get())
+ .ifPresent(value -> representativeRepository.deleteRepresentativeByEmail(value.getEmail()));
+ representativeRepository.save(representative);
+ studentCodeRepository.save(new StudentCode(code, superiorGroup.get()));
}
- private GeneralGroup getGeneralGroupAssignedToCode (String code)
- throws OTPCodeNotFoundException, WrongOTPFormatException {
+ private SuperiorGroup getSuperiorGroupAssignedToCode (String code)
+ throws StudentCodeNotFoundException, WrongOTPFormatException {
this.validateCode(code);
-
- Optional result = otpRepository.findByCode(code);
-
+ Optional result = studentCodeRepository.findByCode(code);
if (result.isEmpty()) {
- throw new OTPCodeNotFoundException();
+ throw new StudentCodeNotFoundException();
}
-
- return result.get().getGeneralGroup();
+ return result.get().getSuperiorGroup();
}
private void validateCode (String code) throws WrongOTPFormatException {
@@ -155,9 +138,9 @@ private void validateCode (String code) throws WrongOTPFormatException {
}
- private MailDTO createMail (OTPRequest request, String code) {
+ private MailDTO createMail (StudentCodeRequest request, String code) {
return new MailDTO()
- .setTitle("Kod Starosty " + request.getGeneralGroupName())
+ .setTitle("Kod Starosty " + request.getSuperiorGroup())
.setRecipient(request.getEmail())
.setDescription(request.getMailMessage(code));
}
@@ -172,7 +155,7 @@ private String generateNewCode () {
for (int i = 0; i < 6; i++) {
code.append(availableCharacters.charAt(random.nextInt(availableCharacters.length())));
}
- } while (otpRepository.findByCode(code.toString()).isPresent());
+ } while (studentCodeRepository.findByCode(code.toString()).isPresent());
return code.toString();
}
diff --git a/src/main/java/org/pkwmtt/studentCodes/dto/StudentCodeDTO.java b/src/main/java/org/pkwmtt/studentCodes/dto/StudentCodeDTO.java
new file mode 100644
index 0000000..7ca93bb
--- /dev/null
+++ b/src/main/java/org/pkwmtt/studentCodes/dto/StudentCodeDTO.java
@@ -0,0 +1,8 @@
+package org.pkwmtt.studentCodes.dto;
+
+import lombok.Getter;
+
+@Getter
+public class StudentCodeDTO {
+ private String otpCode;
+}
diff --git a/src/main/java/org/pkwmtt/otp/dto/OTPRequest.java b/src/main/java/org/pkwmtt/studentCodes/dto/StudentCodeRequest.java
similarity index 82%
rename from src/main/java/org/pkwmtt/otp/dto/OTPRequest.java
rename to src/main/java/org/pkwmtt/studentCodes/dto/StudentCodeRequest.java
index 9cc360b..b86c97e 100644
--- a/src/main/java/org/pkwmtt/otp/dto/OTPRequest.java
+++ b/src/main/java/org/pkwmtt/studentCodes/dto/StudentCodeRequest.java
@@ -1,13 +1,13 @@
-package org.pkwmtt.otp.dto;
+package org.pkwmtt.studentCodes.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
-public class OTPRequest {
+public class StudentCodeRequest {
private String email;
- private String generalGroupName;
+ private String superiorGroup;
public String getMailMessage (String code) {
return String.format(
@@ -17,7 +17,7 @@ public String getMailMessage (String code) {
Dzięki temu będziesz mógł dodawać oraz usuwać egzaminy dla swojego kierunku w kalendarzu aplikacji.
Wpisz kod w [Ustawienia > Wpisz kod], albo przekaż go osobie odpowiedzialnej za kalendarz egzaminów.
Twój kod: %s
- """, generalGroupName, code
+ """, superiorGroup, code
);
}
}
diff --git a/src/main/java/org/pkwmtt/studentCodes/repository/StudentCodeRepository.java b/src/main/java/org/pkwmtt/studentCodes/repository/StudentCodeRepository.java
new file mode 100644
index 0000000..c2c965c
--- /dev/null
+++ b/src/main/java/org/pkwmtt/studentCodes/repository/StudentCodeRepository.java
@@ -0,0 +1,23 @@
+package org.pkwmtt.studentCodes.repository;
+
+import jakarta.transaction.Transactional;
+import org.pkwmtt.examCalendar.entity.SuperiorGroup;
+import org.pkwmtt.examCalendar.entity.StudentCode;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface StudentCodeRepository extends JpaRepository {
+ Optional findByCode(String code);
+
+ @Transactional
+ void deleteByCode(String code);
+
+ boolean existsBySuperiorGroup(SuperiorGroup superiorGroup);
+
+ boolean existsByCode(String code);
+
+ @Transactional
+ void deleteBySuperiorGroup(SuperiorGroup superiorGroup);
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/pkwmtt/examCalendar/ExamServiceTest.java b/src/test/java/org/pkwmtt/examCalendar/ExamServiceTest.java
index 80bad9d..b820b88 100644
--- a/src/test/java/org/pkwmtt/examCalendar/ExamServiceTest.java
+++ b/src/test/java/org/pkwmtt/examCalendar/ExamServiceTest.java
@@ -86,7 +86,7 @@ void testBlankSubgroupAndMoreArgumentsThatRequiredReturnedByService() {
.build();
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(g12K2);
- Exam exam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam exam = buildExamWithIdAndGroups(studentGroups);
when(examTypeRepository.findByName(requestExamDto.getExamType())).thenReturn(Optional.of(examType));
// more groups than in set
@@ -130,7 +130,7 @@ void addExamForMultipleGeneralGroupsWithEmptySubgroups() {
RequestExamDto requestExamDto = buildExampleExamDto(generalGroups, subgroups, date);
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(generalGroups);
- Exam exam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam exam = buildExamWithIdAndGroups(studentGroups);
when(examTypeRepository.findByName(requestExamDto.getExamType())).thenReturn(Optional.of(examType));
when(timetableService.getGeneralGroupList()).thenReturn(new ArrayList<>(generalGroups));
@@ -359,7 +359,7 @@ void addExamForSingleGeneralGroupWithRepositoryContainingGroup() {
RequestExamDto requestExamDto = buildExampleExamDto(generalGroups, subgroups, date);
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(generalGroups);
- Exam exam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam exam = buildExamWithIdAndGroups(studentGroups);
when(examTypeRepository.findByName(requestExamDto.getExamType())).thenReturn(Optional.of(examType));
when(timetableService.getGeneralGroupList()).thenReturn(new ArrayList<>(generalGroups));
@@ -391,7 +391,7 @@ void addExamWithNonUniqueTitle() {
RequestExamDto requestExamDto = buildExampleExamDto(generalGroups, subgroups, date);
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(generalGroups);
- Exam newExam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam newExam = buildExamWithIdAndGroups(studentGroups);
Exam existingExam = Exam.builder()
.title("title")
.description("description")
@@ -440,7 +440,7 @@ void addExamForSingleGeneralGroupAndSubgroupsWithRepositoryContainingGroups() th
RequestExamDto requestExamDto = buildExampleExamDto(generalGroups, subgroups, date);
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(combinedGroups);
- Exam exam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam exam = buildExamWithIdAndGroups(studentGroups);
when(examTypeRepository.findByName(requestExamDto.getExamType())).thenReturn(Optional.of(examType));
when(timetableService.getGeneralGroupList()).thenReturn(new ArrayList<>(generalGroups));
@@ -549,7 +549,7 @@ void addExamWhenServiceIsUnavailableAndRepositoryContainsGeneralGroups() {
RequestExamDto requestExamDto = buildExampleExamDto(generalGroups, subgroups, date);
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(generalGroups);
- Exam exam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam exam = buildExamWithIdAndGroups(studentGroups);
when(examTypeRepository.findByName(requestExamDto.getExamType())).thenReturn(Optional.of(examType));
when(timetableService.getGeneralGroupList()).thenThrow(new WebPageContentNotAvailableException());
@@ -590,7 +590,7 @@ void addExamWhenServiceIsUnavailableAndRepositoryContainsGroups() throws JsonPro
RequestExamDto requestExamDto = buildExampleExamDto(generalGroups, subgroups, date);
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(combinedGroups);
- Exam exam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam exam = buildExamWithIdAndGroups(studentGroups);
when(examTypeRepository.findByName(requestExamDto.getExamType())).thenReturn(Optional.of(examType));
when(timetableService.getGeneralGroupList()).thenThrow(new WebPageContentNotAvailableException());
@@ -765,19 +765,24 @@ void shouldThrowWhenGeneralGroupsAreFromDifferentYearOfStudy() {
+ // Updated helper methods to match new schema
private static List buildExampleStudentGroupList(Set groupNames) {
- AtomicInteger id = new AtomicInteger();
+ AtomicInteger id = new AtomicInteger(1); // group_id starts from 1
return groupNames.stream()
.map(g -> StudentGroup.builder()
.groupId(id.getAndIncrement())
.name(g)
- .build()
- ).collect(Collectors.toList());
+ .build())
+ .collect(Collectors.toList());
}
- private static Exam buildExamWithIdAndGroups(int id, List groups) {
+ private static Exam buildExamWithIdAndGroups(List groups) {
return Exam.builder()
- .examId(id)
+ .examId(1)
+ .title("title")
+ .description("description")
+ .examDate(LocalDateTime.now().plusDays(1))
+ .examType(buildExampleExamType())
.groups(new HashSet<>(groups))
.build();
}
@@ -820,7 +825,7 @@ private void testExamServiceForSubgroups(Set generalGroups, Set
RequestExamDto requestExamDto = buildExampleExamDto(generalGroups, subgroups, date);
ExamType examType = buildExampleExamType();
List studentGroups = buildExampleStudentGroupList(combinedGroups);
- Exam exam = buildExamWithIdAndGroups(1, studentGroups);
+ Exam exam = buildExamWithIdAndGroups(studentGroups);
when(examTypeRepository.findByName(requestExamDto.getExamType())).thenReturn(Optional.of(examType));
when(timetableService.getGeneralGroupList()).thenReturn(new ArrayList<>(generalGroups));
@@ -846,4 +851,5 @@ private void testExamServiceForSubgroups(Set generalGroups, Set
Exam savedExam = examCaptor.getValue();
assertExam(savedExam, date, savedId, combinedGroups);
}
-}
\ No newline at end of file
+}
+
diff --git a/src/test/java/org/pkwmtt/examCalendar/repository/ExamRepositoryTest.java b/src/test/java/org/pkwmtt/examCalendar/repository/ExamRepositoryTest.java
index e2dd528..c133809 100644
--- a/src/test/java/org/pkwmtt/examCalendar/repository/ExamRepositoryTest.java
+++ b/src/test/java/org/pkwmtt/examCalendar/repository/ExamRepositoryTest.java
@@ -27,231 +27,225 @@
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
@ActiveProfiles("database")
class ExamRepositoryTest {
-
+
@Autowired
private ExamRepository examRepository;
-
+
@Autowired
private ExamTypeRepository examTypeRepository;
-
+
@Autowired
private GroupRepository groupRepository;
-
+
private Integer ex1Id;
private Integer ex2Id;
- private Integer ex3Id;
- private Integer ex4Id;
- private Integer ex5Id;
- private Integer ex6Id;
-
+
@BeforeAll
- void setUp() {
+ void setUp () {
ExamType examType = ExamType.builder()
- .name("exam").build();
+ .name("exam").build();
examTypeRepository.save(examType);
-
- StudentGroup g12A = StudentGroup.builder()
- .name("12A").build();
- StudentGroup g12A1 = StudentGroup.builder()
- .name("12A1").build();
- StudentGroup g12A2 = StudentGroup.builder()
- .name("12A2").build();
-
- StudentGroup g12K = StudentGroup.builder()
- .name("12K").build();
- StudentGroup g12K1 = StudentGroup.builder()
- .name("12K1").build();
- StudentGroup g12K2 = StudentGroup.builder()
- .name("12K2").build();
- StudentGroup g12K3 = StudentGroup.builder()
- .name("12K3").build();
- StudentGroup gL04 = StudentGroup.builder()
- .name("L04").build();
- StudentGroup gL05 = StudentGroup.builder()
- .name("L05").build();
-
+
+ StudentGroup g12A = StudentGroup.builder().name("12A").build();
+ StudentGroup g12A1 = StudentGroup.builder().name("12A1").build();
+ StudentGroup g12A2 = StudentGroup.builder().name("12A2").build();
+ StudentGroup g12K = StudentGroup.builder().name("12K").build();
+ StudentGroup g12K1 = StudentGroup.builder().name("12K1").build();
+ StudentGroup g12K2 = StudentGroup.builder().name("12K2").build();
+ StudentGroup g12K3 = StudentGroup.builder().name("12K3").build();
+ StudentGroup gL04 = StudentGroup.builder().name("L04").build();
+ StudentGroup gL05 = StudentGroup.builder().name("L05").build();
+
groupRepository.save(g12A);
groupRepository.save(g12A1);
groupRepository.save(g12A2);
-
groupRepository.save(g12K);
groupRepository.save(g12K1);
groupRepository.save(g12K2);
groupRepository.save(g12K3);
groupRepository.save(gL04);
groupRepository.save(gL05);
-
+
Exam smallGroupExam1 = Exam.builder()
- .title("small Group Exam 1")
- .description("Linear Algebra")
- .examDate(LocalDateTime.now().plusDays(1))
- .examType(examType)
- .groups(Set.of(g12K, gL04))
- .build();
-
+ .title("small Group Exam 1")
+ .description("Linear Algebra")
+ .examDate(LocalDateTime.now().plusDays(1))
+ .examType(examType)
+ .groups(Set.of(g12K, gL04))
+ .build();
+
Exam smallGroupExam2 = Exam.builder()
- .title("small Group Exam 2")
- .description("Linear Algebra")
- .examDate(LocalDateTime.now().plusDays(1))
- .examType(examType)
- .groups(Set.of(gL04, g12K, gL05))
- .build();
-
+ .title("small Group Exam 2")
+ .description("Linear Algebra")
+ .examDate(LocalDateTime.now().plusDays(1))
+ .examType(examType)
+ .groups(Set.of(gL04, g12K, gL05))
+ .build();
+
Exam smallGroupExam3 = Exam.builder()
- .title("small Group Exam 3")
- .description("Linear Algebra")
- .examDate(LocalDateTime.now().plusDays(1))
- .examType(examType)
- .groups(Set.of(g12A, gL05))
- .build();
-
+ .title("small Group Exam 3")
+ .description("Linear Algebra")
+ .examDate(LocalDateTime.now().plusDays(1))
+ .examType(examType)
+ .groups(Set.of(g12A, gL05))
+ .build();
+
Exam generalGroupExam1 = Exam.builder()
- .title("general Group Exam 1")
- .description("Linear Algebra")
- .examDate(LocalDateTime.now().plusDays(1))
- .examType(examType)
- .groups(Set.of(g12K1, g12K2))
- .build();
-
+ .title("general Group Exam 1")
+ .description("Linear Algebra")
+ .examDate(LocalDateTime.now().plusDays(1))
+ .examType(examType)
+ .groups(Set.of(g12K1, g12K2))
+ .build();
+
Exam generalGroupExam2 = Exam.builder()
- .title("general Group Exam 2")
- .description("Linear Algebra")
- .examDate(LocalDateTime.now().plusDays(1))
- .examType(examType)
- .groups(Set.of(g12K1))
- .build();
-
+ .title("general Group Exam 2")
+ .description("Linear Algebra")
+ .examDate(LocalDateTime.now().plusDays(1))
+ .examType(examType)
+ .groups(Set.of(g12K1))
+ .build();
+
Exam generalGroupExam3 = Exam.builder()
- .title("general Group Exam 3")
- .description("Linear Algebra")
- .examDate(LocalDateTime.now().plusDays(1))
- .examType(examType)
- .groups(Set.of(g12A1, g12A2))
- .build();
-
+ .title("general Group Exam 3")
+ .description("Linear Algebra")
+ .examDate(LocalDateTime.now().plusDays(1))
+ .examType(examType)
+ .groups(Set.of(g12A1, g12A2))
+ .build();
+
ex1Id = examRepository.save(smallGroupExam1).getExamId();
ex2Id = examRepository.save(smallGroupExam2).getExamId();
- ex3Id = examRepository.save(smallGroupExam3).getExamId();
- ex4Id = examRepository.save(generalGroupExam1).getExamId();
- ex5Id = examRepository.save(generalGroupExam2).getExamId();
- ex6Id = examRepository.save(generalGroupExam3).getExamId();
+ examRepository.save(smallGroupExam3).getExamId();
+ examRepository.save(generalGroupExam1).getExamId();
+ examRepository.save(generalGroupExam2).getExamId();
+ examRepository.save(generalGroupExam3).getExamId();
}
-
+
@Test
- void shouldReturnExamsWhenNotAllSubgroupsFromRepositoryMatched() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K", Set.of("12K3"), Set.of("L04"));
+ void shouldReturnExamsWhenNotAllSubgroupsFromRepositoryMatched () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K", Set.of("12K3"), Set.of("L04"));
assertEquals(2, exams.size());
List examTitles = exams.stream().map(Exam::getTitle).sorted().toList();
assertEquals("small Group Exam 1", examTitles.get(0));
assertEquals("small Group Exam 2", examTitles.get(1));
}
-
+
@Test
- void shouldReturnExamWhenNotAllSubgroupsFromArgumentsMatchedAndNotReturnExamsForWrongGeneralGroup() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K", Set.of("12K3"), Set.of("L05"));
+ void shouldReturnExamWhenNotAllSubgroupsFromArgumentsMatchedAndNotReturnExamsForWrongGeneralGroup () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K", Set.of("12K3"), Set.of("L05"));
assertEquals(1, exams.size());
List examTitles = exams.stream().map(Exam::getTitle).sorted().toList();
assertEquals("small Group Exam 2", examTitles.getFirst());
}
-
+
@Test
- void shouldReturnExamsWhenMultipleArgumentsMatch() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K", Set.of("12K3"), Set.of("L04", "L05"));
+ void shouldReturnExamsWhenMultipleArgumentsMatch () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K", Set.of("12K3"), Set.of("L04", "L05"));
assertEquals(2, exams.size());
Set examTitles = exams.stream().map(Exam::getTitle).collect(Collectors.toSet());
assertTrue(examTitles.contains("small Group Exam 1"));
assertTrue(examTitles.contains("small Group Exam 2"));
}
-
+
@Test
- void shouldReturnOnlyExamsForGeneralGroups() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K", Set.of("12K1"), Set.of("L01", "L08"));
+ void shouldReturnOnlyExamsForGeneralGroups () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K", Set.of("12K1"), Set.of("L01", "L08"));
assertEquals(2, exams.size());
Set examTitles = exams.stream().map(Exam::getTitle).collect(Collectors.toSet());
assertTrue(examTitles.contains("general Group Exam 1"));
assertTrue(examTitles.contains("general Group Exam 2"));
}
-
+
@Test
- void shouldReturnGeneralGroupExamsWhenSubgroupsIsEmpty() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K", Set.of("12K1"), Set.of());
+ void shouldReturnGeneralGroupExamsWhenSubgroupsIsEmpty () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K", Set.of("12K1"), Set.of());
assertEquals(2, exams.size());
Set examTitles = exams.stream().map(Exam::getTitle).collect(Collectors.toSet());
assertTrue(examTitles.contains("general Group Exam 1"));
assertTrue(examTitles.contains("general Group Exam 2"));
}
-
+
@Test
- void shouldReturnExamsForGeneralAndSubgroups() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K", Set.of("12K2"), Set.of("L04", "L05"));
+ void shouldReturnExamsForGeneralAndSubgroups () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K", Set.of("12K2"), Set.of("L04", "L05"));
assertEquals(3, exams.size());
Set examTitles = exams.stream().map(Exam::getTitle).collect(Collectors.toSet());
assertTrue(examTitles.contains("small Group Exam 1"));
assertTrue(examTitles.contains("small Group Exam 2"));
assertTrue(examTitles.contains("general Group Exam 1"));
}
-
+
@Test
- void ShouldReturnEmptyListWhenSubgroupsSetIsEmpty() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K", Set.of(), Set.of());
+ void ShouldReturnEmptyListWhenSubgroupsSetIsEmpty () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K", Set.of(), Set.of());
assertTrue(exams.isEmpty());
}
-
+
@Test
- void shouldReturnEmptyListWhenGeneralGroupIdentifierHasInvalidFormat() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12K2", Set.of(), Set.of("L04"));
+ void shouldReturnEmptyListWhenGeneralGroupIdentifierHasInvalidFormat () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12K2", Set.of(), Set.of("L04"));
assertTrue(exams.isEmpty());
}
-
+
@Test
- void shouldReturnEmptyListWhenGeneralGroupIdentifierDontMatch() {
- Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup("12B", Set.of("12B1"), Set.of("L04", "L05"));
+ void shouldReturnEmptyListWhenGeneralGroupIdentifierDontMatch () {
+ Set exams = examRepository.findAllBySubgroupsOfSuperiorGroupAndGeneralGroup(
+ "12B", Set.of("12B1"), Set.of("L04", "L05"));
assertTrue(exams.isEmpty());
}
-
-// findCommonExamIdsForGroups
-
+
+ // findCommonExamIdsForGroups
+
@Test
- void shouldReturnWhenThereAreMoreGroupsInRepositoryThanArguments() {
-// when
+ void shouldReturnWhenThereAreMoreGroupsInRepositoryThanArguments () {
+ // when
Set ids = examRepository.findCommonExamIdsForGroups(Set.of("12K", "L04"), 2);
-// then
+ // then
assertEquals(2, ids.size());
assertTrue(ids.contains(ex1Id));
assertTrue(ids.contains(ex2Id));
}
-
+
@Test
- void shouldReturnOnlyWhenAllGroupsMatch() {
-// when
+ void shouldReturnOnlyWhenAllGroupsMatch () {
+ // when
Set ids = examRepository.findCommonExamIdsForGroups(Set.of("12K", "L04", "L05"), 3);
-// then
+ // then
assertEquals(1, ids.size());
assertTrue(ids.contains(ex2Id));
}
-
+
@Test
- void shouldReturnEmptySetWhenArgumentListIsEmpty() {
-// when
+ void shouldReturnEmptySetWhenArgumentListIsEmpty () {
+ // when
Set ids = examRepository.findCommonExamIdsForGroups(Set.of(), 0);
-// then
+ // then
assertTrue(ids.isEmpty());
}
-
+
@Test
- void shouldReturnEmptySetWhenThereAreMoreArgumentsThanGroupsInRepository() {
-// when
- Set ids = examRepository.findCommonExamIdsForGroups(Set.of("12K", "L04", "L05","L06"), 4);
-// then
+ void shouldReturnEmptySetWhenThereAreMoreArgumentsThanGroupsInRepository () {
+ // when
+ Set