From 35bcf420f6bf542ba1d5bb774345e03af7758fe3 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Mon, 23 Sep 2024 19:59:52 +0900 Subject: [PATCH 01/46] style:[#22]-format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 주석 추가,플러그인 버전 분리,중복되는 모듈 삭제 --- build.gradle | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 483de16..83f3fe2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,18 @@ +buildscript { + ext { + spring_boot_version = '3.3.3' + spring_dependency_management = '1.1.6' + } + + repositories { + mavenCentral() + } +} + plugins { id 'java' - id 'org.springframework.boot' version '3.3.3' - id 'io.spring.dependency-management' version '1.1.6' + id 'org.springframework.boot' version "${spring_boot_version}" + id 'io.spring.dependency-management' version "${spring_dependency_management}" } group = 'com.helpmeCookies' @@ -24,14 +35,19 @@ repositories { } dependencies { + + // Spring implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + // Lombok compileOnly 'org.projectlombok:lombok' - runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' + + // DB + runtimeOnly 'com.mysql:mysql-connector-j' runtimeOnly 'com.h2database:h2' - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testRuntimeOnly 'org.junit.platform:junit-platform-launcher' // Spring docs implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' From 233084a886305068658ebdd5e0310096df729722 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Mon, 23 Sep 2024 20:01:01 +0900 Subject: [PATCH 02/46] style:[#22]-Add MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JWT관련 의존성 추가 --- build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.gradle b/build.gradle index 83f3fe2..cb1381a 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,11 @@ dependencies { // Spring docs implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0' + + // JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' } tasks.named('test') { From adcd15e405d0cc2ee66d72467f11f9fc5b0d6220 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Mon, 23 Sep 2024 20:02:24 +0900 Subject: [PATCH 03/46] style:[#22]-Add MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spring Security 관련 의존성 추가 --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index cb1381a..e58b589 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'org.springframework.boot:spring-boot-starter-security' // Lombok compileOnly 'org.projectlombok:lombok' From 60d69c0b385b4d5e4030323b2e8a4613e9b321c7 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 00:52:28 +0900 Subject: [PATCH 04/46] feat:[#22]-Add JWT Token --- .../java/com/helpmeCookies/global/jwt/JwtToken.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/global/jwt/JwtToken.java diff --git a/src/main/java/com/helpmeCookies/global/jwt/JwtToken.java b/src/main/java/com/helpmeCookies/global/jwt/JwtToken.java new file mode 100644 index 0000000..ca5c80e --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/jwt/JwtToken.java @@ -0,0 +1,11 @@ +package com.helpmeCookies.global.jwt; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class JwtToken { + private String accessToken; + private String refreshToken; +} \ No newline at end of file From 75bbfea33c201a90f92278f5785c843c8c65f86a Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 00:53:56 +0900 Subject: [PATCH 05/46] feat:[#22]-Add JwtProvider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JwtProvider 구현. reissueAccessToken에 TODO가 존재한다. --- .../helpmeCookies/global/jwt/JwtProvider.java | 125 ++++++++++++++++++ .../com/helpmeCookies/global/jwt/JwtUser.java | 57 ++++++++ 2 files changed, 182 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/global/jwt/JwtProvider.java create mode 100644 src/main/java/com/helpmeCookies/global/jwt/JwtUser.java diff --git a/src/main/java/com/helpmeCookies/global/jwt/JwtProvider.java b/src/main/java/com/helpmeCookies/global/jwt/JwtProvider.java new file mode 100644 index 0000000..7a1e9c2 --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/jwt/JwtProvider.java @@ -0,0 +1,125 @@ +package com.helpmeCookies.global.jwt; + +import java.security.Key; +import java.util.Date; + +import javax.crypto.spec.SecretKeySpec; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +@Component +public class JwtProvider implements InitializingBean { + @Value("${jwt.secret}") + private String secret; + @Value("${jwt.access-token-expire-time}") + private long accessTokenExpireTime; + @Value("${jwt.refresh-token-expire-time}") + private long refreshTokenExpireTime; + private Key secretKey; + private static final String ROLE = "role"; + private static final String IS_ACCESS_TOKEN = "isAccessToken"; + private static final String HEADER_PREFIX = "Bearer "; + + public String parseHeader(String header) { + if (header == null || header.isEmpty()) { + throw new IllegalArgumentException("Authorization 헤더가 없습니다."); + } else if (!header.startsWith(HEADER_PREFIX)) { + throw new IllegalArgumentException("Authorization 올바르지 않습니다."); + } else if (header.split(" ").length != 2) { + throw new IllegalArgumentException("Authorization 올바르지 않습니다."); + } + + return header.split(" ")[1]; + } + + public JwtToken createToken(JwtUser jwtUser) { + String accessToken = generateToken(jwtUser, true); + String refreshToken = generateToken(jwtUser, false); + return JwtToken.builder() + .accessToken(accessToken) + .refreshToken(refreshToken) + .build(); + } + + // 유요한 토큰인지 확인 + public boolean validateToken(String rawToken, boolean isAccessToken) { + try { + // 엑세스 토큰인지 확인 + Claims claims = extractClaims(rawToken); + if (claims.get(IS_ACCESS_TOKEN, Boolean.class) != isAccessToken) { + return false; + } + // 만료시간 확인 + return !claims.getExpiration().before(new Date()); + } catch (Exception e) { + return false; + } + } + + /** + * refreshToken을 통해, accessToken을 재발급하는 메서드. + * refreshToken의 유효성을 검사하고, isAccessToken이 true일때만 accessToken을 재발급한다. + * TODO: refreshToken을 저장하고, 저장된 refreshToken과 비교하는 로직 필요 + */ + public String reissueAccessToken(String refreshToken) { + Claims claims = extractClaims(refreshToken); + if (claims.get(IS_ACCESS_TOKEN, Boolean.class)) { + throw new IllegalArgumentException("리프레시 토큰이 아닙니다."); + } + JwtUser jwtUser = claimsToJwtUser(claims); + return generateToken(jwtUser, true); + } + + /** + * [validateToken] 이후 호출하는 메서드. + * rawToken을 통해 JwtUser를 추출한다. + * [jwtUser]는 userId와 role을 가지고 있다. 즉 JWT에 저장된 정보를 추출한다. + */ + public JwtUser getJwtUser(String rawToken) { + Claims claims = extractClaims(rawToken); + return claimsToJwtUser(claims); + } + + private JwtUser claimsToJwtUser(Claims claims) { + String userId = claims.getSubject(); + return JwtUser.of(Long.parseLong(userId)); + } + + /** + * Jwt 토큰생성 + * accessToken과 refreshToken의 다른점은 만료시간과, isAccessToken이다. + */ + private String generateToken(JwtUser jwtUser, boolean isAccessToken) { + long expireTime = isAccessToken ? accessTokenExpireTime : refreshTokenExpireTime; + Date expireDate = new Date(System.currentTimeMillis() + expireTime); + return Jwts.builder() + .signWith(secretKey) + .claim(IS_ACCESS_TOKEN, isAccessToken) + .setSubject(jwtUser.getId().toString()) + .setExpiration(expireDate) + .compact(); + } + + + private Claims extractClaims(String rawToken) { + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(rawToken) + .getBody(); + } + + /** + * HS256방식의 키를 생성한다. + */ + @Override + public void afterPropertiesSet() { + secretKey = new SecretKeySpec(secret.getBytes(), SignatureAlgorithm.HS256.getJcaName()); + } +} diff --git a/src/main/java/com/helpmeCookies/global/jwt/JwtUser.java b/src/main/java/com/helpmeCookies/global/jwt/JwtUser.java new file mode 100644 index 0000000..bc60b98 --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/jwt/JwtUser.java @@ -0,0 +1,57 @@ +package com.helpmeCookies.global.jwt; + +import java.util.Collection; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class JwtUser implements UserDetails { + private Long id; + + public static JwtUser of(Long id) { + return JwtUser.builder() + .id(id) + .build(); + } + + @Override + public Collection getAuthorities() { + return null; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getUsername() { + return null; + } + + @Override + public boolean isAccountNonExpired() { + return false; + } + + @Override + public boolean isAccountNonLocked() { + return false; + } + + @Override + public boolean isCredentialsNonExpired() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } + +} \ No newline at end of file From 817e4eff0ef3f179dfd5eba971ebf0e08cf4dd2f Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 00:57:00 +0900 Subject: [PATCH 06/46] feat:[#22]-Add Error Handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JWT 토큰 관련 예외처리시 사용할 핸들러. Error 메시지에 대한 추가 구현이 남아있음. --- .../security/JwtAccessDeniedHandler.java | 32 +++++++++++++++++++ .../security/JwtAuthenticationEntryPoint.java | 29 +++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/global/security/JwtAccessDeniedHandler.java create mode 100644 src/main/java/com/helpmeCookies/global/security/JwtAuthenticationEntryPoint.java diff --git a/src/main/java/com/helpmeCookies/global/security/JwtAccessDeniedHandler.java b/src/main/java/com/helpmeCookies/global/security/JwtAccessDeniedHandler.java new file mode 100644 index 0000000..f6dde1c --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/security/JwtAccessDeniedHandler.java @@ -0,0 +1,32 @@ +package com.helpmeCookies.global.security; + +import java.io.IOException; +import java.io.PrintWriter; + +import org.springframework.http.MediaType; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +@RequiredArgsConstructor +public class JwtAccessDeniedHandler implements AccessDeniedHandler { + private final ObjectMapper objectMapper; + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, + AccessDeniedException accessDeniedException) { + log.error("Token : {}", request.getHeader("Authorization")); + // TODO: 에러코드 추가 + response.setStatus(403); + } +} \ No newline at end of file diff --git a/src/main/java/com/helpmeCookies/global/security/JwtAuthenticationEntryPoint.java b/src/main/java/com/helpmeCookies/global/security/JwtAuthenticationEntryPoint.java new file mode 100644 index 0000000..2072bb2 --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/security/JwtAuthenticationEntryPoint.java @@ -0,0 +1,29 @@ +package com.helpmeCookies.global.security; + +import java.io.IOException; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Component +@RequiredArgsConstructor +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + private final ObjectMapper objectMapper; + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { + log.debug("Token : {}", request.getHeader("Authorization")); + response.setStatus(401); + } +} From 203326b2f23e45aa2d0249ab3c6c91baf93b360b Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 00:58:12 +0900 Subject: [PATCH 07/46] feat:[#22]-Add JwtFilter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JWT 로직을 처리할 서블릿 필터 구현. UserDetailsService 부분이 추가 구현사항으로 남아있다. --- .../security/JwtAuthenticationFilter.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/global/security/JwtAuthenticationFilter.java diff --git a/src/main/java/com/helpmeCookies/global/security/JwtAuthenticationFilter.java b/src/main/java/com/helpmeCookies/global/security/JwtAuthenticationFilter.java new file mode 100644 index 0000000..1e70986 --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/security/JwtAuthenticationFilter.java @@ -0,0 +1,54 @@ +package com.helpmeCookies.global.security; + +import java.io.IOException; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import com.helpmeCookies.global.jwt.JwtProvider; +import com.helpmeCookies.global.jwt.JwtUser; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@RequiredArgsConstructor +@Slf4j +@Component +public class JwtAuthenticationFilter extends OncePerRequestFilter { + private final JwtProvider jwtProvider; + + private static final String AUTHORIZATION_HEADER = "Authorization"; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + log.info("JwtAuthenticationFilter"); + String rawToken; + + // 토큰 추출 + try { + rawToken = jwtProvider.parseHeader(request.getHeader(AUTHORIZATION_HEADER)); + } catch (Exception e) { + filterChain.doFilter(request, response); + return; + } + + // TODO: UserDetailsService를 통해 사용자 정보를 가져와 인증을 진행한다. + if (jwtProvider.validateToken(rawToken, true)) { + JwtUser jwtUser = jwtProvider.getJwtUser(rawToken); + Authentication authentication = new UsernamePasswordAuthenticationToken(jwtUser, null, + jwtUser.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + + filterChain.doFilter(request, response); + } +} \ No newline at end of file From d12f48149a093de761bc9def9cc161b98c39ec69 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 00:59:35 +0900 Subject: [PATCH 08/46] fix:[#22]- ChangeTableName MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 주문 도메인과 테이블명이 중복. 추후 협의후 최종 수정 예정. --- src/main/java/com/helpmeCookies/user/entity/User.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/helpmeCookies/user/entity/User.java b/src/main/java/com/helpmeCookies/user/entity/User.java index 08604fb..fe51ef9 100644 --- a/src/main/java/com/helpmeCookies/user/entity/User.java +++ b/src/main/java/com/helpmeCookies/user/entity/User.java @@ -49,7 +49,7 @@ public class User { // 별도의 테이블 생성. 문자열로 저장 @ElementCollection(targetClass = HashTag.class) - @CollectionTable(name = "user_hashtags") + @CollectionTable(name = "user_hashtag") @Enumerated(EnumType.STRING) private List hashTags; } From 69122c9164bf4b1767aa94fb2a53b2500896aadd Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 01:00:12 +0900 Subject: [PATCH 09/46] feat:[#22]- add UserRepository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JPA유저레포지토리 구현. --- .../helpmeCookies/user/repository/UserRepository.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/repository/UserRepository.java diff --git a/src/main/java/com/helpmeCookies/user/repository/UserRepository.java b/src/main/java/com/helpmeCookies/user/repository/UserRepository.java new file mode 100644 index 0000000..f17d2a6 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/repository/UserRepository.java @@ -0,0 +1,11 @@ +package com.helpmeCookies.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.helpmeCookies.user.entity.User; + +@Repository +public interface UserRepository extends JpaRepository { + +} From 4ec64194d9b7ea2afbceda84c61ca442c7a99639 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 01:00:41 +0900 Subject: [PATCH 10/46] feat:[#22]- add WebSecurityConfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WebSecurityConfig 구현. --- .../global/security/WebSecurityConfig.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java diff --git a/src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java b/src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java new file mode 100644 index 0000000..1703aa0 --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java @@ -0,0 +1,68 @@ +package com.helpmeCookies.global.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.stereotype.Controller; + +import lombok.RequiredArgsConstructor; + +@EnableMethodSecurity +@Configuration +@EnableWebSecurity +@RequiredArgsConstructor + + +@Controller +public class WebSecurityConfig { + private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; + private final JwtAccessDeniedHandler jwtAccessDeniedHandler; + private final JwtAuthenticationFilter jwtAuthenticationFilter; + + @Bean + public WebSecurityCustomizer configure() { + return (web) -> web.ignoring() + .requestMatchers("/static/**") + .requestMatchers("/test/**"); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf(AbstractHttpConfigurer::disable); + http.sessionManagement((session) -> session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS)); + + http.authorizeHttpRequests((authorize) -> + authorize + .requestMatchers( + "/login", "/signup", "/", "/user", + "/api/auth/**", + "/swagger-ui/**" + ).permitAll() + .anyRequest().authenticated() + ); + + http.exceptionHandling((exception) -> exception + .authenticationEntryPoint(jwtAuthenticationEntryPoint) + .accessDeniedHandler(jwtAccessDeniedHandler) + ); + + http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + +} \ No newline at end of file From 7b2c5755193d19043fd2994cd39dd61fba4a21b6 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 01:02:25 +0900 Subject: [PATCH 11/46] feat:[#22]- add LoginController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 임시 컨트롤러. 서비스 로직 완성후 의존성 변경이 필요하며, 이후 data.sql를 통해 진행한다. --- .../user/controller/LoginController.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/controller/LoginController.java diff --git a/src/main/java/com/helpmeCookies/user/controller/LoginController.java b/src/main/java/com/helpmeCookies/user/controller/LoginController.java new file mode 100644 index 0000000..393dba7 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/controller/LoginController.java @@ -0,0 +1,48 @@ +package com.helpmeCookies.user.controller; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.helpmeCookies.global.jwt.JwtProvider; +import com.helpmeCookies.global.jwt.JwtToken; +import com.helpmeCookies.global.jwt.JwtUser; +import com.helpmeCookies.product.entity.HashTag; +import com.helpmeCookies.user.entity.User; +import com.helpmeCookies.user.repository.UserRepository; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +//Todo: Swagger 추가 +public class LoginController { + private final UserRepository userRepository; + private final JwtProvider jwtProvider; + + // 임시 회원가입 url. 유저를 생성하고 jwt 토큰을 반환한다. + @GetMapping("/test/signup") + public JwtToken signup() { + User user = User.builder() + .nickname("test") + .email("test@test") + .birthdate("1999-01-01") + .address("서울시 강남구") + .phone("010-1234-5678") + .hashTags(List.of(HashTag.autumn, HashTag.winter)) + .build(); + userRepository.save(user); + return jwtProvider.createToken(JwtUser.of(user.getId())); + } + + // 임시 로그인 url. 로그인한 유저의 정보의 일부를 반환한다. + @GetMapping("/test/login") + public String login(@AuthenticationPrincipal JwtUser jwtUser) { + User user = userRepository.findById(jwtUser.getId()).get(); + return user.getEmail(); + } +} From 96fbb003e6ae3c2a157fc58c55d606cb2412de78 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 01:05:25 +0900 Subject: [PATCH 12/46] establish:[#22]- change gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit yaml 파일 gitignore에 추가. --- src/main/resources/application.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 8c37f1b..2e7bc5b 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -15,4 +15,8 @@ spring: # test profile logging.level: org.hibernate: orm.jdbc.bind: trace - SQL: debug \ No newline at end of file + SQL: debug +jwt: + secret: 4099a46b-39db-4860-a61b-2ae76ea24c43 + access-token-expire-time: 1800000 # 30 minutes + refresh-token-expire-time: 2592000000 # 30 days \ No newline at end of file From 5cc28b6812c89c7f9059fa59607c090c9774d6d2 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Tue, 24 Sep 2024 01:06:03 +0900 Subject: [PATCH 13/46] establish:[#22]- change gitignore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit yaml 파일 gitignore에 추가. --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c2065bc..546e78e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ -HELP.md .gradle + build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ +!**/src/main/resource/application.yaml !**/src/test/**/build/ ### STS ### From 699df05b47a87881d409340750c69c91bd1a102d Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 25 Sep 2024 00:55:12 +0900 Subject: [PATCH 14/46] =?UTF-8?q?feat:=20[#26]=20=ED=95=B4=EC=8B=9C?= =?UTF-8?q?=ED=83=9C=EA=B7=B8,=20=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20EN?= =?UTF-8?q?UM=20=ED=95=AD=EB=AA=A9=20=EC=B6=94=EA=B0=80=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=EC=8B=9C=20=EC=B6=94=ED=9B=84=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../helpmeCookies/product/entity/Category.java | 17 ++++++++++++++++- .../helpmeCookies/product/entity/HashTag.java | 11 ++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/helpmeCookies/product/entity/Category.java b/src/main/java/com/helpmeCookies/product/entity/Category.java index f160ccd..65f94ab 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Category.java +++ b/src/main/java/com/helpmeCookies/product/entity/Category.java @@ -1,5 +1,20 @@ package com.helpmeCookies.product.entity; public enum Category { - PICTURE; + PICTURE("사진"), + ORIENTAL("동양화"), + WESTERN("서양화"), + PIECE("조각화"), + CERAMIC("도예/공예"), + NEWMEDIA("뉴미디어"), + DESIGN("디자인"), + DRAWING("드로잉/판화"), + CALLIGRAPHY("서예/캘리그라피") + ; + + private String name; + + Category(String name) { + this.name = name; + } } diff --git a/src/main/java/com/helpmeCookies/product/entity/HashTag.java b/src/main/java/com/helpmeCookies/product/entity/HashTag.java index 8cb93f3..854c870 100644 --- a/src/main/java/com/helpmeCookies/product/entity/HashTag.java +++ b/src/main/java/com/helpmeCookies/product/entity/HashTag.java @@ -1,7 +1,16 @@ package com.helpmeCookies.product.entity; public enum HashTag { - autumn("가을"), winter("겨울"); + SERENITY("고요함"), + MELANCHOLY("멜랑꼴리"), + VIBRANCE("활기"), + NOSTALGIA("향수"), + MYSTERY("신비로움"), + JOYFUL("기쁨"), + LONELINESS("고독"), + CONTEMPLATION("사색"), + WONDER("경이로움"), + DREAMLIKE("몽환적"); private String name; From aa2dd0b53bb6fa739c77aac808f14afb41747686 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 25 Sep 2024 10:32:32 +0900 Subject: [PATCH 15/46] =?UTF-8?q?feat:=20[#25]=20String=20->=20ENUM=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/entity/Category.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/helpmeCookies/product/entity/Category.java b/src/main/java/com/helpmeCookies/product/entity/Category.java index 65f94ab..a58a7c0 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Category.java +++ b/src/main/java/com/helpmeCookies/product/entity/Category.java @@ -1,5 +1,8 @@ package com.helpmeCookies.product.entity; +import java.util.HashMap; +import java.util.Map; + public enum Category { PICTURE("사진"), ORIENTAL("동양화"), @@ -12,9 +15,29 @@ public enum Category { CALLIGRAPHY("서예/캘리그라피") ; - private String name; + private final String name; + private static final Map nameToCategoryMap = new HashMap<>(); + + static { + for (Category category : Category.values()) { + nameToCategoryMap.put(category.getName(), category); + } + } Category(String name) { this.name = name; } + + public String getName() { + return name; + } + + public static Category fromString(String name) { + System.out.println(name); + Category category = nameToCategoryMap.get(name); + if (category == null) { + throw new IllegalArgumentException(name + "에 해당하는 카테고리가 없습니다."); + } + return category; + } } From 4db141d337c1b1b54f1ef82a6291fad25e4be6d0 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 25 Sep 2024 10:33:56 +0900 Subject: [PATCH 16/46] =?UTF-8?q?feat:=20[#25]=20product=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=EA=B8=B0=EB=8A=A5=20ArtistInfo=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EB=8A=94=20=EC=B6=94=ED=9B=84=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 27 ++++++++++++++++ .../product/dto/ProductSaveRequest.java | 32 +++++++++++++++++++ .../helpmeCookies/product/entity/Product.java | 25 +++++++++++++-- .../product/repository/ProductRepository.java | 9 ++++++ .../product/service/ProductService.java | 23 +++++++++++++ 5 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/helpmeCookies/product/controller/ProductController.java create mode 100644 src/main/java/com/helpmeCookies/product/dto/ProductSaveRequest.java create mode 100644 src/main/java/com/helpmeCookies/product/repository/ProductRepository.java create mode 100644 src/main/java/com/helpmeCookies/product/service/ProductService.java diff --git a/src/main/java/com/helpmeCookies/product/controller/ProductController.java b/src/main/java/com/helpmeCookies/product/controller/ProductController.java new file mode 100644 index 0000000..dbc6768 --- /dev/null +++ b/src/main/java/com/helpmeCookies/product/controller/ProductController.java @@ -0,0 +1,27 @@ +package com.helpmeCookies.product.controller; + +import com.helpmeCookies.product.dto.ProductSaveRequest; +import com.helpmeCookies.product.entity.Product; +import com.helpmeCookies.product.service.ProductService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/products") +public class ProductController { + + private final ProductService productService; + + public ProductController(ProductService productService) { + this.productService = productService; + } + + @PostMapping + public ResponseEntity saveProduct(@RequestBody ProductSaveRequest productSaveRequest) { + Product product = productService.save(productSaveRequest); + return ResponseEntity.ok().body(product); + } +} diff --git a/src/main/java/com/helpmeCookies/product/dto/ProductSaveRequest.java b/src/main/java/com/helpmeCookies/product/dto/ProductSaveRequest.java new file mode 100644 index 0000000..8155748 --- /dev/null +++ b/src/main/java/com/helpmeCookies/product/dto/ProductSaveRequest.java @@ -0,0 +1,32 @@ +package com.helpmeCookies.product.dto; + +import com.helpmeCookies.product.entity.Category; +import com.helpmeCookies.product.entity.HashTag; +import com.helpmeCookies.product.entity.Product; +import com.helpmeCookies.user.entity.ArtistInfo; + +import java.util.List; + +public record ProductSaveRequest( + String name, + String category, + String size, + Long price, + String description, + String preferredLocation, + List hashTags, + Long artistInfo +) { + public Product toEntity(ArtistInfo artistInfo) { + return Product.builder() + .name(name) + .category(Category.fromString(category)) + .size(size) + .price(price) + .description(description) + .preferredLocation(preferredLocation) + .hashTags(hashTags) + .artistInfo(artistInfo) + .build(); + } +} diff --git a/src/main/java/com/helpmeCookies/product/entity/Product.java b/src/main/java/com/helpmeCookies/product/entity/Product.java index 145631c..1862d87 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Product.java +++ b/src/main/java/com/helpmeCookies/product/entity/Product.java @@ -14,7 +14,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; -import jakarta.persistence.OneToMany; +import lombok.Builder; @Entity public class Product { @@ -25,22 +25,41 @@ public class Product { @Column(nullable = false) private String name; + @Column(nullable = false) + @Enumerated(EnumType.STRING) private Category category; + @Column(nullable = false) private String size; + @Column(nullable = false) private Long price; + @Column(nullable = false) private String description; + @Column(nullable = false) private String preferredLocation; @ElementCollection(targetClass = HashTag.class) - @CollectionTable(name = "user_hashtags") + @CollectionTable(name = "product_hashtags") @Enumerated(EnumType.STRING) - private List hashTag; + private List hashTags; @ManyToOne private ArtistInfo artistInfo; + + public Product() {} + @Builder + public Product(String name, Category category, String size, Long price, String description, String preferredLocation, List hashTags, ArtistInfo artistInfo) { + this.name = name; + this.category = category; + this.size = size; + this.price = price; + this.description = description; + this.preferredLocation = preferredLocation; + this.hashTags = hashTags; + this.artistInfo = artistInfo; + } } diff --git a/src/main/java/com/helpmeCookies/product/repository/ProductRepository.java b/src/main/java/com/helpmeCookies/product/repository/ProductRepository.java new file mode 100644 index 0000000..d8b05f3 --- /dev/null +++ b/src/main/java/com/helpmeCookies/product/repository/ProductRepository.java @@ -0,0 +1,9 @@ +package com.helpmeCookies.product.repository; + +import com.helpmeCookies.product.entity.Product; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProductRepository extends JpaRepository { +} diff --git a/src/main/java/com/helpmeCookies/product/service/ProductService.java b/src/main/java/com/helpmeCookies/product/service/ProductService.java new file mode 100644 index 0000000..cb8dcfc --- /dev/null +++ b/src/main/java/com/helpmeCookies/product/service/ProductService.java @@ -0,0 +1,23 @@ +package com.helpmeCookies.product.service; + +import com.helpmeCookies.product.dto.ProductSaveRequest; +import com.helpmeCookies.product.entity.Product; +import com.helpmeCookies.product.repository.ProductRepository; +import org.springframework.stereotype.Service; + +@Service +public class ProductService { + private final ProductRepository productRepository; + + public ProductService(ProductRepository productRepository) { + this.productRepository = productRepository; + } + + public Product save(ProductSaveRequest productSaveRequest) { + //TODO ArtistInfo 코드 병합시 수정 예정 + Product product = productSaveRequest.toEntity(null); + productRepository.save(product); + return product; + } + +} From b9fa4730beff4a9d8754c59e9bb9120ad896c303 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Wed, 25 Sep 2024 11:15:58 +0900 Subject: [PATCH 17/46] =?UTF-8?q?feat:=20[#25]=20product=20=EA=B0=9C?= =?UTF-8?q?=EB=B3=84=20=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20ArtistInfo=20=EA=B4=80=EB=A0=A8=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=8A=94=20=EC=B6=94=ED=9B=84=20=EC=88=98=EC=A0=95=20=EC=98=88?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 12 +++-- .../product/dto/ProductResponse.java | 53 +++++++++++++++++++ .../helpmeCookies/product/entity/Product.java | 37 +++++++++++++ .../product/service/ProductService.java | 3 ++ 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/helpmeCookies/product/dto/ProductResponse.java diff --git a/src/main/java/com/helpmeCookies/product/controller/ProductController.java b/src/main/java/com/helpmeCookies/product/controller/ProductController.java index dbc6768..a16bcd7 100644 --- a/src/main/java/com/helpmeCookies/product/controller/ProductController.java +++ b/src/main/java/com/helpmeCookies/product/controller/ProductController.java @@ -1,13 +1,11 @@ package com.helpmeCookies.product.controller; +import com.helpmeCookies.product.dto.ProductResponse; import com.helpmeCookies.product.dto.ProductSaveRequest; import com.helpmeCookies.product.entity.Product; import com.helpmeCookies.product.service.ProductService; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/v1/products") @@ -24,4 +22,10 @@ public ResponseEntity saveProduct(@RequestBody ProductSaveRequest produ Product product = productService.save(productSaveRequest); return ResponseEntity.ok().body(product); } + + @GetMapping("/{productId}") + public ResponseEntity getProductInfo(@PathVariable("productId") Long productId) { + Product product = productService.find(productId); + return ResponseEntity.ok(ProductResponse.from(product)); + } } diff --git a/src/main/java/com/helpmeCookies/product/dto/ProductResponse.java b/src/main/java/com/helpmeCookies/product/dto/ProductResponse.java new file mode 100644 index 0000000..36b6e95 --- /dev/null +++ b/src/main/java/com/helpmeCookies/product/dto/ProductResponse.java @@ -0,0 +1,53 @@ +package com.helpmeCookies.product.dto; + +import com.helpmeCookies.product.entity.HashTag; +import com.helpmeCookies.product.entity.Product; + +import java.util.List; + +public record ProductResponse( + Long id, + String name, + String category, + String size, + Long price, + String description, + String preferredLocation, + List hashTags, + ArtistInfo artistInfo +) { + public static class ArtistInfo { + private final Long artistId; + private final String name; + + public ArtistInfo(Long artistId, String name) { + this.artistId = artistId; + this.name = name; + } + + public Long getArtistId() { + return artistId; + } + + public String getName() { + return name; + } + } + + public static ProductResponse from(Product product) { + //TODO artistInfo 코드 개발 이후 수정 예정 + return new ProductResponse( + product.getId(), + product.getName(), + product.getCategory().getName(), + product.getSize(), + product.getPrice(), + product.getDescription(), + product.getPreferredLocation(), + product.getHashTags(), + new ArtistInfo( + 1L, "임시" + ) + ); + } +} diff --git a/src/main/java/com/helpmeCookies/product/entity/Product.java b/src/main/java/com/helpmeCookies/product/entity/Product.java index 1862d87..4823196 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Product.java +++ b/src/main/java/com/helpmeCookies/product/entity/Product.java @@ -51,6 +51,7 @@ public class Product { private ArtistInfo artistInfo; public Product() {} + @Builder public Product(String name, Category category, String size, Long price, String description, String preferredLocation, List hashTags, ArtistInfo artistInfo) { this.name = name; @@ -62,4 +63,40 @@ public Product(String name, Category category, String size, Long price, String d this.hashTags = hashTags; this.artistInfo = artistInfo; } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public Category getCategory() { + return category; + } + + public String getSize() { + return size; + } + + public Long getPrice() { + return price; + } + + public String getDescription() { + return description; + } + + public String getPreferredLocation() { + return preferredLocation; + } + + public List getHashTags() { + return hashTags; + } + + public ArtistInfo getArtistInfo() { + return artistInfo; + } } diff --git a/src/main/java/com/helpmeCookies/product/service/ProductService.java b/src/main/java/com/helpmeCookies/product/service/ProductService.java index cb8dcfc..686d72f 100644 --- a/src/main/java/com/helpmeCookies/product/service/ProductService.java +++ b/src/main/java/com/helpmeCookies/product/service/ProductService.java @@ -20,4 +20,7 @@ public Product save(ProductSaveRequest productSaveRequest) { return product; } + public Product find(Long productId) { + return productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 id입니다")); + } } From 3359119f2cc79f32f3a4ccaab8ce5337fcff99e6 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 27 Sep 2024 18:33:42 +0900 Subject: [PATCH 18/46] test:[#22]- Add data.sql MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테스트를 위한 data.sql추가 --- src/main/resources/data.sql | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/main/resources/data.sql diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..74c89be --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,81 @@ +INSERT INTO users (nickname, email, birthdate, phone, address, created_at) +VALUES + ('JohnDoe', 'johndoe@example.com', '1990-01-15', '010-1234-5678', 'Seoul, South Korea', '2024-09-23T12:00:00'), + ('JaneSmith', 'janesmith@example.com', '1985-05-23', '010-9876-5432', 'Busan, South Korea', '2024-09-23T12:00:00'), + ('MikeJohnson', 'mikejohnson@example.com', '1992-03-10', '010-5678-1234', 'Incheon, South Korea', '2024-09-23T12:00:00'), + ('EmilyDavis', 'emilydavis@example.com', '1988-08-17', '010-8765-4321', 'Daegu, South Korea', '2024-09-23T12:00:00'), + ('DavidWilson', 'davidwilson@example.com', '1995-07-07', '010-1111-2222', 'Daejeon, South Korea', '2024-09-23T12:00:00'), + ('SophiaMiller', 'sophiamiller@example.com', '1989-02-25', '010-3333-4444', 'Gwangju, South Korea', '2024-09-23T12:00:00'), + ('JamesBrown', 'jamesbrown@example.com', '1993-11-30', '010-5555-6666', 'Ulsan, South Korea', '2024-09-23T12:00:00'), + ('OliviaTaylor', 'oliviataylor@example.com', '1996-05-05', '010-7777-8888', 'Jeonju, South Korea', '2024-09-23T12:00:00'), + ('BenjaminLee', 'benjaminlee@example.com', '1987-09-15', '010-9999-0000', 'Cheongju, South Korea', '2024-09-23T12:00:00'), + ('IsabellaClark', 'isabellaclark@example.com', '1991-12-12', '010-1122-3344', 'Suwon, South Korea', '2024-09-23T12:00:00'), + ('HenryWhite', 'henrywhite@example.com', '1986-04-18', '010-2233-4455', 'Seongnam, South Korea', '2024-09-23T12:00:00'), + ('MiaHarris', 'miaharris@example.com', '1994-10-10', '010-3344-5566', 'Pohang, South Korea', '2024-09-23T12:00:00'), + ('LucasMartin', 'lucasmartin@example.com', '1997-06-06', '010-4455-6677', 'Changwon, South Korea', '2024-09-23T12:00:00'), + ('EllaYoung', 'ellayoung@example.com', '1998-03-03', '010-5566-7788', 'Yeosu, South Korea', '2024-09-23T12:00:00'), + ('WilliamKing', 'williamking@example.com', '1983-08-08', '010-6677-8899', 'Jeju, South Korea', '2024-09-23T12:00:00'), + ('AmeliaScott', 'ameliascott@example.com', '1990-07-17', '010-7788-9900', 'Gimhae, South Korea', '2024-09-23T12:00:00'), + ('JackMoore', 'jackmoore@example.com', '1984-02-02', '010-8899-0011', 'Ansan, South Korea', '2024-09-23T12:00:00'), + ('AvaWalker', 'avawalker@example.com', '1999-11-11', '010-9900-1122', 'Guri, South Korea', '2024-09-23T12:00:00'), + ('DanielPerez', 'danielperez@example.com', '1992-05-21', '010-0011-2233', 'Yangsan, South Korea', '2024-09-23T12:00:00'), + ('LilyHall', 'lilyhall@example.com', '1991-01-01', '010-1122-3344', 'Iksan, South Korea', '2024-09-23T12:00:00'); +-- User 1 (JohnDoe) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (1, 'autumn'), (1, 'winter'); + +-- User 2 (JaneSmith) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (2, 'autumn'); + +-- User 3 (MikeJohnson) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (3, 'winter'); + +-- User 4 (EmilyDavis) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (4, 'autumn'), (4, 'winter'); + +-- User 5 (DavidWilson) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (5, 'autumn'); + +-- User 6 (SophiaMiller) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (6, 'winter'); + +-- User 7 (JamesBrown) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (7, 'autumn'); + +-- User 8 (OliviaTaylor) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (8, 'winter'); + +-- User 9 (BenjaminLee) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (9, 'autumn'); + +-- User 10 (IsabellaClark) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (10, 'winter'); + +-- User 11 (HenryWhite) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (11, 'autumn'), (11, 'winter'); + +-- User 12 (MiaHarris) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (12, 'autumn'); + +-- User 13 (LucasMartin) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (13, 'winter'); + +-- User 14 (EllaYoung) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (14, 'autumn'); + +-- User 15 (WilliamKing) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (15, 'winter'); + +-- User 16 (AmeliaScott) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (16, 'autumn'), (16, 'winter'); + +-- User 17 (JackMoore) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (17, 'autumn'); + +-- User 18 (AvaWalker) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (18, 'winter'); + +-- User 19 (DanielPerez) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (19, 'autumn'); + +-- User 20 (LilyHall) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (20, 'winter'); From 6f7a3ab40dabd283d58de642bbc9a252486a09f9 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 27 Sep 2024 18:37:05 +0900 Subject: [PATCH 19/46] feat:[#24]- Add BusinessArtist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit userId 추가. --- .../helpmeCookies/user/entity/BusinessArtist.java | 13 +++++++++++++ .../helpmeCookies/user/entity/StudentArtist.java | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/main/java/com/helpmeCookies/user/entity/BusinessArtist.java b/src/main/java/com/helpmeCookies/user/entity/BusinessArtist.java index b5a3835..67334ad 100644 --- a/src/main/java/com/helpmeCookies/user/entity/BusinessArtist.java +++ b/src/main/java/com/helpmeCookies/user/entity/BusinessArtist.java @@ -6,13 +6,26 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@AllArgsConstructor +@Builder public class BusinessArtist { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(nullable = false) + private Long userId; + @Column(nullable = false) private String businessNumber; diff --git a/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java b/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java index aa90533..d98bffb 100644 --- a/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java +++ b/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java @@ -6,14 +6,27 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@AllArgsConstructor +@Builder public class StudentArtist { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(nullable = false) + private Long userId; + @Column(nullable = false) private String schoolEmail; @Column(nullable = false) From c1c0608efab28675debf5c953ab2223367a76b40 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 27 Sep 2024 18:37:46 +0900 Subject: [PATCH 20/46] feat:[#24]- Add LocalDateTime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit String으로 관리하던 타입을 LocalDateTime으로 변경 --- .../java/com/helpmeCookies/user/entity/User.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/helpmeCookies/user/entity/User.java b/src/main/java/com/helpmeCookies/user/entity/User.java index fe51ef9..0e5a85f 100644 --- a/src/main/java/com/helpmeCookies/user/entity/User.java +++ b/src/main/java/com/helpmeCookies/user/entity/User.java @@ -1,7 +1,11 @@ package com.helpmeCookies.user.entity; +import java.time.LocalDateTime; import java.util.List; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.format.annotation.DateTimeFormat; + import com.helpmeCookies.product.entity.HashTag; import jakarta.persistence.CollectionTable; @@ -47,9 +51,14 @@ public class User { @Column(nullable = false) private String address; + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + @CreatedDate + @Column(nullable = false, updatable = false) + protected LocalDateTime createdAt; + // 별도의 테이블 생성. 문자열로 저장 @ElementCollection(targetClass = HashTag.class) - @CollectionTable(name = "user_hashtag") + @CollectionTable(name = "user_hashtags") @Enumerated(EnumType.STRING) - private List hashTags; -} + private List hashTags; // 기본 FetchType.LAZY +} \ No newline at end of file From d374059a6ffd6d7f926cf796b497753303e6cd3e Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 27 Sep 2024 18:38:09 +0900 Subject: [PATCH 21/46] feat:[#24]- Add FetchType MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FetchType을 Lazy로 변경. --- src/main/java/com/helpmeCookies/user/entity/Social.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/helpmeCookies/user/entity/Social.java b/src/main/java/com/helpmeCookies/user/entity/Social.java index b56f515..4c06bae 100644 --- a/src/main/java/com/helpmeCookies/user/entity/Social.java +++ b/src/main/java/com/helpmeCookies/user/entity/Social.java @@ -2,6 +2,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -17,7 +18,6 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -@Table(name = "users") // 예약어 회피 @AllArgsConstructor @Builder public class Social { @@ -26,9 +26,9 @@ public class Social { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private User follower; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private ArtistInfo following; } From 3b4ada535e3b82050c23ffa6a5d821cdff8344da Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 27 Sep 2024 18:38:37 +0900 Subject: [PATCH 22/46] feat:[#24]- Add repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JpaRepository 생성 --- .../user/repository/ArtistInfoRepository.java | 8 ++++++++ .../user/repository/BusinessArtistRepository.java | 8 ++++++++ .../helpmeCookies/user/repository/SocialRepository.java | 8 ++++++++ 3 files changed, 24 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/repository/ArtistInfoRepository.java create mode 100644 src/main/java/com/helpmeCookies/user/repository/BusinessArtistRepository.java create mode 100644 src/main/java/com/helpmeCookies/user/repository/SocialRepository.java diff --git a/src/main/java/com/helpmeCookies/user/repository/ArtistInfoRepository.java b/src/main/java/com/helpmeCookies/user/repository/ArtistInfoRepository.java new file mode 100644 index 0000000..b2120eb --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/repository/ArtistInfoRepository.java @@ -0,0 +1,8 @@ +package com.helpmeCookies.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.helpmeCookies.user.entity.ArtistInfo; + +public interface ArtistInfoRepository extends JpaRepository { +} diff --git a/src/main/java/com/helpmeCookies/user/repository/BusinessArtistRepository.java b/src/main/java/com/helpmeCookies/user/repository/BusinessArtistRepository.java new file mode 100644 index 0000000..3d8e33d --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/repository/BusinessArtistRepository.java @@ -0,0 +1,8 @@ +package com.helpmeCookies.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.helpmeCookies.user.entity.BusinessArtist; + +public interface BusinessArtistRepository extends JpaRepository { +} diff --git a/src/main/java/com/helpmeCookies/user/repository/SocialRepository.java b/src/main/java/com/helpmeCookies/user/repository/SocialRepository.java new file mode 100644 index 0000000..027839c --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/repository/SocialRepository.java @@ -0,0 +1,8 @@ +package com.helpmeCookies.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.helpmeCookies.user.entity.Social; + +public interface SocialRepository extends JpaRepository { +} From 3b8dcacc671dcbc4521da11b25b806a7f926ae86 Mon Sep 17 00:00:00 2001 From: bokyeong Date: Sun, 29 Sep 2024 17:18:35 +0900 Subject: [PATCH 23/46] =?UTF-8?q?feat:=20[#25]=20product=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=20ArtistInfo?= =?UTF-8?q?=20=EA=B4=80=EB=A0=A8=EC=BD=94=EB=93=9C=EB=8A=94=20=EC=B6=94?= =?UTF-8?q?=ED=9B=84=20=EC=88=98=EC=A0=95=20=EC=98=88=EC=A0=95,=20put=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=99=9C=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 15 +++++++++---- ...ctSaveRequest.java => ProductRequest.java} | 2 +- .../helpmeCookies/product/entity/Product.java | 11 ++++++++++ .../product/service/ProductService.java | 21 +++++++++++++++++-- 4 files changed, 42 insertions(+), 7 deletions(-) rename src/main/java/com/helpmeCookies/product/dto/{ProductSaveRequest.java => ProductRequest.java} (96%) diff --git a/src/main/java/com/helpmeCookies/product/controller/ProductController.java b/src/main/java/com/helpmeCookies/product/controller/ProductController.java index a16bcd7..02b718f 100644 --- a/src/main/java/com/helpmeCookies/product/controller/ProductController.java +++ b/src/main/java/com/helpmeCookies/product/controller/ProductController.java @@ -1,7 +1,7 @@ package com.helpmeCookies.product.controller; +import com.helpmeCookies.product.dto.ProductRequest; import com.helpmeCookies.product.dto.ProductResponse; -import com.helpmeCookies.product.dto.ProductSaveRequest; import com.helpmeCookies.product.entity.Product; import com.helpmeCookies.product.service.ProductService; import org.springframework.http.ResponseEntity; @@ -18,9 +18,9 @@ public ProductController(ProductService productService) { } @PostMapping - public ResponseEntity saveProduct(@RequestBody ProductSaveRequest productSaveRequest) { - Product product = productService.save(productSaveRequest); - return ResponseEntity.ok().body(product); + public ResponseEntity saveProduct(@RequestBody ProductRequest productRequest) { + Product product = productService.save(productRequest); + return ResponseEntity.ok().build(); } @GetMapping("/{productId}") @@ -28,4 +28,11 @@ public ResponseEntity getProductInfo(@PathVariable("productId") Product product = productService.find(productId); return ResponseEntity.ok(ProductResponse.from(product)); } + + @PutMapping("/{productId}") + public ResponseEntity editProductInfo(@PathVariable("productId") Long productId, + @RequestBody ProductRequest productRequest) { + productService.edit(productId, productRequest); + return ResponseEntity.ok().build(); + } } diff --git a/src/main/java/com/helpmeCookies/product/dto/ProductSaveRequest.java b/src/main/java/com/helpmeCookies/product/dto/ProductRequest.java similarity index 96% rename from src/main/java/com/helpmeCookies/product/dto/ProductSaveRequest.java rename to src/main/java/com/helpmeCookies/product/dto/ProductRequest.java index 8155748..e1dfa2d 100644 --- a/src/main/java/com/helpmeCookies/product/dto/ProductSaveRequest.java +++ b/src/main/java/com/helpmeCookies/product/dto/ProductRequest.java @@ -7,7 +7,7 @@ import java.util.List; -public record ProductSaveRequest( +public record ProductRequest( String name, String category, String size, diff --git a/src/main/java/com/helpmeCookies/product/entity/Product.java b/src/main/java/com/helpmeCookies/product/entity/Product.java index 4823196..d44b972 100644 --- a/src/main/java/com/helpmeCookies/product/entity/Product.java +++ b/src/main/java/com/helpmeCookies/product/entity/Product.java @@ -99,4 +99,15 @@ public List getHashTags() { public ArtistInfo getArtistInfo() { return artistInfo; } + + public void update(String name, Category category, String size, Long price, String description, String preferredLocation, List hashTags, ArtistInfo artistInfo) { + this.name = name; + this.category = category; + this.size = size; + this.price = price; + this.description = description; + this.preferredLocation = preferredLocation; + this.hashTags = hashTags; + this.artistInfo = artistInfo; + } } diff --git a/src/main/java/com/helpmeCookies/product/service/ProductService.java b/src/main/java/com/helpmeCookies/product/service/ProductService.java index 686d72f..d165b6d 100644 --- a/src/main/java/com/helpmeCookies/product/service/ProductService.java +++ b/src/main/java/com/helpmeCookies/product/service/ProductService.java @@ -1,9 +1,11 @@ package com.helpmeCookies.product.service; -import com.helpmeCookies.product.dto.ProductSaveRequest; +import com.helpmeCookies.product.dto.ProductRequest; +import com.helpmeCookies.product.entity.Category; import com.helpmeCookies.product.entity.Product; import com.helpmeCookies.product.repository.ProductRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service public class ProductService { @@ -13,7 +15,7 @@ public ProductService(ProductRepository productRepository) { this.productRepository = productRepository; } - public Product save(ProductSaveRequest productSaveRequest) { + public Product save(ProductRequest productSaveRequest) { //TODO ArtistInfo 코드 병합시 수정 예정 Product product = productSaveRequest.toEntity(null); productRepository.save(product); @@ -23,4 +25,19 @@ public Product save(ProductSaveRequest productSaveRequest) { public Product find(Long productId) { return productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 id입니다")); } + + @Transactional + public void edit(Long productId, ProductRequest productRequest) { + Product product = productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 id입니다")); + //TODO ArtistInfo 코드 병합시 수정 예정 + product.update( + productRequest.name(), + Category.fromString(productRequest.category()), + productRequest.size(), + productRequest.price(), + productRequest.description(), + productRequest.preferredLocation(), + productRequest.hashTags(), + null); + } } From b1f875d4e946928351aa91957ad3684cc629d4bd Mon Sep 17 00:00:00 2001 From: bokyeong Date: Sun, 29 Sep 2024 17:23:14 +0900 Subject: [PATCH 24/46] =?UTF-8?q?feat:=20[#25]=20product=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../helpmeCookies/product/controller/ProductController.java | 6 ++++++ .../com/helpmeCookies/product/service/ProductService.java | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/com/helpmeCookies/product/controller/ProductController.java b/src/main/java/com/helpmeCookies/product/controller/ProductController.java index 02b718f..c87732e 100644 --- a/src/main/java/com/helpmeCookies/product/controller/ProductController.java +++ b/src/main/java/com/helpmeCookies/product/controller/ProductController.java @@ -35,4 +35,10 @@ public ResponseEntity editProductInfo(@PathVariable("productId") Long prod productService.edit(productId, productRequest); return ResponseEntity.ok().build(); } + + @DeleteMapping("/{productId}") + public ResponseEntity deleteProduct(@PathVariable("productId") Long productId) { + productService.delete(productId); + return ResponseEntity.noContent().build(); + } } diff --git a/src/main/java/com/helpmeCookies/product/service/ProductService.java b/src/main/java/com/helpmeCookies/product/service/ProductService.java index d165b6d..1a16699 100644 --- a/src/main/java/com/helpmeCookies/product/service/ProductService.java +++ b/src/main/java/com/helpmeCookies/product/service/ProductService.java @@ -40,4 +40,9 @@ public void edit(Long productId, ProductRequest productRequest) { productRequest.hashTags(), null); } + + public void delete(Long productId) { + Product product = productRepository.findById(productId).orElseThrow(() -> new IllegalArgumentException("유효하지 않은 id입니다")); + productRepository.deleteById(productId); + } } From a1b891b9cafca53fc007aa195c2ccc88bbe4accd Mon Sep 17 00:00:00 2001 From: donghyuun Date: Mon, 30 Sep 2024 18:12:05 +0900 Subject: [PATCH 25/46] =?UTF-8?q?feat:=20[kakao-tech-campus-2nd-step3#31]?= =?UTF-8?q?=20Grafana,=20Prometheus=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++++ src/main/resources/application.yaml | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e58b589..24868cc 100644 --- a/build.gradle +++ b/build.gradle @@ -57,6 +57,10 @@ dependencies { implementation 'io.jsonwebtoken:jjwt-api:0.11.5' implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' + + // Monitoring + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'io.micrometer:micrometer-registry-prometheus' } tasks.named('test') { diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 2e7bc5b..1493b69 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -16,7 +16,17 @@ logging.level: org.hibernate: orm.jdbc.bind: trace SQL: debug + jwt: secret: 4099a46b-39db-4860-a61b-2ae76ea24c43 access-token-expire-time: 1800000 # 30 minutes - refresh-token-expire-time: 2592000000 # 30 days \ No newline at end of file + refresh-token-expire-time: 2592000000 # 30 days + +management: + endpoints: + web: + exposure: # 외부에 노출할 엔드포인트 + include: prometheus, health, info, swagger-ui + metrics: + tags: + application: "katecam" # 메트릭 데이터에 태그를 추가 \ No newline at end of file From cc9709d509dbc73f0dc33742a001cf7d3fa29bbe Mon Sep 17 00:00:00 2001 From: donghyuun Date: Mon, 30 Sep 2024 18:13:54 +0900 Subject: [PATCH 26/46] =?UTF-8?q?feat:=20[kakao-tech-campus-2nd-step3#31]?= =?UTF-8?q?=20=EB=AA=A8=EB=8B=88=ED=84=B0=EB=A7=81=20=EC=97=94=EB=93=9C?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=8B=9C=ED=81=90=EB=A6=AC?= =?UTF-8?q?=ED=8B=B0=20=EC=A0=81=EC=9A=A9=20=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/helpmeCookies/global/security/WebSecurityConfig.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java b/src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java index 1703aa0..793f211 100644 --- a/src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java +++ b/src/main/java/com/helpmeCookies/global/security/WebSecurityConfig.java @@ -45,7 +45,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers( "/login", "/signup", "/", "/user", "/api/auth/**", - "/swagger-ui/**" + "/swagger-ui/**", + "/actuator/**" ).permitAll() .anyRequest().authenticated() ); From a479f51cd08ef9947fb02bde8228640ac63ae68d Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:27:11 +0900 Subject: [PATCH 27/46] feat:[#24]- Add findById MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit findById 명시적으로 추가 --- .../com/helpmeCookies/user/repository/UserRepository.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/helpmeCookies/user/repository/UserRepository.java b/src/main/java/com/helpmeCookies/user/repository/UserRepository.java index f17d2a6..c3ce1bc 100644 --- a/src/main/java/com/helpmeCookies/user/repository/UserRepository.java +++ b/src/main/java/com/helpmeCookies/user/repository/UserRepository.java @@ -1,5 +1,7 @@ package com.helpmeCookies.user.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -7,5 +9,5 @@ @Repository public interface UserRepository extends JpaRepository { - + Optional findById(Long id); } From c4129bd0e3c144663a3ba601a42b75a9abc88db9 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:28:52 +0900 Subject: [PATCH 28/46] feat:[#24]- Add EntityListeners MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 자동 날짜 추가를 위해 JPAConfig와 EntityListeners 추가 --- .../java/com/helpmeCookies/global/config/JpaConfig.java | 9 +++++++++ src/main/java/com/helpmeCookies/user/entity/User.java | 3 +++ 2 files changed, 12 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/global/config/JpaConfig.java diff --git a/src/main/java/com/helpmeCookies/global/config/JpaConfig.java b/src/main/java/com/helpmeCookies/global/config/JpaConfig.java new file mode 100644 index 0000000..28fe6fe --- /dev/null +++ b/src/main/java/com/helpmeCookies/global/config/JpaConfig.java @@ -0,0 +1,9 @@ +package com.helpmeCookies.global.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@Configuration +@EnableJpaAuditing +public class JpaConfig { +} \ No newline at end of file diff --git a/src/main/java/com/helpmeCookies/user/entity/User.java b/src/main/java/com/helpmeCookies/user/entity/User.java index 0e5a85f..c62de27 100644 --- a/src/main/java/com/helpmeCookies/user/entity/User.java +++ b/src/main/java/com/helpmeCookies/user/entity/User.java @@ -4,6 +4,7 @@ import java.util.List; import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; import org.springframework.format.annotation.DateTimeFormat; import com.helpmeCookies.product.entity.HashTag; @@ -12,6 +13,7 @@ import jakarta.persistence.Column; import jakarta.persistence.ElementCollection; import jakarta.persistence.Entity; +import jakarta.persistence.EntityListeners; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; @@ -30,6 +32,7 @@ @Table(name = "users") // 예약어 회피 @AllArgsConstructor @Builder +@EntityListeners(AuditingEntityListener.class) public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From 77c60cd2cf21ff14610a6183eb68e40550ed5932 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:29:59 +0900 Subject: [PATCH 29/46] refactor:[#24]- refact data.sql MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 변경사이에 맞게 data.sql 변경 --- src/test/resources/data.sql | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/test/resources/data.sql diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql new file mode 100644 index 0000000..f765a99 --- /dev/null +++ b/src/test/resources/data.sql @@ -0,0 +1,81 @@ +INSERT INTO users (nickname, email, birthdate, phone, address, created_at) +VALUES + ('JohnDoe', 'johndoe@example.com', '1990-01-15', '010-1234-5678', 'Seoul, South Korea', '2024-09-23T12:00:00'), + ('JaneSmith', 'janesmith@example.com', '1985-05-23', '010-9876-5432', 'Busan, South Korea', '2024-09-23T12:00:00'), + ('MikeJohnson', 'mikejohnson@example.com', '1992-03-10', '010-5678-1234', 'Incheon, South Korea', '2024-09-23T12:00:00'), + ('EmilyDavis', 'emilydavis@example.com', '1988-08-17', '010-8765-4321', 'Daegu, South Korea', '2024-09-23T12:00:00'), + ('DavidWilson', 'davidwilson@example.com', '1995-07-07', '010-1111-2222', 'Daejeon, South Korea', '2024-09-23T12:00:00'), + ('SophiaMiller', 'sophiamiller@example.com', '1989-02-25', '010-3333-4444', 'Gwangju, South Korea', '2024-09-23T12:00:00'), + ('JamesBrown', 'jamesbrown@example.com', '1993-11-30', '010-5555-6666', 'Ulsan, South Korea', '2024-09-23T12:00:00'), + ('OliviaTaylor', 'oliviataylor@example.com', '1996-05-05', '010-7777-8888', 'Jeonju, South Korea', '2024-09-23T12:00:00'), + ('BenjaminLee', 'benjaminlee@example.com', '1987-09-15', '010-9999-0000', 'Cheongju, South Korea', '2024-09-23T12:00:00'), + ('IsabellaClark', 'isabellaclark@example.com', '1991-12-12', '010-1122-3344', 'Suwon, South Korea', '2024-09-23T12:00:00'), + ('HenryWhite', 'henrywhite@example.com', '1986-04-18', '010-2233-4455', 'Seongnam, South Korea', '2024-09-23T12:00:00'), + ('MiaHarris', 'miaharris@example.com', '1994-10-10', '010-3344-5566', 'Pohang, South Korea', '2024-09-23T12:00:00'), + ('LucasMartin', 'lucasmartin@example.com', '1997-06-06', '010-4455-6677', 'Changwon, South Korea', '2024-09-23T12:00:00'), + ('EllaYoung', 'ellayoung@example.com', '1998-03-03', '010-5566-7788', 'Yeosu, South Korea', '2024-09-23T12:00:00'), + ('WilliamKing', 'williamking@example.com', '1983-08-08', '010-6677-8899', 'Jeju, South Korea', '2024-09-23T12:00:00'), + ('AmeliaScott', 'ameliascott@example.com', '1990-07-17', '010-7788-9900', 'Gimhae, South Korea', '2024-09-23T12:00:00'), + ('JackMoore', 'jackmoore@example.com', '1984-02-02', '010-8899-0011', 'Ansan, South Korea', '2024-09-23T12:00:00'), + ('AvaWalker', 'avawalker@example.com', '1999-11-11', '010-9900-1122', 'Guri, South Korea', '2024-09-23T12:00:00'), + ('DanielPerez', 'danielperez@example.com', '1992-05-21', '010-0011-2233', 'Yangsan, South Korea', '2024-09-23T12:00:00'), + ('LilyHall', 'lilyhall@example.com', '1991-01-01', '010-1122-3344', 'Iksan, South Korea', '2024-09-23T12:00:00'); +-- User 1 (JohnDoe) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (1, 'DREAMLIKE'); + +-- User 2 (JaneSmith) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (2, 'DREAMLIKE'); + +-- User 3 (MikeJohnson) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (3, 'DREAMLIKE'); + +-- User 4 (EmilyDavis) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (4, 'DREAMLIKE'); + +-- User 5 (DavidWilson) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (5, 'DREAMLIKE'); + +-- User 6 (SophiaMiller) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (6, 'DREAMLIKE'); + +-- User 7 (JamesBrown) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (7, 'DREAMLIKE'); + +-- User 8 (OliviaTaylor) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (8, 'DREAMLIKE'); + +-- User 9 (BenjaminLee) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (9, 'DREAMLIKE'); + +-- User 10 (IsabellaClark) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (10, 'DREAMLIKE'); + +-- User 11 (HenryWhite) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (11, 'DREAMLIKE'); + +-- User 12 (MiaHarris) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (12, 'DREAMLIKE'); + +-- User 13 (LucasMartin) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (13, 'DREAMLIKE'); + +-- User 14 (EllaYoung) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (14, 'DREAMLIKE'); + +-- User 15 (WilliamKing) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (15, 'DREAMLIKE'); + +-- User 16 (AmeliaScott) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (16, 'DREAMLIKE'); + +-- User 17 (JackMoore) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (17, 'DREAMLIKE'); + +-- User 18 (AvaWalker) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (18, 'DREAMLIKE'); + +-- User 19 (DanielPerez) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (19, 'DREAMLIKE'); + +-- User 20 (LilyHall) +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (20, 'DREAMLIKE'); From c49e395b3c43fc37c05a55c60c6865f6189c84c0 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:31:27 +0900 Subject: [PATCH 30/46] feat:[#24]- add CascadeType.ALL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ArtistInfo와 StudentArtist 사이의 CascadeType.ALL 설정 --- .../java/com/helpmeCookies/user/entity/StudentArtist.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java b/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java index d98bffb..db44f6d 100644 --- a/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java +++ b/src/main/java/com/helpmeCookies/user/entity/StudentArtist.java @@ -1,10 +1,12 @@ package com.helpmeCookies.user.entity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import lombok.AccessLevel; @@ -35,6 +37,7 @@ public class StudentArtist { private String major; // 매핑 - @OneToOne + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "artist_info_id") private ArtistInfo artistInfo; } From bf798932ca8a4e875d2f936edb661bc776ad303d Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:32:16 +0900 Subject: [PATCH 31/46] refactor:[#24]- refact testUser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 변경 사항에 맞게 테스트 유저 변경 --- .../com/helpmeCookies/user/controller/LoginController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/helpmeCookies/user/controller/LoginController.java b/src/main/java/com/helpmeCookies/user/controller/LoginController.java index 393dba7..c004414 100644 --- a/src/main/java/com/helpmeCookies/user/controller/LoginController.java +++ b/src/main/java/com/helpmeCookies/user/controller/LoginController.java @@ -33,16 +33,16 @@ public JwtToken signup() { .birthdate("1999-01-01") .address("서울시 강남구") .phone("010-1234-5678") - .hashTags(List.of(HashTag.autumn, HashTag.winter)) + .hashTags(List.of(HashTag.DREAMLIKE, HashTag.VIBRANCE)) .build(); userRepository.save(user); return jwtProvider.createToken(JwtUser.of(user.getId())); } // 임시 로그인 url. 로그인한 유저의 정보의 일부를 반환한다. - @GetMapping("/test/login") + @GetMapping("/login") public String login(@AuthenticationPrincipal JwtUser jwtUser) { - User user = userRepository.findById(jwtUser.getId()).get(); + User user = userRepository.findById(jwtUser.getId()).orElseThrow(); return user.getEmail(); } } From 559514020a6f69dae8ec584397189e806293589c Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:33:11 +0900 Subject: [PATCH 32/46] feat:[#22]- add authorities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 권한 설정이 가능하도록 추가 구현 --- .../com/helpmeCookies/global/jwt/JwtUser.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/helpmeCookies/global/jwt/JwtUser.java b/src/main/java/com/helpmeCookies/global/jwt/JwtUser.java index bc60b98..e66d7b0 100644 --- a/src/main/java/com/helpmeCookies/global/jwt/JwtUser.java +++ b/src/main/java/com/helpmeCookies/global/jwt/JwtUser.java @@ -1,8 +1,10 @@ package com.helpmeCookies.global.jwt; import java.util.Collection; +import java.util.List; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import lombok.Builder; @@ -12,6 +14,8 @@ @Getter public class JwtUser implements UserDetails { private Long id; + private String username; + private Collection authorities; public static JwtUser of(Long id) { return JwtUser.builder() @@ -20,8 +24,9 @@ public static JwtUser of(Long id) { } @Override + // 임시 기본 권한을 USER로 설정 public Collection getAuthorities() { - return null; + return List.of(new SimpleGrantedAuthority("ROLE_" + "USER")); } @Override @@ -31,27 +36,27 @@ public String getPassword() { @Override public String getUsername() { - return null; + return this.username; } @Override public boolean isAccountNonExpired() { - return false; + return true; } @Override public boolean isAccountNonLocked() { - return false; + return true; } @Override public boolean isCredentialsNonExpired() { - return false; + return true; } @Override public boolean isEnabled() { - return false; + return true; } } \ No newline at end of file From 5f0c1d15daa91c299137de0af7011b9663bd2491 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:34:31 +0900 Subject: [PATCH 33/46] feat:[#22]- add ArtistInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ArtistInfo에 롬복 추가. about에 기본 값 추가. 추후 nullable = false를 고려 --- .../com/helpmeCookies/user/entity/ArtistInfo.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/helpmeCookies/user/entity/ArtistInfo.java b/src/main/java/com/helpmeCookies/user/entity/ArtistInfo.java index 83d86e7..3f5ba93 100644 --- a/src/main/java/com/helpmeCookies/user/entity/ArtistInfo.java +++ b/src/main/java/com/helpmeCookies/user/entity/ArtistInfo.java @@ -5,8 +5,17 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@AllArgsConstructor +@Builder public class ArtistInfo { @Id @@ -18,5 +27,5 @@ public class ArtistInfo { @Column(nullable = false) private Long totalLikes; - private String about; + private String about = ""; } From 9c785a8b211644f35b5b4318cad972c03a2ba8e4 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:35:36 +0900 Subject: [PATCH 34/46] feat:[#24]- add userDto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User에 사용할 UserDto및 artist의 response,request를 구현 --- .../helpmeCookies/user/dto/ArtistInfoDto.java | 11 +++++++ .../user/dto/BusinessArtistDto.java | 27 ++++++++++++++++ .../user/dto/StudentArtistDto.java | 27 ++++++++++++++++ .../com/helpmeCookies/user/dto/UserDto.java | 31 +++++++++++++++++++ .../user/dto/request/BusinessArtistReq.java | 11 +++++++ .../user/dto/request/StudentArtistReq.java | 10 ++++++ .../user/dto/response/ArtistInfoRes.java | 16 ++++++++++ .../user/dto/response/BusinessArtistRes.java | 19 ++++++++++++ .../user/dto/response/StudentArtistRes.java | 19 ++++++++++++ 9 files changed, 171 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/dto/ArtistInfoDto.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/BusinessArtistDto.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/StudentArtistDto.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/UserDto.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/request/BusinessArtistReq.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/request/StudentArtistReq.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/response/ArtistInfoRes.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/response/BusinessArtistRes.java create mode 100644 src/main/java/com/helpmeCookies/user/dto/response/StudentArtistRes.java diff --git a/src/main/java/com/helpmeCookies/user/dto/ArtistInfoDto.java b/src/main/java/com/helpmeCookies/user/dto/ArtistInfoDto.java new file mode 100644 index 0000000..afad531 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/ArtistInfoDto.java @@ -0,0 +1,11 @@ +package com.helpmeCookies.user.dto; + +public record ArtistInfoDto( + Long totalFollowers, + Long totalLikes, + String about +) { + public static ArtistInfoDto of(Long totalFollowers, Long totalLikes, String about) { + return new ArtistInfoDto(totalFollowers, totalLikes, about); + } +} diff --git a/src/main/java/com/helpmeCookies/user/dto/BusinessArtistDto.java b/src/main/java/com/helpmeCookies/user/dto/BusinessArtistDto.java new file mode 100644 index 0000000..a677d95 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/BusinessArtistDto.java @@ -0,0 +1,27 @@ +package com.helpmeCookies.user.dto; + +import com.helpmeCookies.user.entity.BusinessArtist; + +public record BusinessArtistDto( + Long id, + Long userId, + String businessNumber, + String openDate, + String headName, + ArtistInfoDto artistInfo +) { + public static BusinessArtistDto fromEntity(BusinessArtist businessArtist){ + return new BusinessArtistDto( + businessArtist.getId(), + businessArtist.getUserId(), + businessArtist.getBusinessNumber(), + businessArtist.getOpenDate(), + businessArtist.getHeadName(), + ArtistInfoDto.of( + businessArtist.getArtistInfo().getTotalFollowers(), + businessArtist.getArtistInfo().getTotalLikes(), + businessArtist.getArtistInfo().getAbout() + ) + ); + } +} diff --git a/src/main/java/com/helpmeCookies/user/dto/StudentArtistDto.java b/src/main/java/com/helpmeCookies/user/dto/StudentArtistDto.java new file mode 100644 index 0000000..f453c3a --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/StudentArtistDto.java @@ -0,0 +1,27 @@ +package com.helpmeCookies.user.dto; + +import com.helpmeCookies.user.entity.StudentArtist; + +public record StudentArtistDto( + Long id, + Long userId, + String schoolEmail, + String schoolName, + String major, + ArtistInfoDto artistInfo +) { + public static StudentArtistDto fromEntity(StudentArtist studentArtist) { + return new StudentArtistDto( + studentArtist.getId(), + studentArtist.getUserId(), + studentArtist.getSchoolEmail(), + studentArtist.getSchoolName(), + studentArtist.getMajor(), + ArtistInfoDto.of( + studentArtist.getArtistInfo().getTotalFollowers(), + studentArtist.getArtistInfo().getTotalLikes(), + studentArtist.getArtistInfo().getAbout() + ) + ); + } +} diff --git a/src/main/java/com/helpmeCookies/user/dto/UserDto.java b/src/main/java/com/helpmeCookies/user/dto/UserDto.java new file mode 100644 index 0000000..74cc627 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/UserDto.java @@ -0,0 +1,31 @@ +package com.helpmeCookies.user.dto; + +import java.time.LocalDateTime; +import java.util.List; + +import com.helpmeCookies.product.entity.HashTag; +import com.helpmeCookies.user.entity.User; + +public record UserDto( + Long id, + String nickname, + String email, + String birthdate, + String phone, + String address, + LocalDateTime createdAt, + List hashTags +) { + public static UserDto fromEntity(User user) { + return new UserDto( + user.getId(), + user.getNickname(), + user.getEmail(), + user.getBirthdate(), + user.getPhone(), + user.getAddress(), + user.getCreatedAt(), + user.getHashTags() + ); + } +} diff --git a/src/main/java/com/helpmeCookies/user/dto/request/BusinessArtistReq.java b/src/main/java/com/helpmeCookies/user/dto/request/BusinessArtistReq.java new file mode 100644 index 0000000..607a2f6 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/request/BusinessArtistReq.java @@ -0,0 +1,11 @@ +package com.helpmeCookies.user.dto.request; + +import com.helpmeCookies.user.dto.ArtistInfoDto; + +public record BusinessArtistReq( + String businessNumber, + String openDate, + String headName +) { + +} diff --git a/src/main/java/com/helpmeCookies/user/dto/request/StudentArtistReq.java b/src/main/java/com/helpmeCookies/user/dto/request/StudentArtistReq.java new file mode 100644 index 0000000..8b5d205 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/request/StudentArtistReq.java @@ -0,0 +1,10 @@ +package com.helpmeCookies.user.dto.request; + +import com.helpmeCookies.user.dto.StudentArtistDto; + +public record StudentArtistReq( + String schoolEmail, + String schoolName, + String major +) { +} diff --git a/src/main/java/com/helpmeCookies/user/dto/response/ArtistInfoRes.java b/src/main/java/com/helpmeCookies/user/dto/response/ArtistInfoRes.java new file mode 100644 index 0000000..c6bd44a --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/response/ArtistInfoRes.java @@ -0,0 +1,16 @@ +package com.helpmeCookies.user.dto.response; + +import com.helpmeCookies.user.dto.ArtistInfoDto; + +public record ArtistInfoRes( + Long totalFollowers, + Long totalLikes, + String about +) { + public static ArtistInfoRes from(ArtistInfoDto artistInfoDto) { + return new ArtistInfoRes( + artistInfoDto.totalFollowers(), + artistInfoDto.totalLikes(), + artistInfoDto.about()); + } +} diff --git a/src/main/java/com/helpmeCookies/user/dto/response/BusinessArtistRes.java b/src/main/java/com/helpmeCookies/user/dto/response/BusinessArtistRes.java new file mode 100644 index 0000000..ad95d6c --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/response/BusinessArtistRes.java @@ -0,0 +1,19 @@ +package com.helpmeCookies.user.dto.response; + +import com.helpmeCookies.user.dto.BusinessArtistDto; + +public record BusinessArtistRes( + String businessNumber, + String openDate, + String headName, + ArtistInfoRes artistInfo +) { + public static BusinessArtistRes from(BusinessArtistDto businessArtistDto) { + return new BusinessArtistRes( + businessArtistDto.businessNumber(), + businessArtistDto.openDate(), + businessArtistDto.headName(), + ArtistInfoRes.from(businessArtistDto.artistInfo()) + ); + } +} diff --git a/src/main/java/com/helpmeCookies/user/dto/response/StudentArtistRes.java b/src/main/java/com/helpmeCookies/user/dto/response/StudentArtistRes.java new file mode 100644 index 0000000..af688ca --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/dto/response/StudentArtistRes.java @@ -0,0 +1,19 @@ +package com.helpmeCookies.user.dto.response; + +import com.helpmeCookies.user.dto.StudentArtistDto; + +public record StudentArtistRes( + String schoolEmail, + String schoolName, + String major, + ArtistInfoRes artistInfo +) { + public static StudentArtistRes from(StudentArtistDto studentArtistDto) { + return new StudentArtistRes( + studentArtistDto.schoolEmail(), + studentArtistDto.schoolName(), + studentArtistDto.major(), + ArtistInfoRes.from(studentArtistDto.artistInfo()) + ); + } +} From c5054d80ef20a6282e8e8f8ecb9a240f6f4d9933 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:36:21 +0900 Subject: [PATCH 35/46] chore:[#24]- add security test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테스트를 위한 security-test 추가 --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 24868cc..1ed3bd7 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.security:spring-security-test' implementation 'org.springframework.boot:spring-boot-starter-security' // Lombok From 3357746ecd0ce721f21cfb8b1bdebbe4a96d2345 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:37:00 +0900 Subject: [PATCH 36/46] feat:[#24]- add data.sql MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테스트를 위한 data.sql 별도 생성 --- src/main/resources/data.sql | 40 ++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 74c89be..f765a99 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -21,61 +21,61 @@ VALUES ('DanielPerez', 'danielperez@example.com', '1992-05-21', '010-0011-2233', 'Yangsan, South Korea', '2024-09-23T12:00:00'), ('LilyHall', 'lilyhall@example.com', '1991-01-01', '010-1122-3344', 'Iksan, South Korea', '2024-09-23T12:00:00'); -- User 1 (JohnDoe) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (1, 'autumn'), (1, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (1, 'DREAMLIKE'); -- User 2 (JaneSmith) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (2, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (2, 'DREAMLIKE'); -- User 3 (MikeJohnson) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (3, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (3, 'DREAMLIKE'); -- User 4 (EmilyDavis) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (4, 'autumn'), (4, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (4, 'DREAMLIKE'); -- User 5 (DavidWilson) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (5, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (5, 'DREAMLIKE'); -- User 6 (SophiaMiller) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (6, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (6, 'DREAMLIKE'); -- User 7 (JamesBrown) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (7, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (7, 'DREAMLIKE'); -- User 8 (OliviaTaylor) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (8, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (8, 'DREAMLIKE'); -- User 9 (BenjaminLee) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (9, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (9, 'DREAMLIKE'); -- User 10 (IsabellaClark) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (10, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (10, 'DREAMLIKE'); -- User 11 (HenryWhite) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (11, 'autumn'), (11, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (11, 'DREAMLIKE'); -- User 12 (MiaHarris) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (12, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (12, 'DREAMLIKE'); -- User 13 (LucasMartin) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (13, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (13, 'DREAMLIKE'); -- User 14 (EllaYoung) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (14, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (14, 'DREAMLIKE'); -- User 15 (WilliamKing) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (15, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (15, 'DREAMLIKE'); -- User 16 (AmeliaScott) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (16, 'autumn'), (16, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (16, 'DREAMLIKE'); -- User 17 (JackMoore) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (17, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (17, 'DREAMLIKE'); -- User 18 (AvaWalker) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (18, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (18, 'DREAMLIKE'); -- User 19 (DanielPerez) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (19, 'autumn'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (19, 'DREAMLIKE'); -- User 20 (LilyHall) -INSERT INTO user_hashtags (user_id, hash_tags) VALUES (20, 'winter'); +INSERT INTO user_hashtags (user_id, hash_tags) VALUES (20, 'DREAMLIKE'); From e3d7758059e33f6ee34500bffe1246c106426cbd Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:37:16 +0900 Subject: [PATCH 37/46] feat:[#24]- add test yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테스트를 위한 yaml 별도 생성 --- src/test/resources/application.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/test/resources/application.yaml diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml new file mode 100644 index 0000000..bf26694 --- /dev/null +++ b/src/test/resources/application.yaml @@ -0,0 +1,24 @@ +spring: # test profile + datasource: + url: "jdbc:h2:mem:Code2CV" + username: "sa" + password: "" + driver-class-name: org.h2.Driver + jpa: + hibernate: + ddl-auto: create-drop + defer-datasource-initialization: true + properties: + hibernate: + dialect: org.hibernate.dialect.H2Dialect + format_sql: true # SQL 포맷팅 + highlight_sql: true +logging.level: + org.hibernate: + orm.jdbc.bind: trace + SQL: debug + +jwt: + secret: testtesttesttesttesttesttesttesttest + access-token-expire-time: 1800000 # 30 minutes + refresh-token-expire-time: 2592000000 # 30 days \ No newline at end of file From 2183a14950fa9c8ebe5e4392f5e8995658558d79 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:37:43 +0900 Subject: [PATCH 38/46] feat:[#24]- add jwtTestUtils MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 토큰 테스트를 위한 별도의 유틸 클래스 생성 --- .../com/helpmeCookies/e2e/JwtTestUtils.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/java/com/helpmeCookies/e2e/JwtTestUtils.java diff --git a/src/test/java/com/helpmeCookies/e2e/JwtTestUtils.java b/src/test/java/com/helpmeCookies/e2e/JwtTestUtils.java new file mode 100644 index 0000000..6093b44 --- /dev/null +++ b/src/test/java/com/helpmeCookies/e2e/JwtTestUtils.java @@ -0,0 +1,23 @@ +package com.helpmeCookies.e2e; + +import java.util.List; + +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import com.helpmeCookies.global.jwt.JwtProvider; +import com.helpmeCookies.global.jwt.JwtToken; +import com.helpmeCookies.global.jwt.JwtUser; + + +public class JwtTestUtils { + + public static JwtToken generateValidToken(JwtProvider jwtProvider, Long userId, String username, String role) { + JwtUser jwtUser = JwtUser.builder() + .id(userId) + .username(username) + .authorities(List.of(new SimpleGrantedAuthority("ROLE_" + role))) + .build(); + + return jwtProvider.createToken(jwtUser); + } +} From b1f5377f76bd9c6262e6e6d2f3badbd6dc83a483 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:38:26 +0900 Subject: [PATCH 39/46] feat:[#24]- add UserController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 추후 필요한 내용 ToDo에 추가 --- .../user/controller/UserController.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/controller/UserController.java diff --git a/src/main/java/com/helpmeCookies/user/controller/UserController.java b/src/main/java/com/helpmeCookies/user/controller/UserController.java new file mode 100644 index 0000000..c123502 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/controller/UserController.java @@ -0,0 +1,36 @@ +package com.helpmeCookies.user.controller; + +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; + +import com.helpmeCookies.global.jwt.JwtUser; +import com.helpmeCookies.user.dto.UserDto; +import com.helpmeCookies.user.service.UserService; + +import lombok.RequiredArgsConstructor; + +@Controller +@RequiredArgsConstructor +public class UserController { + private final UserService userService; + + // TODO: 이후 추가되는 요구사항에 따라 별도의 UserRes로 반환 + // TODO: 구매 판매 내역에 대한 추가 정보 필요. Product 도메인 완성이후 추가 + @GetMapping("/v1/users/{userId}") + public UserDto getUsers( + @PathVariable Long userId + ) { + return userService.getUser(userId); + } + + //유저 팔로우 목록 조회 + @GetMapping("/v1/users/{userId}/follows") + public String getFollows() { + + return "ok"; + } +} From da981c86b5442345d3e982a9dc193dcb6f8a437d Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:39:04 +0900 Subject: [PATCH 40/46] feat:[#24]- add ArtistService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ArtistService의 내용 추가. 에러 처리 구현이 현재 안되어있음. --- .../user/service/ArtistService.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/service/ArtistService.java diff --git a/src/main/java/com/helpmeCookies/user/service/ArtistService.java b/src/main/java/com/helpmeCookies/user/service/ArtistService.java new file mode 100644 index 0000000..8941696 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/service/ArtistService.java @@ -0,0 +1,69 @@ +package com.helpmeCookies.user.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.helpmeCookies.user.dto.ArtistInfoDto; +import com.helpmeCookies.user.dto.BusinessArtistDto; +import com.helpmeCookies.user.dto.StudentArtistDto; +import com.helpmeCookies.user.dto.request.BusinessArtistReq; +import com.helpmeCookies.user.dto.request.StudentArtistReq; +import com.helpmeCookies.user.entity.ArtistInfo; +import com.helpmeCookies.user.entity.BusinessArtist; +import com.helpmeCookies.user.entity.StudentArtist; +import com.helpmeCookies.user.repository.ArtistInfoRepository; +import com.helpmeCookies.user.repository.BusinessArtistRepository; +import com.helpmeCookies.user.repository.StudentArtistRepository; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +public class ArtistService { + private final BusinessArtistRepository businessArtistRepository; + private final StudentArtistRepository studentArtistRepository; + + @Transactional + public StudentArtistDto registerStudentsArtist(StudentArtistReq studentArtistReq, Long userId) { + // StudentArtist 생성 + ArtistInfo artistInfo = ArtistInfo.builder() + .totalFollowers(0L) + .totalLikes(0L) + .build(); + + StudentArtist studentArtist = StudentArtist.builder() + .userId(userId) + .schoolEmail(studentArtistReq.schoolEmail()) + .schoolName(studentArtistReq.schoolName()) + .major(studentArtistReq.major()) + .artistInfo(artistInfo) + .build(); + + studentArtist = studentArtistRepository.save(studentArtist); + + return StudentArtistDto.fromEntity(studentArtist); + } + + @Transactional + public BusinessArtistDto registerBusinessArtist(BusinessArtistReq businessArtistReq, Long userId) { + // BusinessArtist 생성 + ArtistInfo artistInfo = ArtistInfo.builder() + .totalFollowers(0L) + .totalLikes(0L) + .build(); + + BusinessArtist businessArtist = BusinessArtist + .builder() + .userId(userId) + .businessNumber(businessArtistReq.businessNumber()) + .openDate(businessArtistReq.openDate()) + .headName(businessArtistReq.headName()) + .artistInfo(artistInfo) + .build(); + + businessArtist = businessArtistRepository.save(businessArtist); + + return BusinessArtistDto.fromEntity(businessArtist); + } + +} From c402de3050cf2db23aa4efa2aa82ebc598ab8ed7 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:39:39 +0900 Subject: [PATCH 41/46] feat:[#24]- add StudentArtistRepository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JPA를 상속받는 StudentArtistRepositor 인터페이스 구현 --- .../user/repository/StudentArtistRepository.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/repository/StudentArtistRepository.java diff --git a/src/main/java/com/helpmeCookies/user/repository/StudentArtistRepository.java b/src/main/java/com/helpmeCookies/user/repository/StudentArtistRepository.java new file mode 100644 index 0000000..84102a8 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/repository/StudentArtistRepository.java @@ -0,0 +1,10 @@ +package com.helpmeCookies.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.helpmeCookies.user.entity.StudentArtist; + +@Repository +public interface StudentArtistRepository extends JpaRepository { +} From 856f034a9df6f19e53ee6aafcb6b644a8a8ec313 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:40:19 +0900 Subject: [PATCH 42/46] feat:[#24]- add ArtistController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ArtistController의 일부 기능 구현. --- .../user/controller/ArtistController.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/controller/ArtistController.java diff --git a/src/main/java/com/helpmeCookies/user/controller/ArtistController.java b/src/main/java/com/helpmeCookies/user/controller/ArtistController.java new file mode 100644 index 0000000..536d814 --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/controller/ArtistController.java @@ -0,0 +1,59 @@ +package com.helpmeCookies.user.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import com.helpmeCookies.global.jwt.JwtProvider; +import com.helpmeCookies.global.jwt.JwtUser; +import com.helpmeCookies.user.dto.request.BusinessArtistReq; +import com.helpmeCookies.user.dto.request.StudentArtistReq; +import com.helpmeCookies.user.dto.response.BusinessArtistRes; +import com.helpmeCookies.user.dto.response.StudentArtistRes; +import com.helpmeCookies.user.service.ArtistService; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +public class ArtistController { + private final ArtistService artistService; + private final JwtProvider jwtProvider; + + @PostMapping("/v1/artists/students") + public ResponseEntity registerStudents( + @RequestBody StudentArtistReq studentArtistReq, + @AuthenticationPrincipal JwtUser jwtUser + ) { + StudentArtistRes response = StudentArtistRes.from(artistService.registerStudentsArtist(studentArtistReq, jwtUser.getId())); + return ResponseEntity.ok(response); + } + + @PostMapping("/v1/artists/bussinesses") + public ResponseEntity registerbussinsess( + @RequestBody BusinessArtistReq businessArtistReq, + @AuthenticationPrincipal JwtUser jwtUser + ) { + BusinessArtistRes response = BusinessArtistRes.from(artistService.registerBusinessArtist(businessArtistReq, jwtUser.getId())); + return ResponseEntity.ok(response); + } + + // 작가 목록 조회(페이징) + // TODO: 6주차 회의 이후 추가 + @GetMapping("/v1/artists") + public String getArtists() { + return "ok"; + } + + // 작가 프로필 조회 + // TODO: 6주차 회의 이후 추가 + @GetMapping("/v1/artists/{userId}") + public String getArtist() { + return "ok"; + } +} From a2725c78cff4abff74878ddb2a8e84314420abb0 Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:40:38 +0900 Subject: [PATCH 43/46] feat:[#24]- add UserService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UserService 일부 구현 --- .../user/service/UserService.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/com/helpmeCookies/user/service/UserService.java diff --git a/src/main/java/com/helpmeCookies/user/service/UserService.java b/src/main/java/com/helpmeCookies/user/service/UserService.java new file mode 100644 index 0000000..d5b6aef --- /dev/null +++ b/src/main/java/com/helpmeCookies/user/service/UserService.java @@ -0,0 +1,20 @@ +package com.helpmeCookies.user.service; + +import org.springframework.stereotype.Service; + +import com.helpmeCookies.global.jwt.JwtUser; +import com.helpmeCookies.user.dto.UserDto; +import com.helpmeCookies.user.repository.UserRepository; + +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class UserService { + private final UserRepository userRepository; + + public UserDto getUser(Long userId) { + return UserDto.fromEntity(userRepository.findById(userId).orElseThrow()); + } +} From e4ee47b7787abbb34f334fd7739f0f2cac38c9bd Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:43:03 +0900 Subject: [PATCH 44/46] feat:[#24]- add LoginE2ETest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 임시 로그인 E2E 테스트 구현 --- .../com/helpmeCookies/e2e/LoginE2ETest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/test/java/com/helpmeCookies/e2e/LoginE2ETest.java diff --git a/src/test/java/com/helpmeCookies/e2e/LoginE2ETest.java b/src/test/java/com/helpmeCookies/e2e/LoginE2ETest.java new file mode 100644 index 0000000..c088555 --- /dev/null +++ b/src/test/java/com/helpmeCookies/e2e/LoginE2ETest.java @@ -0,0 +1,42 @@ +package com.helpmeCookies.e2e; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.Test; +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.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import com.helpmeCookies.e2e.JwtTestUtils; +import com.helpmeCookies.global.jwt.JwtProvider; +import com.helpmeCookies.global.jwt.JwtToken; + +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") // 테스트용 프로파일 사용 +public class LoginE2ETest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private JwtProvider jwtProvider; + + @Test + public void testRegisterStudents_withValidToken() throws Exception { + // given + JwtToken token = JwtTestUtils.generateValidToken(jwtProvider, 1L, "JohnDoe", "ROLE_USER"); + + // when & then + mockMvc.perform(get("/login") + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token.getAccessToken())) + .andExpect(status().isOk()) + .andExpect(content().contentType("text/plain;charset=UTF-8")) + .andExpect(content().string("johndoe@example.com")); + } +} From 21cf8a0268a402571dd0480b89fac712ccb1f96b Mon Sep 17 00:00:00 2001 From: yooonwodyd Date: Fri, 4 Oct 2024 22:43:20 +0900 Subject: [PATCH 45/46] feat:[#24]- add ArtistE2Etest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 임시 Artist 테스트 구현 --- .../com/helpmeCookies/e2e/ArtistE2Etest.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/test/java/com/helpmeCookies/e2e/ArtistE2Etest.java diff --git a/src/test/java/com/helpmeCookies/e2e/ArtistE2Etest.java b/src/test/java/com/helpmeCookies/e2e/ArtistE2Etest.java new file mode 100644 index 0000000..6d76c7b --- /dev/null +++ b/src/test/java/com/helpmeCookies/e2e/ArtistE2Etest.java @@ -0,0 +1,67 @@ +package com.helpmeCookies.e2e; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.List; + +import org.junit.jupiter.api.Test; +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.security.core.authority.SimpleGrantedAuthority; +import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.helpmeCookies.global.jwt.JwtProvider; +import com.helpmeCookies.global.jwt.JwtUser; +import com.helpmeCookies.user.dto.request.StudentArtistReq; + +@SpringBootTest +@AutoConfigureMockMvc +public class ArtistE2Etest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private JwtProvider jwtProvider; + + @Test + public void testRegisterStudents_withValidToken() throws Exception { + // given + String token = jwtProvider.createToken( + JwtUser.builder() + .id(1L) + .username("JohnDoe") + .authorities(List.of(new SimpleGrantedAuthority("ROLE_USER"))) + .build() + ).getAccessToken(); + + StudentArtistReq request = new StudentArtistReq( + "student@example.com", + "Example University", + "Computer Science" + ); + + String requestJson = objectMapper.writeValueAsString(request); + + // when & then + mockMvc.perform(post("/v1/artists/students") + .contentType(MediaType.APPLICATION_JSON) + .content(requestJson) + .header("Authorization", "Bearer " + token)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.schoolEmail").value("student@example.com")) + .andExpect(jsonPath("$.schoolName").value("Example University")) + .andExpect(jsonPath("$.major").value("Computer Science")) + .andExpect(jsonPath("$.artistInfo.totalFollowers").value(0)) + .andExpect(jsonPath("$.artistInfo.totalLikes").value(0)) + .andExpect(jsonPath("$.artistInfo.about").doesNotExist()); + } +} From 0eace57bd0fddbae720e68be12268e4f2b902a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=9E=AC=EC=9A=A9?= <103253736+yooonwodyd@users.noreply.github.com> Date: Fri, 4 Oct 2024 23:28:47 +0900 Subject: [PATCH 46/46] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 611eb8a..7cee267 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,15 @@ ## 리뷰사항 연휴 이후 다음주 부터 본격적인 개발에 들어가려 합니다. 열심히하겠습니다! 감사합니다. + + + +# 5주차 github 코드리뷰 질문 +(윤재용) +몇몇 컨트롤러에 대한 E2E 테스트를 작성하였습니다. +처음에는 @WithMockUser 를 사용해서 테스트를 진행하려고 했는데, Header를 검증하다보니 불가능했습니다. +저희의 요구사항이 특정 url이 아니라면 헤더에 토큰이 필요하다보니 사용이 불가능하였기에 JwtTestUtils 클래스를 통해 테스트 유저를 사용하였습니다. + +이런 전체 테스트를 처음 구현하다 보니 +현재 작성한 테스트가 E2E 테스트라고 불려도 될 지 잘 모르겠습니다..! +추가로 테스트코드의 개선점이 있을지 궁금합니다.