Skip to content

Commit

Permalink
Merge pull request #4 from 1Cezzo/implement-quiz
Browse files Browse the repository at this point in the history
Quiz model, repository and service, many to many with user
  • Loading branch information
EmilJohns1 authored Mar 22, 2024
2 parents a4382c9 + d25de33 commit a3b8882
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 14 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.4.0</version>
</dependency>
</dependencies>

<build>
Expand Down
69 changes: 69 additions & 0 deletions src/main/java/com/idatt2105/backend/controller/QuizController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.idatt2105.backend.controller;

import com.idatt2105.backend.model.Quiz;
import com.idatt2105.backend.service.QuizService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/quizzes")
@Tag(name = "Quizzes", description = "Operations related to quizzes")
public class QuizController {

private final QuizService quizService;

@Autowired
public QuizController(QuizService quizService) {
this.quizService = quizService;
}

@GetMapping
@Operation(summary = "Get all quizzes")
public ResponseEntity<List<Quiz>> getAllQuizzes() {
List<Quiz> quizzes = quizService.getAllQuizzes();
return new ResponseEntity<>(quizzes, HttpStatus.OK);
}

@GetMapping("/{id}")
@Operation(summary = "Get quiz by id")
public ResponseEntity<Quiz> getQuizById(@PathVariable("id") Long id) {
Optional<Quiz> quiz = quizService.getQuizById(id);
return quiz.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
}

@PostMapping
@Operation(summary = "Create quiz")
public ResponseEntity<Quiz> createQuiz(@RequestBody Quiz quiz) {
Quiz createdQuiz = quizService.saveQuiz(quiz);
return new ResponseEntity<>(createdQuiz, HttpStatus.CREATED);
}

@DeleteMapping("/{id}")
@Operation(summary = "Delete quiz")
public ResponseEntity<Void> deleteQuiz(@PathVariable("id") Long id) {
quizService.deleteQuiz(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

@PostMapping("/{quizId}/users/{userId}")
@Operation(summary = "Add user to quiz")
public ResponseEntity<Void> addUserToQuiz(@PathVariable("quizId") Long quizId, @PathVariable("userId") Long userId) {
quizService.addUserToQuiz(userId, quizId);
return new ResponseEntity<>(HttpStatus.CREATED);
}

@DeleteMapping("/{quizId}/users/{userId}")
@Operation(summary = "Remove user from quiz")
public ResponseEntity<Void> removeUserFromQuiz(@PathVariable("quizId") Long quizId, @PathVariable("userId") Long userId) {
quizService.removeUserFromQuiz(userId, quizId);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
45 changes: 45 additions & 0 deletions src/main/java/com/idatt2105/backend/model/Quiz.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.idatt2105.backend.model;

import lombok.Data;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotEmpty;

/**
* Represents a quiz.
*/
@Entity
@Data
@Table(name = "quizzes")
public class Quiz {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotEmpty
@Column(name = "title", nullable = false)
private String title;

@Column(name = "description", columnDefinition = "TEXT")
private String description;

@Column(name = "creation_date")
private LocalDateTime creationDate;

@Column(name = "last_modified_date")
private LocalDateTime lastModifiedDate;

@ManyToMany(mappedBy = "quizzes")
private Set<User> users = new HashSet<>();
}
40 changes: 27 additions & 13 deletions src/main/java/com/idatt2105/backend/model/User.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,42 @@
package com.idatt2105.backend.model;

import java.util.HashSet;
import java.util.Set;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotEmpty;
import jakarta.persistence.JoinColumn;

import lombok.Data;

/**
* Represents a user.
*/
@Entity
@Data
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotEmpty
@Column(name = "username", nullable = false)
private String username;
@NotEmpty
@Column(name = "password", nullable = false)
private String password;
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotEmpty
@Column(name = "username", nullable = false)
private String username;

@NotEmpty
@Column(name = "password", nullable = false)
private String password;

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "user_quiz",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "quiz_id", referencedColumnName = "id"))
private Set<Quiz> quizzes = new HashSet<>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.idatt2105.backend.repositories;

import com.idatt2105.backend.model.Quiz;

import java.util.Optional;

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

@Repository
public interface QuizRepository extends JpaRepository<Quiz, Long> {
Optional <Quiz> findByTitle(String title);
}
75 changes: 75 additions & 0 deletions src/main/java/com/idatt2105/backend/service/QuizService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.idatt2105.backend.service;

import com.idatt2105.backend.model.Quiz;
import com.idatt2105.backend.model.User;
import com.idatt2105.backend.repositories.QuizRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class QuizService {

private final QuizRepository quizRepository;
private final UserService userService;

@Autowired
public QuizService(QuizRepository quizRepository, UserService userService) {
this.quizRepository = quizRepository;
this.userService = userService;
}

public List<Quiz> getAllQuizzes() {
return quizRepository.findAll();
}

public Optional<Quiz> getQuizById(Long id) {
return quizRepository.findById(id);
}

public Quiz saveQuiz(Quiz quiz) {
return quizRepository.save(quiz);
}

public void deleteQuiz(Long id) {
quizRepository.deleteById(id);
}

public void addUserToQuiz(Long userId, Long quizId) {
Optional<Quiz> quizOptional = quizRepository.findById(quizId);
if (quizOptional.isPresent()) {
Quiz quiz = quizOptional.get();
User user = userService.getUserById(userId);
if (user != null) {
quiz.getUsers().add(user);
quizRepository.save(quiz);
} else {
// Handle user not found
}
} else {
// Handle quiz not found
}
}

public void removeUserFromQuiz(Long userId, Long quizId) {
Optional<Quiz> quizOptional = quizRepository.findById(quizId);
if (quizOptional.isPresent()) {
Quiz quiz = quizOptional.get();
User user = userService.getUserById(userId);
if (user != null) {
quiz.getUsers().remove(user);
quizRepository.save(quiz);
} else {
// Handle user not found
}
} else {
// Handle quiz not found
}
}

public Optional<Quiz> getQuizByTitle(String title) {
return quizRepository.findByTitle(title);
}
}
25 changes: 24 additions & 1 deletion src/main/java/com/idatt2105/backend/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.idatt2105.backend.service;

import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.idatt2105.backend.model.Quiz;
import com.idatt2105.backend.model.User;
import com.idatt2105.backend.repositories.UserRepository;

Expand All @@ -21,7 +24,7 @@ public List<User> getUsers() {
return userRepository.findAll();
}

public User getUser(Long id) {
public User getUserById(Long id) {
return userRepository.findById(id).orElseThrow(() -> new IllegalStateException("User with id " + id + " not found"));
}

Expand Down Expand Up @@ -50,4 +53,24 @@ public User getUserByUsername(String username) {
public boolean userExists(String username) {
return userRepository.findByUsername(username).isPresent();
}

public Set<Quiz> getQuizzesByUserId(Long userId) {
User user = userRepository.findById(userId).orElseThrow(() -> new IllegalStateException("User with id " + userId + " not found"));
return user.getQuizzes();
}

public void addQuizToUser(Long userId, Quiz quiz) {
User user = userRepository.findById(userId).orElseThrow(() -> new IllegalStateException("User with id " + userId + " not found"));
user.getQuizzes().add(quiz);
userRepository.save(user);
}

public void removeQuizFromUser(Long userId, Long quizId) {
User user = userRepository.findById(userId).orElseThrow(() -> new IllegalStateException("User with id " + userId + " not found"));
Optional<Quiz> quizOptional = user.getQuizzes().stream().filter(q -> q.getId().equals(quizId)).findFirst();
quizOptional.ifPresent(quiz -> {
user.getQuizzes().remove(quiz);
userRepository.save(user);
});
}
}

0 comments on commit a3b8882

Please sign in to comment.