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

[FEAT] 신고된 응원톡 가리기/가리기 해제 기능 #238

Merged
merged 19 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
61d3f70
[FEAT] 응원톡 가리기/가리기 해제 기능 구현 #231
Zena0128 Sep 23, 2024
3ae269f
[TEST] 응원톡 가리기/가리기 해제 기능 서비스 테스트 #231
Zena0128 Sep 23, 2024
df66d7d
[DOCS] 응원톡 가리기/가리기 해제 기능 문서화 #231
Zena0128 Sep 23, 2024
ff98d1a
[CHORE] security config에 엔드포인트 등록
Zena0128 Sep 23, 2024
19cb2b5
[REFACTOR] RequestMapping에 공통되는 엔드포인트 추가 #231
Zena0128 Sep 24, 2024
ac2620f
[FIX] 응원톡 가리거나 해제할 때 신고 객체 없어도 가능하도록 수정 #231
Zena0128 Sep 24, 2024
62c714e
[REFACTOR] report 객체 상태 확인하는 코드 삭제 #231
Zena0128 Sep 24, 2024
2aa029a
[FIX] 이미 가려진/가리기 취소된 응원톡에 대해서 예외 발생시키지 않도록 테스트 수정 #231
Zena0128 Sep 24, 2024
24df89e
[FIX] Report 객체에서 누락된 부분 추가 #231
Zena0128 Sep 24, 2024
ecad95f
[DOCS] 피드백 받으며 수정한 부분 문서화 추가 #231
Zena0128 Sep 24, 2024
37b82d4
[MERGE] 메인 브랜치와 병합
Zena0128 Sep 24, 2024
8064ebd
[TEST] 테스트명 변경 #231
Zena0128 Sep 25, 2024
02919e6
[REFACTOR] 중복되는 코드 제거 #231
Zena0128 Sep 25, 2024
240a9a3
[TEST] 추후 반영해야 하는 사항에 todo 추가
Zena0128 Sep 25, 2024
cd00368
[REFACTOR] 역할 명확해지도록 메소드명 변경 #231
Zena0128 Sep 25, 2024
a157c6a
[MERGE] 메인 브랜치와 병합
Zena0128 Sep 25, 2024
2908950
[DOCS] LocalDateTime.now() 대신 고정 시간대 확인하도록 수정
Zena0128 Sep 25, 2024
591ac23
[MERGE] 메인 브랜치와 병합
Zena0128 Sep 26, 2024
e53bfc6
[REFACTOR] PermissionValidator 사용하도록 수정 #231
Zena0128 Sep 26, 2024
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
8 changes: 8 additions & 0 deletions src/docs/asciidoc/api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ operation::cheer-talk-query-controller-test/응원톡을_조회한다[snippets='

operation::cheer-talk-query-controller-test/리그의_신고된_응원톡을_조회한다[snippets='http-request,query-parameters,path-parameters,http-response,response-fields']

=== 신고된 응원톡 가리기

operation::cheer-talk-controller-test/신고된_응원톡을_가린다[snippets='http-request,path-parameters,http-response']

=== 가려진 응원톡을 가리기 취소하기
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved

operation::cheer-talk-controller-test/가려진_응원톡을_가리기_취소한다[snippets='http-request,path-parameters,http-response']

== 게임 API

=== 게임 상세 조회
Expand Down
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,38 @@

import static com.sports.server.command.cheertalk.exception.CheerTalkErrorMessages.CHEER_TALK_CONTAINS_BAD_WORD;

import com.sports.server.auth.exception.AuthorizationErrorMessages;
import com.sports.server.command.cheertalk.domain.CheerTalk;
import com.sports.server.command.cheertalk.domain.CheerTalkRepository;
import com.sports.server.command.cheertalk.domain.LanguageFilter;
import com.sports.server.command.cheertalk.dto.CheerTalkRequest;
import com.sports.server.command.cheertalk.exception.CheerTalkErrorMessages;
import com.sports.server.command.league.domain.League;
import com.sports.server.command.member.domain.Member;
import com.sports.server.command.report.domain.Report;
import com.sports.server.command.report.domain.ReportRepository;
import com.sports.server.command.report.domain.ReportState;
import com.sports.server.command.report.exception.ReportErrorMessage;
import com.sports.server.common.application.EntityUtils;
import com.sports.server.common.exception.CustomException;
import com.sports.server.common.exception.UnauthorizedException;
import com.sports.server.query.repository.CheerTalkDynamicRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.Key;

@Service
@Transactional
@RequiredArgsConstructor
public class CheerTalkService {

private final CheerTalkRepository cheerTalkRepository;
private final ReportRepository reportRepository;
private final LanguageFilter languageFilter;
private final EntityUtils entityUtils;

public void register(final CheerTalkRequest cheerTalkRequest) {
validateContent(cheerTalkRequest.content());
Expand All @@ -31,4 +46,56 @@ private void validateContent(final String content) {
throw new CustomException(HttpStatus.BAD_REQUEST, CHEER_TALK_CONTAINS_BAD_WORD);
}
}

public void block(final Long leagueId, final Long cheerTalkId, final Member manager) {
checkPermission(leagueId, manager);
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved

CheerTalk cheerTalk = entityUtils.getEntity(cheerTalkId, CheerTalk.class);
if (cheerTalk.isBlocked()) {
throw new CustomException(HttpStatus.BAD_REQUEST, CheerTalkErrorMessages.CHEER_TALK_ALREADY_BLOCKED);
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved
}

Report report = checkReportPendingAndGetReport(cheerTalk);
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved
report.updateToValid(); // 해당 cheerTalk도 같이 block

}

public void unblock(final Long leagueId, final Long cheerTalkId, final Member manager) {
checkPermission(leagueId, manager);

CheerTalk cheerTalk = entityUtils.getEntity(cheerTalkId, CheerTalk.class);
if (!cheerTalk.isBlocked()) {
throw new CustomException(HttpStatus.BAD_REQUEST, CheerTalkErrorMessages.CHEER_TALK_ALREADY_UNBLOCKED);
}

Report report = checkReportValidAndGetReport(cheerTalk);
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved
report.updateToInvalid(); // 해당 cheerTalk도 같이 unblock
}

private void checkPermission(final Long leagueId, final Member manager) {

League league = entityUtils.getEntity(leagueId, League.class);

if (!league.isManagedBy(manager)) {
throw new UnauthorizedException(AuthorizationErrorMessages.PERMISSION_DENIED);
}
}

private Report checkReportPendingAndGetReport(CheerTalk cheerTalk) {
Report report = reportRepository.findByCheerTalk(cheerTalk)
.orElseThrow(() -> new CustomException(HttpStatus.NOT_FOUND, ReportErrorMessage.REPORT_NOT_EXIST));
if (!report.getState().equals(ReportState.PENDING)) {
throw new CustomException(HttpStatus.BAD_REQUEST, ReportErrorMessage.REPORT_NOT_PENDING);
}
return report;
}

private Report checkReportValidAndGetReport(CheerTalk cheerTalk) {
Report report = reportRepository.findByCheerTalk(cheerTalk)
.orElseThrow(() -> new CustomException(HttpStatus.NOT_FOUND, ReportErrorMessage.REPORT_NOT_EXIST));
if (!report.getState().equals(ReportState.VALID)) {
throw new CustomException(HttpStatus.BAD_REQUEST, ReportErrorMessage.REPORT_NOT_VALID);
}
return report;
}
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ public void block() {
this.isBlocked = true;
}

public void unblock() {
this.isBlocked = false;
}

public CheerTalk(final String content, final Long gameTeamId) {
this.createdAt = LocalDateTime.now();
this.content = content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

public class CheerTalkErrorMessages {
public static final String CHEER_TALK_CONTAINS_BAD_WORD = "댓글에 욕설이 포함되어 있어 저장할 수 없습니다.";
public static final String CHEER_TALK_ALREADY_BLOCKED = "이미 가려진 채팅입니다.";
public static final String CHEER_TALK_ALREADY_UNBLOCKED = "이미 신고 취소된 채팅입니다.";
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.sports.server.command.cheertalk.application.CheerTalkService;
import com.sports.server.command.cheertalk.dto.CheerTalkRequest;
import com.sports.server.command.member.domain.Member;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -18,4 +19,20 @@ public ResponseEntity<Void> register(@RequestBody @Valid final CheerTalkRequest
cheerTalkService.register(cheerTalkRequest);
return ResponseEntity.ok(null);
}

@PatchMapping("/cheer-talks/{leagueId}/{cheerTalkId}/block")
Zena0128 marked this conversation as resolved.
Show resolved Hide resolved
public ResponseEntity<Void> block(@PathVariable Long leagueId,
@PathVariable Long cheerTalkId,
final Member manager) {
cheerTalkService.block(leagueId, cheerTalkId, manager);
return ResponseEntity.ok().build();
}

@PatchMapping("/cheer-talks/{leagueId}/{cheerTalkId}/unblock")
public ResponseEntity<Void> unblock(@PathVariable Long leagueId,
@PathVariable Long cheerTalkId,
final Member manager) {
cheerTalkService.unblock(leagueId, cheerTalkId, manager);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ public void updateToValid() {
cheerTalk.block();
}

public void updateToInvalid() {
this.state = ReportState.INVALID;
cheerTalk.unblock();
Jin409 marked this conversation as resolved.
Show resolved Hide resolved
}

public void updateToPending() {
this.state = ReportState.PENDING;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ public class ReportErrorMessage {

public static final String INVALID_REPORT_BLOCKED_CHEER_TALK = "이미 블락된 응원톡은 신고할 수 없습니다.";
public static final String REPORT_CHECK_SERVER_ERROR = "신고 검사 서버에 문제가 발생했습니다";
public static final String REPORT_NOT_EXIST = "해당 응원톡에 대한 신고가 존재하지 않습니다.";
public static final String REPORT_NOT_PENDING = "대기 상태가 아닌 신고는 유효 처리할 수 없습니다.";
public static final String REPORT_NOT_VALID = "유효하지 않은 신고는 무효 처리할 수 없습니다.";
}
Loading
Loading