Skip to content

Commit

Permalink
Merge pull request #190 from hufscheer/feat/#189-league-delete
Browse files Browse the repository at this point in the history
[FEAT] 리그 삭제
  • Loading branch information
Jin409 authored Aug 16, 2024
2 parents de92c7d + 675790f commit b83c01f
Show file tree
Hide file tree
Showing 11 changed files with 363 additions and 168 deletions.
4 changes: 4 additions & 0 deletions src/docs/asciidoc/api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ operation::league-team-controller-test/리그팀을_삭제한다[snippets='http-

operation::league-query-controller-test/리그를_하나_조회한다[snippets='http-request,path-parameters,http-response,response-fields']

=== 리그 삭제

operation::league-controller-test/리그를_삭제한다[snippets='http-request,path-parameters,http-response']

=== 리그팀 상세 조회

operation::league-query-controller-test/리그팀을_상세_조회한다[snippets='http-request,path-parameters,http-response,response-fields']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc
.requestMatchers(mvc.pattern("/manager/**"),
mvc.pattern(HttpMethod.GET, "/members/info"),
mvc.pattern(HttpMethod.POST, "/leagues"),
mvc.pattern(HttpMethod.DELETE, "/leagues/{leagueId}"),
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
@@ -1,25 +1,34 @@
package com.sports.server.command.league.application;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sports.server.auth.exception.AuthorizationErrorMessages;
import com.sports.server.command.league.domain.League;
import com.sports.server.command.league.domain.LeagueRepository;
import com.sports.server.command.league.dto.LeagueRequestDto;
import com.sports.server.command.member.domain.Member;
import com.sports.server.command.organization.domain.Organization;
import com.sports.server.common.application.EntityUtils;

import com.sports.server.common.exception.UnauthorizedException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RequiredArgsConstructor
public class LeagueService {
private final EntityUtils entityUtils;
private final LeagueRepository leagueRepository;
private final EntityUtils entityUtils;
private final LeagueRepository leagueRepository;

public void register(final Member manager, final LeagueRequestDto.Register request) {
Organization organization = entityUtils.getEntity(request.organizationId(), Organization.class);
leagueRepository.save(request.toEntity(manager, organization));
}

public void register(final Member manager, final LeagueRequestDto.Register request) {
Organization organization = entityUtils.getEntity(request.organizationId(), Organization.class);
leagueRepository.save(request.toEntity(manager, organization));
}
public void delete(final Member manager, final Long leagueId) {
League league = entityUtils.getEntity(leagueId, League.class);
if (!league.isManagedBy(manager)) {
throw new UnauthorizedException(AuthorizationErrorMessages.PERMISSION_DENIED);
}
leagueRepository.delete(league);
}
}
50 changes: 30 additions & 20 deletions src/main/java/com/sports/server/command/league/domain/League.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

@Entity
@Table(name = "leagues")
@Where(clause = "is_deleted = 0")
@SQLDelete(sql = "UPDATE leagues SET is_deleted = 1 WHERE id = ?")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class League extends BaseEntity<League> {
Expand Down Expand Up @@ -48,25 +50,33 @@ public class League extends BaseEntity<League> {
@Column(name = "is_deleted", nullable = false)
private boolean isDeleted;

public League(
final Member manager,
final Organization organization,
final String name,
final LocalDateTime startAt,
final LocalDateTime endAt,
final Round maxRound
) {
this.manager = manager;
this.organization = organization;
this.name = name;
this.startAt = startAt;
this.endAt = endAt;
this.maxRound = maxRound;
this.inProgressRound = maxRound;
this.isDeleted = false;
}
public League(
final Member manager,
final Organization organization,
final String name,
final LocalDateTime startAt,
final LocalDateTime endAt,
final Round maxRound
) {
this.manager = manager;
this.organization = organization;
this.name = name;
this.startAt = startAt;
this.endAt = endAt;
this.maxRound = maxRound;
this.inProgressRound = maxRound;
this.isDeleted = false;
}

public boolean isManagedBy(Member manager) {
return this.manager.equals(manager);
}
public boolean isManagedBy(Member manager) {
return this.manager.equals(manager);
}

public void delete() {
this.isDeleted = true;
}

public String manager() {
return manager.getEmail();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
import org.springframework.data.repository.Repository;

public interface LeagueRepository extends Repository<League, Integer> {
void save(League league);
void save(League league);

void delete(League league);
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
package com.sports.server.command.league.presentation;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.sports.server.command.league.application.LeagueService;
import com.sports.server.command.league.dto.LeagueRequestDto;
import com.sports.server.command.member.domain.Member;

import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/leagues")
public class LeagueController {
private final LeagueService leagueService;
private final LeagueService leagueService;

@PostMapping
public ResponseEntity<Void> register(@RequestBody final LeagueRequestDto.Register register, Member member) {
leagueService.register(member, register);
return ResponseEntity.ok().build();
}

@PostMapping("/leagues")
public ResponseEntity<Void> register(@RequestBody final LeagueRequestDto.Register register, Member member) {
leagueService.register(member, register);
return ResponseEntity.ok().build();
}
@DeleteMapping("/{leagueId}")
public ResponseEntity<Void> delete(final Member member, @PathVariable final Long leagueId) {
leagueService.delete(member, leagueId);
return ResponseEntity.ok().build();
}
}
63 changes: 53 additions & 10 deletions src/main/resources/static/docs/api.html
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,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 @@ -1585,16 +1586,16 @@ <h4 id="_리그_생성_http_request"><a class="link" href="#_리그_생성_http_
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">POST /leagues HTTP/1.1
Content-Type: application/json
Content-Length: 178
Content-Length: 179
Host: www.api.hufstreaming.site
Cookie: HCC_SES=temp-cookie

{
"organizationId" : 1,
"name" : "우물정 제기차기 대회",
"maxRound" : "4강",
"startAt" : "2024-08-08T16:15:24.740259",
"endAt" : "2024-08-08T16:15:24.74027"
"startAt" : "2024-08-08T00:01:18.197184",
"endAt" : "2024-08-08T00:01:18.197192"
}</code></pre>
</div>
</div>
Expand Down Expand Up @@ -1912,11 +1913,6 @@ <h4 id="_리그에_해당하는_리그팀_전체_조회_response_fields"><a clas
<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">리그의 팀 로고 이미지 URL®</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>[].sizeOfLeagueTeamPlayers</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Number</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">리그팀 선수의 인원수</p></td>
</tr>
</tbody>
</table>
</div>
Expand Down Expand Up @@ -2306,6 +2302,53 @@ <h4 id="_리그_상세_조회_response_fields"><a class="link" href="#_리그_
</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">DELETE /leagues/1 HTTP/1.1
Content-Type: application/json
Host: www.api.hufstreaming.site
Cookie: HCC_SES=temp-cookie</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}</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>
</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 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>
Expand Down Expand Up @@ -2930,7 +2973,7 @@ <h4 id="_사용자_로그인_http_response"><a class="link" href="#_사용자_
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Set-Cookie: HCC_SES=testAccessToken; Path=/; Max-Age=604800; Expires=Thu, 15 Aug 2024 07:15:21 GMT; Secure; HttpOnly; SameSite=Strict</code></pre>
Set-Cookie: HCC_SES=testAccessToken; Path=/; Max-Age=604800; Expires=Fri, 9 Aug 2024 06:22:34 GMT; Secure; HttpOnly; SameSite=Strict</code></pre>
</div>
</div>
</div>
Expand Down Expand Up @@ -3004,7 +3047,7 @@ <h4 id="_사용자_정보_조회_response_fields"><a class="link" href="#_사용
<div id="footer">
<div id="footer-text">
Version 0.0.1-SNAPSHOT<br>
Last updated 2024-08-08 16:14:48 +0900
Last updated 2024-08-03 14:57:29 +0900
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js"></script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,58 @@
package com.sports.server.command.league.acceptance;

import static org.assertj.core.api.Assertions.*;

import java.time.LocalDateTime;

import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import com.sports.server.command.league.dto.LeagueRequestDto;
import com.sports.server.support.AcceptanceTest;

import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import java.time.LocalDateTime;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.jdbc.Sql;

@Sql("/league-fixture.sql")
public class LeagueAcceptanceTest extends AcceptanceTest {
@Test
void 대회를_저장한다() throws Exception {
// given
LeagueRequestDto.Register request = new LeagueRequestDto.Register(1L, "우물정 제기차기 대회", "4강", LocalDateTime.now(),
LocalDateTime.now());

configureMockJwtForEmail("[email protected]");

// when
ExtractableResponse<Response> response = RestAssured.given().log().all()
.cookie(COOKIE_NAME, mockToken)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(request)
.post("/leagues")
.then().log().all()
.extract();

// then
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value());
}
@Test
void 대회를_저장한다() {
// given
LeagueRequestDto.Register request = new LeagueRequestDto.Register(1L, "우물정 제기차기 대회", "4강", LocalDateTime.now(),
LocalDateTime.now());

configureMockJwtForEmail("[email protected]");

// when
ExtractableResponse<Response> response = RestAssured.given().log().all()
.cookie(COOKIE_NAME, mockToken)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.body(request)
.post("/leagues")
.then().log().all()
.extract();

// then
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value());
}

@Test
void 리그를_삭제한다() {
// given
Long leagueId = 1L;

configureMockJwtForEmail("[email protected]");

// when
ExtractableResponse<Response> response = RestAssured.given().log().all()
.cookie(COOKIE_NAME, mockToken)
.pathParam("leagueId", leagueId)
.contentType(MediaType.APPLICATION_JSON_VALUE)
.delete("/leagues/{leagueId}")
.then().log().all()
.extract();

// then
assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value());
}
}
Loading

0 comments on commit b83c01f

Please sign in to comment.