Skip to content

Commit

Permalink
Merge pull request #24 from LandvibeDev/feat/add-message
Browse files Browse the repository at this point in the history
Close: #19 
메시지 전송 api 구현
  • Loading branch information
so3500 authored Aug 30, 2020
2 parents ce7b639 + 56cf4c8 commit bd1e2ed
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 4 deletions.
14 changes: 14 additions & 0 deletions src/main/java/web/chat/backend/controller/RoomController.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;
import web.chat.backend.controller.request.MessageRequest;
import web.chat.backend.controller.request.RoomRequest;
import web.chat.backend.controller.response.MessageResponse;
import web.chat.backend.controller.response.RoomResponse;
Expand Down Expand Up @@ -52,6 +53,19 @@ public List<MessageResponse> getMessages(@PathVariable Long id) {
return messages.stream().collect(new MessageCollector());
}

@PostMapping("/{roomId}/messages")
@ResponseStatus(HttpStatus.CREATED)
public MessageResponse createMessage(@PathVariable Long roomId, @RequestBody @Valid MessageRequest messageRequest) {
Message message = new Message();
message.setContents(messageRequest.getContents());

Room room = roomService.getOrThrow(roomId);

Message savedMessage = messageService.createMessage(room, message);

return new MessageResponse(savedMessage);
}

@PostMapping("")
@ResponseStatus(HttpStatus.CREATED)
public RoomResponse createRoom(@RequestBody @Valid RoomRequest roomRequest) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
package web.chat.backend.controller.request;

import javax.validation.constraints.Size;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class MessageRequest {

@Size(min = 1)
private String contents;
}
3 changes: 3 additions & 0 deletions src/main/java/web/chat/backend/entity/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
Expand All @@ -13,13 +14,15 @@
import javax.persistence.ManyToOne;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Message {

@Id
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/web/chat/backend/entity/Room.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
@Getter
@Setter
@Entity
@Builder

public class Room {

@Id
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/web/chat/backend/service/MessageService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import lombok.RequiredArgsConstructor;
import web.chat.backend.entity.Message;
import web.chat.backend.entity.Room;
import web.chat.backend.exception.NotFoundException;
import web.chat.backend.repository.MessageRepository;

Expand All @@ -21,4 +22,10 @@ public List<Message> getMessagesBy(Long roomId) {

return messageRepository.findAllByRoomId(roomId);
}

public Message createMessage(Room room, Message message) {
message.setRoom(room);

return messageRepository.save(message);
}
}
6 changes: 6 additions & 0 deletions src/main/java/web/chat/backend/service/RoomService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import lombok.RequiredArgsConstructor;
import web.chat.backend.entity.Room;
import web.chat.backend.exception.NotFoundException;
import web.chat.backend.repository.RoomRepository;

@RequiredArgsConstructor
Expand All @@ -21,4 +22,9 @@ public Room createRoom(Room room) {
public List<Room> getRooms() {
return roomRepository.findAll();
}

public Room getOrThrow(Long roomId) {
return roomRepository.findById(roomId)
.orElseThrow(() -> new NotFoundException(String.format("Room [id:%d] not found", roomId)));
}
}
52 changes: 52 additions & 0 deletions src/test/java/web/chat/backend/controller/MessageCreationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package web.chat.backend.controller;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestConstructor;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import web.chat.backend.controller.request.MessageRequest;

@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
@RequiredArgsConstructor
@AutoConfigureMockMvc
@SpringBootTest
public class MessageCreationTest {

final MockMvc mockMvc;
final ObjectMapper objectMapper;

final RoomController roomController;

@Test
@Sql("/test-sql/messages.sql")
void createMessage() throws Exception {

// given
MessageRequest req = new MessageRequest();
req.setContents("hi hello");

final String body = objectMapper.writeValueAsString(req);

// when
ResultActions action = mockMvc.perform(
post("/api/rooms/{roomId}/messages", 1)
.contentType(MediaType.APPLICATION_JSON)
.content(body));

// then
action.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.contents").value(req.getContents()));
}
}
57 changes: 55 additions & 2 deletions src/test/java/web/chat/backend/controller/RoomControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.mockito.ArgumentMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.BDDMockito.any;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
Expand All @@ -24,11 +25,11 @@
import org.springframework.web.bind.MethodArgumentNotValidException;

import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.RequiredArgsConstructor;
import web.chat.backend.controller.request.MessageRequest;
import web.chat.backend.controller.request.RoomRequest;
import web.chat.backend.controller.response.RoomResponse;

import web.chat.backend.entity.Message;
import web.chat.backend.entity.Room;
import web.chat.backend.service.MessageService;
import web.chat.backend.service.RoomService;
Expand Down Expand Up @@ -152,4 +153,56 @@ void createRoom_titleLengthExceed_20() throws Exception {
.andDo(print());

}

@Test
void createMessage() throws Exception {

// given
MessageRequest req = new MessageRequest();
req.setContents("hi hello");

final String body = objectMapper.writeValueAsString(req);

Message expected = new Message();
expected.setId(1L);
expected.setContents(req.getContents());

given(roomService.getOrThrow(anyLong())).willReturn(new Room());
given(messageService.createMessage(any(), any())).willReturn(expected);

// when
ResultActions action = mockMvc.perform(
post("/api/rooms/1/messages")
.contentType(MediaType.APPLICATION_JSON)
.content(body));

// then
action.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.id").value(expected.getId()))
.andExpect(jsonPath("$.contents").value(expected.getContents()));
}

@DisplayName("Message 의 contents 빈값 불가능")
@Test
void createMessage_contentsLengthLessThan_1() throws Exception {

// given
MessageRequest req = new MessageRequest();
req.setContents("");

final String body = objectMapper.writeValueAsString(req);

// when
ResultActions action = mockMvc.perform(
post("/api/rooms/1/messages")
.contentType(MediaType.APPLICATION_JSON)
.content(body));

// then
action.andDo(print())
.andExpect(status().is4xxClientError())
.andExpect(result -> assertTrue(result.getResolvedException() instanceof MethodArgumentNotValidException));

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package web.chat.backend.repository;

import static org.assertj.core.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.test.context.TestConstructor;

import lombok.RequiredArgsConstructor;
import web.chat.backend.entity.Message;
import web.chat.backend.entity.Room;

@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
@RequiredArgsConstructor
@EnableJpaAuditing
@DataJpaTest
class MessageRepositoryTest {

final TestEntityManager entityManager;
final MessageRepository messageRepository;

@Test
void save() {

// given
Room room = new Room();
room.setTitle("room");

entityManager.persist(room);

Message message = new Message();
message.setContents("hi hello");
message.setRoom(room);

// when
Message savedMessage = messageRepository.save(message);

// then
assertThat(savedMessage.getId()).isNotNull();
assertThat(savedMessage.getContents()).isEqualTo(message.getContents());
assertThat(savedMessage.getCreatedAt()).isNotNull();
assertThat(savedMessage.getRoom()).isNotNull();
assertThat(savedMessage.getRoom().getTitle()).isEqualTo(room.getTitle());
}
}

0 comments on commit bd1e2ed

Please sign in to comment.