-
Notifications
You must be signed in to change notification settings - Fork 5
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
[BE] 행사 생성 기능 구현 #41
[BE] 행사 생성 기능 구현 #41
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package server.haengdong.application; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import server.haengdong.application.request.EventAppRequest; | ||
import server.haengdong.application.response.EventAppResponse; | ||
import server.haengdong.domain.Event; | ||
import server.haengdong.domain.EventTokenProvider; | ||
import server.haengdong.persistence.EventRepository; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class EventService { | ||
|
||
private final EventRepository eventRepository; | ||
private final EventTokenProvider eventTokenProvider; | ||
|
||
public EventAppResponse saveEvent(EventAppRequest request) { | ||
String token = eventTokenProvider.createToken(); | ||
Event event = request.toEvent(token); | ||
eventRepository.save(event); | ||
|
||
return EventAppResponse.of(event); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package server.haengdong.application.request; | ||
|
||
import server.haengdong.domain.Event; | ||
|
||
public record EventAppRequest(String name) { | ||
|
||
public Event toEvent(String token) { | ||
return new Event(name, token); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package server.haengdong.application.response; | ||
|
||
import server.haengdong.domain.Event; | ||
|
||
public record EventAppResponse(String token) { | ||
|
||
public static EventAppResponse of(Event event) { | ||
return new EventAppResponse(event.getToken()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,9 @@ public class Event { | |
private String name; | ||
|
||
private String token; | ||
|
||
public Event(String name, String token) { | ||
this.name = name; | ||
this.token = token; | ||
} | ||
Comment on lines
+24
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [R] : name 검증이 없는 것 같아요. |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package server.haengdong.domain; | ||
|
||
import java.util.UUID; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class EventTokenProvider { | ||
|
||
public String createToken() { | ||
return UUID.randomUUID().toString(); | ||
} | ||
} | ||
Comment on lines
+6
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [R] EventTokenProvider 생성 정책이 바뀔 가능성이 있을 것 같은데 인터페이스로 하는 것은 어떨까요? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package server.haengdong.persistence; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
import server.haengdong.domain.Event; | ||
|
||
@Repository | ||
public interface EventRepository extends JpaRepository<Event, Long> { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package server.haengdong.presentation; | ||
|
||
import java.net.URI; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import server.haengdong.application.EventService; | ||
import server.haengdong.application.response.EventAppResponse; | ||
import server.haengdong.presentation.request.EventSaveRequest; | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
public class EventController { | ||
|
||
private final EventService eventService; | ||
|
||
@PostMapping("/api/events") | ||
public ResponseEntity<Void> saveEvent(EventSaveRequest request) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [R] : |
||
EventAppResponse eventAppResponse = eventService.saveEvent(request.toAppRequest()); | ||
|
||
return ResponseEntity.ok() | ||
.location(URI.create("events/" + eventAppResponse.token())) | ||
.build(); | ||
Comment on lines
+22
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [R] create()를 사용해서 status code를 201로 하는 것은 어떨까요? |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package server.haengdong.presentation.request; | ||
|
||
import server.haengdong.application.request.EventAppRequest; | ||
|
||
public record EventSaveRequest(String name) { | ||
|
||
public EventAppRequest toAppRequest() { | ||
return new EventAppRequest(name); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package server.haengdong.application; | ||
|
||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.BDDMockito.given; | ||
|
||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import server.haengdong.application.request.EventAppRequest; | ||
import server.haengdong.application.response.EventAppResponse; | ||
import server.haengdong.domain.EventTokenProvider; | ||
|
||
@SpringBootTest | ||
class EventServiceTest { | ||
|
||
@Autowired | ||
private EventService eventService; | ||
|
||
@MockBean | ||
private EventTokenProvider eventTokenProvider; | ||
|
||
@DisplayName("행사를 생성한다") | ||
@Test | ||
void saveEventTest() { | ||
EventAppRequest request = new EventAppRequest("test"); | ||
given(eventTokenProvider.createToken()).willReturn("TOKEN"); | ||
|
||
EventAppResponse response = eventService.saveEvent(request); | ||
|
||
assertThat(response.token()).isEqualTo("TOKEN"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package server.haengdong.presentation; | ||
|
||
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.result.MockMvcResultHandlers.print; | ||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||
import org.springframework.boot.test.mock.mockito.MockBean; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers; | ||
import server.haengdong.application.EventService; | ||
import server.haengdong.application.request.EventAppRequest; | ||
import server.haengdong.application.response.EventAppResponse; | ||
import server.haengdong.presentation.request.EventSaveRequest; | ||
|
||
@WebMvcTest(EventController.class) | ||
class EventControllerTest { | ||
|
||
@Autowired | ||
private MockMvc mockMvc; | ||
|
||
@Autowired | ||
private ObjectMapper objectMapper; | ||
|
||
@MockBean | ||
private EventService eventService; | ||
|
||
@DisplayName("이벤트를 생성한다") | ||
@Test | ||
void saveEvent() throws Exception { | ||
EventSaveRequest eventSaveRequest = new EventSaveRequest("test"); | ||
String requestBody = objectMapper.writeValueAsString(eventSaveRequest); | ||
String token = "TOKEN"; | ||
EventAppResponse eventAppResponse = new EventAppResponse(token); | ||
given(eventService.saveEvent(any(EventAppRequest.class))).willReturn(eventAppResponse); | ||
|
||
mockMvc.perform(post("/api/events") | ||
.contentType(MediaType.APPLICATION_JSON) | ||
.content(requestBody)) | ||
.andDo(print()) | ||
.andExpect(status().isOk()) | ||
.andExpect(MockMvcResultMatchers.redirectedUrl("events/" + token)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[R] 중복된 토큰이 생성될 수 있으니 저장 전에 검증을 한 번 해 주면 좋을 것 같습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매 초 100만개의 UUID를 100년동안 생성할때 0.00009% 확률로 중복이 발생합니다.
라고 하는데 굳이 검증을 해야할까요?DB에서 unique 조건을 한 번 걸어주는 것만으로 충분하다고 생각합니다.