Skip to content

Commit

Permalink
merge: Feature/#156 관리자 권한 설정
Browse files Browse the repository at this point in the history
  • Loading branch information
amaran-th authored Nov 28, 2023
2 parents 342c752 + 5160b41 commit 2968c47
Show file tree
Hide file tree
Showing 34 changed files with 729 additions and 203 deletions.
14 changes: 14 additions & 0 deletions backend/emm-sale/src/documentTest/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,20 @@ include::{snippets}/delete-notifications/http-response.adoc[]

== 관리자 API

=== `POST` : 관리자 로그인

.HTTP request
include::{snippets}/admin-login-snippet/http-request.adoc[]

.HTTP request 설명
include::{snippets}/admin-login-snippet/request-fields.adoc[]

.HTTP response
include::{snippets}/admin-login-snippet/http-response.adoc[]

.HTTP response 설명
include::{snippets}/admin-login-snippet/response-fields.adoc[]

=== `POST` : 행사 생성

.HTTP request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import com.emmsale.activity.application.dto.ActivityAddRequest;
import com.emmsale.activity.application.dto.ActivityResponse;
import com.emmsale.activity.domain.ActivityType;
import com.emmsale.admin.activity.api.AdminActivityApi;
import com.emmsale.member.domain.Member;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand All @@ -27,64 +29,67 @@
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

@WebMvcTest(ActivityApi.class)
@WebMvcTest({ActivityApi.class, AdminActivityApi.class}) // TODO: 2023/11/18 Admin API Test 분리하기
class ActivityApiTest extends MockMvcTestHelper {

@Test
@DisplayName("Activity를 전제 조회할 수 있으면 200 OK를 반환한다.")
void findAll() throws Exception {
// given
final ResponseFieldsSnippet responseFields = PayloadDocumentation.responseFields(
fieldWithPath("[].id").type(JsonFieldType.NUMBER).description("activity id"),
fieldWithPath("[].activityType").type(JsonFieldType.STRING).description("activity 분류"),
fieldWithPath("[].name").type(JsonFieldType.STRING).description("activity 이름")
fieldWithPath("[].id").type(JsonFieldType.NUMBER).description("activity id"),
fieldWithPath("[].activityType").type(JsonFieldType.STRING).description("activity 분류"),
fieldWithPath("[].name").type(JsonFieldType.STRING).description("activity 이름")
);

final List<ActivityResponse> expected = List.of(
new ActivityResponse(1L, "동아리", "YAPP"),
new ActivityResponse(2L, "동아리", "DND"),
new ActivityResponse(3L, "동아리", "nexters"),
new ActivityResponse(4L, "컨퍼런스", "인프콘"),
new ActivityResponse(5L, "교육", "우아한테크코스"),
new ActivityResponse(6L, "직무", "Backend")
new ActivityResponse(1L, "동아리", "YAPP"),
new ActivityResponse(2L, "동아리", "DND"),
new ActivityResponse(3L, "동아리", "nexters"),
new ActivityResponse(4L, "컨퍼런스", "인프콘"),
new ActivityResponse(5L, "교육", "우아한테크코스"),
new ActivityResponse(6L, "직무", "Backend")
);

Mockito.when(activityQueryService.findAll()).thenReturn(expected);

// when & then
mockMvc.perform(MockMvcRequestBuilders.get("/activities"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcRestDocumentation.document("find-all-activities", responseFields));
.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("활동 이름")
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,
ActivityType.CLUB.getValue(),
"DND"
ActivityType.CLUB.getValue(),
"DND"
);
final String accessToken = "Bearer accessToken";

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

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("id").type(JsonFieldType.NUMBER).description("활동 식별자"),
fieldWithPath("activityType").type(JsonFieldType.STRING).description("활동 종류"),
fieldWithPath("name").type(JsonFieldType.STRING).description("활동 이름")
fieldWithPath("id").type(JsonFieldType.NUMBER).description("활동 식별자"),
fieldWithPath("activityType").type(JsonFieldType.STRING).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));
mockMvc.perform(post("/admin/activities")
.header("Authorization", accessToken)
.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
@@ -1,5 +1,6 @@
package com.emmsale;

import static com.emmsale.member.MemberFixture.adminMember;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
Expand All @@ -11,6 +12,7 @@
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.emmsale.admin.event.api.AdminEventApi;
import com.emmsale.event.EventFixture;
import com.emmsale.event.api.EventApi;
import com.emmsale.event.application.dto.EventDetailRequest;
Expand All @@ -19,6 +21,7 @@
import com.emmsale.event.domain.EventMode;
import com.emmsale.event.domain.EventType;
import com.emmsale.event.domain.PaymentType;
import com.emmsale.member.domain.Member;
import com.emmsale.tag.TagFixture;
import com.emmsale.tag.application.dto.TagRequest;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -49,12 +52,15 @@
import org.springframework.restdocs.request.RequestParametersSnippet;
import org.springframework.restdocs.request.RequestPartsSnippet;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;

@WebMvcTest(EventApi.class)
@WebMvcTest({EventApi.class, AdminEventApi.class})
class EventApiTest extends MockMvcTestHelper {

private static final String accessToken = "Bearer accessToken";

private static final ResponseFieldsSnippet EVENT_DETAIL_RESPONSE_FILED = PayloadDocumentation.responseFields(
fieldWithPath("id").type(JsonFieldType.NUMBER).description("event 식별자"),
fieldWithPath("name").type(JsonFieldType.STRING)
Expand Down Expand Up @@ -232,7 +238,8 @@ void updateEventTest() throws Exception {
"image1.jpg", request.getType().toString(),
List.of("imageUrl1", "imageUrl2"), "행사기관", "유료", "온라인");

Mockito.when(eventCommandService.updateEvent(eq(eventId), any(EventDetailRequest.class), any()))
Mockito.when(
eventCommandService.updateEvent(eq(eventId), any(EventDetailRequest.class), any(), any()))
.thenReturn(response);

final String contents = objectMapper.writeValueAsString(request);
Expand All @@ -258,12 +265,13 @@ void updateEventTest() throws Exception {
);

//when
final MockMultipartHttpServletRequestBuilder builder = multipart(HttpMethod.PUT,
"/events/" + eventId)
final MockHttpServletRequestBuilder builder = multipart(HttpMethod.PUT,
"/admin/events/" + eventId)
.file("images", image1.getBytes())
.file("images", image2.getBytes())
.file(new MockMultipartFile("request", "", "application/json", contents.getBytes(
StandardCharsets.UTF_8)));
StandardCharsets.UTF_8)))
.header("Authorization", accessToken);

final ResultActions result = mockMvc.perform(builder);

Expand All @@ -282,10 +290,11 @@ void deleteEventTest() throws Exception {
//given
final long eventId = 1L;

Mockito.doNothing().when(eventCommandService).deleteEvent(eventId);
Mockito.doNothing().when(eventCommandService).deleteEvent(eventId, adminMember());
//when
final ResultActions result = mockMvc.perform(
delete("/events/" + eventId));
delete("/admin/events/" + eventId)
.header("Authorization", accessToken));

//then
result.andExpect(status().isNoContent())
Expand Down Expand Up @@ -334,7 +343,8 @@ void addEventTest() throws Exception {
"image1.jpg", request.getType().toString(),
List.of("imageUrl1", "imageUrl2"), "행사기관", "무료", "오프라인");

Mockito.when(eventCommandService.addEvent(any(EventDetailRequest.class), any()))
Mockito.when(
eventCommandService.addEvent(any(EventDetailRequest.class), any(), any(Member.class)))
.thenReturn(response);

final String contents = objectMapper.writeValueAsString(request);
Expand All @@ -360,13 +370,13 @@ void addEventTest() throws Exception {
);

//when
final MockMultipartHttpServletRequestBuilder builder = multipart("/events")
final MockMultipartHttpServletRequestBuilder builder = multipart("/admin/events")
.file("images", image1.getBytes())
.file("images", image2.getBytes())
.file(new MockMultipartFile("request", "", "application/json", contents.getBytes(
StandardCharsets.UTF_8)));

final ResultActions result = mockMvc.perform(builder);
final ResultActions result = mockMvc.perform(builder.header("Authorization", accessToken));

//then
result.andExpect(status().isCreated())
Expand Down Expand Up @@ -407,11 +417,12 @@ void addEventWithEmptyNameTest(final String eventName) throws Exception {
event.getPaymentType(), event.getOrganization());
final String contents = objectMapper.writeValueAsString(request);
//when & then
mockMvc.perform(multipart("/events")
mockMvc.perform(multipart("/admin/events")
.file("images", image1.getBytes())
.file("images", image2.getBytes())
.file(new MockMultipartFile("request", "", "application/json", contents.getBytes(
StandardCharsets.UTF_8)))
.header("Authorization", accessToken)
)
.andExpect(status().isBadRequest());
}
Expand Down Expand Up @@ -448,11 +459,12 @@ void addEventWithEmptyLocationTest(final String eventLocation) throws Exception
event.getPaymentType(), event.getOrganization());
final String contents = objectMapper.writeValueAsString(request);
//when & then
mockMvc.perform(multipart("/events")
mockMvc.perform(multipart("/admin/events")
.file("images", image1.getBytes())
.file("images", image2.getBytes())
.file(new MockMultipartFile("request", "", "application/json", contents.getBytes(
StandardCharsets.UTF_8)))
.header("Authorization", accessToken)
)
.andExpect(status().isBadRequest());
}
Expand Down Expand Up @@ -490,11 +502,12 @@ void addEventWithInvalidInformationUrlTest(final String informationUrl) throws E
event.getPaymentType(), event.getOrganization());
final String contents = objectMapper.writeValueAsString(request);
//when & then
mockMvc.perform(multipart("/events")
mockMvc.perform(multipart("/admin/events")
.file("images", image1.getBytes())
.file("images", image2.getBytes())
.file(new MockMultipartFile("request", "", "application/json", contents.getBytes(
StandardCharsets.UTF_8)))
.header("Authorization", accessToken)
)
.andExpect(status().isBadRequest());
}
Expand Down Expand Up @@ -538,11 +551,12 @@ void addEventWithUnformattedStartDateTimeTest(final String startDateTime)

final String contents = objectMapper.writeValueAsString(request);
//when & then
mockMvc.perform(multipart("/events")
mockMvc.perform(multipart("/admin/events")
.file("images", image1.getBytes())
.file("images", image2.getBytes())
.file(new MockMultipartFile("request", "", "application/json", contents.getBytes(
StandardCharsets.UTF_8)))
.header("Authorization", accessToken)
)
.andExpect(status().isBadRequest());
}
Expand Down Expand Up @@ -585,11 +599,12 @@ void addEventWithUnformattedEndDateTimeTest(final String endDateTime) throws Exc

final String contents = objectMapper.writeValueAsString(request);
//when & then
mockMvc.perform(multipart("/events")
mockMvc.perform(multipart("/admin/events")
.file("images", image1.getBytes())
.file("images", image2.getBytes())
.file(new MockMultipartFile("request", "", "application/json", contents.getBytes(
StandardCharsets.UTF_8)))
.header("Authorization", accessToken)
)
.andExpect(status().isBadRequest());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
package com.emmsale;

import static org.mockito.ArgumentMatchers.any;
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.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.emmsale.admin.login.api.AdminLoginApi;
import com.emmsale.admin.login.application.dto.AdminLoginRequest;
import com.emmsale.admin.login.application.dto.AdminTokenResponse;
import com.emmsale.login.api.LoginApi;
import com.emmsale.login.application.dto.TokenResponse;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
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;
import org.springframework.restdocs.request.RequestParametersSnippet;
import org.springframework.test.web.servlet.ResultActions;

@WebMvcTest(LoginApi.class)
@WebMvcTest({LoginApi.class, AdminLoginApi.class})
class LoginApiTest extends MockMvcTestHelper {

@Test
Expand Down Expand Up @@ -62,4 +69,35 @@ void illegalLoginTest() throws Exception {
result.andExpect(status().isBadRequest())
.andDo(print());
}

@Test
@DisplayName("id와 password가 유효할 경우 200과 함께 AdminTokenResponse를 반환해 준다.")
void availableAdminLoginTest() throws Exception {
// given
final AdminLoginRequest request = new AdminLoginRequest("관리자 id", "관리자 password");
final AdminTokenResponse adminTokenResponse = new AdminTokenResponse("access_token");

BDDMockito.given(adminLoginService.createAdminToken(any())).willReturn(adminTokenResponse);

final RequestFieldsSnippet requestFields = requestFields(
fieldWithPath("id").type(JsonFieldType.STRING).description("관리자 로그인 id"),
fieldWithPath("password").type(JsonFieldType.STRING).description("관리자 로그인 password")
);

final ResponseFieldsSnippet responseFields = responseFields(
fieldWithPath("accessToken").type(JsonFieldType.STRING).description("관리자 Access Token 값")
);

// when
final ResultActions result = mockMvc.perform(
post("/admin/login")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsString(request))
);

// then
result.andExpect(status().isOk())
.andDo(print())
.andDo(document("admin-login-snippet", requestFields, responseFields));
}
}
Loading

0 comments on commit 2968c47

Please sign in to comment.