Skip to content

Commit

Permalink
러너 게시글 생성 API 수정 (#348)
Browse files Browse the repository at this point in the history
* refactor: RunnerPostService create 로직 변경

* test: 게시글 생성  인수테스트 작성

* test: restdos 테스트 추가

* docs: restdocs 파일 포맷팅

* test: HttpHeaders 를 spring 패키지를 import 를 받도록 변경

* refactor: FutureValidator 에서 null 인 localdatetime을 체크 안하도록 변경

* refactor: 없던 중괄호 추가
  • Loading branch information
cookienc authored Aug 15, 2023
1 parent 97a39a5 commit 8f32337
Show file tree
Hide file tree
Showing 11 changed files with 366 additions and 115 deletions.
27 changes: 27 additions & 0 deletions backend/baton/src/docs/asciidoc/RunnerPostCreateApi.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
ifndef::snippets[]
:snippets: ../../../build/generated-snippets
endif::[]
:doctype: book
:icons: font
:source-highlighter: highlight.js
:toc: left
:toclevels: 3
:sectlinks:
:operation-http-request-title: Example Request
:operation-http-response-title: Example Response

=== *러너 게시글 생성*

==== *러너 게시글 생성 API*

===== *Http Request*

include::{snippets}/../../build/generated-snippets/runner-post-create-api-test/create-runner-post/http-request.adoc[]

===== *Http Request Header*

include::{snippets}/../../build/generated-snippets/runner-post-create-api-test/create-runner-post/request-headers.adoc[]

===== *Http Response Header*

include::{snippets}/../../build/generated-snippets/runner-post-create-api-test/create-runner-post/response-headers.adoc[]
2 changes: 2 additions & 0 deletions backend/baton/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ include::RunnerPostDeleteApi.adoc[]
include::RunnerProfileReadApi.adoc[]
include::RunnerLoginProfileReadApi.adoc[]
include::RunnerProfileUpdateApi.adoc[]
include::RunnerPostCreateApi.adoc[]

== *[ 서포터 ]*

include::SupporterProfileReadApi.adoc[]

include::SupporterProfileUpdateApi.adoc[]
include::RunnerPostUpdateApi.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import touch.baton.domain.common.exception.ClientRequestException;

import java.time.LocalDateTime;
import java.util.Objects;

public class FutureValidator implements ConstraintValidator<ValidFuture, LocalDateTime> {

Expand All @@ -18,7 +19,7 @@ public void initialize(final ValidFuture constraintAnnotation) {

@Override
public boolean isValid(final LocalDateTime value, final ConstraintValidatorContext context) {
if (value.isBefore(LocalDateTime.now())) {
if (Objects.nonNull(value) && value.isBefore(LocalDateTime.now())) {
throw new ClientRequestException(errorCode);
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import touch.baton.domain.common.exception.ClientErrorCode;
import touch.baton.domain.common.exception.ClientRequestException;

import java.util.Objects;

public class MaxLengthValidator implements ConstraintValidator<ValidMaxLength, String> {

private ClientErrorCode errorCode;
Expand All @@ -18,7 +20,7 @@ public void initialize(final ValidMaxLength constraintAnnotation) {

@Override
public boolean isValid(final String value, final ConstraintValidatorContext context) {
if (value.length() > max) {
if (Objects.nonNull(value) && value.length() > max) {
throw new ClientRequestException(errorCode);
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,35 @@ public Long createRunnerPost(final Runner runner, final RunnerPostCreateRequest
final RunnerPost runnerPost = toDomain(runner, request);
runnerPostRepository.save(runnerPost);

List<Tag> toSaveTags = new ArrayList<>();
for (final String tagName : request.tags()) {
final Optional<Tag> maybeTag = tagRepository.findByTagName(new TagName(tagName));
final List<Tag> tags = findTagsAfterSave(request.tags());

if (maybeTag.isEmpty()) {
final Tag savedTag = tagRepository.save(Tag.newInstance(tagName));
toSaveTags.add(savedTag);
continue;
}

final Tag presentTag = maybeTag.get();
toSaveTags.add(presentTag);
}

final List<RunnerPostTag> postTags = toSaveTags.stream()
final List<RunnerPostTag> runnerPostTags = tags.stream()
.map(tag -> RunnerPostTag.builder()
.tag(tag)
.runnerPost(runnerPost).build())
.toList();

runnerPost.addAllRunnerPostTags(postTags);
runnerPost.addAllRunnerPostTags(runnerPostTags);
return runnerPost.getId();
}

private List<Tag> findTagsAfterSave(final List<String> tagNames) {
final List<Tag> tags = new ArrayList<>();
for (String tagName : tagNames) {
tagRepository.findByTagName(new TagName(tagName))
.ifPresentOrElse(tags::add, addTagAfterSave(tags, tagName));
}

return tags;
}

private Runnable addTagAfterSave(final List<Tag> tags, final String tagName) {
return () -> {
final Tag savedTag = tagRepository.save(Tag.newInstance(tagName));
tags.add(savedTag);
};
}

private RunnerPost toDomain(final Runner runner, final RunnerPostCreateRequest request) {
return RunnerPost.newInstance(request.title(),
request.contents(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,22 @@ public static ExtractableResponse<Response> post(final String uri,
.extract();
}

public static ExtractableResponse<Response> get(final String uri, final String accessToken) {
public static ExtractableResponse<Response> post(final String uri, final Object params, final String accessToken) {
return RestAssured
.given().log().ifValidationFails()
.auth().preemptive().oauth2(accessToken)
.contentType(APPLICATION_JSON_VALUE)
.body(params)
.when().log().ifValidationFails()
.get(uri)
.post(uri)
.then().log().ifError()
.extract();
}

public static ExtractableResponse<Response> get(final String uri, final String pathParamName, final Long id) {
public static ExtractableResponse<Response> get(final String uri, final String accessToken) {
return RestAssured
.given().log().ifValidationFails()
.pathParam(pathParamName, id)
.auth().preemptive().oauth2(accessToken)
.when().log().ifValidationFails()
.get(uri)
.then().log().ifError()
Expand All @@ -85,6 +87,15 @@ public static ExtractableResponse<Response> get(final String uri,
.extract();
}

public static ExtractableResponse<Response> get(final String uri, final String pathParamName, final Long id) {
return RestAssured
.given().log().ifValidationFails()
.pathParam(pathParamName, id)
.when().log().ifValidationFails()
.get(uri)
.then().log().ifError()
.extract();
}

public static ExtractableResponse<Response> get(final String uri, final Map<String, Object> queryParams) {
return RestAssured
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,22 @@
import org.springframework.http.HttpStatus;
import touch.baton.assure.common.AssuredSupport;
import touch.baton.assure.common.HttpStatusAndLocationHeader;
import touch.baton.domain.common.response.ErrorResponse;
import touch.baton.domain.common.response.PageResponse;
import touch.baton.domain.runner.Runner;
import touch.baton.domain.runner.controller.response.RunnerResponse;
import touch.baton.domain.runnerpost.controller.response.RunnerPostResponse;
import touch.baton.domain.runnerpost.service.dto.RunnerPostCreateRequest;
import touch.baton.domain.runnerpost.service.dto.RunnerPostUpdateRequest;
import touch.baton.domain.runnerpost.vo.ReviewStatus;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static org.apache.http.HttpHeaders.LOCATION;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.SoftAssertions.assertSoftly;
import static org.springframework.http.HttpHeaders.LOCATION;

@SuppressWarnings("NonAsciiCharacters")
public class RunnerPostAssuredSupport {
Expand Down Expand Up @@ -81,6 +83,11 @@ public static class RunnerPostClientRequestBuilder {
return this;
}

public RunnerPostClientRequestBuilder 러너_게시글_등록_요청한다(final RunnerPostCreateRequest 게시글_생성_요청) {
response = AssuredSupport.post("/api/v1/posts/runner", 게시글_생성_요청, accessToken);
return this;
}

public RunnerPostClientRequestBuilder 러너_게시글_식별자값으로_러너_게시글을_조회한다(final Long 러너_게시글_식별자값) {
response = AssuredSupport.get("/api/v1/posts/runner/{runnerPostId}", "runnerPostId", 러너_게시글_식별자값, accessToken);
return this;
Expand Down Expand Up @@ -201,5 +208,22 @@ public RunnerPostServerResponseBuilder(final ExtractableResponse<Response> respo
}
);
}

public void 러너_게시글_등록_성공을_검증한다(final HttpStatusAndLocationHeader 게시글_등록_성공_응답) {
assertSoftly(softly -> {
softly.assertThat(response.statusCode()).isEqualTo(게시글_등록_성공_응답.getHttpStatus().value());
softly.assertThat(response.header(LOCATION)).contains(게시글_등록_성공_응답.getLocation());
}
);
}

public void 러너_게시글_등록_실패를_검증한다(final ErrorResponse 예상_에러_응답) {
final ErrorResponse 실제_에러_응답 = response.as(ErrorResponse.class);

assertSoftly(softly -> {
softly.assertThat(실제_에러_응답.errorCode()).isEqualTo(예상_에러_응답.errorCode());
softly.assertThat(실제_에러_응답.message()).isEqualTo(예상_에러_응답.message());
});
}
}
}
Loading

0 comments on commit 8f32337

Please sign in to comment.