Skip to content

Commit

Permalink
Merge pull request #71 from Arquisoft/feat/questions
Browse files Browse the repository at this point in the history
Feat/questions
  • Loading branch information
UO283615 authored Mar 3, 2024
2 parents 5563bde + 1319697 commit 915fe27
Show file tree
Hide file tree
Showing 16 changed files with 303 additions and 7 deletions.
28 changes: 28 additions & 0 deletions api/src/main/java/lab/en2b/quizapi/questions/answer/Answer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package lab.en2b.quizapi.questions.answer;

import jakarta.persistence.*;
import lab.en2b.quizapi.questions.question.Question;
import lombok.*;

import java.util.List;

@Entity
@Table(name = "answers")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
private Long id;
private String text;
private AnswerCategory category;
@OneToMany(mappedBy = "correctAnswer", fetch = FetchType.EAGER)
private List<Question> questions;

@ManyToMany(mappedBy = "answers", fetch = FetchType.EAGER)
private List<Question> questionsWithThisAnswer;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package lab.en2b.quizapi.questions.answer;

public enum AnswerCategory {
CITY, COUNTRY, PERSON, EVENT, DATE, OTHER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package lab.en2b.quizapi.questions.answer.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

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

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

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class AnswerResponseDto {
private Long id;
private String text;
private AnswerCategory category;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package lab.en2b.quizapi.questions.answer.mappers;

import lab.en2b.quizapi.questions.answer.Answer;
import lab.en2b.quizapi.questions.answer.dtos.AnswerResponseDto;
import org.springframework.stereotype.Service;

import java.util.function.Function;

@Service
public class AnswerResponseDtoMapper implements Function<Answer, AnswerResponseDto> {
@Override
public AnswerResponseDto apply(Answer answer) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package lab.en2b.quizapi.questions.question;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lab.en2b.quizapi.questions.answer.Answer;
import lab.en2b.quizapi.questions.answer.AnswerCategory;
import lombok.*;

import java.util.List;

@Entity
@Table(name = "questions")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Question {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter(AccessLevel.NONE)
private Long id;
private String content;
@NotNull
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name="questions_answers",
joinColumns=
@JoinColumn(name="question_id", referencedColumnName="id"),
inverseJoinColumns=
@JoinColumn(name="answer_id", referencedColumnName="id")
)
private List<Answer> answers;
@ManyToOne
@JoinColumn(name = "correct_answer_id")
private Answer correctAnswer;
private QuestionCategory questionCategory;
private AnswerCategory answerCategory;
private String language;
private QuestionType type;


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package lab.en2b.quizapi.questions.question;

public enum QuestionCategory {
HISTORY, GEOGRAPHY, SCIENCE, MATH, LITERATURE, ART, SPORTS, MUSIC, MOVIES, TV, POLITICS, OTHER
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
package lab.en2b.quizapi.questions.question;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lab.en2b.quizapi.questions.answer.dtos.AnswerDto;
import lab.en2b.quizapi.questions.question.dtos.AnswerCheckResponseDto;
import lab.en2b.quizapi.questions.question.dtos.QuestionResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/questions")
@RequiredArgsConstructor
public class QuestionController {
@GetMapping("/dummy")
private String getDummyQuestion(){
return "Who the hell is Steve Jobs?";
private final QuestionService questionService;

// TODO: REMOVE WHEN NOT USED FOR TESTING
@GetMapping
private ResponseEntity<List<QuestionResponseDto>> getQuestions() {
return ResponseEntity.ok(questionService.getQuestions());
}

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

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

@GetMapping("/{id}")
private ResponseEntity<QuestionResponseDto> getQuestionById(@PathVariable Long id){
return ResponseEntity.ok(questionService.getQuestionById(id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package lab.en2b.quizapi.questions.question;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface QuestionRepository extends JpaRepository<Question,Long> {
@Query(value = "SELECT * FROM questions ORDER BY RAND() LIMIT 1", nativeQuery = true)
Question findRandomQuestion();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package lab.en2b.quizapi.questions.question;

import lab.en2b.quizapi.questions.answer.dtos.AnswerDto;
import lab.en2b.quizapi.questions.question.dtos.AnswerCheckResponseDto;
import lab.en2b.quizapi.questions.question.dtos.QuestionResponseDto;
import lab.en2b.quizapi.questions.question.mappers.QuestionResponseDtoMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class QuestionService {

private final QuestionRepository questionRepository;
private final QuestionResponseDtoMapper questionResponseDtoMapper;
public List<QuestionResponseDto> getQuestions() {
return questionRepository.findAll().stream().map(questionResponseDtoMapper).toList();
}

public AnswerCheckResponseDto answerQuestion(Long id, AnswerDto answerDto) {
Question question = questionRepository.findById(id).orElseThrow();
if(question.getCorrectAnswer().getId().equals(answerDto.getAnswerId())){
return new AnswerCheckResponseDto(true);
}
else if(question.getAnswers().stream().noneMatch(i -> i.getId().equals(answerDto.getAnswerId()))){
throw new IllegalArgumentException("The answer you provided is not one of the options");
}
else {
return new AnswerCheckResponseDto(false);
}
}

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

public QuestionResponseDto getQuestionById(Long id) {
return questionResponseDtoMapper.apply(questionRepository.findById(id).orElseThrow());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package lab.en2b.quizapi.questions.question;

public enum QuestionType {
TEXT, VIDEO, IMAGE, AUDIO

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

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

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class AnswerCheckResponseDto {
private boolean wasCorrect;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package lab.en2b.quizapi.questions.question.dtos;

import lab.en2b.quizapi.questions.answer.AnswerCategory;
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 java.util.List;

@Builder
public class QuestionResponseDto {
private Long id;
private String content;
private List<AnswerResponseDto> answers;
private QuestionCategory questionCategory;
private AnswerCategory answerCategory;
private String language;
private QuestionType type;



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package lab.en2b.quizapi.questions.question.mappers;

import lab.en2b.quizapi.questions.answer.mappers.AnswerResponseDtoMapper;
import lab.en2b.quizapi.questions.question.Question;
import lab.en2b.quizapi.questions.question.dtos.QuestionResponseDto;
import org.springframework.stereotype.Service;

import java.util.function.Function;

@Service
public class QuestionResponseDtoMapper implements Function<Question, QuestionResponseDto> {

@Override
public QuestionResponseDto apply(Question question) {
return QuestionResponseDto.builder()
.id(question.getId())
.content(question.getContent())
.type(question.getType())
.answerCategory(question.getAnswerCategory())
.answers(question.getAnswers().stream().map(new AnswerResponseDtoMapper()).toList())
.language(question.getLanguage())
.questionCategory(question.getQuestionCategory())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package lab.en2b.quizapi;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package lab.en2b.quizapi.questions;

import lab.en2b.quizapi.auth.config.SecurityConfig;
import lab.en2b.quizapi.auth.jwt.JwtUtils;
import lab.en2b.quizapi.questions.question.QuestionController;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(QuestionController.class)
@AutoConfigureMockMvc
@Import(SecurityConfig.class)
public class QuestionControllerTest {
@Autowired
MockMvc mockMvc;
@Mock
JwtUtils jwtUtils;
@Test
void getQuestionShouldReturn200() throws Exception {
mockMvc.perform(get("/questions")
.contentType("application/json")
.with(csrf()))
.andExpect(status().isOk());
}
}

0 comments on commit 915fe27

Please sign in to comment.