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

✅ test: Add ItemController Test #63

Merged
merged 4 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import com.depromeet.streetdrop.domains.common.annotation.IsLongitude;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.validation.annotation.Validated;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Validated
public class ItemLocationRequestDto {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class MusicRequestDto {
@Schema(description = "노래제목", example = "하입보이")
@NotNull(message = "Title is required")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
package com.depromeet.streetdrop.unit.apis.item.controller;

import com.depromeet.streetdrop.apis.item.controller.ItemController;
import com.depromeet.streetdrop.domains.item.dto.request.ItemLocationRequestDto;
import com.depromeet.streetdrop.domains.item.dto.request.ItemRequestDto;
import com.depromeet.streetdrop.domains.item.dto.request.NearItemRequestDto;
import com.depromeet.streetdrop.domains.item.dto.response.ItemLocationResponseDto;
import com.depromeet.streetdrop.domains.item.dto.response.ItemResponseDto;
import com.depromeet.streetdrop.domains.item.dto.response.ItemsResponseDto;
import com.depromeet.streetdrop.domains.item.dto.response.PoiResponseDto;
import com.depromeet.streetdrop.domains.item.service.ItemService;
import com.depromeet.streetdrop.domains.music.dto.request.MusicRequestDto;
import com.depromeet.streetdrop.domains.music.dto.response.MusicResponseDto;
import com.depromeet.streetdrop.domains.user.dto.response.UserResponseDto;
import com.depromeet.streetdrop.domains.user.entity.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

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

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
Expand All @@ -36,9 +45,184 @@ public class ItemControllerTest {
@Autowired
MockMvc mvc;

@Autowired
private ObjectMapper objectMapper;

@MockBean
ItemService itemService;

@DisplayName("[POST] 아이템 드랍 저장")
@Nested
class CreateItemDropTest {
@Mock
private User mockUser;

@Nested
@DisplayName("성공")
class Success {
@DisplayName("아이템 드랍 성공")
@Test
void createItem_ValidRequest_ReturnsCreated() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto("Love Dive", "IVE", "1st EP IVE", "https://www.youtube.com/watch?v=YGieI3KoeZk", List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(37.123456, 127.123456, "서울시 성수동 성수 1가");
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));
response.andExpect(status().isCreated());
}
}

@Nested
@DisplayName("아이템 드랍 실패")
class Fail {
@DisplayName("음악 유효성 검사 실패 - 음악 제목이 없는 경우")
@Test
void createItem_InvalidMusicTitle_ReturnsBadRequest() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto(null, "IVE", "1st EP IVE", "https://www.youtube.com/watch?v=YGieI3KoeZk", List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(37.123456, 127.123456, "서울시 성수동 성수 1가");
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));

response.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("Title is required"));
}

@DisplayName("음악 유효성 검사 실패 - 아티스트가 없는 경우")
@Test
void createItem_InvalidMusicArtist_ReturnsBadRequest() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto("Love Dive", null, "1st EP IVE", "https://www.youtube.com/watch?v=YGieI3KoeZk", List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(37.123456, 127.123456, "서울시 성수동 성수 1가");
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));

response.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("Artist is required"));
}

@DisplayName("음악 유효성 검사 실패 - 앨범명이 없는 경우")
@Test
void createItem_InvalidMusicAlbum_ReturnsBadRequest() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto("Love Dive", "IVE", null, "https://www.youtube.com/watch?v=YGieI3KoeZk", List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(37.123456, 127.123456, "서울시 성수동 성수 1가");
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));

response.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("Album name is required"));
}

@DisplayName("음악 유효성 검사 실패 - 앨범 커버 이미지가 없는 경우")
@Test
void createItem_InvalidAlbumCover_ReturnsBadRequest() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto("Love Dive", "IVE", "아이브 정규1집", null, List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(37.123456, 127.123456, "서울시 성수동 성수 1가");
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));

response.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("Album image is required"));
}

@DisplayName("위치 유효성 검사 실패 - latitude 값이 범위에 맞지 않는 경우")
@Test
void createItem_InvalidLatitudeRequest_ReturnsBadRequest() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto("Love Dive", "IVE", "1st EP IVE", "https://www.youtube.com/watch?v=YGieI3KoeZk", List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(100000000.0, 127.123456, "서울시 성수동 성수 1가");
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));

response.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("Not valid latitude, must be between -90 and 90"));
}

@DisplayName("위치 유효성 검사 실패 - longitude 값이 범위에 맞지 않는 경우")
@Test
void createItem_InvalidLogitudeRequest_ReturnsBadRequest() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto("Love Dive", "IVE", "1st EP IVE", "https://www.youtube.com/watch?v=YGieI3KoeZk", List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(37.123456, 100000000.0, "서울시 성수동 성수 1가");
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));

response.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("Not valid longitude, must be between -180 and 180"));
}

@DisplayName("위치 유효성 검사 실패 - 주소명이 없는 경우")
@Test
void createItem_InvalidAddressRequest_ReturnsBadRequest() throws Exception {
MusicRequestDto musicRequestDto = new MusicRequestDto("Love Dive", "IVE", "1st EP IVE", "https://www.youtube.com/watch?v=YGieI3KoeZk", List.of("K-POP", "HipHop"));
ItemLocationRequestDto itemLocationRequestDto = new ItemLocationRequestDto(37.123456, 127.123456, null);
ItemRequestDto itemRequestDto = new ItemRequestDto(itemLocationRequestDto, musicRequestDto, "블라블라");
ItemResponseDto itemResponseDto = createValidItemResponseDto();

given(itemService.create(mockUser, itemRequestDto)).willReturn(itemResponseDto);

var response = mvc.perform(
post("/items")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(itemRequestDto)));

response.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("Address is required"));
}
}

private ItemResponseDto createValidItemResponseDto() {
UserResponseDto userResponse = new UserResponseDto("User1", "https://s3.orbi.kr/data/file/united/35546557a06831597f6e7851cb6c86e9.jpg", "youtubemusic");
ItemLocationResponseDto locationResponse = new ItemLocationResponseDto("서울시 성수동 성수 1가");
ItemResponseDto itemResponseDto = new ItemResponseDto(1L, userResponse, locationResponse, LocalDateTime.now());
return itemResponseDto;
}
}

@DisplayName("[GET] 내 주변 드랍 아이템 poi 조회")
@Nested
class GetNearItemPointsTest {
Expand Down