Skip to content
Snippets Groups Projects
Commit 5f17325f authored by Kristiane Skogvang Kolshus's avatar Kristiane Skogvang Kolshus
Browse files

Revert changes to functionality, implement request header

parent d1e15117
No related branches found
No related tags found
1 merge request!50Questions endpoint
Pipeline #270149 passed
Showing
with 93 additions and 102 deletions
...@@ -37,31 +37,22 @@ public class QuestionController { ...@@ -37,31 +37,22 @@ public class QuestionController {
* @param questionDTO The question data to be saved. * @param questionDTO The question data to be saved.
* @return The saved question DTO. * @return The saved question DTO.
*/ */
@PostMapping("/newQuestion") @PostMapping("/save")
public QuestionDTO createNewQuestion(@RequestBody QuestionDTO questionDTO) { public QuestionDTO saveQuestion(@RequestBody QuestionDTO questionDTO) {
if (questionDTO.getId() != null) { Question question = questionService.createOrUpdateQuestion(questionDTO);
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ID should be null for new questions");
}
Question question = questionService.createQuestion(questionDTO);
return mapQuestionToQuestionDTO(question);
}
/** // TODO: make a mapper class to do this
* Endpoint for updating an existing question. return new QuestionDTO(
* @param questionDTO The question data to be updated question.getId(),
* @return The updated question DTO. question.getQuestionText(),
*/ question.getType(),
@PutMapping("/questions/{id}") question.getAnswer(),
public QuestionDTO updateExistingQuestion(@PathVariable Integer id, @RequestBody QuestionDTO questionDTO) { question.getOptionsList(),
if (questionDTO.getId() == null || !questionDTO.getId().equals(id)) { question.getScore(),
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Question ID mismatch"); question.getQuiz().getId()
} );
Question question = questionService.updateQuestion(questionDTO);
return mapQuestionToQuestionDTO(question);
} }
/** /**
* Endpoint for retrieving a question by ID. * Endpoint for retrieving a question by ID.
* *
...@@ -72,6 +63,7 @@ public class QuestionController { ...@@ -72,6 +63,7 @@ public class QuestionController {
public QuestionDTO getQuestion(@PathVariable Integer questionId) { public QuestionDTO getQuestion(@PathVariable Integer questionId) {
Question question = questionService.findQuestionById(questionId); Question question = questionService.findQuestionById(questionId);
return new QuestionDTO( return new QuestionDTO(
question.getId(),
question.getQuestionText(), question.getQuestionText(),
question.getType(), question.getType(),
question.getAnswer(), question.getAnswer(),
...@@ -81,6 +73,7 @@ public class QuestionController { ...@@ -81,6 +73,7 @@ public class QuestionController {
); );
} }
/** /**
* Endpoint for deleting a question by ID. * Endpoint for deleting a question by ID.
* *
...@@ -102,6 +95,7 @@ public class QuestionController { ...@@ -102,6 +95,7 @@ public class QuestionController {
List<Question> questions = questionService.findAllQuestionsToAQuiz(quizId); List<Question> questions = questionService.findAllQuestionsToAQuiz(quizId);
return questions.stream() return questions.stream()
.map(question -> new QuestionDTO( .map(question -> new QuestionDTO(
question.getId(),
question.getQuestionText(), question.getQuestionText(),
question.getType(), question.getType(),
question.getAnswer(), question.getAnswer(),
...@@ -111,16 +105,4 @@ public class QuestionController { ...@@ -111,16 +105,4 @@ public class QuestionController {
)) ))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
private QuestionDTO mapQuestionToQuestionDTO(Question question) {
return new QuestionDTO(
question.getQuestionText(),
question.getType(),
question.getAnswer(),
question.getOptionsList(),
question.getScore(),
question.getQuiz().getId()
);
}
} }
...@@ -29,6 +29,7 @@ public class QuestionDTO { ...@@ -29,6 +29,7 @@ public class QuestionDTO {
/** /**
* Constructor for QuestionDTO. * Constructor for QuestionDTO.
* *
* @param id The ID of the question.
* @param questionText The text of the question. * @param questionText The text of the question.
* @param type The type of the question. * @param type The type of the question.
* @param answer The correct answer to the question. * @param answer The correct answer to the question.
...@@ -36,7 +37,8 @@ public class QuestionDTO { ...@@ -36,7 +37,8 @@ public class QuestionDTO {
* @param score The score assigned to the question. * @param score The score assigned to the question.
* @param quizId The ID of the quiz the question belongs to. * @param quizId The ID of the quiz the question belongs to.
*/ */
public QuestionDTO(String questionText, QuestionType type, String answer, List<String> options, int score, Integer quizId) { public QuestionDTO(Integer id, String questionText, QuestionType type, String answer, List<String> options, int score, Integer quizId) {
this.id = id;
this.questionText = questionText; this.questionText = questionText;
this.type = type; this.type = type;
this.answer = answer; this.answer = answer;
...@@ -45,6 +47,7 @@ public class QuestionDTO { ...@@ -45,6 +47,7 @@ public class QuestionDTO {
this.quizId = quizId; this.quizId = quizId;
} }
/** /**
* Get the ID of the question. * Get the ID of the question.
* *
......
...@@ -35,51 +35,43 @@ public class QuestionService { ...@@ -35,51 +35,43 @@ public class QuestionService {
} }
/** /**
* Creates a question. * Creates or updates a question.
* *
* @param questionDTO The DTO containing the question details. * @param questionDTO The DTO containing the question details.
* @return The created question. * @return The created or updated question.
*/ */
public Question createQuestion(QuestionDTO questionDTO) { @Transactional
Question question = new Question(); public Question createOrUpdateQuestion(QuestionDTO questionDTO) {
question.setQuestionText(questionDTO.getQuestionText());
question.setType(questionDTO.getType()); Question question;
if (questionDTO.getType() == QuestionType.TRUE_OR_FALSE) { if (questionDTO.getId() != null) {
question.setOptions("TRUE*FALSE"); Optional<Question> optionalQuestion = questionRepository.findById(questionDTO.getId());
} else if (questionDTO.getOptions() != null) { if (!optionalQuestion.isPresent()) {
question.setOptions(questionDTO.getOptionsAsString()); return null;
} }
question.setAnswer(questionDTO.getAnswer()); question = optionalQuestion.get();
question.setScore(questionDTO.getScore()); } else {
question.setQuiz(quizRepository.findById(questionDTO.getQuizId()) question = new Question();
.orElseThrow(() -> new EntityNotFoundException("Quiz not found for ID: " + questionDTO.getQuizId())));
return questionRepository.save(question);
} }
/**
* Updates a question
*
* @param questionDTO The DTO containing the question details.
* @return The updated question.
*/
public Question updateQuestion(QuestionDTO questionDTO) {
Question question = questionRepository.findById(questionDTO.getId())
.orElseThrow(() -> new EntityNotFoundException("Question not found for ID: " + questionDTO.getId()));
question.setQuestionText(questionDTO.getQuestionText()); question.setQuestionText(questionDTO.getQuestionText());
question.setType(questionDTO.getType()); question.setType(questionDTO.getType());
if (questionDTO.getOptions() != null) {
if (questionDTO.getType().equals(QuestionType.MULTIPLE_CHOICE)) {
question.setOptions(questionDTO.getOptionsAsString()); question.setOptions(questionDTO.getOptionsAsString());
} else if (questionDTO.getType().equals(QuestionType.TRUE_OR_FALSE)) {
question.setOptions("TRUE*FALSE");
} else {
question.setOptions(null);
} }
question.setAnswer(questionDTO.getAnswer()); question.setAnswer(questionDTO.getAnswer());
question.setScore(questionDTO.getScore()); question.setScore(questionDTO.getScore());
question.setQuiz(quizRepository.findById(questionDTO.getQuizId()).orElse(null));
return questionRepository.save(question); return questionRepository.save(question);
} }
/** /**
* Deletes a question by its ID. * Deletes a question by its ID.
* *
......
/*
package edu.ntnu.idatt2105.service; package edu.ntnu.idatt2105.service;
import edu.ntnu.idatt2105.dto.QuestionDTO; import edu.ntnu.idatt2105.dto.QuestionDTO;
import edu.ntnu.idatt2105.model.Question; import edu.ntnu.idatt2105.model.Question;
import edu.ntnu.idatt2105.model.QuestionType; import edu.ntnu.idatt2105.model.QuestionType;
import edu.ntnu.idatt2105.model.Quiz;
import edu.ntnu.idatt2105.repository.QuestionRepository; import edu.ntnu.idatt2105.repository.QuestionRepository;
import edu.ntnu.idatt2105.repository.QuizRepository; import edu.ntnu.idatt2105.repository.QuizRepository;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
...@@ -29,20 +27,15 @@ class QuestionServiceTest { ...@@ -29,20 +27,15 @@ class QuestionServiceTest {
private QuizRepository quizRepository; private QuizRepository quizRepository;
private Quiz quiz;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
questionRepository = mock(QuestionRepository.class); questionRepository = mock(QuestionRepository.class);
quizRepository = mock(QuizRepository.class); quizRepository = mock(QuizRepository.class);
questionService = new QuestionService(questionRepository, quizRepository); questionService = new QuestionService(questionRepository, quizRepository);
quiz = new Quiz();
quiz.setId(1);
} }
@Test @Test
void testCreateQuestion_NewMultipleChoice() { void testCreateOrUpdateQuestion_NewMultipleChoice() {
QuestionDTO questionDTO = new QuestionDTO(); QuestionDTO questionDTO = new QuestionDTO();
questionDTO.setType(QuestionType.MULTIPLE_CHOICE); questionDTO.setType(QuestionType.MULTIPLE_CHOICE);
questionDTO.setQuestionText("What is the largest planet?"); questionDTO.setQuestionText("What is the largest planet?");
...@@ -53,12 +46,11 @@ class QuestionServiceTest { ...@@ -53,12 +46,11 @@ class QuestionServiceTest {
when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0)); when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0));
Question result = questionService.createQuestion(questionDTO); Question result = questionService.createOrUpdateQuestion(questionDTO);
verify(questionRepository).save(any(Question.class)); verify(questionRepository).save(any(Question.class));
assertNotNull(result); assertNotNull(result);
assertEquals(1,result.getId());
assertEquals("Jupiter", result.getAnswer()); assertEquals("Jupiter", result.getAnswer());
assertEquals(2, result.getScore()); assertEquals(2, result.getScore());
assertEquals("What is the largest planet?", result.getQuestionText()); assertEquals("What is the largest planet?", result.getQuestionText());
...@@ -66,6 +58,7 @@ class QuestionServiceTest { ...@@ -66,6 +58,7 @@ class QuestionServiceTest {
assertEquals("Earth*Mars*Jupiter*Venus", result.getOptions()); assertEquals("Earth*Mars*Jupiter*Venus", result.getOptions());
} }
@Test @Test
void testCreateOrUpdateQuestion_TrueOrFalse() { void testCreateOrUpdateQuestion_TrueOrFalse() {
QuestionDTO questionDTO = new QuestionDTO(); QuestionDTO questionDTO = new QuestionDTO();
...@@ -77,7 +70,7 @@ class QuestionServiceTest { ...@@ -77,7 +70,7 @@ class QuestionServiceTest {
when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0)); when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0));
Question result = questionService.createQuestion(questionDTO); Question result = questionService.createOrUpdateQuestion(questionDTO);
verify(questionRepository).save(any(Question.class)); verify(questionRepository).save(any(Question.class));
...@@ -101,7 +94,7 @@ class QuestionServiceTest { ...@@ -101,7 +94,7 @@ class QuestionServiceTest {
when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0)); when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0));
Question result = questionService.createQuestion(questionDTO); Question result = questionService.createOrUpdateQuestion(questionDTO);
verify(questionRepository).save(any(Question.class)); verify(questionRepository).save(any(Question.class));
...@@ -124,7 +117,7 @@ class QuestionServiceTest { ...@@ -124,7 +117,7 @@ class QuestionServiceTest {
when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0)); when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0));
Question result = questionService.createQuestion(questionDTO); Question result = questionService.createOrUpdateQuestion(questionDTO);
verify(questionRepository).save(any(Question.class)); verify(questionRepository).save(any(Question.class));
...@@ -142,7 +135,7 @@ class QuestionServiceTest { ...@@ -142,7 +135,7 @@ class QuestionServiceTest {
when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0)); when(questionRepository.save(any(Question.class))).thenAnswer(invocation -> invocation.getArgument(0));
Question updatedResult = questionService.updateQuestion(questionDTO); Question updatedResult = questionService.createOrUpdateQuestion(questionDTO);
assertEquals("Mercury", updatedResult.getAnswer()); assertEquals("Mercury", updatedResult.getAnswer());
...@@ -185,5 +178,3 @@ class QuestionServiceTest { ...@@ -185,5 +178,3 @@ class QuestionServiceTest {
} }
*/
\ No newline at end of file
import axios from 'axios'; import axios from 'axios';
import {getToken} from "@/tokenController.js";
export const apiClient = axios.create({ export const apiClient = axios.create({
baseURL: 'http://localhost:8080/api', baseURL: 'http://localhost:8080/api',
//TODO: set api URL //TODO: set api URL
}); });
apiClient.interceptors.request.use(
(config) => {
const token = getToken();
if(token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
});
\ No newline at end of file
import axios from "axios"; import axios from "axios";
axios.defaults.baseURL= 'http://localhost:5173/'; axios.defaults.baseURL= 'http://localhost:5173/';
//axios.defaults.headers.common['Authorization'] = 'Bearer' + getToken();
...@@ -126,7 +126,7 @@ export default { ...@@ -126,7 +126,7 @@ export default {
}, },
async handleSubmit() { async handleSubmit() {
try { try {
await apiClient.post('/questions/newQuestion', { await apiClient.post('/questions/save', {
//TODO: add questionID //TODO: add questionID
questionText: this.questionText, questionText: this.questionText,
type: this.type, type: this.type,
...@@ -147,9 +147,11 @@ export default { ...@@ -147,9 +147,11 @@ export default {
selectOption(option) { selectOption(option) {
this.correctAnswer = option; this.correctAnswer = option;
console.log(this.correctAnswer); console.log(this.correctAnswer);
},
} }
} }
};
</script> </script>
<template> <template>
......
...@@ -24,7 +24,7 @@ export default { ...@@ -24,7 +24,7 @@ export default {
try { try {
//this.findCorrectAnswer(); //this.findCorrectAnswer();
//console.log(this.correctAnswer); //console.log(this.correctAnswer);
await apiClient.post('/questions/newQuestion', { await apiClient.post('/questions/save', {
questionText: this.questionText, questionText: this.questionText,
type: this.type, type: this.type,
answer: this.correctAnswer.text, answer: this.correctAnswer.text,
......
...@@ -17,7 +17,7 @@ export default { ...@@ -17,7 +17,7 @@ export default {
} }
}, },
beforeMount() { beforeMount() {
this.quizId = this.$route.params.quizId; this.quizId = Number(this.$route.params.quizId);
}, },
data() { data() {
return { return {
......
...@@ -76,14 +76,18 @@ export default { ...@@ -76,14 +76,18 @@ export default {
}, },
hideNewQuestion() { hideNewQuestion() {
this.showNewQuestion = false; this.showNewQuestion = false;
//TODO: questions answers, +question count
}, },
deleteQuiz() { deleteQuiz() {
//API req, quizId try {
apiClient.post('/quiz/delete/' + this.questionId, )
} catch (error) {
this.errorMsg = 'Error deleting quiz';
}
} }
}, },
}; };
/** /**
function createQuestion() { function createQuestion() {
showNewQuestionModal.value = true; showNewQuestionModal.value = true;
...@@ -183,7 +187,7 @@ async function submitQuestion() { ...@@ -183,7 +187,7 @@ async function submitQuestion() {
<div class="footer"> <div class="footer">
<button @click="newQuestion" class="add-Btn"> Add Question </button> <button @click="newQuestion" class="add-Btn"> Add Question </button>
<button class="delete-btn"> DELETE QUIZ </button> <button class="delete-btn" @click="deleteQuiz"> DELETE QUIZ </button>
<button class="save-Btn"> SAVE QUIZ </button> <button class="save-Btn"> SAVE QUIZ </button>
</div> </div>
</div> </div>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="headerDiv"> <div class="headerDiv">
<router-link to="/dashboard" ><Svg name="go-back-icon" class="go-back-icon"/></router-link> <router-link to="/dashboard" ><Svg name="go-back-icon" class="go-back-icon"/></router-link>
<h1>Your quizzes</h1> <h1>Your quizzes</h1>
<router-link to="/create-quiz" class="add-Btn">Create new quiz</router-link> <router-link to="/createQuiz" class="add-Btn">Create new quiz</router-link>
</div> </div>
<p>Play, edit or delete a quiz saved from your profile</p> <p>Play, edit or delete a quiz saved from your profile</p>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment