Skip to content

Commit

Permalink
Merge pull request #86 from Arquisoft/test/question-tests
Browse files Browse the repository at this point in the history
Fixed mistakes found within AnswerQuestion and started testing of QuestionController/QuestionService
  • Loading branch information
Toto-hitori authored Mar 6, 2024
2 parents 0b19163 + f1b1756 commit ac8015f
Show file tree
Hide file tree
Showing 22 changed files with 343 additions and 70 deletions.
1 change: 1 addition & 0 deletions api/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lombok.addLombokGeneratedAnnotation = true
24 changes: 21 additions & 3 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
<description>Api for quiz ap[l]i[cation]</description>
<properties>
<java.version>17</java.version>
<!-- JaCoCo Properties -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
</properties>
<dependencies>
<dependency>
Expand Down Expand Up @@ -113,12 +118,25 @@
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<configuration>
<excludes>
<exclude>**/quizapi/commons/utils/**</exclude>
<exclude>**/quizapi/commons/exceptions/**</exclude>
<exclude>**/quizapi/auth/jwt/**</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>report-aggregate</id>
<phase>verify</phase>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>package</phase>
<goals>
<goal>report-aggregate</goal>
<goal>report</goal>
</goals>
</execution>
</executions>
Expand Down
17 changes: 8 additions & 9 deletions api/src/main/java/lab/en2b/quizapi/auth/AuthController.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package lab.en2b.quizapi.auth;

import jakarta.validation.Valid;
import lab.en2b.quizapi.auth.dtos.LoginDto;
import lab.en2b.quizapi.auth.dtos.RefreshTokenDto;
import lab.en2b.quizapi.auth.dtos.RegisterDto;
import lab.en2b.quizapi.auth.dtos.*;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -17,17 +15,18 @@ public class AuthController {
private final AuthService authService;

@PostMapping("/register")
public ResponseEntity<?> registerUser(@Valid @RequestBody RegisterDto registerRequest){
return authService.register(registerRequest);
public ResponseEntity<String> registerUser(@Valid @RequestBody RegisterDto registerRequest){
authService.register(registerRequest);
return ResponseEntity.ok("User registered successfully!");
}

@PostMapping("/login")
public ResponseEntity<?> loginUser(@Valid @RequestBody LoginDto loginRequest){
return authService.login(loginRequest);
public ResponseEntity<JwtResponseDto> loginUser(@Valid @RequestBody LoginDto loginRequest){
return ResponseEntity.ok(authService.login(loginRequest));
}

@PostMapping("/refresh-token")
public ResponseEntity<?> refreshToken(@Valid @RequestBody RefreshTokenDto refreshTokenRequest){
return authService.refreshToken(refreshTokenRequest);
public ResponseEntity<RefreshTokenResponseDto> refreshToken(@Valid @RequestBody RefreshTokenDto refreshTokenRequest){
return ResponseEntity.ok(authService.refreshToken(refreshTokenRequest));
}
}
17 changes: 6 additions & 11 deletions api/src/main/java/lab/en2b/quizapi/auth/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@
import lab.en2b.quizapi.commons.user.User;
import lab.en2b.quizapi.commons.user.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Set;

@Service
@RequiredArgsConstructor
public class AuthService {
Expand All @@ -30,30 +27,28 @@ public class AuthService {
* @return a response containing a fresh jwt token and a refresh token
*/
@Transactional
public ResponseEntity<JwtResponseDto> login(LoginDto loginRequest){
public JwtResponseDto login(LoginDto loginRequest){
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getEmail(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();

return ResponseEntity.ok(new JwtResponseDto(
return new JwtResponseDto(
jwtUtils.generateJwtTokenUserPassword(authentication),
userService.assignNewRefreshToken(userDetails.getId()),
userDetails.getId(),
userDetails.getUsername(),
userDetails.getEmail(),
userDetails.getStringRoles())
userDetails.getStringRoles()
);
}

/**
* Registers a user. Throws an 400 unauthorized exception otherwise
* @param registerRequest the request containing the register info
* @return a response containing a message
*/
public ResponseEntity<?> register(RegisterDto registerRequest) {
public void register(RegisterDto registerRequest) {
userService.createUser(registerRequest,"user");
return ResponseEntity.ok("User registered successfully!");
}

/**
Expand All @@ -62,9 +57,9 @@ public ResponseEntity<?> register(RegisterDto registerRequest) {
* @param refreshTokenRequest the request containing the refresh token
* @return a response containing a fresh jwt token and a refresh token
*/
public ResponseEntity<?> refreshToken(RefreshTokenDto refreshTokenRequest) {
public RefreshTokenResponseDto refreshToken(RefreshTokenDto refreshTokenRequest) {
User user = userService.findByRefreshToken(refreshTokenRequest.getRefreshToken()).orElseThrow(() -> new TokenRefreshException(
"Refresh token is not in database!"));
return ResponseEntity.ok(new RefreshTokenResponseDto(jwtUtils.generateTokenFromEmail(user.getEmail()), user.obtainRefreshIfValid()));
return new RefreshTokenResponseDto(jwtUtils.generateTokenFromEmail(user.getEmail()), user.obtainRefreshIfValid());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lab.en2b.quizapi.commons.user.User;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
Expand All @@ -15,6 +16,7 @@
import java.util.stream.Collectors;

@Getter
@Setter
@AllArgsConstructor
public class UserDetailsImpl implements UserDetails {
private Long id;
Expand Down Expand Up @@ -58,4 +60,9 @@ public boolean equals(Object o) {
UserDetailsImpl user = (UserDetailsImpl) o;
return Objects.equals(id, user.id);
}

@Override
public int hashCode() {
return Objects.hash(id, username, email, password, authorities);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@Builder
public class RefreshTokenResponseDto {

private String token;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public class UserService implements UserDetailsService {
private final UserRepository userRepository;
@Value("${REFRESH_TOKEN_DURATION_MS}")
private long REFRESH_TOKEN_DURATION_MS;
private long refreshTokenDurationMs;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return UserDetailsImpl.build(userRepository.findByEmail(email).orElseThrow(() -> new InvalidAuthenticationException("Invalid email or password provided!")));
Expand All @@ -45,7 +45,7 @@ public Optional<User> findByRefreshToken(String refreshToken) {
public String assignNewRefreshToken(Long id) {
User user = userRepository.findById(id).orElseThrow();
user.setRefreshToken(UUID.randomUUID().toString());
user.setRefreshExpiration(Instant.now().plusMillis(REFRESH_TOKEN_DURATION_MS));
user.setRefreshExpiration(Instant.now().plusMillis(refreshTokenDurationMs));
userRepository.save(user);
return user.getRefreshToken();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
@AllArgsConstructor
@Getter
@Setter
@Builder
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package lab.en2b.quizapi.questions.answer.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.*;

@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Setter
public class AnswerDto {
@JsonProperty("answer_id")
@NonNull
@NotNull
@PositiveOrZero
private Long answerId;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package lab.en2b.quizapi.questions.answer.dtos;

import lab.en2b.quizapi.questions.answer.AnswerCategory;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
@EqualsAndHashCode
public class AnswerResponseDto {
private Long id;
private String text;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
public class AnswerResponseDtoMapper implements Function<Answer, AnswerResponseDto> {
@Override
public AnswerResponseDto apply(Answer answer) {
return null;
return AnswerResponseDto.builder()
.id(answer.getId())
.text(answer.getText())
.category(answer.getCategory())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@AllArgsConstructor
@Getter
@Setter
@Builder
public class Question {

@Id
Expand All @@ -31,6 +32,7 @@ public class Question {
)
private List<Answer> answers;
@ManyToOne
@NotNull
@JoinColumn(name = "correct_answer_id")
private Answer correctAnswer;
private QuestionCategory questionCategory;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package lab.en2b.quizapi.questions.question;

import jakarta.validation.Valid;
import jakarta.validation.constraints.PositiveOrZero;
import lab.en2b.quizapi.questions.answer.dtos.AnswerDto;
import lab.en2b.quizapi.questions.question.dtos.AnswerCheckResponseDto;
import lab.en2b.quizapi.questions.question.dtos.QuestionResponseDto;
Expand All @@ -22,17 +24,17 @@ private ResponseEntity<List<QuestionResponseDto>> getQuestions() {
}

@PostMapping("/{questionId}/answer")
private ResponseEntity<AnswerCheckResponseDto> answerQuestion(@PathVariable Long questionId, @RequestBody AnswerDto answerDto){
private ResponseEntity<AnswerCheckResponseDto> answerQuestion(@PathVariable @PositiveOrZero Long questionId, @Valid @RequestBody AnswerDto answerDto){
return ResponseEntity.ok(questionService.answerQuestion(questionId,answerDto));
}

@GetMapping("/new")
private ResponseEntity<QuestionResponseDto> generateQuestion(){
return ResponseEntity.ok(questionService.getQuestion());
return ResponseEntity.ok(questionService.getRandomQuestion());
}

@GetMapping("/{id}")
private ResponseEntity<QuestionResponseDto> getQuestionById(@PathVariable Long id){
private ResponseEntity<QuestionResponseDto> getQuestionById(@PathVariable @PositiveOrZero Long id){
return ResponseEntity.ok(questionService.getQuestionById(id));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ else if(question.getAnswers().stream().noneMatch(i -> i.getId().equals(answerDto
}
}

public QuestionResponseDto getQuestion() {
public QuestionResponseDto getRandomQuestion() {
return questionResponseDtoMapper.apply(questionRepository.findRandomQuestion());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package lab.en2b.quizapi.questions.question.dtos;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class AnswerCheckResponseDto {
private boolean wasCorrect;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
import lab.en2b.quizapi.questions.answer.dtos.AnswerResponseDto;
import lab.en2b.quizapi.questions.question.QuestionCategory;
import lab.en2b.quizapi.questions.question.QuestionType;
import lombok.Builder;
import lombok.*;

import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
@EqualsAndHashCode
public class QuestionResponseDto {
private Long id;
private String content;
Expand All @@ -17,7 +22,4 @@ public class QuestionResponseDto {
private AnswerCategory answerCategory;
private String language;
private QuestionType type;



}

This file was deleted.

Loading

0 comments on commit ac8015f

Please sign in to comment.