Skip to content

Commit

Permalink
Merge pull request #69 from f-lab-edu/feature/68-instructiontest
Browse files Browse the repository at this point in the history
[#68]Argument Resolver 리팩토링/Jacoco Report 설정/테스트커버리지80%달정
  • Loading branch information
hoa0217 authored Apr 1, 2024
2 parents d179dd3 + 02dc6ae commit 82b3e7d
Show file tree
Hide file tree
Showing 38 changed files with 1,047 additions and 394 deletions.
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

0 comments on commit 82b3e7d

Please sign in to comment.