Skip to content

Commit

Permalink
Merge pull request #213 from hufscheer/feat/#208-game
Browse files Browse the repository at this point in the history
[FEAT] 게임 정보 수정 기능 추가
  • Loading branch information
Zena0128 authored Sep 23, 2024
2 parents 8f47e02 + cd3ee17 commit 22870d7
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 61 deletions.
4 changes: 4 additions & 0 deletions src/docs/asciidoc/api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ operation::game-query-controller-test/출전_선수를_조회한다[snippets='ht

operation::game-controller-test/경기를_등록한다[snippets='http-request,path-parameters,http-response']

=== 게임 수정

operation::game-controller-test/경기를_수정한다[snippets='http-request,path-parameters,http-response']

== 라인업 API

=== 라인업 선수 선발로 변경
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc
mvc.pattern(HttpMethod.GET, "/members/info"),
mvc.pattern(HttpMethod.POST, "/leagues"),
mvc.pattern(HttpMethod.PUT, "/leagues/{leagueId}"),
mvc.pattern(HttpMethod.PUT, "/leagues/{leagueId}/{gameId}"),
mvc.pattern(HttpMethod.POST, "/leagues/*/teams"),
mvc.pattern(HttpMethod.POST, "/leagues/{leagueId}/teams"),
mvc.pattern(HttpMethod.PUT, "/leagues/{leagueId}/teams/{teamId}"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.sports.server.auth.exception.AuthorizationErrorMessages;
import com.sports.server.command.game.domain.Game;
import com.sports.server.command.game.domain.GameRepository;
import com.sports.server.command.game.domain.GameState;
import com.sports.server.command.game.domain.GameTeam;
import com.sports.server.command.game.dto.GameRequestDto;
import com.sports.server.command.league.domain.League;
import com.sports.server.command.league.domain.Round;
import com.sports.server.command.leagueteam.domain.LeagueTeam;
import com.sports.server.command.member.domain.Member;
import com.sports.server.command.sport.domain.Sport;
Expand Down Expand Up @@ -69,4 +71,19 @@ private League getLeagueAndCheckPermission(final Long leagueId, final Member man

return league;
}

@Transactional
public void updateGame(Long leagueId, Long gameId, GameRequestDto.Update request, Member manager) {
League league = entityUtils.getEntity(leagueId, League.class);
if (!league.isManagedBy(manager)) {
throw new UnauthorizedException(AuthorizationErrorMessages.PERMISSION_DENIED);
}
Game game = entityUtils.getEntity(gameId, Game.class);
game.updateName(request.name());
game.updateStartTime(request.startTime());
game.updateVideoId(request.videoId());
game.updateGameQuarter(request.quarter());
game.updateState(GameState.from(request.state()));
game.updateRound(Round.from(request.round()));
}
}
33 changes: 33 additions & 0 deletions src/main/java/com/sports/server/command/game/domain/Game.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.sports.server.command.game.domain;

import com.sports.server.command.game.dto.GameRequestDto;
import com.sports.server.command.league.domain.League;
import com.sports.server.command.league.domain.Round;
import com.sports.server.command.member.domain.Member;
Expand All @@ -23,6 +24,7 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.util.StringUtils;
import org.springframework.http.HttpStatus;

@Entity
Expand Down Expand Up @@ -114,6 +116,37 @@ public void cancelScore(LineupPlayer scorer) {
scoredTeam.cancelScore();
}

public void updateName(String name) {
if (StringUtils.hasText(name)) {
this.name = name;
}
}

public void updateStartTime(LocalDateTime startTime) {
this.startTime = startTime;
}

public void updateVideoId(String videoId) {
if (StringUtils.hasText(videoId)) {
this.videoId = videoId;
}
}

public void updateGameQuarter(String gameQuarter) {
if (StringUtils.hasText(gameQuarter)) {
this.gameQuarter = gameQuarter;
}
}

public void updateState(GameState state) {
this.state = state;
}

public void updateRound(Round round) {
this.round = round;
}


public Game(Sport sport, Member manager, League league, String name, LocalDateTime startTime,
String videoId, String gameQuarter, GameState state, Round round) {
this.sport = sport;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,14 @@ public Game toEntity(Sport sport, Member manager, League league) {
Round.from(round));
}
}
}

public record Update(
String name,
String round,
String quarter,
String state,
LocalDateTime startTime,
String videoId
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
import java.net.URI;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
Expand Down Expand Up @@ -53,6 +49,15 @@ public ResponseEntity<Void> registerGame(@PathVariable final Long leagueId,
return ResponseEntity.created(URI.create("")).build();
}

@PutMapping("/leagues/{leagueId}/{gameId}")
public ResponseEntity<Void> updateGame(@PathVariable final Long leagueId,
@PathVariable final Long gameId,
@RequestBody final GameRequestDto.Update requestDto,
final Member member) {
gameService.updateGame(leagueId, gameId, requestDto, member);
return ResponseEntity.ok().build();
}

@PatchMapping("/games/{gameId}/{gameTeamId}/lineup-players/{lineupPlayerId}/captain/register")
public ResponseEntity<Void> changePlayerToCaptain(@PathVariable final Long gameId,
@PathVariable final Long lineupPlayerId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public record GameDetailResponse(
String gameName,
String sportName,
List<TeamResponse> gameTeams,
String state
String state,
String round
) {

public GameDetailResponse(Game game, List<GameTeam> gameTeams) {
Expand All @@ -27,7 +28,8 @@ public GameDetailResponse(Game game, List<GameTeam> gameTeams) {
.sorted(Comparator.comparingLong(GameTeam::getId))
.map(TeamResponse::new)
.toList(),
game.getState().name()
game.getState().name(),
game.getRound().name()
);
}

Expand Down
77 changes: 72 additions & 5 deletions src/main/resources/static/docs/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ <h1>훕치치 서버 API 문서</h1>
<li><a href="#_게임_라인업_조회">게임 라인업 조회</a></li>
<li><a href="#_게임_출전_선수_조회">게임 출전 선수 조회</a></li>
<li><a href="#_게임_등록">게임 등록</a></li>
<li><a href="#_게임_수정">게임 수정</a></li>
</ul>
</li>
<li><a href="#_라인업_api">라인업 API</a>
Expand Down Expand Up @@ -765,13 +766,13 @@ <h4 id="_게임_상세_조회_http_response"><a class="link" href="#_게임_상
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 403
Content-Length: 431

{
"startTime" : "2024-01-19T13:00:00",
"videoId" : "videoId",
"gameQuarter" : "전반전",
"gameName" : "4강",
"gameName" : "여름축구",
"sportName" : "축구",
"gameTeams" : [ {
"gameTeamId" : 1,
Expand All @@ -784,7 +785,8 @@ <h4 id="_게임_상세_조회_http_response"><a class="link" href="#_게임_상
"logoImageUrl" : "logo.com",
"score" : 1
} ],
"state" : "PLAYING"
"state" : "PLAYING",
"round" : "4강"
}</code></pre>
</div>
</div>
Expand Down Expand Up @@ -831,9 +833,9 @@ <h4 id="_게임_상세_조회_response_fields"><a class="link" href="#_게임_
<td class="tableblock halign-left valign-top"><p class="tableblock">종목</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>sportName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>round</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">종목</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">게임의 라운드</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gameTeams[].gameTeamId</code></p></td>
Expand Down Expand Up @@ -1644,6 +1646,67 @@ <h4 id="_게임_등록_http_response"><a class="link" href="#_게임_등록_http
</div>
</div>
</div>
<div class="sect2">
<h3 id="_게임_수정"><a class="link" href="#_게임_수정">게임 수정</a></h3>
<div class="sect3">
<h4 id="_게임_수정_http_request"><a class="link" href="#_게임_수정_http_request">HTTP request</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">PUT /leagues/1/1 HTTP/1.1
Content-Type: application/json
Content-Length: 172
Host: www.api.hufstreaming.site
Cookie: HCC_SES=temp-cookie

{
"name" : "게임 이름",
"round" : "16강",
"quarter" : "전반전",
"state" : "PLAYING",
"startTime" : "2024-09-14T01:15:12.238992",
"videoId" : "videoId"
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_게임_수정_path_parameters"><a class="link" href="#_게임_수정_path_parameters">Path parameters</a></h4>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">Table 1. /leagues/{leagueId}/{gameId}</caption>
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Parameter</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>leagueId</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">리그의 ID</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>gameId</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경기의 ID</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_게임_수정_http_response"><a class="link" href="#_게임_수정_http_response">HTTP response</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
Expand Down Expand Up @@ -2865,7 +2928,11 @@ <h4 id="_매니저가_생성한_리그_전체_조회_http_response"><a class="li
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
<<<<<<< HEAD
Content-Length: 629
=======
Content-Length: 633
>>>>>>> 841548f ([DOCS] 문서화 테스트 추가 #215)

[ {
"id" : 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;

import com.sports.server.command.game.domain.GameState;
import com.sports.server.command.game.domain.LineupPlayerState;
import com.sports.server.command.game.dto.CheerCountUpdateRequest;
import com.sports.server.command.game.dto.GameRequestDto;
import com.sports.server.command.league.domain.Round;
import com.sports.server.query.dto.response.GameDetailResponse;
import com.sports.server.query.dto.response.GameTeamCheerResponseDto;
import com.sports.server.query.dto.response.LineupPlayerResponse;
import com.sports.server.support.AcceptanceTest;
Expand Down Expand Up @@ -159,6 +162,52 @@ public class GameAcceptanceTest extends AcceptanceTest {
assertThat(response.statusCode()).isEqualTo(HttpStatus.CREATED.value());
}

@Test
void 경기_정보를_수정한__다시_가져와_확인한다() throws Exception {

// given
Long leagueId = 1L;
Long gameId = 1L;
String name = "경기 이름";
String round = "16강";
String quarter = "후반전";
String state = "PLAYING";
LocalDateTime fixedLocalDateTime = LocalDateTime.of(2024, 9, 11, 12, 0, 0);
String videoId = "videoId";
GameRequestDto.Update request = new GameRequestDto.Update(name, round, quarter, state, fixedLocalDateTime, videoId);

configureMockJwtForEmail(MOCK_EMAIL);

// when
ExtractableResponse<Response> putResponse = RestAssured.given().log().all()
.cookie(COOKIE_NAME, mockToken)
.pathParam("leagueId", leagueId)
.pathParam("gameId", gameId)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(request)
.put("/leagues/{leagueId}/{gameId}")
.then().log().all()
.extract();
ExtractableResponse<Response> getResponse = RestAssured.given().log().all()
.when()
.contentType(MediaType.APPLICATION_JSON_VALUE)
.get("/games/{gameId}", gameId)
.then().log().all()
.extract();

// then
GameDetailResponse updatedGame = toResponse(getResponse, GameDetailResponse.class);
assertAll(
() -> assertThat(putResponse.statusCode()).isEqualTo(HttpStatus.OK.value()),
() -> assertThat(updatedGame.gameQuarter()).isEqualTo(quarter),
() -> assertThat(updatedGame.round()).isEqualTo(Round.from(round).name()),
() -> assertThat(updatedGame.gameName()).isEqualTo(name),
() -> assertThat(updatedGame.startTime()).isEqualTo(fixedLocalDateTime),
() -> assertThat(updatedGame.state()).isEqualTo(state),
() -> assertThat(updatedGame.videoId()).isEqualTo(videoId)
);
}

@Test
void 라인업_선수를_주장으로_등록한다() throws Exception {

Expand Down Expand Up @@ -238,5 +287,4 @@ public class GameAcceptanceTest extends AcceptanceTest {
() -> assertThat(actual.get(0).isCaptain()).isEqualTo(false)
);
}

}
Loading

0 comments on commit 22870d7

Please sign in to comment.