Skip to content

Commit

Permalink
Merge pull request #532 from woowacourse-teams/feat/495-none-member
Browse files Browse the repository at this point in the history
비회원 조회 가능하도록 태그, 카테고리, 템플릿 조회 시 MemberDto 제거
  • Loading branch information
HoeSeong123 authored Aug 22, 2024
2 parents a6aed99 + 9e90520 commit 359b338
Show file tree
Hide file tree
Showing 26 changed files with 167 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public String createCredential(Member member) {
@Override
public Member extractMember(String credential) {
String[] nameAndPassword = BasicAuthDecoder.decodeBasicAuth(credential);
Member member = memberRepository.fetchByname(nameAndPassword[0]);
Member member = memberRepository.fetchByName(nameAndPassword[0]);
checkMatchPassword(member, nameAndPassword[1]);
return member;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public LoginAndCredentialDto login(LoginRequest loginRequest) {
}

private Member getVerifiedMember(String name, String password) {
Member member = memberRepository.fetchByname(name);
Member member = memberRepository.fetchByName(name);
validateCorrectPassword(member, password);
return member;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ public ResponseEntity<CreateCategoryResponse> createCategory(

@GetMapping
public ResponseEntity<FindAllCategoriesResponse> getCategories(
@AuthenticationPrinciple MemberDto memberDto,
@RequestParam Long memberId
) {
return ResponseEntity.ok(memberCategoryApplicationService.findAllByMember(memberDto, memberId));
return ResponseEntity.ok(memberCategoryApplicationService.findAllByMember(memberId));
}

@PutMapping("/{id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ ResponseEntity<CreateCategoryResponse> createCategory(
@Operation(summary = "카테고리 목록 조회", description = "생성된 모든 카테고리를 조회합니다.")
@ApiResponse(responseCode = "200", description = "조회 성공",
content = {@Content(schema = @Schema(implementation = FindAllCategoriesResponse.class))})
ResponseEntity<FindAllCategoriesResponse> getCategories(MemberDto memberDto, Long memberId);
ResponseEntity<FindAllCategoriesResponse> getCategories(Long memberId);

@SecurityRequirement(name = "쿠키 인증 토큰")
@Operation(summary = "카테고리 수정", description = "해당하는 식별자의 카테고리를 수정합니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ public Long create(MemberDto memberDto, CreateCategoryRequest createCategoryRequ
return categoryService.create(member, createCategoryRequest).id();
}

public FindAllCategoriesResponse findAllByMember(MemberDto memberDto, Long memberId) {
memberService.validateMemberIdentity(memberDto, memberId);
Member member = memberService.getById(memberDto.id());
public FindAllCategoriesResponse findAllByMember(Long memberId) {
Member member = memberService.getById(memberId);
return categoryService.findAllByMember(member);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public ResponseEntity<Void> signup(@Valid @RequestBody SignupRequest request) {
@GetMapping("/check-name")
@ResponseStatus(HttpStatus.OK)
public void checkUniquename(@RequestParam String name) {
memberService.assertUniquename(name);
memberService.assertUniqueName(name);
}

@GetMapping("/members/{id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.http.HttpStatus;

import codezap.global.exception.CodeZapException;
Expand All @@ -16,12 +17,20 @@ default Member fetchById(Long id) {
() -> new CodeZapException(HttpStatus.NOT_FOUND, "식별자 " + id + "에 해당하는 멤버가 존재하지 않습니다."));
}

default Member fetchByname(String name) {
return findByname(name)
default Member fetchByName(String name) {
return findByName(name)
.orElseThrow(() -> new CodeZapException(HttpStatus.UNAUTHORIZED, "존재하지 않는 아이디 " + name + " 입니다."));
}

Optional<Member> findByname(String name);
default Member fetchByTemplateId(Long templateId) {
return findByTemplateId(templateId)
.orElseThrow(() -> new CodeZapException(HttpStatus.NOT_FOUND, "템플릿에 대한 멤버가 존재하지 않습니다."));
}

@Query("SELECT t.member FROM Template t WHERE t.id = :templateId")
Optional<Member> findByTemplateId(Long templateId);

Optional<Member> findByName(String name);

boolean existsByname(String name);
boolean existsByName(String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ public interface MemberRepository {

Member fetchById(Long id);

Member fetchByname(String name);
Member fetchByName(String name);

boolean existsByname(String name);
Member fetchByTemplateId(Long templateId);

boolean existsByName(String name);

boolean existsById(Long id);

Expand Down
20 changes: 7 additions & 13 deletions backend/src/main/java/codezap/member/service/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ public class MemberService {
private final CategoryRepository categoryRepository;

public Long signup(SignupRequest request) {
assertUniquename(request.name());
assertUniqueName(request.name());
Member member = memberRepository.save(new Member(request.name(), request.password()));
categoryRepository.save(Category.createDefaultCategory(member));
return member.getId();
}

public void assertUniquename(String name) {
if (memberRepository.existsByname(name)) {
public void assertUniqueName(String name) {
if (memberRepository.existsByName(name)) {
throw new CodeZapException(HttpStatus.CONFLICT, "아이디가 이미 존재합니다.");
}
}
Expand All @@ -40,22 +40,16 @@ public FindMemberResponse findMember(MemberDto memberDto, Long id) {
return FindMemberResponse.from(memberRepository.fetchById(id));
}

public Member getByTemplateId(Long templateId) {
return memberRepository.fetchByTemplateId(templateId);
}

private void checkSameMember(MemberDto memberDto, Long id) {
if (!Objects.equals(memberDto.id(), id)) {
throw new CodeZapException(HttpStatus.FORBIDDEN, "본인의 정보만 조회할 수 있습니다.");
}
}

public void validateMemberIdentity(MemberDto memberDto, Long id) {
if (!id.equals(memberDto.id())) {
throw new CodeZapException(HttpStatus.UNAUTHORIZED, "인증 정보에 포함된 멤버 ID와 파라미터로 받은 멤버 ID가 다릅니다.");
}

if (!memberRepository.existsById(id)) {
throw new CodeZapException(HttpStatus.UNAUTHORIZED, "로그인 정보가 잘못되었습니다.");
}
}

public Member getById(Long id) {
return memberRepository.fetchById(id);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package codezap.tag.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

import codezap.global.swagger.error.ApiErrorResponse;
import codezap.global.swagger.error.ErrorCase;
import codezap.member.dto.MemberDto;
import codezap.tag.dto.response.FindAllTagsResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
Expand All @@ -17,9 +13,5 @@ public interface SpringDocTagController {
@SecurityRequirement(name = "쿠키 인증 토큰")
@Operation(summary = "태그 조회", description = "해당 멤버의 템플릿들에 포함된 태그를 조회합니다.")
@ApiResponse(responseCode = "200", description = "태그 조회 성공")
@ApiErrorResponse(status = HttpStatus.UNAUTHORIZED,
instance = "/tags/1", errorCases = {
@ErrorCase(description = "인증 정보와 멤버 ID가 다른 경우", exampleMessage = "인증 정보에 포함된 멤버 ID와 파라미터로 받은 멤버 ID가 다릅니다."),
})
ResponseEntity<FindAllTagsResponse> getTags(MemberDto memberDto, Long memberId);
ResponseEntity<FindAllTagsResponse> getTags(Long memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ public class TagController implements SpringDocTagController {

@GetMapping
public ResponseEntity<FindAllTagsResponse> getTags(
@AuthenticationPrinciple MemberDto memberDto,
@RequestParam Long memberId
) {
FindAllTagsResponse response = memberTemplateApplicationService.getAllTagsByMemberId(memberDto, memberId);
FindAllTagsResponse response = memberTemplateApplicationService.getAllTagsByMemberId(memberId);
return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,7 @@ ResponseEntity<FindAllTemplatesResponse> getTemplates(
@ApiErrorResponse(status = HttpStatus.BAD_REQUEST, instance = "/templates/1", errorCases = {
@ErrorCase(description = "해당하는 ID 값인 템플릿이 없는 경우", exampleMessage = "식별자 1에 해당하는 템플릿이 존재하지 않습니다."),
})
@ApiErrorResponse(status = HttpStatus.UNAUTHORIZED, instance = "/templates/1", errorCases = {
@ErrorCase(description = "자신의 템플릿이 아닐 경우", exampleMessage = "해당 템플릿에 대한 권한이 없습니다."),
})
@ApiErrorResponse(status = HttpStatus.NOT_FOUND, instance = "/templates/1", errorCases = {
@ErrorCase(description = "인증 정보에 포함된 멤버가 없는 경우", exampleMessage = "식별자 1에 해당하는 멤버가 존재하지 않습니다."),
})
ResponseEntity<FindTemplateResponse> getTemplateById(MemberDto memberDto, Long id);
ResponseEntity<FindTemplateResponse> getTemplateById(Long id);

@SecurityRequirement(name = "쿠키 인증 토큰")
@Operation(summary = "템플릿 수정", description = "해당하는 식별자의 템플릿을 수정합니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,16 @@ public ResponseEntity<FindAllTemplatesResponse> getTemplates(
@RequestParam(required = false) List<Long> tagIds,
@PageableDefault(size = 20, page = 1) Pageable pageable
) {
FindAllTemplatesResponse response = templateApplicationService.findAllBy(
FindAllTemplatesResponse response = memberTemplateApplicationService.getAllTemplatesBy(
memberId, keyword, categoryId, tagIds, pageable);
return ResponseEntity.ok(response);
}

@GetMapping("/{id}")
public ResponseEntity<FindTemplateResponse> getTemplateById(
@AuthenticationPrinciple MemberDto memberDto,
@PathVariable Long id
) {
return ResponseEntity.ok(memberTemplateApplicationService.getByIdAndMember(memberDto, id));
return ResponseEntity.ok(memberTemplateApplicationService.getTemplateById(id));
}

@PostMapping("/{id}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.time.LocalDateTime;
import java.util.List;

import codezap.member.domain.Member;
import codezap.tag.domain.Tag;
import codezap.tag.dto.response.FindTagResponse;
import codezap.template.domain.SourceCode;
Expand All @@ -12,6 +13,8 @@
public record FindAllTemplateItemResponse(
@Schema(description = "템플릿 ID", example = "0")
Long id,
@Schema(description = "회원 설명")
FindMemberResponse member,
@Schema(description = "템플릿명", example = "스프링 로그인 구현")
String title,
@Schema(description = "템플릿 설명", example = "Jwt 토큰을 이용하여 로그인 기능을 구현합니다.")
Expand All @@ -30,6 +33,7 @@ public static FindAllTemplateItemResponse of(
) {
return new FindAllTemplateItemResponse(
template.getId(),
null,
template.getTitle(),
template.getDescription(),
templateTags.stream()
Expand All @@ -40,4 +44,17 @@ public static FindAllTemplateItemResponse of(
template.getModifiedAt()
);
}

public FindAllTemplateItemResponse updateMember(Member member) {
return new FindAllTemplateItemResponse(
id,
new FindMemberResponse(member.getId(), member.getName()),
title,
description,
tags,
thumbnail,
createdAt,
modifiedAt
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ public record FindAllTemplatesResponse(
@Schema(description = "템플릿 목록")
List<FindAllTemplateItemResponse> templates
) {

public FindAllTemplatesResponse updateTemplates(List<FindAllTemplateItemResponse> templates) {
return new FindAllTemplatesResponse(totalPages, totalElements, templates);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;

import codezap.category.dto.response.FindCategoryResponse;
import codezap.member.domain.Member;
import codezap.tag.domain.Tag;
import codezap.tag.dto.response.FindTagResponse;
import codezap.template.domain.SourceCode;
Expand Down Expand Up @@ -52,6 +53,20 @@ public static FindTemplateResponse of(Template template, List<SourceCode> source
);
}

public FindTemplateResponse updateMember(Member member) {
return new FindTemplateResponse(
id,
new FindMemberResponse(member.getId(), member.getName()),
title,
description,
sourceCodes,
category,
tags,
createdAt,
modifiedAt
);
}

private static List<FindAllSourceCodeByTemplateResponse> mapToFindAllSourceCodeByTemplateResponse(
List<SourceCode> sourceCodes
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ public Template createTemplate(Member member, CreateTemplateRequest createTempla
return templateRepository.save(template);
}

public Template getByMemberAndId(Member member, Long id) {
Template template = templateRepository.fetchById(id);
template.validateAuthorization(member);
return template;
public Template getById(Long id) {
return templateRepository.fetchById(id);
}

public List<Template> getByMemberId(Long memberId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import codezap.tag.dto.response.FindAllTagsResponse;
import codezap.template.dto.request.CreateTemplateRequest;
import codezap.template.dto.request.UpdateTemplateRequest;
import codezap.template.dto.response.FindAllTemplateItemResponse;
import codezap.template.dto.response.FindAllTemplatesResponse;
import codezap.template.dto.response.FindTemplateResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -27,14 +28,21 @@ public Long createTemplate(MemberDto memberDto, CreateTemplateRequest createTemp
return categoryTemplateApplicationService.createTemplate(member, createTemplateRequest);
}

public FindAllTagsResponse getAllTagsByMemberId(MemberDto memberDto, Long memberId) {
memberService.validateMemberIdentity(memberDto, memberId);
public FindAllTagsResponse getAllTagsByMemberId(Long memberId) {
return templateApplicationService.getAllTagsByMemberId(memberId);
}

public FindTemplateResponse getByIdAndMember(MemberDto memberDto, Long id) {
Member member = memberService.getById(memberDto.id());
return templateApplicationService.getByMemberAndId(member, id);
public FindAllTemplatesResponse getAllTemplatesBy(Long memberId, String keyword, Long categoryId, List<Long> tagIds, Pageable pageable) {
FindAllTemplatesResponse findAllTemplatesResponse = templateApplicationService.findAllBy(memberId, keyword, categoryId, tagIds, pageable);
List<FindAllTemplateItemResponse> findAllTemplateItemResponsesWithMember = findAllTemplatesResponse.templates().stream()
.map(findAllTemplateItemResponse -> findAllTemplateItemResponse.updateMember(memberService.getByTemplateId(findAllTemplateItemResponse.id())))
.toList();
return findAllTemplatesResponse.updateTemplates(findAllTemplateItemResponsesWithMember);
}

public FindTemplateResponse getTemplateById(Long id) {
FindTemplateResponse findTemplateResponse = templateApplicationService.getById(id);
return findTemplateResponse.updateMember(memberService.getByTemplateId(id));
}

public void update(MemberDto memberDto, Long templateId, UpdateTemplateRequest updateTemplateRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public Long createTemplate(Member member, Category category, CreateTemplateReque
return template.getId();
}

public FindTemplateResponse getByMemberAndId(Member member, Long id) {
Template template = templateService.getByMemberAndId(member, id);
public FindTemplateResponse getById(Long id) {
Template template = templateService.getById(id);
List<Tag> tags = templateTagService.getByTemplate(template);

List<SourceCode> sourceCodes = sourceCodeService.findSourceCodesByTemplate(template);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void findAllCategoriesSuccess() throws Exception {
List<Category> categories = List.of(new Category("category1", member), new Category("category1", member));
FindAllCategoriesResponse findAllCategoriesResponse = FindAllCategoriesResponse.from(categories);

when(memberCategoryApplicationService.findAllByMember(any(), any())).thenReturn(findAllCategoriesResponse);
when(memberCategoryApplicationService.findAllByMember(any())).thenReturn(findAllCategoriesResponse);

mvc.perform(get("/categories")
.param("memberId", "1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ void signupSuccess() throws Exception {

@Test
@DisplayName("사용자명 중복 확인 성공")
void checkUniquenameSuccess() throws Exception {
void checkUniqueNameSuccess() throws Exception {
String name = "name";

doNothing().when(memberService).assertUniquename(any(String.class));
doNothing().when(memberService).assertUniqueName(any(String.class));

mvc.perform(get("/check-name")
.param("name", name))
.andDo(print())
.andExpect(status().isOk());
verify(memberService, times(1)).assertUniquename(name);
verify(memberService, times(1)).assertUniqueName(name);
}


Expand Down
Loading

0 comments on commit 359b338

Please sign in to comment.