From 9df83310fd2ecd14deb839c9cb4e87995b4b2a48 Mon Sep 17 00:00:00 2001 From: bc-kim Date: Tue, 25 Apr 2023 23:21:00 +0900 Subject: [PATCH 1/3] =?UTF-8?q?chore:=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - readme.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 readme.md diff --git a/.gitignore b/.gitignore index c2065bc..63d2f1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -HELP.md .gradle build/ !gradle/wrapper/gradle-wrapper.jar diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..097727f --- /dev/null +++ b/readme.md @@ -0,0 +1,31 @@ +# PoolC-Spring-Practice + +iCal 국제 표준을 준수하는 캘린더 서버를 개발해 봅시다. +단순 일정 작성 뿐만 아니라, 반복 일정, 일정 공유/초대 등의 기능등 복잡한 추가 기능도 개발해야 합니다. +물론, 이 과정에서 외부 캘린더와의 import/export도 완벽하게 동작해야 합니다. + +진행 방식 +--- +- Spring 프로그래밍 연습 스터디는, 하나의 큰 과제를 수행해야 합니다. + - Java 스터디에 비해 자유도가 조금 높으며, 요구 사항이 다소 추상적입니다. +- 직접적인 main 브랜치로의 커밋은 금지 되며, 반드시 Step 수행 이후 Pull Request 요청을 통해 확인이 진행됩니다. + - 본인의 닉네임/이름에 해당하는 브랜치를 만들고, 각 Step 에 대한 브랜치를 만들어서 PR을 진행해 주세요. + - ex) KBC 브랜치를 만들고, Step 1에 대한 결과물은 KBC-step1 로 만들어 주세요. + - 그 이후, PR은 KBC-step1 -> KBC 꼴로 요청해 주세요. +- 각 커밋의 단위는 최소화 해야하며, 다음과 같은 커밋 메시지 양식을 준수해 주세요. + - https://vsfe.notion.site/Git-Convention-84e1df4868974a58a1609b052e815095 + +요구 사항 (공통) +--- +- 해당 과제는 여러 Step으로 구성되어 있으며, 앞 Step에 대한 PR 및 리뷰가 완료 되어야 뒤 Step을 진행할 수 있습니다. +- 포함된 라이브러리는 기본적인 라이브러리만 포함되어 있으며, 필요에 따라 추가 라이브러리를 사용해도 됩니다. +- 모든 Java 코드는 반드시 Java 코드 컨벤션 가이드를 준수해야 합니다. +- 작성한 메서드에 대한 테스트 코드 작성이 진행되어야 합니다. + - Jacoco 기준, Test Coverage 및 Branch Coverage가 80% 이상이어야 합니다. + - 통합 테스트/단위 테스트 여부는 자유롭게 설정하셔도 됩니다. + - 하지만, 통합 테스트 수행 시, 실제 DB에 전혀 영향이 가지 않아야 합니다. +- 사용하는 DB는 제한이 없습니다. + +요구 사항 (단계) +--- +- 특정 Step 을 마치지 못했다면, 그 다음 Step의 요구 사항을 보지 않는 것을 권장합니다. https://vsfe.notion.site/Spring-My-Custom-Calendar-9be10f52debd48ad929d0ef56494ebfe From 9c811f3bd3a38c6cf77efa5cbb3ae8b7e7d8fb22 Mon Sep 17 00:00:00 2001 From: sjb7773 Date: Sat, 6 May 2023 12:39:40 +0900 Subject: [PATCH 2/3] feat : login and SignUp first version implement --- build.gradle | 8 + readme.md | 6 +- ...PoolCSpringPracticeSeason2Application.java | 2 +- .../java/org/poolc/config/SecurityConfig.java | 24 +++ .../java/org/poolc/config/SpringConfig.java | 43 +++++ .../org/poolc/controller/HomeController.java | 37 +++++ .../org/poolc/controller/LoginController.java | 66 ++++++++ .../poolc/controller/MemberController.java | 96 +++++++++++ .../controller/form/LoginFormController.java | 30 ++++ .../controller/session/SessionConst.java | 5 + .../controller/session/SessionManager.java | 69 ++++++++ src/main/java/org/poolc/domain/Member.java | 113 +++++++++++++ .../poolc/repository/JpaMemberRepository.java | 47 ++++++ .../poolc/repository/MemberRepository.java | 13 ++ .../repository/MemoryMemberRepository.java | 41 +++++ .../org/poolc/service/LoginServiceImpl.java | 31 ++++ .../java/org/poolc/service/MemberService.java | 16 ++ .../org/poolc/service/MemberServiceImpl.java | 72 +++++++++ src/main/resources/application.properties | 9 +- src/main/resources/static/index.html | 11 ++ src/main/resources/templates/home.html | 18 +++ src/main/resources/templates/loginHome.html | 19 +++ .../templates/members/createMemberForm.html | 40 +++++ .../templates/members/loginMemberForm.html | 19 +++ .../templates/members/memberList.html | 24 +++ .../templates/members/updateMemberForm.html | 40 +++++ .../org/poolc/controller/ControllerTest.java | 140 ++++++++++++++++ .../controller/MemberControllerTest.java | 153 ++++++++++++++++++ .../form/LoginFormControllerTest.java | 33 ++++ .../session/SessionManagerTest.java | 45 ++++++ .../java/org/poolc/domain/MemberTest.java | 92 +++++++++++ .../JpaMemberRepositoryIntegrationTest.java | 64 ++++++++ .../MemoryMemberRepositoryTest.java | 65 ++++++++ .../poolc/service/MemberServiceImplTest.java | 87 ++++++++++ 34 files changed, 1572 insertions(+), 6 deletions(-) rename src/main/java/org/poolc/{springpractice => }/PoolCSpringPracticeSeason2Application.java (90%) create mode 100644 src/main/java/org/poolc/config/SecurityConfig.java create mode 100644 src/main/java/org/poolc/config/SpringConfig.java create mode 100644 src/main/java/org/poolc/controller/HomeController.java create mode 100644 src/main/java/org/poolc/controller/LoginController.java create mode 100644 src/main/java/org/poolc/controller/MemberController.java create mode 100644 src/main/java/org/poolc/controller/form/LoginFormController.java create mode 100644 src/main/java/org/poolc/controller/session/SessionConst.java create mode 100644 src/main/java/org/poolc/controller/session/SessionManager.java create mode 100644 src/main/java/org/poolc/domain/Member.java create mode 100644 src/main/java/org/poolc/repository/JpaMemberRepository.java create mode 100644 src/main/java/org/poolc/repository/MemberRepository.java create mode 100644 src/main/java/org/poolc/repository/MemoryMemberRepository.java create mode 100644 src/main/java/org/poolc/service/LoginServiceImpl.java create mode 100644 src/main/java/org/poolc/service/MemberService.java create mode 100644 src/main/java/org/poolc/service/MemberServiceImpl.java create mode 100644 src/main/resources/static/index.html create mode 100644 src/main/resources/templates/home.html create mode 100644 src/main/resources/templates/loginHome.html create mode 100644 src/main/resources/templates/members/createMemberForm.html create mode 100644 src/main/resources/templates/members/loginMemberForm.html create mode 100644 src/main/resources/templates/members/memberList.html create mode 100644 src/main/resources/templates/members/updateMemberForm.html create mode 100644 src/test/java/org/poolc/controller/ControllerTest.java create mode 100644 src/test/java/org/poolc/controller/MemberControllerTest.java create mode 100644 src/test/java/org/poolc/controller/form/LoginFormControllerTest.java create mode 100644 src/test/java/org/poolc/controller/session/SessionManagerTest.java create mode 100644 src/test/java/org/poolc/domain/MemberTest.java create mode 100644 src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java create mode 100644 src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java create mode 100644 src/test/java/org/poolc/service/MemberServiceImplTest.java diff --git a/build.gradle b/build.gradle index 8d6b6e3..5146da0 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { id 'java' id 'org.springframework.boot' version '2.7.11' id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'jacoco' } group = 'org.poolc' @@ -19,12 +20,19 @@ repositories { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.apache.commons:commons-lang3:3.12.0' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.apache.commons:commons-collections4:4.4' + implementation 'org.eclipse.persistence:javax.persistence:2.2.1' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'com.h2database:h2' testImplementation 'org.springframework.boot:spring-boot-starter-test' + } tasks.named('test') { diff --git a/readme.md b/readme.md index 097727f..d6684c1 100644 --- a/readme.md +++ b/readme.md @@ -1,8 +1,6 @@ # PoolC-Spring-Practice -iCal 국제 표준을 준수하는 캘린더 서버를 개발해 봅시다. -단순 일정 작성 뿐만 아니라, 반복 일정, 일정 공유/초대 등의 기능등 복잡한 추가 기능도 개발해야 합니다. -물론, 이 과정에서 외부 캘린더와의 import/export도 완벽하게 동작해야 합니다. +풀씨 백엔드와 유사하지만, 일부 기능들을 개선한 서버를 만들어봅시다. 물론 풀씨 페이지는 규모가 상당히 크기에, 모든 컴포넌트를 만들 수 없으니 기본적인 것들만 구현해 봅시다. 진행 방식 --- @@ -28,4 +26,4 @@ iCal 국제 표준을 준수하는 캘린더 서버를 개발해 봅시다. 요구 사항 (단계) --- -- 특정 Step 을 마치지 못했다면, 그 다음 Step의 요구 사항을 보지 않는 것을 권장합니다. https://vsfe.notion.site/Spring-My-Custom-Calendar-9be10f52debd48ad929d0ef56494ebfe +- 특정 Step 을 마치지 못했다면, 그 다음 Step의 요구 사항을 보지 않는 것을 권장합니다. https://vsfe.notion.site/Spring-PoolC-Backend-Reborn-281c69c2eaf543459fedace987868ea4 diff --git a/src/main/java/org/poolc/springpractice/PoolCSpringPracticeSeason2Application.java b/src/main/java/org/poolc/PoolCSpringPracticeSeason2Application.java similarity index 90% rename from src/main/java/org/poolc/springpractice/PoolCSpringPracticeSeason2Application.java rename to src/main/java/org/poolc/PoolCSpringPracticeSeason2Application.java index 6c56a52..1e215ab 100644 --- a/src/main/java/org/poolc/springpractice/PoolCSpringPracticeSeason2Application.java +++ b/src/main/java/org/poolc/PoolCSpringPracticeSeason2Application.java @@ -1,4 +1,4 @@ -package org.poolc.springpractice; +package org.poolc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/org/poolc/config/SecurityConfig.java b/src/main/java/org/poolc/config/SecurityConfig.java new file mode 100644 index 0000000..82980bc --- /dev/null +++ b/src/main/java/org/poolc/config/SecurityConfig.java @@ -0,0 +1,24 @@ +package org.poolc.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + + +@Configuration @EnableWebSecurity +public class SecurityConfig{ + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ + http + .csrf().disable() // post 방식으로 값을 전송할 때 token을 사용해야하는 보안 설정을 해제 + .authorizeRequests() + .antMatchers("/", "/members/**").permitAll() + .anyRequest().authenticated(); + return http.build(); + } +} diff --git a/src/main/java/org/poolc/config/SpringConfig.java b/src/main/java/org/poolc/config/SpringConfig.java new file mode 100644 index 0000000..e068b82 --- /dev/null +++ b/src/main/java/org/poolc/config/SpringConfig.java @@ -0,0 +1,43 @@ +package org.poolc.config; + + + +import org.poolc.repository.JpaMemberRepository; +import org.poolc.repository.MemberRepository; +import org.poolc.repository.MemoryMemberRepository; +import org.poolc.service.MemberService; +import org.poolc.service.MemberServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + + +@Configuration +public class SpringConfig { + + @PersistenceContext + private EntityManager em; + + @Bean + public PasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public MemberService memberService(){ + + return new MemberServiceImpl(memberRepository(),bCryptPasswordEncoder() ); + } + + @Bean + public MemberRepository memberRepository(){ + + //return new MemoryMemberRepository(); + return new JpaMemberRepository(em); + } +} diff --git a/src/main/java/org/poolc/controller/HomeController.java b/src/main/java/org/poolc/controller/HomeController.java new file mode 100644 index 0000000..24aecd7 --- /dev/null +++ b/src/main/java/org/poolc/controller/HomeController.java @@ -0,0 +1,37 @@ +package org.poolc.controller; + +import lombok.RequiredArgsConstructor; +import org.poolc.controller.session.SessionConst; +import org.poolc.controller.session.SessionManager; +import org.poolc.domain.Member; +import org.poolc.repository.MemberRepository; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.CookieValue; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.SessionAttribute; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +@Controller +@RequiredArgsConstructor +public class HomeController { + + private final MemberRepository memberRepository; + private final SessionManager sessionManager; + + @GetMapping("/") + public String homeLoginV2( + @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model){ + + //세션에 회원데이터가 없으면 home + if(loginMember ==null){ + return "home"; + } + + //세션이 유지되면 회원 홈(로그인 모드 홈)으로 이동 + model.addAttribute("member", loginMember); + return "loginHome"; + } +} diff --git a/src/main/java/org/poolc/controller/LoginController.java b/src/main/java/org/poolc/controller/LoginController.java new file mode 100644 index 0000000..4c653c7 --- /dev/null +++ b/src/main/java/org/poolc/controller/LoginController.java @@ -0,0 +1,66 @@ +package org.poolc.controller; + +import lombok.RequiredArgsConstructor; +import org.poolc.controller.form.LoginFormController; +import org.poolc.controller.session.SessionConst; +import org.poolc.controller.session.SessionManager; +import org.poolc.domain.Member; +import org.poolc.service.LoginServiceImpl; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Controller; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.util.CookieGenerator; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.validation.Valid; + +@Controller +@RequiredArgsConstructor +public class LoginController { + + private final LoginServiceImpl loginService; + + // 로그인 페이지로 이동 + @GetMapping("/members/login") + public String loginForm(@ModelAttribute("loginForm") LoginFormController form){ + return "members/loginMemberForm"; + } + + @PostMapping("/members/login") + public String login(@Valid @ModelAttribute("loginForm") LoginFormController form, BindingResult bindingResult, HttpServletRequest request){ + // valid한 입력이 아닐경우(채우지 않은 칸이 존재), 로그인 화면으로 다시 redirection + if(bindingResult.hasErrors()){ + return "members/loginMemberForm"; + } + // 가입하지 않은 아이디일 경우, 로그인 화면으로 다시 redirection + Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); + if(loginMember == null){ + return "members/loginMemberForm"; + } + + //로그인 성공 -> 세션이 있으면 해당 세션 반환, 없으면 신규세션 생성(default=true) false면 세션 없으면 null을 반환 + HttpSession session = request.getSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember); + + return "redirect:/"; + } + + // 로그아웃 page로 이동 + @RequestMapping(value="/members/logout" , method = {RequestMethod.GET, RequestMethod.POST}) + public String logout(HttpServletRequest request){ + //로그아웃시 해당 세션 삭제 후 홈으로 이동 + HttpSession session = request.getSession(false); + if(session != null){ + session.invalidate(); + } + return "redirect:/"; + } + + + +} diff --git a/src/main/java/org/poolc/controller/MemberController.java b/src/main/java/org/poolc/controller/MemberController.java new file mode 100644 index 0000000..b993d5f --- /dev/null +++ b/src/main/java/org/poolc/controller/MemberController.java @@ -0,0 +1,96 @@ +package org.poolc.controller; + +import com.sun.xml.bind.v2.TODO; +import org.poolc.controller.session.SessionConst; +import org.poolc.domain.Member; +import org.poolc.service.MemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.SessionAttribute; + +import javax.validation.Valid; +import java.util.List; +import java.util.Optional; + +@Controller +public class MemberController { + + private final MemberService memberService; + + @Autowired + public MemberController(MemberService memberService){ + this.memberService = memberService; + } + + //회원 가입 페이지 + @GetMapping("/members/new") + public String createForm(@ModelAttribute("member") Member member){ + return "members/createMemberForm"; + } + + @PostMapping("/members/new") + + public String create(@Valid @ModelAttribute("member") Member member, BindingResult bindingResult){ + // 회원가입 정보가 valid하지않은 경우(채우지 않은 칸 존재) -> 다시 회원 가입 창으로 redirection + if(bindingResult.hasErrors()){ + return "members/createMemberForm"; + } + + //기존에 있는 회원 아이디와 동이한지 체크 + if(memberService.findByUserId(member.getUserId()).isPresent()){ + return "members/createMemberForm"; + } + + memberService.join(member); + + return "redirect:/"; + } + + // 회원들 리스트 나열 + @GetMapping("/members") + public String list(Model model){ + List members = memberService.findMembers(); + model.addAttribute("members", members); + return "members/memberList"; + } + + // 회원정보 수정 창 -> 회원 전용 홈(후술 로그인 홈)에서만 접근 가능해야함 + @GetMapping("/members/update") + public String UpdateForm(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) + Member loginMember, Model model){ + //세션에 회원데이터가 없으면 home + if(loginMember ==null){ + return "home"; + } + + //세션이 유지되면(로그인된 상태면) 회원 업데이트 화면으로 이동 + model.addAttribute("member", loginMember); + return "members/updateMemberForm"; + } + + + @PostMapping("/members/update") + public String update(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, + @Valid @ModelAttribute("member") Member member, BindingResult bindingResult){ + //세션에 회원데이터가 없으면 home ->의도적 API접근 막기 위함 + if(loginMember ==null){ + return "home"; + } + if(bindingResult.hasErrors()){ + return "members/updateMemberForm"; + } + // 업데이트 + memberService.update(loginMember.getId(), member); + + return "redirect:/members/logout"; + } + + + +} diff --git a/src/main/java/org/poolc/controller/form/LoginFormController.java b/src/main/java/org/poolc/controller/form/LoginFormController.java new file mode 100644 index 0000000..d880e8d --- /dev/null +++ b/src/main/java/org/poolc/controller/form/LoginFormController.java @@ -0,0 +1,30 @@ +package org.poolc.controller.form; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; + +public class LoginFormController { + + @NotEmpty + private String loginId; + + @NotEmpty + private String password; + + public String getLoginId() { + return loginId; + } + + public void setLoginId(String loginId) { + this.loginId = loginId; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/src/main/java/org/poolc/controller/session/SessionConst.java b/src/main/java/org/poolc/controller/session/SessionConst.java new file mode 100644 index 0000000..5596c66 --- /dev/null +++ b/src/main/java/org/poolc/controller/session/SessionConst.java @@ -0,0 +1,5 @@ +package org.poolc.controller.session; + +public abstract class SessionConst { + public static final String LOGIN_MEMBER = "loginMember"; +} diff --git a/src/main/java/org/poolc/controller/session/SessionManager.java b/src/main/java/org/poolc/controller/session/SessionManager.java new file mode 100644 index 0000000..7678177 --- /dev/null +++ b/src/main/java/org/poolc/controller/session/SessionManager.java @@ -0,0 +1,69 @@ +package org.poolc.controller.session; + +import org.springframework.stereotype.Component; +import org.springframework.web.util.CookieGenerator; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +@Component +public class SessionManager { + + private static final String SESSION_COOKIE_NAME = "mySessionId"; + private Map sessionStore = new ConcurrentHashMap<>(); + + /** + * 세션 생성 + */ + public void createSession(Object value, HttpServletResponse response){ + + //세션 id 생성 후 값을 세션에 저장 + String sessionId = UUID.randomUUID().toString(); + sessionStore.put(sessionId, value); + + // Cookie mySessionCookie = new Cookie(SESSION_COOKIE_NAME, sessionId); + + CookieGenerator cg = new CookieGenerator(); + cg.setCookieName(SESSION_COOKIE_NAME); + cg.addCookie(response, sessionId); + +// mySessionCookie.setPath("/"); +// response.addCookie(mySessionCookie); + } + + /** + * 세션 조회 ->request로부터 온 Session에 저장해둔 memberID가 있는지 체크/ 있다면 value return + */ + public Object getSession(HttpServletRequest request) { + Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME); + if (sessionCookie == null) { + return null; + } + return sessionStore.get(sessionCookie.getValue()); + } + /** + * 세션 만료 + */ + public void expire(HttpServletRequest request) { + Cookie sessionCookie = findCookie(request, SESSION_COOKIE_NAME); + if (sessionCookie != null) { + sessionStore.remove(sessionCookie.getValue()); + } + + } + + private Cookie findCookie(HttpServletRequest request, String cookieName) { + if (request.getCookies() == null) { + return null; + } + return Arrays.stream(request.getCookies()) + .filter(cookie -> cookie.getName().equals(cookieName)) + .findAny() + .orElse(null); + } +} diff --git a/src/main/java/org/poolc/domain/Member.java b/src/main/java/org/poolc/domain/Member.java new file mode 100644 index 0000000..0891da7 --- /dev/null +++ b/src/main/java/org/poolc/domain/Member.java @@ -0,0 +1,113 @@ +package org.poolc.domain; + +import lombok.Data; + +import javax.persistence.*; +import javax.validation.constraints.NotEmpty; + +@Entity //@Data가 들어왔을때 전체 coverage 가능한 테스트는 어떻게 할까? +public class Member { + + //this is PK + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "USERID") @NotEmpty + private String userId; + + @Column(name = "NAME") @NotEmpty + private String name; + + @Column(name = "PASSWORD") @NotEmpty + private String passWord; + + @Column(name = "EMAIL") @NotEmpty + private String email; + + @Column(name = "PHONENUM") @NotEmpty + private String phoneNum; + + @Column(name = "DEPARTMENT") @NotEmpty + private String department; + + @Column(name = "STUDENTID") @NotEmpty + private String studentId; + + public Member(){} + + public Member( String userId, String name, String passWord, + String email, String phoneNum, String department, String studentId) { + this.userId = userId; + this.name = name; + this.passWord = passWord; + this.email = email; + this.phoneNum = phoneNum; + this.department = department; + this.studentId = studentId; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassWord() { + return passWord; + } + + public void setPassWord(String passWord) { + this.passWord = passWord; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhoneNum() { + return phoneNum; + } + + public void setPhoneNum(String phoneNum) { + this.phoneNum = phoneNum; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public String getStudentId() { + return studentId; + } + + public void setStudentId(String studentId) { + this.studentId = studentId; + } + +} diff --git a/src/main/java/org/poolc/repository/JpaMemberRepository.java b/src/main/java/org/poolc/repository/JpaMemberRepository.java new file mode 100644 index 0000000..a0e280f --- /dev/null +++ b/src/main/java/org/poolc/repository/JpaMemberRepository.java @@ -0,0 +1,47 @@ +package org.poolc.repository; + +import org.poolc.domain.Member; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import java.util.List; +import java.util.Optional; + +@Transactional +public class JpaMemberRepository implements MemberRepository{ + + private final EntityManager em; + + public JpaMemberRepository(EntityManager em) { + this.em = em; + } + + @Override + public Member save(Member member) { + em.persist(member); + return member; + } + + @Override + public Optional findById(Long id) { + Member member = em.find(Member.class, id); + return Optional.ofNullable(member); + } + + @Override + public Optional findByUserId(String userId) { + List result = em.createQuery("select m from Member m where m.userId = :userId", + Member.class) + .setParameter("userId", userId) + .getResultList(); + return result.stream().findAny(); + } + + @Override + public List findAll() { + return em.createQuery("select m from Member m", Member.class) + .getResultList(); + } + +} diff --git a/src/main/java/org/poolc/repository/MemberRepository.java b/src/main/java/org/poolc/repository/MemberRepository.java new file mode 100644 index 0000000..d6da963 --- /dev/null +++ b/src/main/java/org/poolc/repository/MemberRepository.java @@ -0,0 +1,13 @@ +package org.poolc.repository; + +import org.poolc.domain.Member; + +import java.util.List; +import java.util.Optional; + +public interface MemberRepository { + Member save(Member member); + Optional findById(Long id); + Optional findByUserId(String userId); + List findAll(); +} diff --git a/src/main/java/org/poolc/repository/MemoryMemberRepository.java b/src/main/java/org/poolc/repository/MemoryMemberRepository.java new file mode 100644 index 0000000..983c594 --- /dev/null +++ b/src/main/java/org/poolc/repository/MemoryMemberRepository.java @@ -0,0 +1,41 @@ +package org.poolc.repository; + +import org.poolc.domain.Member; + +import java.util.*; + +public class MemoryMemberRepository implements MemberRepository{ + + //저장공간 ->key:회원id/value:Member static으로 공유변수일때는 동시성 문제때문에 concurrnetHashmap써야함 + private static Map store = new HashMap<>(); + //키값을 생성해주는얘, 애도 동시성 문제때문에 atom long등을 해주어야함 + private static long sequence = 0L; + + @Override + public Member save(Member member) { + member.setId(++sequence); + store.put(member.getId(),member); + return member; + } + + @Override + public Optional findById(Long id) { + return Optional.ofNullable(store.get(id)); + } + + @Override + public Optional findByUserId(String userId) { + return store.values().stream().filter(member -> member.getUserId().equals(userId)) + .findAny(); + } + + @Override + public List findAll() { + return new ArrayList<>(store.values()); + } + + + public void clearStore(){ + store.clear(); + } +} diff --git a/src/main/java/org/poolc/service/LoginServiceImpl.java b/src/main/java/org/poolc/service/LoginServiceImpl.java new file mode 100644 index 0000000..3fc64ea --- /dev/null +++ b/src/main/java/org/poolc/service/LoginServiceImpl.java @@ -0,0 +1,31 @@ +package org.poolc.service; + +import lombok.RequiredArgsConstructor; +import org.poolc.domain.Member; +import org.poolc.repository.MemberRepository; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class LoginServiceImpl { + + private final MemberRepository memberRepository; + private final PasswordEncoder passwordEncoder; + + /** + * + * @return null->로그인 실패 + */ + public Member login(String loginId, String password){ + //로그인 시도한 아이디가 있는지 체크 + Optional findMember = memberRepository.findByUserId(loginId); + //암호화된 비밀번호화 Match 되었는지 체크 + return findMember.filter(m->passwordEncoder.matches(password,m.getPassWord())) + .orElse(null); + + } + +} diff --git a/src/main/java/org/poolc/service/MemberService.java b/src/main/java/org/poolc/service/MemberService.java new file mode 100644 index 0000000..5730697 --- /dev/null +++ b/src/main/java/org/poolc/service/MemberService.java @@ -0,0 +1,16 @@ +package org.poolc.service; + +import org.poolc.domain.Member; + +import java.util.List; +import java.util.Optional; + +public interface MemberService { + + Long join(Member member); + List findMembers(); + Optional findOne(Long memberId); + Optional findByUserId(String userId); + Long update(Long id, Member afterMember); + +} diff --git a/src/main/java/org/poolc/service/MemberServiceImpl.java b/src/main/java/org/poolc/service/MemberServiceImpl.java new file mode 100644 index 0000000..c2be2e7 --- /dev/null +++ b/src/main/java/org/poolc/service/MemberServiceImpl.java @@ -0,0 +1,72 @@ +package org.poolc.service; + +import org.poolc.domain.Member; +import org.poolc.repository.MemberRepository; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + + + +public class MemberServiceImpl implements MemberService{ + + private final MemberRepository memberRepository; + private final PasswordEncoder bCryptPasswordEncoder; + + //member Repository를 외부에서 넣어주도록 설계. + public MemberServiceImpl(MemberRepository memberRepository, PasswordEncoder bCryptPasswordEncoder) { + this.memberRepository = memberRepository; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + @Override + public Long join(Member member) { + validateDuplicateMember(member); //중복회원 검증 후 비밀번호 암호화해서 저장 + member.setPassWord(bCryptPasswordEncoder.encode(member.getPassWord())); + memberRepository.save(member); + + return member.getId(); + } + + @Override + public List findMembers() { + return memberRepository.findAll(); + } + + @Override + public Optional findOne(Long id) { + return memberRepository.findById(id); + } + + @Override + public Optional findByUserId(String userId){ + return memberRepository.findByUserId(userId); + } + + private void validateDuplicateMember(Member member){ + //ifPresent-> 해당 userID를 가지고 있는 user가 있으면 예외 발생 + memberRepository.findByUserId(member.getUserId()) + .ifPresent(m->{ + throw new IllegalStateException("이미 존재하는 회원입니다."); + }); + } + + @Override @Transactional //DB에서 자동으로 수정된 정보 반영 + public Long update(Long id, Member afterMember) { + validateDuplicateMember(afterMember); + afterMember.setPassWord(bCryptPasswordEncoder.encode(afterMember.getPassWord())); + Member beforeMember = memberRepository.findById(id).get(); + beforeMember.setEmail(afterMember.getEmail()); + beforeMember.setUserId(afterMember.getUserId()); + beforeMember.setName(afterMember.getName()); + beforeMember.setPassWord(afterMember.getPassWord()); + beforeMember.setPhoneNum(afterMember.getPhoneNum()); + beforeMember.setDepartment(afterMember.getDepartment()); + beforeMember.setStudentId(afterMember.getStudentId()); + + return beforeMember.getId(); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..b71bfa0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,8 @@ - +spring.security.user.name = sjb7773 +spring.security.user.password =1234 +server.servlet.session.tracking-modes=cookie +spring.datasource.url=jdbc:h2:tcp://localhost/~/test +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.jpa.show-sql=true +spring.jpa.hibernate.ddl-auto=none \ No newline at end of file diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100644 index 0000000..355ea40 --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1,11 @@ + + + + + + + +Hello +hello + + \ No newline at end of file diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html new file mode 100644 index 0000000..098819f --- /dev/null +++ b/src/main/resources/templates/home.html @@ -0,0 +1,18 @@ + + + + +
+
+

Hello Spring JB

+

회원 기능

+

+ 로그인 + 회원 가입 + 회원 목록 +

+
+
+ + + diff --git a/src/main/resources/templates/loginHome.html b/src/main/resources/templates/loginHome.html new file mode 100644 index 0000000..89c4d54 --- /dev/null +++ b/src/main/resources/templates/loginHome.html @@ -0,0 +1,19 @@ + + + + +
+
+

Hello Spring JB

+

로그인 사용자 이름

+

회원 기능

+
+ + 회원 정보 수정 +
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/members/createMemberForm.html b/src/main/resources/templates/members/createMemberForm.html new file mode 100644 index 0000000..52a9de8 --- /dev/null +++ b/src/main/resources/templates/members/createMemberForm.html @@ -0,0 +1,40 @@ + + + + +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/members/loginMemberForm.html b/src/main/resources/templates/members/loginMemberForm.html new file mode 100644 index 0000000..449245a --- /dev/null +++ b/src/main/resources/templates/members/loginMemberForm.html @@ -0,0 +1,19 @@ + + + + +
+
+
+ + +
+
+ + +
+ +
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/members/memberList.html b/src/main/resources/templates/members/memberList.html new file mode 100644 index 0000000..e40fce6 --- /dev/null +++ b/src/main/resources/templates/members/memberList.html @@ -0,0 +1,24 @@ + + + + +
+
+ + + + + + + + + + + + + +
#이름
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/members/updateMemberForm.html b/src/main/resources/templates/members/updateMemberForm.html new file mode 100644 index 0000000..89b5d75 --- /dev/null +++ b/src/main/resources/templates/members/updateMemberForm.html @@ -0,0 +1,40 @@ + + + +

회원 수정란

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+ + \ No newline at end of file diff --git a/src/test/java/org/poolc/controller/ControllerTest.java b/src/test/java/org/poolc/controller/ControllerTest.java new file mode 100644 index 0000000..84d5a9e --- /dev/null +++ b/src/test/java/org/poolc/controller/ControllerTest.java @@ -0,0 +1,140 @@ +package org.poolc.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.poolc.controller.form.LoginFormController; +import org.poolc.controller.session.SessionConst; +import org.poolc.controller.session.SessionManager; +import org.poolc.domain.Member; +import org.poolc.repository.MemberRepository; +import org.poolc.service.LoginServiceImpl; +import org.poolc.service.MemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.transaction.annotation.Transactional; + +import javax.servlet.http.HttpServletRequest; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +//@WebMvcTest(HomeController.class) +@AutoConfigureMockMvc @SpringBootTest @Transactional +public class ControllerTest { + + + @Autowired + private SessionManager sessionManager; + + + @Autowired + private MemberService memberService; + @Autowired + private LoginServiceImpl loginService; + + ObjectMapper objectMapper = new ObjectMapper(); + + + @Autowired + private MockMvc mvc; + + + @Test + public void home() throws Exception { + + // perform() - 요청을 전송하는 역할, 결과로 ResultActions객체를 받고, 이 객체에서 리턴값을 검증하고 확인할 수 있는 andExcpect()메소드를 제공함. + mvc.perform(MockMvcRequestBuilders.get("/")) + //상태코드 -> isOk()는 상태코드 200 + .andExpect(status().isOk()) + // 응답본문의 내용을 검증함 -> Controller에서 'home'을 리턴하기 때문에 이값이 맞는지 검증한다. + .andExpect(view().name("home")); + } + + @Test + public void loginHome() throws Exception { + + Member member =new Member("123","김","123","123","123", + "123","123"); + memberService.join(member); + loginService.login("123", "123"); + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + //request에 응답 쿠키 저장 + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpSession session = new MockHttpSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + + mvc.perform(MockMvcRequestBuilders.get("/") + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("loginHome")); + } + + @Test + public void loginGet() throws Exception { + + mvc.perform(MockMvcRequestBuilders.get("/members/login")) + .andExpect(status().isOk()) + .andExpect(view().name("members/loginMemberForm")); + } + + @Test + public void loginPost() throws Exception { + Member member =new Member("123","김","123","123","123", + "123","123"); + memberService.join(member); + LoginFormController form = new LoginFormController(); + form.setLoginId("1234"); + form.setPassword("1234"); + mvc.perform(post("/members/login")) + .andExpect(status().isOk()) + //나중에 변경 + .andExpect(view().name("members/loginMemberForm")); + + mvc.perform(post("/members/login") + .flashAttr("loginForm",form)) + .andExpect(status().isOk()) + //나중에 변경 + .andExpect(view().name("members/loginMemberForm")); + form.setLoginId("123"); + form.setPassword("123"); + mvc.perform(post("/members/login") + .flashAttr("loginForm",form)) + //나중에 변경 + .andExpect(view().name("redirect:/")); + } + + @Test + public void logoutGetAndPost() throws Exception { + Member member =new Member("123","김","123","123","123", + "123","123"); + memberService.join(member); + loginService.login("123", "123"); + + mvc.perform(MockMvcRequestBuilders.get("/members/logout")) + .andExpect(view().name("redirect:/")); + + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + MockHttpSession session = new MockHttpSession(); + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + mvc.perform(post("/members/logout") + .session(session)) + .andExpect(view().name("redirect:/")); + } + +} diff --git a/src/test/java/org/poolc/controller/MemberControllerTest.java b/src/test/java/org/poolc/controller/MemberControllerTest.java new file mode 100644 index 0000000..e810fe2 --- /dev/null +++ b/src/test/java/org/poolc/controller/MemberControllerTest.java @@ -0,0 +1,153 @@ +package org.poolc.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.poolc.controller.session.SessionConst; +import org.poolc.controller.session.SessionManager; +import org.poolc.domain.Member; +import org.poolc.repository.MemberRepository; +import org.poolc.service.LoginServiceImpl; +import org.poolc.service.MemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.ModelAttribute; + +import javax.servlet.http.HttpSession; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +@SpringBootTest @Transactional @AutoConfigureMockMvc +public class MemberControllerTest { + + + @Autowired + private MemberService memberService; + @Autowired + private LoginServiceImpl loginService; + @Autowired + SessionManager sessionManager; + + ObjectMapper objectMapper = new ObjectMapper(); + + @Autowired + private MockMvc mvc; + + @Test + public void createFormGet() throws Exception { + + mvc.perform(MockMvcRequestBuilders.get("/members/new")) + .andExpect(status().isOk()) + .andExpect(view().name("members/createMemberForm")); + } + + @Test + public void createFormPost() throws Exception { + mvc.perform(MockMvcRequestBuilders.post("/members/new")) + .andExpect(status().isOk()) + .andExpect(view().name("members/createMemberForm")); + + Member member =new Member("123","김","123","123","123", + "123","123"); + memberService.join(member); + + Member member2 =new Member("123","김","123","123","123", + "123","123"); + mvc.perform(MockMvcRequestBuilders.post("/members/new") + .flashAttr("member", member2)) + .andExpect(status().isOk()) + .andExpect(view().name("members/createMemberForm")); + + member2.setUserId("456"); + member2.setPassWord("456"); + member2.setName("성"); + mvc.perform(MockMvcRequestBuilders.post("/members/new") + .flashAttr("member", member2)) + .andExpect(view().name("redirect:/")); + } + + @Test + public void MemberListGet() throws Exception { + + mvc.perform(MockMvcRequestBuilders.get("/members")) + .andExpect(status().isOk()) + .andExpect(view().name("members/memberList")); + } + + @Test + public void updateFormGet() throws Exception { + + Member member =new Member("123","김","123","123","123", + "123","123"); + memberService.join(member); + loginService.login("123", "123"); + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + + mvc.perform(MockMvcRequestBuilders.get("/members/update")) + .andExpect(status().isOk()) + .andExpect(view().name("home")); + //request에 응답 쿠키 저장 + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpSession session = new MockHttpSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + mvc.perform(MockMvcRequestBuilders.get("/members/update") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("members/updateMemberForm")); + } + + @Test @Transactional + public void updateFormPost() throws Exception { + Member member =new Member("123","김","123","123","123", + "123","123"); + memberService.join(member); + loginService.login("123", "123"); + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + + mvc.perform(MockMvcRequestBuilders.post("/members/update")) + .andExpect(status().isOk()) + .andExpect(view().name("home")); + + //request에 응답 쿠키 저장 + MockHttpServletRequest request = new MockHttpServletRequest(); + + MockHttpSession session = new MockHttpSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + mvc.perform(MockMvcRequestBuilders.post("/members/update") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("members/updateMemberForm")); + + + + Member member2 =new Member("1234","김","1234","1234","1234", + "1234","1234"); + + mvc.perform(MockMvcRequestBuilders.post("/members/update") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session) + .flashAttr("member", member2)) + .andExpect(view().name("redirect:/members/logout")); + } +} diff --git a/src/test/java/org/poolc/controller/form/LoginFormControllerTest.java b/src/test/java/org/poolc/controller/form/LoginFormControllerTest.java new file mode 100644 index 0000000..cab4844 --- /dev/null +++ b/src/test/java/org/poolc/controller/form/LoginFormControllerTest.java @@ -0,0 +1,33 @@ +package org.poolc.controller.form; + +import org.junit.jupiter.api.Test; +import org.poolc.domain.Member; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class LoginFormControllerTest { + + @Test + void getLoginId() { + LoginFormController form = new LoginFormController(); + form.setLoginId("123"); + assertThat("123").isEqualTo(form.getLoginId()); + } + + @Test + void getPassword() { + LoginFormController form = new LoginFormController(); + form.setPassword("123"); + assertThat("123").isEqualTo(form.getPassword()); + } + + @Test + void testEquals() { + LoginFormController form = new LoginFormController(); + LoginFormController form1 = form; + assertThat(form.equals(form1)).isEqualTo(true); + } + + +} \ No newline at end of file diff --git a/src/test/java/org/poolc/controller/session/SessionManagerTest.java b/src/test/java/org/poolc/controller/session/SessionManagerTest.java new file mode 100644 index 0000000..6a7a230 --- /dev/null +++ b/src/test/java/org/poolc/controller/session/SessionManagerTest.java @@ -0,0 +1,45 @@ +package org.poolc.controller.session; + + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.poolc.domain.Member; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import static org.assertj.core.api.Assertions.assertThat; + +class SessionManagerTest { + SessionManager sessionManager = new SessionManager(); + + @Test + void sessionTest(){ + + MockHttpServletResponse response = new MockHttpServletResponse(); + Member member = new Member(); + sessionManager.createSession(member, response); + + //request에 응답 쿠키 저장 + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setCookies(response.getCookies()); + + //session 조회 + Object result = sessionManager.getSession(request); + assertThat(result).isEqualTo(member); + + //session 만료 + sessionManager.expire(request); + Object expired = sessionManager.getSession(request); + assertThat(expired).isEqualTo(null); + } + + @Test + void nullSessionTest(){ + MockHttpServletRequest request = new MockHttpServletRequest(); + assertThat(sessionManager.getSession(request)).isNull(); + sessionManager.expire(request); + } +} diff --git a/src/test/java/org/poolc/domain/MemberTest.java b/src/test/java/org/poolc/domain/MemberTest.java new file mode 100644 index 0000000..5d62bf1 --- /dev/null +++ b/src/test/java/org/poolc/domain/MemberTest.java @@ -0,0 +1,92 @@ +package org.poolc.domain; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + + +class MemberTest { + + @Test + void constructorTest(){ + Member member =new Member(); + member.setUserId("123"); + member.setPassWord("123"); + member.setName("123"); + member.setDepartment("123"); + member.setEmail("123"); + member.setStudentId("123"); + member.setPhoneNum("123"); + Member member2 = new Member("123","123","123", + "123","123","123","123"); + assertThat(member.getUserId()).isEqualTo(member2.getUserId()); + } + + @Test + void getId() { + Member member = new Member(); + member.setId(99999L); + assertThat(99999L).isEqualTo(member.getId()); + } + + @Test + void getUserId() { + Member member = new Member(); + member.setUserId("123"); + assertThat("123").isEqualTo(member.getUserId()); + } + + @Test + void getName() { + Member member = new Member(); + member.setName("123"); + assertThat("123").isEqualTo(member.getName()); + } + + @Test + void getPassWord() { + Member member = new Member(); + member.setPassWord("123"); + assertThat("123").isEqualTo(member.getPassWord()); + } + + @Test + void getEmail() { + Member member = new Member(); + member.setEmail("123"); + assertThat("123").isEqualTo(member.getEmail()); + } + + @Test + void getPhoneNum() { + Member member = new Member(); + member.setPhoneNum("123"); + assertThat("123").isEqualTo(member.getPhoneNum()); + } + + @Test + void getDepartment() { + Member member = new Member(); + member.setDepartment("123"); + assertThat("123").isEqualTo(member.getDepartment()); + } + + @Test + void getStudentId() { + Member member = new Member(); + member.setStudentId("123"); + assertThat("123").isEqualTo(member.getStudentId()); + } + + + + @Test + void testEquals() { + Member member = new Member(); + Member member1 = member; + assertThat(member1.equals(member)).isEqualTo(true); + } + + +} \ No newline at end of file diff --git a/src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java b/src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java new file mode 100644 index 0000000..a0601c8 --- /dev/null +++ b/src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java @@ -0,0 +1,64 @@ +package org.poolc.repository; + +import org.junit.jupiter.api.Test; +import org.poolc.domain.Member; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + + +@Transactional @SpringBootTest +public class JpaMemberRepositoryIntegrationTest { + + @Autowired + MemberRepository repository; + + @Test + public void saveAndFindById(){ + //given + Member member =new Member("star123","홍길동","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + + //when + repository.save(member); + + //then + Member result = repository.findById(member.getId()).get(); + assertThat(member).isEqualTo(result); + } + + + @Test + public void findByUserId(){ + + Member member1 =new Member("star1234","spring1","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + repository.save(member1); + + Member member2 =new Member("star1234","spring2","good2345!","123@1235","010-1212-12123", + "컴퓨터과학","20121212123"); + repository.save(member2); + + Member result = repository.findByUserId("star1234").get(); + assertThat(result).isEqualTo(member1); + } + + + @Test + public void findAll(){ + Member member1 =new Member("star1234","spring1","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + repository.save(member1); + + Member member2 =new Member("star1234","spring2","good2345!","123@1235","010-1212-12123", + "컴퓨터과학","20121212123"); + repository.save(member2); + + List result = repository.findAll(); + assertThat(result.size()).isEqualTo(2); + } +} diff --git a/src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java b/src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java new file mode 100644 index 0000000..a051dce --- /dev/null +++ b/src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java @@ -0,0 +1,65 @@ +package org.poolc.repository; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +import org.poolc.domain.Member; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@Transactional +public class MemoryMemberRepositoryTest { + + MemoryMemberRepository repository = new MemoryMemberRepository(); + + + @AfterEach + public void afterEach(){ + repository.clearStore(); + } + + @Test + public void saveAndFindById(){ + //given + Member member =new Member("star","spring1","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + + //when + repository.save(member); + + //then + Member result = repository.findById(member.getId()).get(); + assertThat(member).isEqualTo(result); + } + + @Test + public void findByUserId(){ + Member member1 =new Member("star1234","sprin","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + Member member2 =new Member("sta2345","spring2","good2345!","123@1235","010-1212-12123", + "컴퓨터과학","20121212123"); + repository.save(member1); + repository.save(member2); + + Member result = repository.findByUserId("star1234").get(); + assertThat(result).isEqualTo(member1); + } + + + @Test + public void findAll(){ + Member member1 =new Member("star2345","spring1","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + repository.save(member1); + + Member member2 =new Member("star1234","spring2","good2345!","123@1235","010-1212-12123", + "컴퓨터과학","20121212123"); + repository.save(member2); + + List result = repository.findAll(); + assertThat(result.size()).isEqualTo(2); + } +} diff --git a/src/test/java/org/poolc/service/MemberServiceImplTest.java b/src/test/java/org/poolc/service/MemberServiceImplTest.java new file mode 100644 index 0000000..c07acb0 --- /dev/null +++ b/src/test/java/org/poolc/service/MemberServiceImplTest.java @@ -0,0 +1,87 @@ +package org.poolc.service; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.poolc.domain.Member; +import org.poolc.repository.MemoryMemberRepository; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MemberServiceImplTest { + + MemoryMemberRepository repository; + MemberService memberService; + PasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();; + + + //매 동작 전전 + @BeforeEach + public void beforeEach(){ + repository = new MemoryMemberRepository(); + memberService = new MemberServiceImpl(repository,bCryptPasswordEncoder); + } + + + @AfterEach + public void afterEach(){ + repository.clearStore(); + } + + @Test + void SuccessJoin() { + Member member =new Member("star123","홍길동","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + + memberService.join(member); + + Member result = repository.findByUserId("star123").get(); + assertThat(result).isEqualTo(member); + } + + @Test + void DuplicateJoin() { + Member member1 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + Member member2 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + + memberService.join(member1); + Assertions.assertThatThrownBy(()->memberService.join(member2)) + .isInstanceOf(java.lang.IllegalStateException.class); + } + + @Test + void findMembers() { + Member member1 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + Member member2 =new Member("star234555","성종빈","good2345!","123@1235","010-1212-12123", + "컴퓨터과학","201814777"); + + memberService.join(member1); + memberService.join(member2); + + List result = repository.findAll(); + assertThat(result.size()).isEqualTo(2); + } + + @Test + void findOne() { + Member member1 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", + "컴퓨터과학","2012121212"); + Member member2 =new Member("star234555","성종빈","good2345!","123@1235","010-1212-12123", + "컴퓨터과학","201814777"); + + memberService.join(member1); + memberService.join(member2); + + Member result = memberService.findOne(member2.getId()).get(); + assertThat(result).isEqualTo(member2); + } + +} From 7b936b59086e82e06679e1259464281af120369e Mon Sep 17 00:00:00 2001 From: sjb7773 Date: Fri, 19 May 2023 15:47:23 +0900 Subject: [PATCH 3/3] feat: SJB-STEP2 --- build.gradle | 41 +++-- .../java/org/poolc/config/SecurityConfig.java | 15 +- .../java/org/poolc/config/SpringConfig.java | 24 ++- .../org/poolc/controller/HomeController.java | 10 +- .../org/poolc/controller/LoginController.java | 44 +++--- .../poolc/controller/MemberController.java | 65 +++----- .../controller/RoleMypageController.java | 67 +++++++++ .../controller/form/LoginFormController.java | 2 - .../java/org/poolc/domain/MEMBER_ROLE.java | 9 ++ src/main/java/org/poolc/domain/Member.java | 45 ++++-- .../org/poolc/filter/LoginCheckFilter.java | 74 +++++++++ .../poolc/repository/JpaMemberRepository.java | 5 +- .../repository/MemoryMemberRepository.java | 14 +- ...oginServiceImpl.java => LoginService.java} | 9 +- .../java/org/poolc/service/MemberService.java | 75 +++++++++- .../org/poolc/service/MemberServiceImpl.java | 72 --------- src/main/resources/templates/home.html | 20 +-- src/main/resources/templates/loginHome.html | 25 ++-- .../members/adminAPI/memberRoleChange.html | 51 +++++++ .../templates/members/loginMemberForm.html | 11 +- .../templates/members/memberList.html | 1 + .../members/memberRole/AdminMemberMypage.html | 22 +++ .../memberRole/bronzeMemberMypage.html | 21 +++ .../members/memberRole/goldmemberMypage.html | 21 +++ .../memberRole/silverMemberMypage.html | 21 +++ src/test/java/org/poolc/TestConfig.java | 8 + .../org/poolc/controller/ControllerTest.java | 58 +++----- .../controller/MemberControllerTest.java | 73 +++++---- .../controller/RoleMypageControllerTest.java | 140 ++++++++++++++++++ .../java/org/poolc/domain/MemberTest.java | 18 ++- .../JpaMemberRepositoryIntegrationTest.java | 32 ++-- .../MemoryMemberRepositoryTest.java | 30 ++-- .../poolc/service/MemberServiceImplTest.java | 87 ----------- .../org/poolc/service/MemberServiceTest.java | 89 +++++++++++ 34 files changed, 861 insertions(+), 438 deletions(-) create mode 100644 src/main/java/org/poolc/controller/RoleMypageController.java create mode 100644 src/main/java/org/poolc/domain/MEMBER_ROLE.java create mode 100644 src/main/java/org/poolc/filter/LoginCheckFilter.java rename src/main/java/org/poolc/service/{LoginServiceImpl.java => LoginService.java} (71%) delete mode 100644 src/main/java/org/poolc/service/MemberServiceImpl.java create mode 100644 src/main/resources/templates/members/adminAPI/memberRoleChange.html create mode 100644 src/main/resources/templates/members/memberRole/AdminMemberMypage.html create mode 100644 src/main/resources/templates/members/memberRole/bronzeMemberMypage.html create mode 100644 src/main/resources/templates/members/memberRole/goldmemberMypage.html create mode 100644 src/main/resources/templates/members/memberRole/silverMemberMypage.html create mode 100644 src/test/java/org/poolc/TestConfig.java create mode 100644 src/test/java/org/poolc/controller/RoleMypageControllerTest.java delete mode 100644 src/test/java/org/poolc/service/MemberServiceImplTest.java create mode 100644 src/test/java/org/poolc/service/MemberServiceTest.java diff --git a/build.gradle b/build.gradle index 5146da0..42fe188 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,8 @@ plugins { - id 'java' - id 'org.springframework.boot' version '2.7.11' - id 'io.spring.dependency-management' version '1.0.15.RELEASE' - id 'jacoco' + id 'java' + id 'org.springframework.boot' version '2.7.11' + id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id 'jacoco' } group = 'org.poolc' @@ -10,31 +10,30 @@ version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' configurations { - compileOnly { - extendsFrom annotationProcessor - } + compileOnly { + extendsFrom annotationProcessor + } } repositories { - mavenCentral() + mavenCentral() } dependencies { - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.apache.commons:commons-lang3:3.12.0' - implementation 'org.springframework.boot:spring-boot-starter-security' - implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'org.apache.commons:commons-collections4:4.4' - implementation 'org.eclipse.persistence:javax.persistence:2.2.1' - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - runtimeOnly 'com.h2database:h2' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.apache.commons:commons-lang3:3.12.0' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.apache.commons:commons-collections4:4.4' + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'com.h2database:h2' + testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform() } diff --git a/src/main/java/org/poolc/config/SecurityConfig.java b/src/main/java/org/poolc/config/SecurityConfig.java index 82980bc..01e42a1 100644 --- a/src/main/java/org/poolc/config/SecurityConfig.java +++ b/src/main/java/org/poolc/config/SecurityConfig.java @@ -4,20 +4,23 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; -@Configuration @EnableWebSecurity -public class SecurityConfig{ +@Configuration +@EnableWebSecurity +public class SecurityConfig { + @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + + http .csrf().disable() // post 방식으로 값을 전송할 때 token을 사용해야하는 보안 설정을 해제 .authorizeRequests() - .antMatchers("/", "/members/**").permitAll() + .antMatchers("/", "/members/**", "/login", "/loginedMembers/**", "/role", "/admin/**").permitAll() +// .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated(); return http.build(); } diff --git a/src/main/java/org/poolc/config/SpringConfig.java b/src/main/java/org/poolc/config/SpringConfig.java index e068b82..430a247 100644 --- a/src/main/java/org/poolc/config/SpringConfig.java +++ b/src/main/java/org/poolc/config/SpringConfig.java @@ -1,13 +1,8 @@ package org.poolc.config; - -import org.poolc.repository.JpaMemberRepository; -import org.poolc.repository.MemberRepository; -import org.poolc.repository.MemoryMemberRepository; -import org.poolc.service.MemberService; -import org.poolc.service.MemberServiceImpl; -import org.springframework.beans.factory.annotation.Autowired; +import org.poolc.filter.LoginCheckFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -15,6 +10,7 @@ import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; +import javax.servlet.Filter; @Configuration @@ -28,16 +24,14 @@ public PasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } - @Bean - public MemberService memberService(){ - - return new MemberServiceImpl(memberRepository(),bCryptPasswordEncoder() ); - } @Bean - public MemberRepository memberRepository(){ + public FilterRegistrationBean loginCheckFilter() { + FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>(); + filterRegistrationBean.setFilter(new LoginCheckFilter()); + filterRegistrationBean.setOrder(1); + filterRegistrationBean.addUrlPatterns("/*"); - //return new MemoryMemberRepository(); - return new JpaMemberRepository(em); + return filterRegistrationBean; } } diff --git a/src/main/java/org/poolc/controller/HomeController.java b/src/main/java/org/poolc/controller/HomeController.java index 24aecd7..c519d1d 100644 --- a/src/main/java/org/poolc/controller/HomeController.java +++ b/src/main/java/org/poolc/controller/HomeController.java @@ -7,13 +7,9 @@ import org.poolc.repository.MemberRepository; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.SessionAttribute; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - @Controller @RequiredArgsConstructor public class HomeController { @@ -23,10 +19,10 @@ public class HomeController { @GetMapping("/") public String homeLoginV2( - @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model){ + @SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model) { - //세션에 회원데이터가 없으면 home - if(loginMember ==null){ + //로그인 여부에 따라 유저에게 다른 홈화면 제공 + if (loginMember == null) { return "home"; } diff --git a/src/main/java/org/poolc/controller/LoginController.java b/src/main/java/org/poolc/controller/LoginController.java index 4c653c7..56bec66 100644 --- a/src/main/java/org/poolc/controller/LoginController.java +++ b/src/main/java/org/poolc/controller/LoginController.java @@ -3,64 +3,64 @@ import lombok.RequiredArgsConstructor; import org.poolc.controller.form.LoginFormController; import org.poolc.controller.session.SessionConst; -import org.poolc.controller.session.SessionManager; import org.poolc.domain.Member; -import org.poolc.service.LoginServiceImpl; -import org.springframework.security.crypto.password.PasswordEncoder; +import org.poolc.service.LoginService; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; -import org.springframework.web.util.CookieGenerator; -import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.validation.Valid; + @Controller @RequiredArgsConstructor public class LoginController { - private final LoginServiceImpl loginService; + private final LoginService loginService; // 로그인 페이지로 이동 - @GetMapping("/members/login") - public String loginForm(@ModelAttribute("loginForm") LoginFormController form){ + @GetMapping("/login") + public String loginForm(@ModelAttribute("loginForm") LoginFormController form) { return "members/loginMemberForm"; } - @PostMapping("/members/login") - public String login(@Valid @ModelAttribute("loginForm") LoginFormController form, BindingResult bindingResult, HttpServletRequest request){ + @PostMapping("/login") + public String login(@Valid @ModelAttribute("loginForm") LoginFormController form, BindingResult bindingResult, + @RequestParam(defaultValue = "/") String redirectURL, + HttpServletRequest request) { // valid한 입력이 아닐경우(채우지 않은 칸이 존재), 로그인 화면으로 다시 redirection - if(bindingResult.hasErrors()){ + if (bindingResult.hasErrors()) { return "members/loginMemberForm"; } - // 가입하지 않은 아이디일 경우, 로그인 화면으로 다시 redirection Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); - if(loginMember == null){ + // 가입하지 않은 아이디일 경우, 로그인 화면으로 다시 redirection + if (loginMember == null) { return "members/loginMemberForm"; } - //로그인 성공 -> 세션이 있으면 해당 세션 반환, 없으면 신규세션 생성(default=true) false면 세션 없으면 null을 반환 HttpSession session = request.getSession(); //세션에 로그인 회원 정보 보관. session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember); - return "redirect:/"; + return "redirect:" + redirectURL; } - // 로그아웃 page로 이동 - @RequestMapping(value="/members/logout" , method = {RequestMethod.GET, RequestMethod.POST}) - public String logout(HttpServletRequest request){ + // 로그아웃 page로 이동 -> "/logout"시 query parameter(/login?logout)로 redirect 문제 차후 (Get, POST)분리 + @RequestMapping(value = "/loginedMembers/logout", method = {RequestMethod.GET, RequestMethod.POST}) + public String logout(HttpServletRequest request) { //로그아웃시 해당 세션 삭제 후 홈으로 이동 + sessionDelete(request); + return "redirect:/"; + } + + public void sessionDelete(HttpServletRequest request) { HttpSession session = request.getSession(false); - if(session != null){ + if (session != null) { session.invalidate(); } - return "redirect:/"; } - } diff --git a/src/main/java/org/poolc/controller/MemberController.java b/src/main/java/org/poolc/controller/MemberController.java index b993d5f..f6da0e0 100644 --- a/src/main/java/org/poolc/controller/MemberController.java +++ b/src/main/java/org/poolc/controller/MemberController.java @@ -1,96 +1,79 @@ package org.poolc.controller; -import com.sun.xml.bind.v2.TODO; +import lombok.RequiredArgsConstructor; import org.poolc.controller.session.SessionConst; +import org.poolc.domain.MEMBER_ROLE; import org.poolc.domain.Member; import org.poolc.service.MemberService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.SessionAttribute; +import org.springframework.web.bind.annotation.*; import javax.validation.Valid; import java.util.List; -import java.util.Optional; @Controller +@RequiredArgsConstructor +@RequestMapping("/members") public class MemberController { private final MemberService memberService; - @Autowired - public MemberController(MemberService memberService){ - this.memberService = memberService; - } //회원 가입 페이지 - @GetMapping("/members/new") - public String createForm(@ModelAttribute("member") Member member){ + @GetMapping("/new") + public String createForm(@ModelAttribute("member") Member member) { return "members/createMemberForm"; } - @PostMapping("/members/new") + @PostMapping("/new") + public String create(@Valid @ModelAttribute("member") Member member, BindingResult bindingResult) { - public String create(@Valid @ModelAttribute("member") Member member, BindingResult bindingResult){ // 회원가입 정보가 valid하지않은 경우(채우지 않은 칸 존재) -> 다시 회원 가입 창으로 redirection - if(bindingResult.hasErrors()){ + if (bindingResult.hasErrors()) { return "members/createMemberForm"; } - //기존에 있는 회원 아이디와 동이한지 체크 - if(memberService.findByUserId(member.getUserId()).isPresent()){ + if (memberService.findByUserId(member.getUserId()).isPresent()) { return "members/createMemberForm"; } - + // 신규회원의 등급은 브론즈로 설정 + member.setRole(MEMBER_ROLE.ROLE_BRONZE); memberService.join(member); return "redirect:/"; } // 회원들 리스트 나열 - @GetMapping("/members") - public String list(Model model){ + @GetMapping("") + public String list(Model model) { List members = memberService.findMembers(); model.addAttribute("members", members); return "members/memberList"; } - // 회원정보 수정 창 -> 회원 전용 홈(후술 로그인 홈)에서만 접근 가능해야함 - @GetMapping("/members/update") + // 회원정보 수정 창 + @GetMapping("/update") public String UpdateForm(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) - Member loginMember, Model model){ - //세션에 회원데이터가 없으면 home - if(loginMember ==null){ - return "home"; - } - - //세션이 유지되면(로그인된 상태면) 회원 업데이트 화면으로 이동 + Member loginMember, Model model) { + //회원 업데이트 화면으로 이동 model.addAttribute("member", loginMember); return "members/updateMemberForm"; } - @PostMapping("/members/update") + @PostMapping("/update") public String update(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, - @Valid @ModelAttribute("member") Member member, BindingResult bindingResult){ - //세션에 회원데이터가 없으면 home ->의도적 API접근 막기 위함 - if(loginMember ==null){ - return "home"; - } - if(bindingResult.hasErrors()){ + @Valid @ModelAttribute("member") Member member, BindingResult bindingResult) { + + if (bindingResult.hasErrors()) { return "members/updateMemberForm"; } - // 업데이트 memberService.update(loginMember.getId(), member); - return "redirect:/members/logout"; + return "redirect:/loginedMembers/logout"; } - } diff --git a/src/main/java/org/poolc/controller/RoleMypageController.java b/src/main/java/org/poolc/controller/RoleMypageController.java new file mode 100644 index 0000000..f727961 --- /dev/null +++ b/src/main/java/org/poolc/controller/RoleMypageController.java @@ -0,0 +1,67 @@ +package org.poolc.controller; + +import lombok.RequiredArgsConstructor; +import org.poolc.controller.session.SessionConst; +import org.poolc.domain.MEMBER_ROLE; +import org.poolc.domain.Member; +import org.poolc.service.MemberService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.SessionAttribute; + +import java.util.List; + +@Controller +@RequiredArgsConstructor +public class RoleMypageController { + + private final MemberService memberService; + + //model -> 컨트롤러에서 생성한 데이터를 담아서 view로 전달할때 사용하는 객체 + @GetMapping("/role") + public String distributeByRole(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) + Member loginMember, Model model) { + + model.addAttribute("member", loginMember); + return RoleDistributor(loginMember.getRole()); + } + + // 현재 회원들의 리스트와 / 올바른 API 검증용 로그인 사용자의 등급을 model로 전달 + @GetMapping("/admin/roleModify") + public String showRoleOfMembers(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) + Member loginMember, Model model) { + List members = memberService.findMembers(); + model.addAttribute("members", members); + model.addAttribute("role", loginMember.getRole()); + return "members/adminAPI/memberRoleChange"; + } + + + // Query Parameter로 관리자가 변경할 회원 아이디와 등급 전달. + @PostMapping("/admin/roleModify") + public String acceptRoleChange(@RequestParam("memberId") String memberId, + @RequestParam("member_role") MEMBER_ROLE member_role) { + System.out.println("memberId = " + memberId); + System.out.println("member_role = " + member_role); + memberService.RoleModify(Long.parseLong(memberId), member_role); + return "redirect:/"; + } + + //if-else문의 문제점 존재 -> 더 나은 방식 없을까? + public String RoleDistributor(MEMBER_ROLE member_role) { + if (member_role == MEMBER_ROLE.ROLE_ADMIN) { + return "members/memberRole/AdminMemberMypage"; + } else if (member_role == MEMBER_ROLE.ROLE_GOLD) { + return "members/memberRole/goldMemberMypage"; + } else if (member_role == MEMBER_ROLE.ROLE_SILVER) { + return "members/memberRole/silverMemberMypage"; + } else { + return "members/memberRole/bronzeMemberMypage"; + } + } + + +} diff --git a/src/main/java/org/poolc/controller/form/LoginFormController.java b/src/main/java/org/poolc/controller/form/LoginFormController.java index d880e8d..83a0d89 100644 --- a/src/main/java/org/poolc/controller/form/LoginFormController.java +++ b/src/main/java/org/poolc/controller/form/LoginFormController.java @@ -1,7 +1,5 @@ package org.poolc.controller.form; -import lombok.Data; - import javax.validation.constraints.NotEmpty; public class LoginFormController { diff --git a/src/main/java/org/poolc/domain/MEMBER_ROLE.java b/src/main/java/org/poolc/domain/MEMBER_ROLE.java new file mode 100644 index 0000000..93ca7cf --- /dev/null +++ b/src/main/java/org/poolc/domain/MEMBER_ROLE.java @@ -0,0 +1,9 @@ +package org.poolc.domain; + +public enum MEMBER_ROLE { + ROLE_ADMIN, + ROLE_GOLD, + ROLE_SILVER, + ROLE_BRONZE; +} + diff --git a/src/main/java/org/poolc/domain/Member.java b/src/main/java/org/poolc/domain/Member.java index 0891da7..4f4590e 100644 --- a/src/main/java/org/poolc/domain/Member.java +++ b/src/main/java/org/poolc/domain/Member.java @@ -1,7 +1,5 @@ package org.poolc.domain; -import lombok.Data; - import javax.persistence.*; import javax.validation.constraints.NotEmpty; @@ -9,34 +7,47 @@ public class Member { //this is PK - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "USERID") @NotEmpty + @Column(name = "USERID") + @NotEmpty private String userId; - @Column(name = "NAME") @NotEmpty + @Column(name = "NAME") + @NotEmpty private String name; - @Column(name = "PASSWORD") @NotEmpty + @Column(name = "PASSWORD") + @NotEmpty private String passWord; - @Column(name = "EMAIL") @NotEmpty + @Column(name = "EMAIL") + @NotEmpty private String email; - @Column(name = "PHONENUM") @NotEmpty + @Column(name = "PHONENUM") + @NotEmpty private String phoneNum; - @Column(name = "DEPARTMENT") @NotEmpty + @Column(name = "DEPARTMENT") + @NotEmpty private String department; - @Column(name = "STUDENTID") @NotEmpty + @Column(name = "STUDENTID") + @NotEmpty private String studentId; - public Member(){} + @Column(name = "ROLE") + private MEMBER_ROLE role; + + + public Member() { + } - public Member( String userId, String name, String passWord, - String email, String phoneNum, String department, String studentId) { + public Member(String userId, String name, String passWord, + String email, String phoneNum, String department, String studentId, MEMBER_ROLE role) { this.userId = userId; this.name = name; this.passWord = passWord; @@ -44,6 +55,7 @@ public Member( String userId, String name, String passWord, this.phoneNum = phoneNum; this.department = department; this.studentId = studentId; + this.role = role; } public Long getId() { @@ -110,4 +122,11 @@ public void setStudentId(String studentId) { this.studentId = studentId; } + public MEMBER_ROLE getRole() { + return role; + } + + public void setRole(MEMBER_ROLE role) { + this.role = role; + } } diff --git a/src/main/java/org/poolc/filter/LoginCheckFilter.java b/src/main/java/org/poolc/filter/LoginCheckFilter.java new file mode 100644 index 0000000..5408b53 --- /dev/null +++ b/src/main/java/org/poolc/filter/LoginCheckFilter.java @@ -0,0 +1,74 @@ +package org.poolc.filter; + +import lombok.extern.slf4j.Slf4j; +import org.poolc.controller.session.SessionConst; +import org.poolc.domain.MEMBER_ROLE; +import org.poolc.domain.Member; +import org.springframework.util.PatternMatchUtils; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; + +@Slf4j +public class LoginCheckFilter implements Filter { + + private static final String[] whitelist = {"/", "/members/new", "/login", + "/loginedMembers/logout", "/css/*"}; + private static final String[] adminlist = {"/admin/**"}; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + String requestURI = httpRequest.getRequestURI(); + HttpServletResponse httpResponse = (HttpServletResponse) response; + try { + log.info("인증 체크 필터 시작 {}", requestURI); + if (isLoginCheckPath(requestURI)) { + log.info("인증 체크 로직 실행 {}", requestURI); + HttpSession session = httpRequest.getSession(false); + if (session == null || + session.getAttribute(SessionConst.LOGIN_MEMBER) == null) { + log.info("미인증 사용자 요청 {}", requestURI); + //로그인으로 redirect + httpResponse.sendRedirect("/login?redirectURL=" + + requestURI); + return; //non-authentication 사용자는 다음으로 진행하지 않고 끝! + } + // 관리자 페이지면 권한 확인 + log.info("관리자 인증 체크 필터 시작 {}", requestURI); + if (isAdminCheckPath(requestURI)) { + Member member = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER); + if (member.getRole() != MEMBER_ROLE.ROLE_ADMIN) { + log.info("관리자 인증 실패 {}", requestURI); + httpResponse.sendRedirect("/"); + return; + } + log.info("관리자 인증 체크 필터 종료 {}", requestURI); + //관리자 성공 + } + + } + chain.doFilter(request, response); + } catch (Exception e) { + throw e; //Exception logging 가능 하지만, Tomcat까지 Exception를 보내주어야 함 + } finally { + log.info("인증 체크 필터 종료 {}", requestURI); + } + } + + //whitelist Path들은 authentication check 면제(return == false 경우). + private boolean isLoginCheckPath(String requestURI) { + return !PatternMatchUtils.simpleMatch(whitelist, requestURI); + } + + //admin Path들은 authentication check 관리자 권한 체크. + private boolean isAdminCheckPath(String requestURI) { + return PatternMatchUtils.simpleMatch(adminlist, requestURI); + } + + +} diff --git a/src/main/java/org/poolc/repository/JpaMemberRepository.java b/src/main/java/org/poolc/repository/JpaMemberRepository.java index a0e280f..ec52db0 100644 --- a/src/main/java/org/poolc/repository/JpaMemberRepository.java +++ b/src/main/java/org/poolc/repository/JpaMemberRepository.java @@ -1,7 +1,7 @@ package org.poolc.repository; import org.poolc.domain.Member; -import org.springframework.data.jpa.repository.Modifying; +import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; @@ -9,7 +9,8 @@ import java.util.Optional; @Transactional -public class JpaMemberRepository implements MemberRepository{ +@Repository +public class JpaMemberRepository implements MemberRepository { private final EntityManager em; diff --git a/src/main/java/org/poolc/repository/MemoryMemberRepository.java b/src/main/java/org/poolc/repository/MemoryMemberRepository.java index 983c594..e1080af 100644 --- a/src/main/java/org/poolc/repository/MemoryMemberRepository.java +++ b/src/main/java/org/poolc/repository/MemoryMemberRepository.java @@ -3,18 +3,20 @@ import org.poolc.domain.Member; import java.util.*; +import java.util.concurrent.atomic.AtomicLong; -public class MemoryMemberRepository implements MemberRepository{ + +public class MemoryMemberRepository implements MemberRepository { //저장공간 ->key:회원id/value:Member static으로 공유변수일때는 동시성 문제때문에 concurrnetHashmap써야함 - private static Map store = new HashMap<>(); + private static Map store = new HashMap<>(); //키값을 생성해주는얘, 애도 동시성 문제때문에 atom long등을 해주어야함 - private static long sequence = 0L; + private static AtomicLong sequence = new AtomicLong(0L); @Override public Member save(Member member) { - member.setId(++sequence); - store.put(member.getId(),member); + member.setId(sequence.incrementAndGet()); + store.put(member.getId(), member); return member; } @@ -35,7 +37,7 @@ public List findAll() { } - public void clearStore(){ + public void clearStore() { store.clear(); } } diff --git a/src/main/java/org/poolc/service/LoginServiceImpl.java b/src/main/java/org/poolc/service/LoginService.java similarity index 71% rename from src/main/java/org/poolc/service/LoginServiceImpl.java rename to src/main/java/org/poolc/service/LoginService.java index 3fc64ea..63c050b 100644 --- a/src/main/java/org/poolc/service/LoginServiceImpl.java +++ b/src/main/java/org/poolc/service/LoginService.java @@ -10,20 +10,19 @@ @Service @RequiredArgsConstructor -public class LoginServiceImpl { +public class LoginService { private final MemberRepository memberRepository; private final PasswordEncoder passwordEncoder; /** - * * @return null->로그인 실패 */ - public Member login(String loginId, String password){ - //로그인 시도한 아이디가 있는지 체크 + public Member login(String loginId, String password) { + //로그인 시도한 아이디가 있는지 체크 ->없으면 null반환. Optional findMember = memberRepository.findByUserId(loginId); //암호화된 비밀번호화 Match 되었는지 체크 - return findMember.filter(m->passwordEncoder.matches(password,m.getPassWord())) + return findMember.filter(m -> passwordEncoder.matches(password, m.getPassWord())) .orElse(null); } diff --git a/src/main/java/org/poolc/service/MemberService.java b/src/main/java/org/poolc/service/MemberService.java index 5730697..7d50347 100644 --- a/src/main/java/org/poolc/service/MemberService.java +++ b/src/main/java/org/poolc/service/MemberService.java @@ -1,16 +1,79 @@ package org.poolc.service; +import org.poolc.domain.MEMBER_ROLE; import org.poolc.domain.Member; +import org.poolc.repository.MemberRepository; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; -public interface MemberService { - Long join(Member member); - List findMembers(); - Optional findOne(Long memberId); - Optional findByUserId(String userId); - Long update(Long id, Member afterMember); +@Service +public class MemberService { + private final MemberRepository memberRepository; + private final PasswordEncoder bCryptPasswordEncoder; + + //member Repository를 외부에서 넣어주도록 설계. + public MemberService(MemberRepository memberRepository, PasswordEncoder bCryptPasswordEncoder) { + this.memberRepository = memberRepository; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + + public Long join(Member member) { + validateDuplicateMember(member); //중복회원 검증 후 비밀번호 암호화해서 저장 + member.setPassWord(bCryptPasswordEncoder.encode(member.getPassWord())); + memberRepository.save(member); + + return member.getId(); + } + + + public List findMembers() { + return memberRepository.findAll(); + } + + + public Optional findOne(Long id) { + return memberRepository.findById(id); + } + + + public Optional findByUserId(String userId) { + return memberRepository.findByUserId(userId); + } + + private void validateDuplicateMember(Member member) { + //ifPresent-> 해당 userID를 가지고 있는 user가 있으면 예외 발생 + memberRepository.findByUserId(member.getUserId()) + .ifPresent(m -> { + throw new IllegalStateException("이미 존재하는 회원입니다."); + }); + } + + @Transactional //DB에서 자동으로 수정된 정보 반영 + public Long update(Long id, Member afterMember) { + validateDuplicateMember(afterMember); + afterMember.setPassWord(bCryptPasswordEncoder.encode(afterMember.getPassWord())); + Member beforeMember = memberRepository.findById(id).get(); + beforeMember.setEmail(afterMember.getEmail()); + beforeMember.setUserId(afterMember.getUserId()); + beforeMember.setName(afterMember.getName()); + beforeMember.setPassWord(afterMember.getPassWord()); + beforeMember.setPhoneNum(afterMember.getPhoneNum()); + beforeMember.setDepartment(afterMember.getDepartment()); + beforeMember.setStudentId(afterMember.getStudentId()); + return beforeMember.getId(); + } + + @Transactional //ROle 변경 + public Long RoleModify(Long id, MEMBER_ROLE member_role) { + Member member = memberRepository.findById(id).get(); + member.setRole(member_role); + return member.getId(); + } } diff --git a/src/main/java/org/poolc/service/MemberServiceImpl.java b/src/main/java/org/poolc/service/MemberServiceImpl.java deleted file mode 100644 index c2be2e7..0000000 --- a/src/main/java/org/poolc/service/MemberServiceImpl.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.poolc.service; - -import org.poolc.domain.Member; -import org.poolc.repository.MemberRepository; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; - - - -public class MemberServiceImpl implements MemberService{ - - private final MemberRepository memberRepository; - private final PasswordEncoder bCryptPasswordEncoder; - - //member Repository를 외부에서 넣어주도록 설계. - public MemberServiceImpl(MemberRepository memberRepository, PasswordEncoder bCryptPasswordEncoder) { - this.memberRepository = memberRepository; - this.bCryptPasswordEncoder = bCryptPasswordEncoder; - } - - @Override - public Long join(Member member) { - validateDuplicateMember(member); //중복회원 검증 후 비밀번호 암호화해서 저장 - member.setPassWord(bCryptPasswordEncoder.encode(member.getPassWord())); - memberRepository.save(member); - - return member.getId(); - } - - @Override - public List findMembers() { - return memberRepository.findAll(); - } - - @Override - public Optional findOne(Long id) { - return memberRepository.findById(id); - } - - @Override - public Optional findByUserId(String userId){ - return memberRepository.findByUserId(userId); - } - - private void validateDuplicateMember(Member member){ - //ifPresent-> 해당 userID를 가지고 있는 user가 있으면 예외 발생 - memberRepository.findByUserId(member.getUserId()) - .ifPresent(m->{ - throw new IllegalStateException("이미 존재하는 회원입니다."); - }); - } - - @Override @Transactional //DB에서 자동으로 수정된 정보 반영 - public Long update(Long id, Member afterMember) { - validateDuplicateMember(afterMember); - afterMember.setPassWord(bCryptPasswordEncoder.encode(afterMember.getPassWord())); - Member beforeMember = memberRepository.findById(id).get(); - beforeMember.setEmail(afterMember.getEmail()); - beforeMember.setUserId(afterMember.getUserId()); - beforeMember.setName(afterMember.getName()); - beforeMember.setPassWord(afterMember.getPassWord()); - beforeMember.setPhoneNum(afterMember.getPhoneNum()); - beforeMember.setDepartment(afterMember.getDepartment()); - beforeMember.setStudentId(afterMember.getStudentId()); - - return beforeMember.getId(); - } -} diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html index 098819f..f08a4d3 100644 --- a/src/main/resources/templates/home.html +++ b/src/main/resources/templates/home.html @@ -1,17 +1,17 @@ - +
-
-

Hello Spring JB

-

회원 기능

-

- 로그인 - 회원 가입 - 회원 목록 -

-
+
+

Hello Spring JB

+

회원 기능

+

+ 로그인 + 회원 가입 + 회원 목록 +

+
diff --git a/src/main/resources/templates/loginHome.html b/src/main/resources/templates/loginHome.html index 89c4d54..87edec1 100644 --- a/src/main/resources/templates/loginHome.html +++ b/src/main/resources/templates/loginHome.html @@ -3,17 +3,20 @@
-
-

Hello Spring JB

-

로그인 사용자 이름

-

회원 기능

-
- - 회원 정보 수정 -
-
+
+

Hello Spring JB

+

로그인 사용자 이름

+

회원 기능

+
+ + 회원 정보 수정 + 마이 페이지 +
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/members/adminAPI/memberRoleChange.html b/src/main/resources/templates/members/adminAPI/memberRoleChange.html new file mode 100644 index 0000000..c069f21 --- /dev/null +++ b/src/main/resources/templates/members/adminAPI/memberRoleChange.html @@ -0,0 +1,51 @@ + + + + +
+
+

변경할 회원을 선택해주세요

+ + + + + + + + + + + + + + + +
#이름등급
+
+
+ + + +
+ +
+ + +
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/members/loginMemberForm.html b/src/main/resources/templates/members/loginMemberForm.html index 449245a..16cca52 100644 --- a/src/main/resources/templates/members/loginMemberForm.html +++ b/src/main/resources/templates/members/loginMemberForm.html @@ -1,16 +1,17 @@ +
-
+
- - + +
- - + +
diff --git a/src/main/resources/templates/members/memberList.html b/src/main/resources/templates/members/memberList.html index e40fce6..15a4751 100644 --- a/src/main/resources/templates/members/memberList.html +++ b/src/main/resources/templates/members/memberList.html @@ -20,5 +20,6 @@
+ \ No newline at end of file diff --git a/src/main/resources/templates/members/memberRole/AdminMemberMypage.html b/src/main/resources/templates/members/memberRole/AdminMemberMypage.html new file mode 100644 index 0000000..6755665 --- /dev/null +++ b/src/main/resources/templates/members/memberRole/AdminMemberMypage.html @@ -0,0 +1,22 @@ + + + + +
+
+

관리자님 환영합니다. 무엇을 도와드릴까요?

+

관리자님

+

회원 기능

+
+ + 회원 권한 수정 + 홈으로 가기 +
+
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/members/memberRole/bronzeMemberMypage.html b/src/main/resources/templates/members/memberRole/bronzeMemberMypage.html new file mode 100644 index 0000000..135cec6 --- /dev/null +++ b/src/main/resources/templates/members/memberRole/bronzeMemberMypage.html @@ -0,0 +1,21 @@ + + + + +
+
+

브론즈 등급의 사용자 환영합니다.

+

브론즈 등급

+

회원 기능

+
+ + 홈으로 가기 +
+
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/members/memberRole/goldmemberMypage.html b/src/main/resources/templates/members/memberRole/goldmemberMypage.html new file mode 100644 index 0000000..541f5ed --- /dev/null +++ b/src/main/resources/templates/members/memberRole/goldmemberMypage.html @@ -0,0 +1,21 @@ + + + + +
+
+

골드 등급의 사용자 환영합니다.

+

골드 등급

+

회원 기능

+
+ + 홈으로 가기 +
+
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/members/memberRole/silverMemberMypage.html b/src/main/resources/templates/members/memberRole/silverMemberMypage.html new file mode 100644 index 0000000..1b408aa --- /dev/null +++ b/src/main/resources/templates/members/memberRole/silverMemberMypage.html @@ -0,0 +1,21 @@ + + + + +
+
+

실버 등급의 사용자 환영합니다.

+

실버 등급

+

회원 기능

+
+ + 홈으로 가기 +
+
+
+ + + + \ No newline at end of file diff --git a/src/test/java/org/poolc/TestConfig.java b/src/test/java/org/poolc/TestConfig.java new file mode 100644 index 0000000..1affd06 --- /dev/null +++ b/src/test/java/org/poolc/TestConfig.java @@ -0,0 +1,8 @@ +package org.poolc; + +import org.springframework.context.annotation.Configuration; + +@Configuration +public class TestConfig { + +} diff --git a/src/test/java/org/poolc/controller/ControllerTest.java b/src/test/java/org/poolc/controller/ControllerTest.java index 84d5a9e..6a2bc15 100644 --- a/src/test/java/org/poolc/controller/ControllerTest.java +++ b/src/test/java/org/poolc/controller/ControllerTest.java @@ -1,22 +1,17 @@ package org.poolc.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Mock; import org.poolc.controller.form.LoginFormController; import org.poolc.controller.session.SessionConst; import org.poolc.controller.session.SessionManager; +import org.poolc.domain.MEMBER_ROLE; import org.poolc.domain.Member; -import org.poolc.repository.MemberRepository; -import org.poolc.service.LoginServiceImpl; +import org.poolc.service.LoginService; import org.poolc.service.MemberService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpSession; @@ -24,28 +19,24 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.transaction.annotation.Transactional; -import javax.servlet.http.HttpServletRequest; - import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; //@WebMvcTest(HomeController.class) -@AutoConfigureMockMvc @SpringBootTest @Transactional +@AutoConfigureMockMvc +@SpringBootTest +@Transactional public class ControllerTest { + ObjectMapper objectMapper = new ObjectMapper(); @Autowired private SessionManager sessionManager; - - @Autowired private MemberService memberService; @Autowired - private LoginServiceImpl loginService; - - ObjectMapper objectMapper = new ObjectMapper(); - - + private LoginService loginService; @Autowired private MockMvc mvc; @@ -64,8 +55,8 @@ public void home() throws Exception { @Test public void loginHome() throws Exception { - Member member =new Member("123","김","123","123","123", - "123","123"); + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); memberService.join(member); loginService.login("123", "123"); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -86,45 +77,44 @@ public void loginHome() throws Exception { @Test public void loginGet() throws Exception { - mvc.perform(MockMvcRequestBuilders.get("/members/login")) + mvc.perform(MockMvcRequestBuilders.get("/login")) .andExpect(status().isOk()) .andExpect(view().name("members/loginMemberForm")); } @Test public void loginPost() throws Exception { - Member member =new Member("123","김","123","123","123", - "123","123"); + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); memberService.join(member); LoginFormController form = new LoginFormController(); form.setLoginId("1234"); form.setPassword("1234"); - mvc.perform(post("/members/login")) + mvc.perform(post("/login")) .andExpect(status().isOk()) //나중에 변경 .andExpect(view().name("members/loginMemberForm")); - mvc.perform(post("/members/login") - .flashAttr("loginForm",form)) + mvc.perform(post("/login") + .flashAttr("loginForm", form)) .andExpect(status().isOk()) - //나중에 변경 .andExpect(view().name("members/loginMemberForm")); form.setLoginId("123"); form.setPassword("123"); - mvc.perform(post("/members/login") - .flashAttr("loginForm",form)) - //나중에 변경 + mvc.perform(post("/login") + .param("redirectURL", "/") + .flashAttr("loginForm", form)) .andExpect(view().name("redirect:/")); } @Test public void logoutGetAndPost() throws Exception { - Member member =new Member("123","김","123","123","123", - "123","123"); + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); memberService.join(member); loginService.login("123", "123"); - mvc.perform(MockMvcRequestBuilders.get("/members/logout")) + mvc.perform(MockMvcRequestBuilders.get("/loginedMembers/logout")) .andExpect(view().name("redirect:/")); MockHttpServletResponse response = new MockHttpServletResponse(); @@ -132,7 +122,7 @@ public void logoutGetAndPost() throws Exception { MockHttpSession session = new MockHttpSession(); session.setAttribute(SessionConst.LOGIN_MEMBER, member); - mvc.perform(post("/members/logout") + mvc.perform(post("/loginedMembers/logout") .session(session)) .andExpect(view().name("redirect:/")); } diff --git a/src/test/java/org/poolc/controller/MemberControllerTest.java b/src/test/java/org/poolc/controller/MemberControllerTest.java index e810fe2..72384cf 100644 --- a/src/test/java/org/poolc/controller/MemberControllerTest.java +++ b/src/test/java/org/poolc/controller/MemberControllerTest.java @@ -4,15 +4,13 @@ import org.junit.jupiter.api.Test; import org.poolc.controller.session.SessionConst; import org.poolc.controller.session.SessionManager; +import org.poolc.domain.MEMBER_ROLE; import org.poolc.domain.Member; -import org.poolc.repository.MemberRepository; -import org.poolc.service.LoginServiceImpl; +import org.poolc.service.LoginService; import org.poolc.service.MemberService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -20,26 +18,23 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.ModelAttribute; - -import javax.servlet.http.HttpSession; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; -@SpringBootTest @Transactional @AutoConfigureMockMvc +@SpringBootTest +@Transactional +@AutoConfigureMockMvc public class MemberControllerTest { - @Autowired - private MemberService memberService; - @Autowired - private LoginServiceImpl loginService; @Autowired SessionManager sessionManager; - ObjectMapper objectMapper = new ObjectMapper(); - + @Autowired + private MemberService memberService; + @Autowired + private LoginService loginService; @Autowired private MockMvc mvc; @@ -57,12 +52,12 @@ public void createFormPost() throws Exception { .andExpect(status().isOk()) .andExpect(view().name("members/createMemberForm")); - Member member =new Member("123","김","123","123","123", - "123","123"); + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); memberService.join(member); - Member member2 =new Member("123","김","123","123","123", - "123","123"); + Member member2 = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); mvc.perform(MockMvcRequestBuilders.post("/members/new") .flashAttr("member", member2)) .andExpect(status().isOk()) @@ -79,7 +74,20 @@ public void createFormPost() throws Exception { @Test public void MemberListGet() throws Exception { - mvc.perform(MockMvcRequestBuilders.get("/members")) + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); + memberService.join(member); + loginService.login("123", "123"); + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + MockHttpSession session = new MockHttpSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + mvc.perform(MockMvcRequestBuilders.get("/members") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) .andExpect(status().isOk()) .andExpect(view().name("members/memberList")); } @@ -87,16 +95,12 @@ public void MemberListGet() throws Exception { @Test public void updateFormGet() throws Exception { - Member member =new Member("123","김","123","123","123", - "123","123"); + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); memberService.join(member); loginService.login("123", "123"); MockHttpServletResponse response = new MockHttpServletResponse(); sessionManager.createSession(member, response); - - mvc.perform(MockMvcRequestBuilders.get("/members/update")) - .andExpect(status().isOk()) - .andExpect(view().name("home")); //request에 응답 쿠키 저장 MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpSession session = new MockHttpSession(); @@ -111,19 +115,15 @@ public void updateFormGet() throws Exception { .andExpect(view().name("members/updateMemberForm")); } - @Test @Transactional + @Test + @Transactional public void updateFormPost() throws Exception { - Member member =new Member("123","김","123","123","123", - "123","123"); + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_SILVER); memberService.join(member); loginService.login("123", "123"); MockHttpServletResponse response = new MockHttpServletResponse(); sessionManager.createSession(member, response); - - mvc.perform(MockMvcRequestBuilders.post("/members/update")) - .andExpect(status().isOk()) - .andExpect(view().name("home")); - //request에 응답 쿠키 저장 MockHttpServletRequest request = new MockHttpServletRequest(); @@ -139,15 +139,14 @@ public void updateFormPost() throws Exception { .andExpect(view().name("members/updateMemberForm")); - - Member member2 =new Member("1234","김","1234","1234","1234", - "1234","1234"); + Member member2 = new Member("1234", "김", "1234", "1234", "1234", + "1234", "1234", MEMBER_ROLE.ROLE_SILVER); mvc.perform(MockMvcRequestBuilders.post("/members/update") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(member)) .session(session) .flashAttr("member", member2)) - .andExpect(view().name("redirect:/members/logout")); + .andExpect(view().name("redirect:/loginedMembers/logout")); } } diff --git a/src/test/java/org/poolc/controller/RoleMypageControllerTest.java b/src/test/java/org/poolc/controller/RoleMypageControllerTest.java new file mode 100644 index 0000000..d8a71b4 --- /dev/null +++ b/src/test/java/org/poolc/controller/RoleMypageControllerTest.java @@ -0,0 +1,140 @@ +package org.poolc.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.poolc.controller.session.SessionConst; +import org.poolc.controller.session.SessionManager; +import org.poolc.domain.MEMBER_ROLE; +import org.poolc.domain.Member; +import org.poolc.service.LoginService; +import org.poolc.service.MemberService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.transaction.annotation.Transactional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view; + +@AutoConfigureMockMvc +@SpringBootTest +@Transactional +class RoleMypageControllerTest { + + + ObjectMapper objectMapper = new ObjectMapper(); + @Autowired + private MemberService memberService; + @Autowired + private LoginService loginService; + @Autowired + private SessionManager sessionManager; + @Autowired + private MockMvc mvc; + + @Test + public void distributeByRoleTest() throws Exception { + + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_BRONZE); + memberService.join(member); + loginService.login("123", "123"); + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + //request에 응답 쿠키 저장 + MockHttpSession session = new MockHttpSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + mvc.perform(MockMvcRequestBuilders.get("/role") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("members/memberRole/bronzeMemberMypage")); + + member.setRole(MEMBER_ROLE.ROLE_SILVER); + mvc.perform(MockMvcRequestBuilders.get("/role") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("members/memberRole/silverMemberMypage")); + + member.setRole(MEMBER_ROLE.ROLE_GOLD); + mvc.perform(MockMvcRequestBuilders.get("/role") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("members/memberRole/goldMemberMypage")); + + member.setRole(MEMBER_ROLE.ROLE_ADMIN); + mvc.perform(MockMvcRequestBuilders.get("/role") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("members/memberRole/AdminMemberMypage")); + + } + + @Test + public void roleModifyGet() throws Exception { + + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_ADMIN); + memberService.join(member); + loginService.login("123", "123"); + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + //request에 응답 쿠키 저장 + MockHttpSession session = new MockHttpSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + mvc.perform(MockMvcRequestBuilders.get("/admin/roleModify") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(status().isOk()) + .andExpect(view().name("members/adminAPI/memberRoleChange")); + } + + @Test + public void roleModifyPost() throws Exception { + + Member member = new Member("123", "김", "123", "123", "123", + "123", "123", MEMBER_ROLE.ROLE_ADMIN); + memberService.join(member); + + Member user = new Member("567", "박", "567", "567", "567", + "567", "567", MEMBER_ROLE.ROLE_BRONZE); + memberService.join(user); + + loginService.login("123", "123"); + MockHttpServletResponse response = new MockHttpServletResponse(); + sessionManager.createSession(member, response); + //request에 응답 쿠키 저장 + MockHttpSession session = new MockHttpSession(); + //세션에 로그인 회원 정보 보관. + session.setAttribute(SessionConst.LOGIN_MEMBER, member); + + + mvc.perform(MockMvcRequestBuilders.post("/admin/roleModify") + .param("memberId", user.getId().toString()) + .param("member_role", MEMBER_ROLE.ROLE_SILVER.toString()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(member)) + .session(session)) + .andExpect(view().name("redirect:/")); + assertThat(user.getRole()).isEqualTo(MEMBER_ROLE.ROLE_SILVER); + } + +} \ No newline at end of file diff --git a/src/test/java/org/poolc/domain/MemberTest.java b/src/test/java/org/poolc/domain/MemberTest.java index 5d62bf1..a158dcf 100644 --- a/src/test/java/org/poolc/domain/MemberTest.java +++ b/src/test/java/org/poolc/domain/MemberTest.java @@ -1,6 +1,5 @@ package org.poolc.domain; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -9,8 +8,8 @@ class MemberTest { @Test - void constructorTest(){ - Member member =new Member(); + void constructorTest() { + Member member = new Member(); member.setUserId("123"); member.setPassWord("123"); member.setName("123"); @@ -18,11 +17,19 @@ void constructorTest(){ member.setEmail("123"); member.setStudentId("123"); member.setPhoneNum("123"); - Member member2 = new Member("123","123","123", - "123","123","123","123"); + member.setRole(MEMBER_ROLE.ROLE_SILVER); + Member member2 = new Member("123", "123", "123", + "123", "123", "123", "123", MEMBER_ROLE.ROLE_SILVER); assertThat(member.getUserId()).isEqualTo(member2.getUserId()); } + @Test + void getRole() { + Member member = new Member(); + member.setRole(MEMBER_ROLE.ROLE_SILVER); + assertThat(MEMBER_ROLE.ROLE_SILVER).isEqualTo(member.getRole()); + } + @Test void getId() { Member member = new Member(); @@ -80,7 +87,6 @@ void getStudentId() { } - @Test void testEquals() { Member member = new Member(); diff --git a/src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java b/src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java index a0601c8..b802bb1 100644 --- a/src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java +++ b/src/test/java/org/poolc/repository/JpaMemberRepositoryIntegrationTest.java @@ -1,6 +1,7 @@ package org.poolc.repository; import org.junit.jupiter.api.Test; +import org.poolc.domain.MEMBER_ROLE; import org.poolc.domain.Member; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -11,17 +12,18 @@ import static org.assertj.core.api.Assertions.assertThat; -@Transactional @SpringBootTest +@Transactional +@SpringBootTest public class JpaMemberRepositoryIntegrationTest { @Autowired MemberRepository repository; @Test - public void saveAndFindById(){ + public void saveAndFindById() { //given - Member member =new Member("star123","홍길동","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); + Member member = new Member("star123", "홍길동", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); //when repository.save(member); @@ -33,14 +35,14 @@ public void saveAndFindById(){ @Test - public void findByUserId(){ + public void findByUserId() { - Member member1 =new Member("star1234","spring1","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); + Member member1 = new Member("star1234", "spring1", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); repository.save(member1); - Member member2 =new Member("star1234","spring2","good2345!","123@1235","010-1212-12123", - "컴퓨터과학","20121212123"); + Member member2 = new Member("star1234", "spring2", "good2345!", "123@1235", "010-1212-12123", + "컴퓨터과학", "20121212123", MEMBER_ROLE.ROLE_SILVER); repository.save(member2); Member result = repository.findByUserId("star1234").get(); @@ -49,16 +51,16 @@ public void findByUserId(){ @Test - public void findAll(){ - Member member1 =new Member("star1234","spring1","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); + public void findAll() { + Member member1 = new Member("star1234", "spring1", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); repository.save(member1); - Member member2 =new Member("star1234","spring2","good2345!","123@1235","010-1212-12123", - "컴퓨터과학","20121212123"); + Member member2 = new Member("star1234", "spring2", "good2345!", "123@1235", "010-1212-12123", + "컴퓨터과학", "20121212123", MEMBER_ROLE.ROLE_SILVER); repository.save(member2); List result = repository.findAll(); - assertThat(result.size()).isEqualTo(2); + assertThat(result.size()).isEqualTo(4); } } diff --git a/src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java b/src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java index a051dce..536e2ae 100644 --- a/src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java +++ b/src/test/java/org/poolc/repository/MemoryMemberRepositoryTest.java @@ -2,8 +2,8 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.poolc.domain.MEMBER_ROLE; import org.poolc.domain.Member; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -17,15 +17,15 @@ public class MemoryMemberRepositoryTest { @AfterEach - public void afterEach(){ + public void afterEach() { repository.clearStore(); } @Test - public void saveAndFindById(){ + public void saveAndFindById() { //given - Member member =new Member("star","spring1","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); + Member member = new Member("star", "spring1", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); //when repository.save(member); @@ -36,11 +36,11 @@ public void saveAndFindById(){ } @Test - public void findByUserId(){ - Member member1 =new Member("star1234","sprin","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); - Member member2 =new Member("sta2345","spring2","good2345!","123@1235","010-1212-12123", - "컴퓨터과학","20121212123"); + public void findByUserId() { + Member member1 = new Member("star1234", "sprin", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); + Member member2 = new Member("sta2345", "spring2", "good2345!", "123@1235", "010-1212-12123", + "컴퓨터과학", "20121212123", MEMBER_ROLE.ROLE_SILVER); repository.save(member1); repository.save(member2); @@ -50,13 +50,13 @@ public void findByUserId(){ @Test - public void findAll(){ - Member member1 =new Member("star2345","spring1","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); + public void findAll() { + Member member1 = new Member("star2345", "spring1", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); repository.save(member1); - Member member2 =new Member("star1234","spring2","good2345!","123@1235","010-1212-12123", - "컴퓨터과학","20121212123"); + Member member2 = new Member("star1234", "spring2", "good2345!", "123@1235", "010-1212-12123", + "컴퓨터과학", "20121212123", MEMBER_ROLE.ROLE_SILVER); repository.save(member2); List result = repository.findAll(); diff --git a/src/test/java/org/poolc/service/MemberServiceImplTest.java b/src/test/java/org/poolc/service/MemberServiceImplTest.java deleted file mode 100644 index c07acb0..0000000 --- a/src/test/java/org/poolc/service/MemberServiceImplTest.java +++ /dev/null @@ -1,87 +0,0 @@ -package org.poolc.service; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.poolc.domain.Member; -import org.poolc.repository.MemoryMemberRepository; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -public class MemberServiceImplTest { - - MemoryMemberRepository repository; - MemberService memberService; - PasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();; - - - //매 동작 전전 - @BeforeEach - public void beforeEach(){ - repository = new MemoryMemberRepository(); - memberService = new MemberServiceImpl(repository,bCryptPasswordEncoder); - } - - - @AfterEach - public void afterEach(){ - repository.clearStore(); - } - - @Test - void SuccessJoin() { - Member member =new Member("star123","홍길동","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); - - memberService.join(member); - - Member result = repository.findByUserId("star123").get(); - assertThat(result).isEqualTo(member); - } - - @Test - void DuplicateJoin() { - Member member1 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); - Member member2 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); - - memberService.join(member1); - Assertions.assertThatThrownBy(()->memberService.join(member2)) - .isInstanceOf(java.lang.IllegalStateException.class); - } - - @Test - void findMembers() { - Member member1 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); - Member member2 =new Member("star234555","성종빈","good2345!","123@1235","010-1212-12123", - "컴퓨터과학","201814777"); - - memberService.join(member1); - memberService.join(member2); - - List result = repository.findAll(); - assertThat(result.size()).isEqualTo(2); - } - - @Test - void findOne() { - Member member1 =new Member("star12355","홍길동","good1234!","123@123","010-1212-1212", - "컴퓨터과학","2012121212"); - Member member2 =new Member("star234555","성종빈","good2345!","123@1235","010-1212-12123", - "컴퓨터과학","201814777"); - - memberService.join(member1); - memberService.join(member2); - - Member result = memberService.findOne(member2.getId()).get(); - assertThat(result).isEqualTo(member2); - } - -} diff --git a/src/test/java/org/poolc/service/MemberServiceTest.java b/src/test/java/org/poolc/service/MemberServiceTest.java new file mode 100644 index 0000000..c6f323b --- /dev/null +++ b/src/test/java/org/poolc/service/MemberServiceTest.java @@ -0,0 +1,89 @@ +package org.poolc.service; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.poolc.domain.MEMBER_ROLE; +import org.poolc.domain.Member; +import org.poolc.repository.MemoryMemberRepository; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class MemberServiceTest { + + MemoryMemberRepository repository; + MemberService memberService; + PasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); + ; + + + //매 동작 전전 + @BeforeEach + public void beforeEach() { + repository = new MemoryMemberRepository(); + memberService = new MemberService(repository, bCryptPasswordEncoder); + } + + @AfterEach + public void afterEach() { + repository.clearStore(); + } + + @Test + void SuccessJoin() { + Member member = new Member("star123", "홍길동", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); + + memberService.join(member); + + Member result = repository.findByUserId("star123").get(); + assertThat(result).isEqualTo(member); + } + + @Test + void DuplicateJoin() { + Member member1 = new Member("star12355", "홍길동", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); + Member member2 = new Member("star12355", "홍길동", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); + + memberService.join(member1); + Assertions.assertThatThrownBy(() -> memberService.join(member2)) + .isInstanceOf(java.lang.IllegalStateException.class); + } + + @Test + void findMembers() { + Member member1 = new Member("star12355", "홍길동", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); + Member member2 = new Member("star234555", "성종빈", "good2345!", "123@1235", "010-1212-12123", + "컴퓨터과학", "201814777", MEMBER_ROLE.ROLE_SILVER); + + memberService.join(member1); + memberService.join(member2); + + List result = repository.findAll(); + assertThat(result.size()).isEqualTo(2); + } + + @Test + void findOne() { + Member member1 = new Member("star12355", "홍길동", "good1234!", "123@123", "010-1212-1212", + "컴퓨터과학", "2012121212", MEMBER_ROLE.ROLE_SILVER); + Member member2 = new Member("star234555", "성종빈", "good2345!", "123@1235", "010-1212-12123", + "컴퓨터과학", "201814777", MEMBER_ROLE.ROLE_SILVER); + + memberService.join(member1); + memberService.join(member2); + + Member result = memberService.findOne(member2.getId()).get(); + assertThat(result).isEqualTo(member2); + } + + +}