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

[#68]Argument Resolver 리팩토링/Jacoco Report 설정/테스트커버리지80%달정 #69

Merged
merged 23 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5634bbc
refactor: Argument Resolver 리팩토링
hoa0217 Mar 27, 2024
421b02b
chore: Jacoco Report to PR Config
hoa0217 Mar 27, 2024
0b6a147
docs: README.md 수정
hoa0217 Mar 27, 2024
19a247a
fix: Report 제목 이모지 제거
hoa0217 Mar 27, 2024
9b3c22a
fix: 워크플로우 권한 부여
hoa0217 Mar 27, 2024
07308b7
fix: 워크플로우 권한 부여
hoa0217 Mar 27, 2024
bee2463
refactor: report limit counter 변경
hoa0217 Mar 28, 2024
acadb68
refactor: excludes class 추가
hoa0217 Mar 28, 2024
8fe348e
refactor: excludes class 추가(builder)
hoa0217 Mar 28, 2024
e6380e0
refactor: ReservationStatus 사용되지 않는 메서드 제거
hoa0217 Mar 29, 2024
9d58d45
test: SpaceService searchSpace, searchSpaceQuery Test 추가
hoa0217 Mar 29, 2024
75311cf
chore: 폴더 구조 변경
hoa0217 Mar 29, 2024
772c731
test: system.out.println 제거
hoa0217 Mar 29, 2024
e05fad8
test: AlarmConsumer, AlarmProducer
hoa0217 Mar 29, 2024
21dae6b
test: FacilityServiceTest
hoa0217 Mar 29, 2024
98ded2d
test: Consume에 실패할 경우, 계속 시도하는 이슈 발생하여 실패 케이스 임시 주석처리
hoa0217 Mar 29, 2024
3ddf8f4
test: FacilityServiceTest
hoa0217 Mar 29, 2024
bd985f8
refactor: Facility Response 분리
hoa0217 Apr 1, 2024
3a2fd29
style: Google CheckStyle 적용
hoa0217 Apr 1, 2024
5efd18e
refactor: 예약검색 리팩토링 (관리자, 호스트, 방문자 request 분리)
hoa0217 Apr 1, 2024
c628b20
refactor: 예약검색 리팩토링 (공통 request 및 공통 검색 쿼리 도출)
hoa0217 Apr 1, 2024
fdfbb19
refactor: 쿼리스트링으로 요청받는 dto제외 setter 제거 및 Request 이름 변경
hoa0217 Apr 1, 2024
02dc6ae
refactor: min coverage 기준 75로 낮춤.
hoa0217 Apr 1, 2024
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
14 changes: 12 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ on:
pull_request:
branches: [ "develop" ]

permissions:
contents: read
permissions: write-all

jobs:
CI:
Expand Down Expand Up @@ -35,3 +34,14 @@ jobs:
- name: Build with Gradle
run: ./gradlew clean build
shell: bash
# 테스트커버리지 체크 결과 확인 (Instruction 기준)
- name: Jacoco Report to PR
id: jacoco
uses: madrapps/[email protected]
with:
paths: ${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml
token: ${{ secrets.GITHUB_TOKEN }}
min-coverage-overall: 75
min-coverage-changed-files: 75
title: "⭐️Code Coverage"
update-comment: true
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
- [CI/CD를 구축해보자2 - JaCoCo와 GitHub Actions으로 CI/CD구축해보기](https://velog.io/@gjwjdghk123/CI-CD2)
- [ObjectOptimisticLockingFailureException과 고아객체(Orphan) 그리고 한방 쿼리](https://velog.io/@gjwjdghk123/ObjectOptimisticLockingFailureException)
- [nGrinder를 이용한 성능 테스트 및 성능 개선(ElasticSearch, Redis)](https://velog.io/@gjwjdghk123/nGrinder%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%84%B1%EB%8A%A5-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%B0%8F-%EC%84%B1%EB%8A%A5-%EA%B0%9C%EC%84%A0ElasticSearch-Redis)
- [ElasticSearch TimeOutException 해결과정](https://velog.io/@gjwjdghk123/ElasticSearch-TimeOutException-%ED%95%B4%EA%B2%B0%EA%B3%BC%EC%A0%95)
- [ElasticSearch TimeOutException 해결과정](https://velog.io/@gjwjdghk123/ElasticSearch-TimeOutException-%ED%95%B4%EA%B2%B0%EA%B3%BC%EC%A0%95)
- [ArgumentResolver를 사용한 중복로직제거 (feat. 필터, 인터셉터)](https://velog.io/@gjwjdghk123/ArgumentResolver%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%9C-%EC%A4%91%EB%B3%B5%EB%A1%9C%EC%A7%81%EC%A0%9C%EA%B1%B0-feat.-%ED%95%84%ED%84%B0-%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0)
7 changes: 4 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ jacocoTestReport {

reports {
html.enabled true
xml.enabled false
xml.enabled true
csv.enabled false
}
}
Expand All @@ -110,14 +110,15 @@ jacocoTestCoverageVerification {
violationRules {
rule {
element 'CLASS'

limit {
counter = 'BRANCH'
counter = 'INSTRUCTION'
value = 'COVEREDRATIO'
minimum = 0.8 // 테스트 커버리지 최소 80%
}

// 커버리지 체크를 제외할 클래스들
excludes = ['*.*Controller', '*.dto.*', '*.config.*', '*.domain.Q*']
excludes = ['*.*Application', '*.*Controller', '*.dto.*', '*.config.*', '*.common.*', '*.domain.Q*', '*.*Builder']
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.modoospace.alarm.repository.EmitterLocalCacheRepository;
import com.modoospace.common.exception.NotFoundEntityException;
import com.modoospace.common.exception.SSEConnectError;
import com.modoospace.config.redis.CachePrefixEvict;
import com.modoospace.config.redis.aspect.CachePrefixEvict;
import com.modoospace.member.domain.Member;
import com.modoospace.member.service.MemberService;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
"/api/v1/spaces/*/facilities/**",
"/api/v1/test/**",
"/api/v1/facilities/*/schedules/**",
"/api/v1/visitors/reservations/facilities/*/availability/**").permitAll()
"/api/v1/visitor/reservations/facilities/*/availability/**").permitAll()
.antMatchers(HttpMethod.POST, "/api/v1/alarms/send/**").permitAll()
.antMatchers("/api/v1/admin/**").hasRole(Role.ADMIN.name())
.antMatchers("/api/v1/hosts/**").hasRole(Role.HOST.name())
.antMatchers("/api/v1/host/**").hasRole(Role.HOST.name())
.anyRequest().authenticated()
)
.oauth2Login().userInfoEndpoint()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RequiredArgsConstructor
@Component
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {

private final HttpSession httpSession;
private final MemberService memberService;

/**
Expand All @@ -28,17 +28,23 @@ public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(LoginMember.class) && parameter.getParameterType().equals(Member.class);
}


/**
* 파라미터에 전달할 객체 생성
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
try {
String email = (String) httpSession.getAttribute("member");
return memberService.findMemberByEmail(email);
return memberService.findMemberByEmail(getLoginEmail(webRequest));
} catch (RuntimeException e) {
throw new UnAuthenticatedException();
}
}

private String getLoginEmail(NativeWebRequest webRequest) {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
HttpSession session = request.getSession(false);
return (String) session.getAttribute("member");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.modoospace.config.redis;
package com.modoospace.config.redis.aspect;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.modoospace.config.redis;
package com.modoospace.config.redis.aspect;

import com.modoospace.common.CustomSpELParser;
import java.util.Set;
Expand All @@ -19,7 +19,7 @@ public class CachePrefixEvictAdvisor {
@Autowired
StringRedisTemplate redisTemplate;

@Around("@annotation(com.modoospace.config.redis.CachePrefixEvict)")
@Around("@annotation(com.modoospace.config.redis.aspect.CachePrefixEvict)")
public Object processCachePrefixEvict(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
CachePrefixEvict annotation = methodSignature.getMethod().getAnnotation(CachePrefixEvict.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
import com.modoospace.member.domain.Member;
import com.modoospace.reservation.controller.dto.ReservationResponse;
import com.modoospace.reservation.controller.dto.ReservationUpdateRequest;
import com.modoospace.reservation.controller.dto.search.AdminSearchRequest;
import com.modoospace.reservation.serivce.ReservationService;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
Expand All @@ -19,37 +25,29 @@ public class AdminReservationController {

private final ReservationService reservationService;

@GetMapping("/visitor/{memberId}")
public ResponseEntity<List<ReservationResponse>> findAllAsMember(@PathVariable Long memberId,
@LoginMember Member loginMember) {
List<ReservationResponse> reservations = reservationService
.findAllAsVisitorByAdmin(memberId, loginMember);
return ResponseEntity.ok().body(reservations);
@GetMapping("/{reservationId}")
public ResponseEntity<ReservationResponse> find(@PathVariable Long reservationId,
@LoginMember Member loginMember) {
ReservationResponse reservation = reservationService.findReservation(reservationId,
loginMember);
return ResponseEntity.ok().body(reservation);
}

@GetMapping("/host/{memberId}")
public ResponseEntity<List<ReservationResponse>> findAllAsHost(@PathVariable Long memberId,
@LoginMember Member loginMember) {
List<ReservationResponse> reservations = reservationService
.findAllAsHostByAdmin(memberId, loginMember);
@GetMapping("")
public ResponseEntity<Page<ReservationResponse>> search(AdminSearchRequest searchRequest,
Pageable pageable,
@LoginMember Member loginMember) {
Page<ReservationResponse> reservations = reservationService.searchReservationByAdmin(
searchRequest, pageable, loginMember);
return ResponseEntity.ok().body(reservations);
}

@PutMapping("/{reservationId}")
public ResponseEntity<Void> update(
@PathVariable Long reservationId,
public ResponseEntity<Void> update(@PathVariable Long reservationId,
@RequestBody @Valid ReservationUpdateRequest updateRequest,
@LoginMember Member loginMember) {

reservationService.updateReservation(reservationId, updateRequest, loginMember);
return ResponseEntity.ok().build();
}

@GetMapping("/{reservationId}")
public ResponseEntity<ReservationResponse> find(@PathVariable Long reservationId,
@LoginMember Member loginMember) {
ReservationResponse reservation = reservationService
.findReservation(reservationId, loginMember);
return ResponseEntity.ok().body(reservation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,33 @@
import com.modoospace.member.domain.Member;
import com.modoospace.reservation.controller.dto.ReservationResponse;
import com.modoospace.reservation.controller.dto.ReservationUpdateRequest;
import com.modoospace.reservation.controller.dto.search.HostSearchRequest;
import com.modoospace.reservation.serivce.ReservationService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/hosts/reservations")
@RequestMapping("/api/v1/host/reservations")
public class HostReservationController {

private final ReservationService reservationService;

@GetMapping
public ResponseEntity<List<ReservationResponse>> findAll(@LoginMember Member loginMember) {
List<ReservationResponse> reservations = reservationService.findAllAsHost(loginMember);
@GetMapping("/{reservationId}")
public ResponseEntity<ReservationResponse> find(@PathVariable Long reservationId,
@LoginMember Member loginMember) {
ReservationResponse reservation = reservationService.findReservation(reservationId, loginMember);
return ResponseEntity.ok().body(reservation);
}

@GetMapping()
public ResponseEntity<Page<ReservationResponse>> search(HostSearchRequest searchRequest, Pageable pageable, @LoginMember Member loginMember) {
Page<ReservationResponse> reservations = reservationService.searchReservationByHost(searchRequest, pageable, loginMember);
return ResponseEntity.ok().body(reservations);
}

Expand All @@ -41,11 +50,4 @@ public ResponseEntity<Void> update(
reservationService.updateReservation(reservationId, updateRequest, loginMember);
return ResponseEntity.ok().build();
}

@GetMapping("/{reservationId}")
public ResponseEntity<ReservationResponse> find(@PathVariable Long reservationId,
@LoginMember Member loginMember) {
ReservationResponse reservation = reservationService.findReservation(reservationId, loginMember);
return ResponseEntity.ok().body(reservation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,58 +6,69 @@
import com.modoospace.reservation.controller.dto.AvailabilityTimeResponse;
import com.modoospace.reservation.controller.dto.ReservationCreateRequest;
import com.modoospace.reservation.controller.dto.ReservationResponse;
import com.modoospace.reservation.controller.dto.search.VisitorSearchRequest;
import com.modoospace.reservation.serivce.ReservationService;
import java.time.LocalDate;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/visitors/reservations")
@RequestMapping("/api/v1/visitor/reservations")
public class VisitorsReservationController {

private final ReservationService reservationService;

@GetMapping
public ResponseEntity<List<ReservationResponse>> findAll(@LoginMember Member loginMember) {
List<ReservationResponse> reservations = reservationService.findAllAsVisitor(loginMember);
@GetMapping("/{reservationId}")
public ResponseEntity<ReservationResponse> find(@PathVariable Long reservationId,
@LoginMember Member loginMember) {
ReservationResponse reservation = reservationService.findReservation(reservationId,
loginMember);
return ResponseEntity.ok().body(reservation);
}

@GetMapping()
public ResponseEntity<Page<ReservationResponse>> search(VisitorSearchRequest searchRequest,
Pageable pageable,
@LoginMember Member loginMember) {
Page<ReservationResponse> reservations = reservationService.searchReservationByVisitor(
searchRequest, pageable, loginMember);
return ResponseEntity.ok().body(reservations);
}

@GetMapping("/facilities/{facilityId}/availability")
public ResponseEntity<AvailabilityTimeResponse> getAvailabilityTime(
@PathVariable Long facilityId,
@RequestParam @DateTimeFormat(pattern = DateFormatManager.DATE_FORMAT) final LocalDate date) {
AvailabilityTimeResponse availableTimes = reservationService
.getAvailabilityTime(facilityId, date);
AvailabilityTimeResponse availableTimes = reservationService.getAvailabilityTime(facilityId,
date);
return ResponseEntity.ok().body(availableTimes);
}

@PostMapping("/facilities/{facilityId}")
public ResponseEntity<Long> createReservation(@PathVariable Long facilityId,
@LoginMember Member loginMember,
@RequestBody @Valid ReservationCreateRequest createRequest) {
Long reservationId = reservationService.createReservation(
createRequest, facilityId, loginMember);
@LoginMember Member loginMember,
@RequestBody @Valid ReservationCreateRequest createRequest) {
Long reservationId = reservationService.createReservation(createRequest, facilityId,
loginMember);
return ResponseEntity.ok().body(reservationId);
}

@GetMapping("/{reservationId}")
public ResponseEntity<ReservationResponse> find(@PathVariable Long reservationId,
@LoginMember Member loginMember) {
ReservationResponse reservation = reservationService.findReservation(
reservationId, loginMember);
return ResponseEntity.ok().body(reservation);
}

@PutMapping("/{reservationId}/cancel")
public ResponseEntity<Void> cancelReservation(@PathVariable Long reservationId,
@LoginMember Member loginMember) {
@LoginMember Member loginMember) {
reservationService.cancelReservation(reservationId, loginMember);
return ResponseEntity.ok().build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.modoospace.reservation.controller.dto;

import com.modoospace.space.controller.dto.facility.FacilityResponse;
import com.modoospace.space.controller.dto.facility.FacilityDetailResponse;
import java.util.List;
import lombok.Getter;

@Getter
public class AvailabilityTimeResponse {

private final FacilityResponse facility;
private final FacilityDetailResponse facility;
private final List<TimeResponse> timeResponses;

public AvailabilityTimeResponse(FacilityResponse facility, List<TimeResponse> timeResponses) {
public AvailabilityTimeResponse(FacilityDetailResponse facility,
List<TimeResponse> timeResponses) {
this.facility = facility;
this.timeResponses = timeResponses;
}
Expand Down
Loading
Loading