Skip to content

Commit

Permalink
Merge pull request #27 from 1Cezzo/implement-category
Browse files Browse the repository at this point in the history
Implement category
  • Loading branch information
SveinKare authored Mar 28, 2024
2 parents 785f04d + d335ea3 commit f119511
Show file tree
Hide file tree
Showing 17 changed files with 145 additions and 86 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>com.idatt2105</groupId>
<artifactId>backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>1.1</version>
<name>backend</name>
<description>Backend for IDATT2105 Project</description>
<properties>
Expand Down
36 changes: 24 additions & 12 deletions src/main/java/com/idatt2105/backend/controller/QuizController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
import org.springframework.web.bind.annotation.RestController;

import com.idatt2105.backend.dto.QuizDTO;
import com.idatt2105.backend.dto.QuizUpdateRequestDTO;
import com.idatt2105.backend.dto.UserDTO;
import com.idatt2105.backend.model.Category;
import com.idatt2105.backend.model.Tag;
import com.idatt2105.backend.service.QuizService;

Expand Down Expand Up @@ -84,17 +84,8 @@ public ResponseEntity<Void> removeUserFromQuiz(
@PutMapping("/{id}")
@Operation(summary = "Update quiz")
public ResponseEntity<Void> updateQuiz(
@PathVariable("id") Long id, @RequestBody QuizUpdateRequestDTO requestDTO) {
if (requestDTO.getQuizPictureUrl() == null) {
requestDTO.setQuizPictureUrl(quizService.getQuizById(id).getQuizPictureUrl());
}
QuizDTO updatedQuiz =
new QuizDTO.Builder()
.setTitle(requestDTO.getTitle())
.setDescription(requestDTO.getDescription())
.setQuizPictureUrl(requestDTO.getQuizPictureUrl())
.build();
quizService.updateQuiz(id, updatedQuiz);
@PathVariable("id") Long id, @RequestBody QuizDTO requestDTO) {
quizService.updateQuiz(id, requestDTO);
return new ResponseEntity<>(HttpStatus.OK);
}

Expand Down Expand Up @@ -139,4 +130,25 @@ public ResponseEntity<List<Tag>> getAllTags() {
List<Tag> tags = quizService.getAllTags();
return new ResponseEntity<>(tags, HttpStatus.OK);
}

@PostMapping("/create/category")
@Operation(summary = "Create a new category")
public ResponseEntity<Category> createCategory(@RequestBody Category category) {
Category createdCategory = quizService.createCategory(category);
return new ResponseEntity<>(createdCategory, HttpStatus.CREATED);
}

@PostMapping("/category")
@Operation(summary = "Get all quizzes with a specific category")
public ResponseEntity<List<QuizDTO>> getQuizzesByCategory(@RequestBody Category category) {
List<QuizDTO> quizzes = quizService.getQuizzesByCategory(category);
return new ResponseEntity<>(quizzes, HttpStatus.OK);
}

@GetMapping("/categories")
@Operation(summary = "Get all categories")
public ResponseEntity<List<Category>> getAllCategories() {
List<Category> categories = quizService.getAllCategories();
return new ResponseEntity<>(categories, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public class QuestionAttemptDTO {
private QuestionType type;
private String questionText;
private String mediaUrl;
private String category;
private int points;
private Set<AlternativeRecord> alternatives = new HashSet<>();
private Boolean userAnswer;
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/idatt2105/backend/dto/QuestionDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public class QuestionDTO {
private Long questionId;
private String questionText;
private String mediaUrl;
private String category;
private int points;
private Long quizId;
private QuestionType type;
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/com/idatt2105/backend/dto/QuizDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class QuizDTO {
private String title;
private String description;
private String quizPictureUrl;
private String categoryName;
private LocalDateTime creationDate;
private LocalDateTime lastModifiedDate;
private Set<UserDTO> userDTOs;
Expand All @@ -44,6 +45,7 @@ public QuizDTO(Quiz quiz) {
this.title = quiz.getTitle();
this.description = quiz.getDescription();
this.quizPictureUrl = quiz.getQuizPictureUrl();
this.categoryName = quiz.getCategory() == null ? null : quiz.getCategory().getName();
this.creationDate = quiz.getCreationDate();
this.lastModifiedDate = quiz.getLastModifiedDate();
this.userDTOs = new HashSet<>();
Expand Down Expand Up @@ -82,6 +84,7 @@ public static class Builder {
private String title;
private String description;
private String quizPictureUrl;
private String categoryName;
private LocalDateTime creationDate;
private LocalDateTime lastModifiedDate;
private Set<UserDTO> userDTOs;
Expand All @@ -107,6 +110,11 @@ public Builder setQuizPictureUrl(String quizPictureUrl) {
return this;
}

public Builder setCategoryName(String categoryName) {
this.categoryName = categoryName;
return this;
}

public Builder setCreationDate(LocalDateTime creationDate) {
this.creationDate = creationDate;
return this;
Expand All @@ -129,7 +137,15 @@ public Builder setTags(Set<Tag> tags) {

public QuizDTO build() {
return new QuizDTO(
id, title, description, quizPictureUrl, creationDate, lastModifiedDate, userDTOs, tags);
id,
title,
description,
quizPictureUrl,
categoryName,
creationDate,
lastModifiedDate,
userDTOs,
tags);
}
}
}
33 changes: 33 additions & 0 deletions src/main/java/com/idatt2105/backend/model/Category.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.idatt2105.backend.model;

import java.util.Set;

import com.fasterxml.jackson.annotation.JsonIgnore;

import io.swagger.v3.oas.annotations.Hidden;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import lombok.Data;

@Entity
@Data
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "name")
private String name;

@Column(name = "picture_url")
private String pictureUrl;

@OneToMany(mappedBy = "category")
@Hidden
@JsonIgnore
private Set<Quiz> quizzes;
}
7 changes: 1 addition & 6 deletions src/main/java/com/idatt2105/backend/model/Question.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ public class Question {
@Column(name = "media_url")
private String mediaUrl;

@Column(name = "category")
private String category;

@Column(name = "points")
private int points;

Expand All @@ -49,7 +46,6 @@ public class Question {
public void extractFromDTO(QuestionDTO dto) {
this.questionText = dto.getQuestionText();
this.mediaUrl = dto.getMediaUrl();
this.category = dto.getCategory();
this.points = dto.getPoints();
}

Expand All @@ -72,13 +68,12 @@ public boolean equals(Object o) {
&& Objects.equals(id, question.id)
&& Objects.equals(questionText, question.questionText)
&& Objects.equals(mediaUrl, question.mediaUrl)
&& Objects.equals(category, question.category)
&& Objects.equals(thisQuizId, thatQuizId);
}

@Override
public int hashCode() {
Long quizId = quiz == null ? null : quiz.getId();
return Objects.hash(id, questionText, mediaUrl, category, points, quizId);
return Objects.hash(id, questionText, mediaUrl, points, quizId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public class QuestionAttempt {
private String questionText;

private String mediaUrl;
private String category;
private int points;

@ManyToOne
Expand All @@ -38,7 +37,6 @@ public class QuestionAttempt {
public void extractFromDTO(QuestionAttemptDTO dto) {
this.questionText = dto.getQuestionText();
this.mediaUrl = dto.getMediaUrl();
this.category = dto.getCategory();
this.points = dto.getPoints();
}
}
3 changes: 3 additions & 0 deletions src/main/java/com/idatt2105/backend/model/Quiz.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotEmpty;
Expand Down Expand Up @@ -72,6 +73,8 @@ public class Quiz {
inverseJoinColumns = @JoinColumn(name = "tag_id"))
private Set<Tag> tags = new HashSet<>();

@ManyToOne private Category category;

public void addTags(Collection<Tag> tags) {
tags.stream().filter(Objects::nonNull).forEach(this.tags::add);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.idatt2105.backend.repository;

import java.util.Optional;

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

import com.idatt2105.backend.model.Category;

public interface CategoryRepository extends JpaRepository<Category, Long> {
Optional<Category> findByName(String name);

boolean existsByName(String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,5 @@
import com.idatt2105.backend.model.Question;

public interface QuestionRepository extends JpaRepository<Question, Long> {
List<Question> findQuestionsByCategory(String category);

List<Question> findQuestionsByQuizId(Long quizId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.idatt2105.backend.model.Category;
import com.idatt2105.backend.model.Quiz;
import com.idatt2105.backend.model.Tag;

Expand All @@ -14,4 +15,6 @@ public interface QuizRepository extends JpaRepository<Quiz, Long> {
Optional<Quiz> findByTitle(String title);

List<Quiz> findByTagsContains(Tag tag);

List<Quiz> findByCategory(Category category);
}
55 changes: 50 additions & 5 deletions src/main/java/com/idatt2105/backend/service/QuizService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@

import com.idatt2105.backend.dto.QuizDTO;
import com.idatt2105.backend.dto.UserDTO;
import com.idatt2105.backend.model.Category;
import com.idatt2105.backend.model.Quiz;
import com.idatt2105.backend.model.Tag;
import com.idatt2105.backend.model.User;
import com.idatt2105.backend.repository.CategoryRepository;
import com.idatt2105.backend.repository.QuizRepository;
import com.idatt2105.backend.repository.TagRepository;
import com.idatt2105.backend.repository.UserRepository;
Expand All @@ -27,13 +29,18 @@ public class QuizService {
private final QuizRepository quizRepository;
private final UserRepository userRepository;
private final TagRepository tagRepository;
private final CategoryRepository categoryRepository;

@Autowired
public QuizService(
QuizRepository quizRepository, UserRepository userRepository, TagRepository tagRepository) {
QuizRepository quizRepository,
UserRepository userRepository,
TagRepository tagRepository,
CategoryRepository categoryRepository) {
this.quizRepository = quizRepository;
this.userRepository = userRepository;
this.tagRepository = tagRepository;
this.categoryRepository = categoryRepository;
}

public List<QuizDTO> getAllQuizzes() {
Expand Down Expand Up @@ -76,10 +83,16 @@ public void updateQuiz(Long id, QuizDTO updatedQuiz) {

Quiz existingQuiz = findQuiz(id);

existingQuiz.setTitle(updatedQuiz.getTitle());
existingQuiz.setDescription(updatedQuiz.getDescription());
existingQuiz.setLastModifiedDate(LocalDateTime.now());
existingQuiz.setQuizPictureUrl(updatedQuiz.getQuizPictureUrl());
// Only update fields that are included in the request
Optional.ofNullable(updatedQuiz.getTitle()).ifPresent(existingQuiz::setTitle);
Optional.ofNullable(updatedQuiz.getDescription()).ifPresent(existingQuiz::setDescription);
Optional.ofNullable(updatedQuiz.getQuizPictureUrl()).ifPresent(existingQuiz::setQuizPictureUrl);
Optional.ofNullable(updatedQuiz.getCategoryName())
.ifPresent(
categoryName -> {
Category category = findCategoryByName(categoryName);
existingQuiz.setCategory(category);
});

quizRepository.save(existingQuiz);
}
Expand Down Expand Up @@ -189,6 +202,32 @@ public List<Tag> getAllTags() {
return tagRepository.findAll();
}

public Category createCategory(Category category) {
if (category == null) {
throw new IllegalArgumentException("Category parameter cannot be null.");
}
if (categoryRepository.existsByName(category.getName())) {
throw new IllegalArgumentException(
"Category with name " + category.getName() + " already exists.");
}
category.setId(null); // Avoids conflicts with existing categories

return categoryRepository.save(category);
}

public List<QuizDTO> getQuizzesByCategory(Category category) {
if (category == null) {
throw new IllegalArgumentException("Category parameter cannot be null.");
}
Category foundCategory = findCategoryByName(category.getName());
List<Quiz> quizzes = quizRepository.findByCategory(foundCategory);
return quizzes.stream().map(QuizDTO::new).toList();
}

public List<Category> getAllCategories() {
return categoryRepository.findAll();
}

private Quiz findQuiz(Long id) {
return quizRepository
.findById(id)
Expand All @@ -200,4 +239,10 @@ private User findUser(Long id) {
.findById(id)
.orElseThrow(() -> new InvalidIdException("User with id " + id + " not found"));
}

private Category findCategoryByName(String name) {
return categoryRepository
.findByName(name)
.orElseThrow(() -> new InvalidIdException("Category with name " + name + " not found"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,6 @@ void testGetMediaUrl() {
assertEquals(mediaUrl, questionAttemptDTO.getMediaUrl());
}

@Test
void testGetCategory() {
String category = "Category";
questionAttemptDTO.setCategory(category);
assertEquals(category, questionAttemptDTO.getCategory());
}

@Test
void testGetPoints() {
int points = 10;
Expand Down Expand Up @@ -109,13 +102,6 @@ void testSetMediaUrl() {
assertEquals(mediaUrl, questionAttemptDTO.getMediaUrl());
}

@Test
void testSetCategory() {
String category = "Category";
questionAttemptDTO.setCategory(category);
assertEquals(category, questionAttemptDTO.getCategory());
}

@Test
void testSetPoints() {
int points = 10;
Expand Down
Loading

0 comments on commit f119511

Please sign in to comment.