Skip to content

Commit

Permalink
merge: Feature/#145 태그 활동 생성 api 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
amaran-th authored Sep 7, 2023
2 parents c3f70c4 + a82e822 commit 3ecc907
Show file tree
Hide file tree
Showing 26 changed files with 448 additions and 14 deletions.
30 changes: 29 additions & 1 deletion backend/emm-sale/src/documentTest/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ include::{snippets}/find-all-activities/http-response.adoc[]
.HTTP response 설명
include::{snippets}/find-all-activities/response-fields.adoc[]

=== `POST`: 새로운 Activity 추가

.HTTP request
include::{snippets}/add-activity/http-request.adoc[]

.HTTP request 설명
include::{snippets}/add-activity/request-fields.adoc[]

.HTTP response
include::{snippets}/add-activity/http-response.adoc[]

.HTTP response 설명
include::{snippets}/add-activity/response-fields.adoc[]

== Member

=== `POST`: 초기 사용자 등록
Expand Down Expand Up @@ -287,7 +301,7 @@ include::{snippets}/update-event/http-response.adoc[]
.HTTP response 설명
include::{snippets}/update-event/response-fields.adoc[]

=== `PUT` : 행사 삭제
=== `DELETE` : 행사 삭제

.HTTP request
include::{snippets}/delete-event/http-request.adoc[]
Expand Down Expand Up @@ -551,6 +565,20 @@ include::{snippets}/find-tags/http-response.adoc[]
.HTTP response 설명
include::{snippets}/find-tags/response-fields.adoc[]

=== `POST` : 새로운 태그 추가

.HTTP request
include::{snippets}/add-tag/http-request.adoc[]

.HTTP request 설명
include::{snippets}/add-tag/request-fields.adoc[]

.HTTP response
include::{snippets}/add-tag/http-response.adoc[]

.HTTP response 설명
include::{snippets}/add-tag/response-fields.adoc[]

== Report

=== `POST` : 특정 사용자의 게시물 신고
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
package com.emmsale;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.emmsale.activity.api.ActivityApi;
import com.emmsale.activity.application.dto.ActivityAddRequest;
import com.emmsale.activity.application.dto.ActivityResponse;
import com.emmsale.activity.application.dto.ActivityResponses;
import com.emmsale.activity.domain.ActivityType;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.restdocs.payload.PayloadDocumentation;
import org.springframework.restdocs.payload.RequestFieldsSnippet;
import org.springframework.restdocs.payload.ResponseFieldsSnippet;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
Expand Down Expand Up @@ -52,12 +65,39 @@ void findAll() throws Exception {
))
);

Mockito.when(activityService.findAll()).thenReturn(activityResponses);
Mockito.when(activityQueryService.findAll()).thenReturn(activityResponses);

// when & then

mockMvc.perform(MockMvcRequestBuilders.get("/activities"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("find-all-activities", responseFields));
}

@Test
@DisplayName("새로운 활동을 생성할 수 있다.")
void addTag() throws Exception {
//given
final RequestFieldsSnippet requestFields = requestFields(
fieldWithPath("activityType").type(JsonFieldType.STRING).description("활동 유형"),
fieldWithPath("name").type(JsonFieldType.STRING).description("활동 이름")
);

final ActivityAddRequest request = new ActivityAddRequest(ActivityType.CLUB, "DND");
final ActivityResponse response = new ActivityResponse(3L, "DND");

when(activityCommandService.addActivity(any(ActivityAddRequest.class))).thenReturn(response);

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("id").type(JsonFieldType.NUMBER).description("활동 식별자"),
fieldWithPath("name").type(JsonFieldType.STRING).description("활동 이름")
);

//when & then
mockMvc.perform(post("/activities")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andDo(document("add-activity", requestFields, responseFields));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;

import com.emmsale.activity.application.ActivityService;
import com.emmsale.activity.application.ActivityCommandService;
import com.emmsale.activity.application.ActivityQueryService;
import com.emmsale.block.application.BlockCommandService;
import com.emmsale.block.application.BlockQueryService;
import com.emmsale.comment.application.CommentCommandService;
Expand All @@ -26,6 +27,7 @@
import com.emmsale.resolver.MemberArgumentResolver;
import com.emmsale.scrap.application.ScrapCommandService;
import com.emmsale.scrap.application.ScrapQueryService;
import com.emmsale.tag.application.TagCommandService;
import com.emmsale.tag.application.TagQueryService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -53,6 +55,8 @@ abstract class MockMvcTestHelper {
@MockBean
protected TagQueryService tagQueryService;
@MockBean
protected TagCommandService tagCommandService;
@MockBean
protected ScrapQueryService scrapQueryService;
@MockBean
protected ScrapCommandService scrapCommandService;
Expand Down Expand Up @@ -91,7 +95,9 @@ abstract class MockMvcTestHelper {
@MockBean
protected BlockQueryService blockQueryService;
@MockBean
protected ActivityService activityService;
protected ActivityQueryService activityQueryService;
@MockBean
protected ActivityCommandService activityCommandService;
@MockBean
protected RecruitmentPostQueryService postQueryService;
@MockBean
Expand Down
31 changes: 31 additions & 0 deletions backend/emm-sale/src/documentTest/java/com/emmsale/TagApiTest.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
package com.emmsale;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.emmsale.tag.api.TagApi;
import com.emmsale.tag.application.dto.TagRequest;
import com.emmsale.tag.application.dto.TagResponse;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.restdocs.payload.RequestFieldsSnippet;
import org.springframework.restdocs.payload.ResponseFieldsSnippet;

@WebMvcTest(TagApi.class)
Expand Down Expand Up @@ -41,4 +47,29 @@ void findAll() throws Exception {
.andExpect(status().isOk())
.andDo(document("find-tags", responseFields));
}

@Test
@DisplayName("새로운 태그를 생성할 수 있다.")
void addTag() throws Exception {
//given
final RequestFieldsSnippet requestFields = requestFields(
fieldWithPath("name").type(JsonFieldType.STRING).description("태그 이름")
);
final TagRequest request = new TagRequest("프론트");
final TagResponse response = new TagResponse(3L, "프론트");

when(tagCommandService.addTag(any(TagRequest.class))).thenReturn(response);

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("id").type(JsonFieldType.NUMBER).description("태그 식별자"),
fieldWithPath("name").type(JsonFieldType.STRING).description("태그 이름")
);

//when & then
mockMvc.perform(post("/tags")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andDo(document("add-tag", requestFields, responseFields));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.emmsale.activity.api;

import com.emmsale.activity.application.ActivityService;
import com.emmsale.activity.application.ActivityCommandService;
import com.emmsale.activity.application.ActivityQueryService;
import com.emmsale.activity.application.dto.ActivityAddRequest;
import com.emmsale.activity.application.dto.ActivityResponse;
import com.emmsale.activity.application.dto.ActivityResponses;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
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;

Expand All @@ -14,11 +20,19 @@
@RequiredArgsConstructor
public class ActivityApi {

private final ActivityService activityService;
private final ActivityQueryService activityQueryService;
private final ActivityCommandService activityCommandService;

@GetMapping
public ResponseEntity<List<ActivityResponses>> findAll() {
return ResponseEntity.ok(activityService.findAll());
return ResponseEntity.ok(activityQueryService.findAll());
}

@PostMapping
public ResponseEntity<ActivityResponse> create(
@RequestBody final ActivityAddRequest request) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(activityCommandService.addActivity(request));
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.emmsale.activity.application;

import com.emmsale.activity.application.dto.ActivityAddRequest;
import com.emmsale.activity.application.dto.ActivityResponse;
import com.emmsale.activity.domain.Activity;
import com.emmsale.activity.domain.ActivityRepository;
import com.emmsale.activity.exception.ActivityException;
import com.emmsale.activity.exception.ActivityExceptionType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class ActivityCommandService {

private final ActivityRepository activityRepository;

public ActivityResponse addActivity(final ActivityAddRequest request) {
final String name = request.getName();
validateAlreadyExist(name);
final Activity activity = new Activity(request.getActivityType(), name);
return ActivityResponse.from(activityRepository.save(activity));
}

private void validateAlreadyExist(final String name) {
if (activityRepository.existsActivityByName(name)) {
throw new ActivityException(ActivityExceptionType.ALEADY_EXIST_ACTIVITY);
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ActivityService {
public class ActivityQueryService {

private final ActivityRepository activityRepository;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.emmsale.activity.application.dto;

import com.emmsale.activity.domain.ActivityType;
import lombok.Getter;

@Getter
public class ActivityAddRequest {

private final ActivityType activityType;
private final String name;

public ActivityAddRequest(final ActivityType activityType, final String name) {
this.activityType = activityType;
this.name = name;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.emmsale.activity.application.dto;

import com.emmsale.activity.domain.Activity;
import lombok.Getter;

@Getter
Expand All @@ -12,4 +13,8 @@ public ActivityResponse(final Long id, final String name) {
this.id = id;
this.name = name;
}

public static ActivityResponse from(final Activity activity) {
return new ActivityResponse(activity.getId(), activity.getName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ public class Activity {

@Column(nullable = false)
private String name;

public Activity(final ActivityType activityType, final String name) {
this.activityType = activityType;
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

public interface ActivityRepository extends JpaRepository<Activity, Long> {

boolean existsActivityByName(String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.emmsale.activity.exception;

import com.emmsale.base.BaseException;
import com.emmsale.base.BaseExceptionType;

public class ActivityException extends BaseException {

private final ActivityExceptionType exceptionType;

public ActivityException(final ActivityExceptionType exceptionType) {
super(exceptionType.errorMessage());
this.exceptionType = exceptionType;
}

@Override
public BaseExceptionType exceptionType() {
return exceptionType;
}
}
Loading

0 comments on commit 3ecc907

Please sign in to comment.