Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Active game and GET /play endpoints #243

Merged
merged 5 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions api/src/main/java/lab/en2b/quizapi/game/GameController.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ public ResponseEntity<GameResponseDto> newGame(@RequestParam(required = false) S
throw new IllegalArgumentException("Custom game mode requires a body");
return ResponseEntity.ok(gameService.newGame(lang,gamemode,customGameDto,authentication));
}
@Operation(summary = "Gets the current game", description = "Requests the API to get the current game")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
@ApiResponse(responseCode = "403", description = "You are not logged in", content = @io.swagger.v3.oas.annotations.media.Content),
@ApiResponse(responseCode = "404", description = "No active game", content = @io.swagger.v3.oas.annotations.media.Content),
})
@GetMapping("/play")
public ResponseEntity<GameResponseDto> getGame(Authentication authentication){
return ResponseEntity.ok(gameService.getGame(authentication));
}

@Operation(summary = "Checks if there is an active game", description = "Requests the API to check if there exists an active game for a given authentication (a player)")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved"),
@ApiResponse(responseCode = "403", description = "You are not logged in", content = @io.swagger.v3.oas.annotations.media.Content),
})
@GetMapping("/is-active")
public ResponseEntity<GameActiveResponseDto> isActive(Authentication authentication){
return ResponseEntity.ok(gameService.isActive(authentication));
}

@Operation(summary = "Starts a new round", description = "Starts the round (asks a question and its possible answers to the API and start the timer) for a given authentication (a player)")
@ApiResponses(value = {
Expand Down
29 changes: 28 additions & 1 deletion api/src/main/java/lab/en2b/quizapi/game/GameService.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public class GameService {
@Transactional
public GameResponseDto newGame(String lang, GameMode gamemode, CustomGameDto newGameDto, Authentication authentication) {
// Check if there is an active game for the user
Optional<Game> game = gameRepository.findActiveGameForUser(userService.getUserByAuthentication(authentication).getId());
Optional<Game> game = getCurrentGameForAuth(authentication);
if (game.isPresent() && !wasGameMeantToBeOver(game.get())){
// If there is an active game and it should not be over, return it
return gameResponseDtoMapper.apply(game.get());
Expand Down Expand Up @@ -179,4 +179,31 @@ public List<GameModeDto> getQuestionGameModes() {
//new GameModeDto("Custom","Don't like our gamemodes? That's fine! (I only feel a bit offended)",GameMode.CUSTOM,"FaCog")
);
}

/**
* Gets the game
* @param authentication the authentication of the user
* @return the game that is currently active
*/
public GameResponseDto getGame(Authentication authentication) {
return gameResponseDtoMapper.apply(getCurrentGameForAuth(authentication).orElseThrow());
}

/**
* Gets the current game for the user
* @param authentication the authentication of the user
* @return the current game
*/
private Optional<Game> getCurrentGameForAuth(Authentication authentication){
return gameRepository.findActiveGameForUser(userService.getUserByAuthentication(authentication).getId());
}

/**
* Checks if the game is active
* @param authentication the authentication of the user
* @return the response of the check
*/
public GameActiveResponseDto isActive(Authentication authentication) {
return new GameActiveResponseDto(getCurrentGameForAuth(authentication).isPresent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package lab.en2b.quizapi.game.dtos;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@Data
@NoArgsConstructor
public class GameActiveResponseDto {
@JsonProperty("is_active")
@Schema(description = "Whether the game is active or not",example = "true")
private boolean isActive;
}
36 changes: 35 additions & 1 deletion api/src/test/java/lab/en2b/quizapi/game/GameControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ void getQuestionCategoriesShouldReturn403() throws Exception{
}

@Test
void getGameModeshouldReturn200() throws Exception{
void getGameModeShouldReturn200() throws Exception{
mockMvc.perform(get("/games/gamemodes")
.with(user("test").roles("user"))
.contentType("application/json")
Expand All @@ -219,5 +219,39 @@ void getGameModesShouldReturn403() throws Exception{
.andExpect(status().isForbidden());
}

@Test
void getGameShouldReturn200() throws Exception{
mockMvc.perform(get("/games/play")
.with(user("test").roles("user"))
.contentType("application/json")
.with(csrf()))
.andExpect(status().isOk());
}

@Test
void getGameShouldReturn403() throws Exception{
mockMvc.perform(get("/games/play")
.contentType("application/json")
.with(csrf()))
.andExpect(status().isForbidden());
}

@Test
void getGameIsActiveShouldReturn200() throws Exception{
mockMvc.perform(get("/games/is-active")
.with(user("test").roles("user"))
.contentType("application/json")
.with(csrf()))
.andExpect(status().isOk());
}

@Test
void getGameIsActiveShouldReturn403() throws Exception{
mockMvc.perform(get("/games/is-active")
.contentType("application/json")
.with(csrf()))
.andExpect(status().isForbidden());
}


}
42 changes: 42 additions & 0 deletions api/src/test/java/lab/en2b/quizapi/game/GameServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,35 @@ public void newGameCustomGame(){

assertEquals(defaultGameResponseDto, gameDto);
}
// GET GAME
@Test
public void getGame(){
Authentication authentication = mock(Authentication.class);
when(userService.getUserByAuthentication(authentication)).thenReturn(defaultUser);
when(gameRepository.findActiveGameForUser(any())).thenReturn(Optional.of(defaultGame));
GameResponseDto gameDto = gameService.getGame(authentication);
gameDto.setId(null);
assertEquals(defaultGameResponseDto, gameDto);
}
@Test
public void getGameNotActive(){
Authentication authentication = mock(Authentication.class);
when(userService.getUserByAuthentication(authentication)).thenReturn(defaultUser);
assertThrows(NoSuchElementException.class, () -> gameService.getGame(authentication));
}

// IS GAME ACTIVE TESTS
@Test
public void isGameActive(){
when(userService.getUserByAuthentication(authentication)).thenReturn(defaultUser);
when(gameRepository.findActiveGameForUser(1L)).thenReturn(Optional.of(defaultGame));
assertTrue(gameService.isActive(authentication).isActive());
}
@Test
public void isGameActiveNoActiveGame(){
when(userService.getUserByAuthentication(authentication)).thenReturn(defaultUser);
assertFalse(gameService.isActive(authentication).isActive());
}

// START ROUND TESTS
@Test
Expand Down Expand Up @@ -263,6 +292,14 @@ public void getCurrentQuestion() {
assertEquals(defaultQuestionResponseDto, questionDto);
}

@Test
public void getCurrentQuestionRoundTimeNull() {
defaultGame.setRoundStartTime(null);
when(gameRepository.findByIdForUser(any(), any())).thenReturn(Optional.of(defaultGame));
when(userService.getUserByAuthentication(authentication)).thenReturn(defaultUser);
assertThrows(IllegalStateException.class, () -> gameService.getCurrentQuestion(1L,authentication));
}

@Test
public void getCurrentQuestionRoundNotStarted() {
when(gameRepository.findByIdForUser(any(), any())).thenReturn(Optional.of(defaultGame));
Expand Down Expand Up @@ -433,4 +470,9 @@ public void testGetQuestionCategories(){
assertEquals(Arrays.asList(QuestionCategory.values()), gameService.getQuestionCategories());
}

@Test
public void testGetGameModes(){
assertFalse(gameService.getQuestionGameModes().isEmpty());
}

}