Skip to content

Commit

Permalink
[SKRB-156] feat: 클럽 조회 기능 구현 (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
choi5798 authored Oct 27, 2023
2 parents b307405 + a3c69cd commit 6003487
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 22 deletions.
12 changes: 8 additions & 4 deletions src/main/java/com/spaceclub/club/controller/ClubController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.spaceclub.club.controller;

import com.spaceclub.club.controller.dto.CreateClubRequest;
import com.spaceclub.club.controller.dto.ClubGetResponse;
import com.spaceclub.club.controller.dto.ClubCreateRequest;
import com.spaceclub.club.domain.Club;
import com.spaceclub.club.service.ClubService;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,7 +24,7 @@ public class ClubController {
private final ClubService service;

@PostMapping("/clubs")
public ResponseEntity<String> createClub(@RequestBody CreateClubRequest request) {
public ResponseEntity<String> createClub(@RequestBody ClubCreateRequest request) {
Club newClub = request.toEntity();
Club createdClub = service.createClub(newClub);
Long id = createdClub.getId();
Expand All @@ -32,8 +33,11 @@ public ResponseEntity<String> createClub(@RequestBody CreateClubRequest request)
}

@GetMapping("/clubs/{clubId}")
public ResponseEntity<String> getClub(@PathVariable Long clubId) {
return ResponseEntity.ok("get club.");
public ResponseEntity<ClubGetResponse> getClub(@PathVariable Long clubId) {
Club club = service.getClub(clubId);
ClubGetResponse response = ClubGetResponse.from(club);

return ResponseEntity.ok(response);
}

@DeleteMapping("/clubs/{clubId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.spaceclub.club.domain.Club;

public record CreateClubRequest(
public record ClubCreateRequest(
String name,
String info,
String owner,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.spaceclub.club.controller.dto;

import com.spaceclub.club.domain.Club;
import com.spaceclub.club.domain.ClubNotice;
import lombok.Builder;

import java.util.ArrayList;
import java.util.List;

public record ClubGetResponse(
String name,
String info,
Long memberCount,
String image,
List<String> notices
) {

@Builder
public ClubGetResponse(String name, String info, Long memberCount, String image, List<String> notices) {
this.name = name;
this.info = info;
this.memberCount = memberCount;
this.image = image;
this.notices = new ArrayList<>(notices);
}

public static ClubGetResponse from(Club club) {
long memberCount = club.getClubUser().stream()
.filter((user) -> user.getClub().getId().equals(club.getId()))
.count();

return ClubGetResponse.builder()
.name(club.getName())
.info(club.getInfo())
.memberCount(memberCount)
.image(club.getImage())
.notices(club.getNotices().stream()
.map(ClubNotice::getNotice)
.toList())
.build();
}

}
22 changes: 21 additions & 1 deletion src/main/java/com/spaceclub/club/domain/Club.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.OneToMany;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Club extends BaseTimeEntity {
Expand All @@ -23,22 +27,34 @@ public class Club extends BaseTimeEntity {
private Long id;

@Column(length = 12, nullable = false)
@Getter
private String name;

@Lob
@Getter
private String image;

@Lob
@Getter
private String info;

@Getter
private String owner;

@Getter
@OneToMany(mappedBy = "club")
private List<ClubNotice> notices = new ArrayList<>();

@Getter
@OneToMany(mappedBy = "club")
private List<ClubUser> clubUser = new ArrayList<>();

private boolean validateNameLength(String name) {
return name.length() <= 12;
}

@Builder
public Club(String name, String image, String info, String owner) {
public Club(String name, String image, String info, String owner, List<ClubNotice> notices) {
Assert.notNull(name, "이름에 null 값이 올 수 없습니다");
Assert.hasText(name, "이름이 빈 값일 수 없습니다");
Assert.isTrue(validateNameLength(name), "이름의 길이는 12글자를 넘을 수 없습니다");
Expand All @@ -48,6 +64,10 @@ public Club(String name, String image, String info, String owner) {
this.image = image;
this.info = info;
this.owner = owner;

if (notices != null) {
this.notices = new ArrayList<>(notices);
}
}

}
31 changes: 31 additions & 0 deletions src/main/java/com/spaceclub/club/domain/ClubNotice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.spaceclub.club.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ClubNotice {

@Id
@Column(name = "club_notice_id")
private Long id;

@ManyToOne
@JoinColumn(name = "club_id")
private Club club;

@Getter
private String notice;

public ClubNotice(String notice) {
this.notice = notice;
}

}
33 changes: 33 additions & 0 deletions src/main/java/com/spaceclub/club/domain/ClubUser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.spaceclub.club.domain;

import com.spaceclub.global.BaseTimeEntity;
import com.spaceclub.user.domain.User;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;

@Table(name = "club_user")
@Entity
public class ClubUser extends BaseTimeEntity {

@Id
@Column(name = "club_user_id")
private Long id;

@Getter
@ManyToOne
@JoinColumn(name = "club_id")
private Club club;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;

@Column(length = 16, nullable = false)
private String role;

}
7 changes: 7 additions & 0 deletions src/main/java/com/spaceclub/club/service/ClubService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.spaceclub.club.repository.ClubRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RequiredArgsConstructor
public class ClubService {

Expand All @@ -15,4 +17,9 @@ public Club createClub(Club club) {
return repository.save(club);
}

public Club getClub(Long clubId) {
return repository.findById(clubId)
.orElseThrow(() -> new IllegalArgumentException("해당하는 클럽이 없습니다"));
}

}
51 changes: 35 additions & 16 deletions src/test/java/com/spaceclub/club/controller/ClubControllerTest.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
package com.spaceclub.club.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.spaceclub.club.controller.dto.CreateClubRequest;
import com.spaceclub.club.controller.dto.ClubCreateRequest;
import com.spaceclub.club.domain.Club;
import com.spaceclub.club.domain.ClubNotice;
import com.spaceclub.club.service.ClubService;
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.restdocs.AutoConfigureRestDocs;
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.restdocs.payload.JsonFieldType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import java.util.List;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
Expand All @@ -25,8 +26,12 @@
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.payload.JsonFieldType.ARRAY;
import static org.springframework.restdocs.payload.JsonFieldType.NUMBER;
import static org.springframework.restdocs.payload.JsonFieldType.STRING;
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.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
Expand All @@ -45,9 +50,8 @@ class ClubControllerTest {
private ClubService clubService;

@Test
@DisplayName("클럽 생성에 성공한다")
@WithMockUser
void createClubTest() throws Exception {
void 클럽_생성에_성공한다() throws Exception {
// given
given(clubService.createClub(any(Club.class))).willReturn(
Club.builder()
Expand All @@ -56,7 +60,7 @@ void createClubTest() throws Exception {
.owner("연어대장")
.image("연어.png")
.build());
CreateClubRequest request = new CreateClubRequest("연사모",
ClubCreateRequest request = new ClubCreateRequest("연사모",
"연어를 사랑하는 모임",
"연어대장",
"연어.png");
Expand All @@ -74,18 +78,26 @@ void createClubTest() throws Exception {
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestFields(
fieldWithPath("name").type(JsonFieldType.STRING).description("클럽 이름"),
fieldWithPath("info").type(JsonFieldType.STRING).description("클럽 소개"),
fieldWithPath("owner").type(JsonFieldType.STRING).description("클럽 생성자"),
fieldWithPath("image").type(JsonFieldType.STRING).description("클럽 썸네일 이미지")
fieldWithPath("name").type(STRING).description("클럽 이름"),
fieldWithPath("info").type(STRING).description("클럽 소개"),
fieldWithPath("owner").type(STRING).description("클럽 생성자"),
fieldWithPath("image").type(STRING).description("클럽 썸네일 이미지")
)));
}

@Test
@DisplayName("클럽 조회에 성공한다")
@WithMockUser
void getClubTest() throws Exception {
void 클럽_조회에_성공한다() throws Exception {
// given
given(clubService.getClub(any(Long.class))).willReturn(
Club.builder()
.name("연사모")
.info("이곳은 연사모입니다")
.image("연어.png")
.owner("연어대장")
.notices(List.of(new ClubNotice("연사모의 공지사항1")))
.build()
);
Long clubId = 1L;

// when
Expand All @@ -98,13 +110,19 @@ void getClubTest() throws Exception {
.andDo(print())
.andDo(document("club/get",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint())));
preprocessResponse(prettyPrint()),
responseFields(
fieldWithPath("name").type(STRING).description("클럽 이름"),
fieldWithPath("info").type(STRING).description("클럽 소개"),
fieldWithPath("memberCount").type(NUMBER).description("클럽 멤버수"),
fieldWithPath("image").type(STRING).description("클럽 썸네일 이미지"),
fieldWithPath("notices").type(ARRAY).description("클럽 공지사항 리스트")
)));
}

@Test
@DisplayName("클럽 삭제에 성공한다")
@WithMockUser
void deleteClubTest() throws Exception {
void 클럽_삭제에_성공한다() throws Exception {
// given
Long clubId = 1L;

Expand All @@ -118,7 +136,8 @@ void deleteClubTest() throws Exception {
.andDo(print())
.andDo(document("club/delete",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint())));
preprocessResponse(prettyPrint())
));
}

}

0 comments on commit 6003487

Please sign in to comment.