스프링 부트와 AWS로 혼자 구현하는 웹 서비스 Chapter5 추가

This commit is contained in:
DESKTOP-FSO9NHB\User
2020-11-30 15:22:46 +09:00
parent 0e8922e8c5
commit f913e656f6
42 changed files with 2596 additions and 21 deletions

View File

@@ -164,3 +164,5 @@ $RECYCLE.BIN/
.idea/jarRepositories.xml .idea/jarRepositories.xml
.idea/misc.xml .idea/misc.xml
.idea/vcs.xml .idea/vcs.xml
application-oauth.properties

View File

@@ -3,4 +3,5 @@
- [Chapter1. 인텔리제이로 스프링 부트 시작하기](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter1.md) - [Chapter1. 인텔리제이로 스프링 부트 시작하기](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter1.md)
- [Chapter2. 스프링 부트에서 테스트 코드를 작성하자](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter2.md) - [Chapter2. 스프링 부트에서 테스트 코드를 작성하자](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter2.md)
- [Chapter3. 스프링 부트에서 JPA로 데이터베이스 다뤄보자](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter3.md) - [Chapter3. 스프링 부트에서 JPA로 데이터베이스 다뤄보자](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter3.md)
- [Chapter4. 머스테치로 화면 구성하기](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter4.md) - [Chapter4. 머스테치로 화면 구성하기](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter4.md)
- [Chapter5. 스프링 시큐리티와 OAuth 2.0으로 로그인 기능 구현하기](https://github.com/banjjoknim/TIL/blob/master/WebServiceBySpringBootAndAWS/src/ChapterDescription/Chapter5.md)

View File

@@ -27,8 +27,12 @@ repositories {
dependencies { dependencies {
compile('org.springframework.boot:spring-boot-starter-web') compile('org.springframework.boot:spring-boot-starter-web')
compile('org.projectlombok:lombok') compile('org.projectlombok:lombok')
annotationProcessor('org.projectlombok:lombok')
compile('org.springframework.boot:spring-boot-starter-data-jpa') compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('com.h2database:h2') compile('com.h2database:h2')
testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.boot:spring-boot-starter-test')
compile('org.springframework.boot:spring-boot-starter-mustache') compile('org.springframework.boot:spring-boot-starter-mustache')
compile('org.springframework.boot:spring-boot-starter-oauth2-client')
compile('org.springframework.session:spring-session-jdbc')
testCompile('org.springframework.security:spring-security-test')
} }

View File

@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Class com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Class com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.banjjoknim.book.springboot.domain.posts.html">com.banjjoknim.book.springboot.domain.posts</a> &gt; PostsRepositoryTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">2</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.162s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
<li>
<a href="#tab1">Standard output</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">BaseTimeEntity_등록</td>
<td class="success">0.013s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">게시글저장_불러오기</td>
<td class="success">0.149s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
<div id="tab1" class="tab">
<h2>Standard output</h2>
<span class="code">
<pre>2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest], using SpringBootContextLoader
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] o.s.t.c.support.AbstractContextLoader : Could not detect default resource locations for test class [com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest]: PostsRepositoryTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.banjjoknim.book.springboot.Application for test class com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.security.test.context.support.ReactorContextTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@494eea6b, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@ad78062, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@70262cf, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@78856d4d, org.springframework.test.context.support.DirtiesContextTestExecutionListener@46a6dd84, org.springframework.test.context.transaction.TransactionalTestExecutionListener@70c481a2, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@6444816f, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@377877af, org.springframework.security.test.context.support.ReactorContextTestExecutionListener@47c2c639, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@135f86f2, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@53d0220f, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@27e1e2d5, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@76c30b1e, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@19c47b22]
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.7.RELEASE)
2020-11-30 15:14:06.020 INFO 10792 --- [ Test worker] c.b.b.s.d.posts.PostsRepositoryTest : Starting PostsRepositoryTest on DESKTOP-FSO9NHB with PID 10792 (started by User in C:\Users\User\IdeaProjects\TIL(Today-I-Learned)\WebServiceBySpringBootAndAWS)
2020-11-30 15:14:06.036 INFO 10792 --- [ Test worker] c.b.b.s.d.posts.PostsRepositoryTest : No active profile set, falling back to default profiles: default
2020-11-30 15:14:06.333 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2020-11-30 15:14:06.380 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 47ms. Found 2 repository interfaces.
2020-11-30 15:14:06.583 INFO 10792 --- [ Test worker] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$d029599b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-11-30 15:14:06.723 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-11-30 15:14:06.879 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2020-11-30 15:14:06.942 INFO 10792 --- [ Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2020-11-30 15:14:07.020 INFO 10792 --- [ Test worker] org.hibernate.Version : HHH000412: Hibernate Core {5.3.10.Final}
2020-11-30 15:14:07.020 INFO 10792 --- [ Test worker] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2020-11-30 15:14:07.067 INFO 10792 --- [ Test worker] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
2020-11-30 15:14:07.223 INFO 10792 --- [ Test worker] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Hibernate: drop table if exists posts
Hibernate: drop table if exists user
Hibernate: create table posts (id bigint not null auto_increment, created_date datetime, modified_date datetime, author varchar(255), content TEXT not null, title varchar(500) not null, primary key (id)) engine=InnoDB
Hibernate: create table user (id bigint not null auto_increment, created_date datetime, modified_date datetime, email varchar(255) not null, name varchar(255) not null, picture varchar(255), role varchar(255) not null, primary key (id)) engine=InnoDB
2020-11-30 15:14:07.739 INFO 10792 --- [ Test worker] o.h.t.schema.internal.SchemaCreatorImpl : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@69028332'
2020-11-30 15:14:07.739 INFO 10792 --- [ Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-11-30 15:14:08.145 INFO 10792 --- [ Test worker] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2020-11-30 15:14:08.410 INFO 10792 --- [ Test worker] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@585acae0, org.springframework.security.web.context.SecurityContextPersistenceFilter@1f9038fa, org.springframework.security.web.header.HeaderWriterFilter@707a5e43, org.springframework.security.web.authentication.logout.LogoutFilter@6938b66c, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@3f52e612, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@5f02912e, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@77710790, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@27a49d1f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1d81f472, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3f2b39c7, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5efb96f4, org.springframework.security.web.session.SessionManagementFilter@3f0ee399, org.springframework.security.web.access.ExceptionTranslationFilter@1572fc36, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@2626e73f]
2020-11-30 15:14:08.676 INFO 10792 --- [ Test worker] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-11-30 15:14:08.692 WARN 10792 --- [ Test worker] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-11-30 15:14:08.723 INFO 10792 --- [ Test worker] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2020-11-30 15:14:09.051 INFO 10792 --- [ Test worker] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2020-11-30 15:14:09.066 INFO 10792 --- [ Test worker] c.b.b.s.d.posts.PostsRepositoryTest : Started PostsRepositoryTest in 3.061 seconds (JVM running for 6.138)
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; createDate=2020-11-30T15:14:09.223147, modifiedDate=2020-11-30T15:14:09.223147
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
</pre>
</span>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 6.5</a> at 2020. 11. 30. 오후 3:14:11</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,154 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Class com.banjjoknim.book.springboot.web.IndexControllerTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Class com.banjjoknim.book.springboot.web.IndexControllerTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.banjjoknim.book.springboot.web.html">com.banjjoknim.book.springboot.web</a> &gt; IndexControllerTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">1</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.135s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
<li>
<a href="#tab1">Standard output</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">메인페이지_로딩</td>
<td class="success">0.135s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
<div id="tab1" class="tab">
<h2>Standard output</h2>
<span class="code">
<pre>2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.banjjoknim.book.springboot.web.IndexControllerTest], using SpringBootContextLoader
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] o.s.t.c.support.AbstractContextLoader : Could not detect default resource locations for test class [com.banjjoknim.book.springboot.web.IndexControllerTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.banjjoknim.book.springboot.web.IndexControllerTest]: IndexControllerTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.banjjoknim.book.springboot.Application for test class com.banjjoknim.book.springboot.web.IndexControllerTest
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.security.test.context.support.ReactorContextTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
2020-11-30 15:14:09.254 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4ce9a2ca, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@55512e1b, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@6b3616af, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@59b63904, org.springframework.test.context.support.DirtiesContextTestExecutionListener@58c82f0a, org.springframework.test.context.transaction.TransactionalTestExecutionListener@435f3fe, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@5fed0eb9, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@37fb7259, org.springframework.security.test.context.support.ReactorContextTestExecutionListener@2e52abd3, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@5d317e4, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@32fc5921, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@5ef98c9d, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@65ceb8a2, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@78bfefc8]
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.7.RELEASE)
2020-11-30 15:14:09.270 INFO 10792 --- [ Test worker] c.b.b.s.web.IndexControllerTest : Starting IndexControllerTest on DESKTOP-FSO9NHB with PID 10792 (started by User in C:\Users\User\IdeaProjects\TIL(Today-I-Learned)\WebServiceBySpringBootAndAWS)
2020-11-30 15:14:09.270 INFO 10792 --- [ Test worker] c.b.b.s.web.IndexControllerTest : No active profile set, falling back to default profiles: default
2020-11-30 15:14:09.426 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2020-11-30 15:14:09.441 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 15ms. Found 2 repository interfaces.
2020-11-30 15:14:09.504 INFO 10792 --- [ Test worker] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$d029599b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-11-30 15:14:09.691 INFO 10792 --- [ Test worker] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 0 (http)
2020-11-30 15:14:09.723 INFO 10792 --- [ Test worker] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-11-30 15:14:09.723 INFO 10792 --- [ Test worker] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.22]
2020-11-30 15:14:09.848 INFO 10792 --- [ Test worker] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-11-30 15:14:09.848 INFO 10792 --- [ Test worker] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 578 ms
2020-11-30 15:14:09.988 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting...
2020-11-30 15:14:09.988 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed.
2020-11-30 15:14:10.004 INFO 10792 --- [ Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2020-11-30 15:14:10.019 INFO 10792 --- [ Test worker] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Hibernate: drop table if exists posts
Hibernate: drop table if exists user
Hibernate: create table posts (id bigint not null auto_increment, created_date datetime, modified_date datetime, author varchar(255), content TEXT not null, title varchar(500) not null, primary key (id)) engine=InnoDB
Hibernate: create table user (id bigint not null auto_increment, created_date datetime, modified_date datetime, email varchar(255) not null, name varchar(255) not null, picture varchar(255), role varchar(255) not null, primary key (id)) engine=InnoDB
2020-11-30 15:14:10.051 INFO 10792 --- [ Test worker] o.h.t.schema.internal.SchemaCreatorImpl : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@69028332'
2020-11-30 15:14:10.051 INFO 10792 --- [ Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-11-30 15:14:10.269 INFO 10792 --- [ Test worker] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2020-11-30 15:14:10.379 INFO 10792 --- [ Test worker] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7e9435ed, org.springframework.security.web.context.SecurityContextPersistenceFilter@2a1f931, org.springframework.security.web.header.HeaderWriterFilter@5b9e89ac, org.springframework.security.web.authentication.logout.LogoutFilter@434ac8c5, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@6c4232aa, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@5c7374b4, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@4eafc850, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@5ee6f3c6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3942deec, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@163ef381, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@23cc4dd2, org.springframework.security.web.session.SessionManagementFilter@a4a4066, org.springframework.security.web.access.ExceptionTranslationFilter@2523df66, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4c0d9bf2]
2020-11-30 15:14:10.504 INFO 10792 --- [ Test worker] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-11-30 15:14:10.504 WARN 10792 --- [ Test worker] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-11-30 15:14:10.535 INFO 10792 --- [ Test worker] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2020-11-30 15:14:10.722 INFO 10792 --- [ Test worker] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2020-11-30 15:14:10.738 INFO 10792 --- [ Test worker] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 12582 (http) with context path ''
2020-11-30 15:14:10.738 INFO 10792 --- [ Test worker] c.b.b.s.web.IndexControllerTest : Started IndexControllerTest in 1.484 seconds (JVM running for 7.815)
2020-11-30 15:14:10.800 INFO 10792 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-11-30 15:14:10.800 INFO 10792 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-11-30 15:14:10.816 INFO 10792 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 16 ms
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_ order by posts0_.id DESC
</pre>
</span>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 6.5</a> at 2020. 11. 30. 오후 3:14:11</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Class com.banjjoknim.book.springboot.web.PostsApiControllerTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Class com.banjjoknim.book.springboot.web.PostsApiControllerTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.banjjoknim.book.springboot.web.html">com.banjjoknim.book.springboot.web</a> &gt; PostsApiControllerTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">2</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.080s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
<li>
<a href="#tab1">Standard output</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">Posts_등록된다</td>
<td class="success">0.055s</td>
<td class="success">passed</td>
</tr>
<tr>
<td class="success">Posts_수정된다</td>
<td class="success">0.025s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
<div id="tab1" class="tab">
<h2>Standard output</h2>
<span class="code">
<pre>2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.banjjoknim.book.springboot.web.PostsApiControllerTest], using SpringBootContextLoader
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] o.s.t.c.support.AbstractContextLoader : Could not detect default resource locations for test class [com.banjjoknim.book.springboot.web.PostsApiControllerTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.banjjoknim.book.springboot.web.PostsApiControllerTest]: PostsApiControllerTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.banjjoknim.book.springboot.Application for test class com.banjjoknim.book.springboot.web.PostsApiControllerTest
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.security.test.context.support.ReactorContextTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@54b84a95, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@5f2e478d, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@329252bb, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@5f6bd033, org.springframework.test.context.support.DirtiesContextTestExecutionListener@4991d5a9, org.springframework.test.context.transaction.TransactionalTestExecutionListener@64aee139, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@4489609d, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@4562ca77, org.springframework.security.test.context.support.ReactorContextTestExecutionListener@29963ef, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@112dfdac, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@1eafea9c, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@4dcdba4c, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@4023e01, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@7a3c73b0]
2020-11-30 15:14:10.894 INFO 10792 --- [ Test worker] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring TestDispatcherServlet ''
2020-11-30 15:14:10.894 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2020-11-30 15:14:10.894 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 0 ms
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
2020-11-30 15:14:10.941 INFO 10792 --- [ Test worker] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring TestDispatcherServlet ''
2020-11-30 15:14:10.941 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2020-11-30 15:14:10.941 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 0 ms
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_0_, posts0_.created_date as created_2_0_0_, posts0_.modified_date as modified3_0_0_, posts0_.author as author4_0_0_, posts0_.content as content5_0_0_, posts0_.title as title6_0_0_ from posts posts0_ where posts0_.id=?
Hibernate: update posts set created_date=?, modified_date=?, author=?, content=?, title=? where id=?
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
</pre>
</span>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 6.5</a> at 2020. 11. 30. 오후 3:14:11</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Class com.banjjoknim.book.springboot.web.dto.HelloResponseDtoTest</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Class com.banjjoknim.book.springboot.web.dto.HelloResponseDtoTest</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt;
<a href="../packages/com.banjjoknim.book.springboot.web.dto.html">com.banjjoknim.book.springboot.web.dto</a> &gt; HelloResponseDtoTest</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">1</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.001s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Tests</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Tests</h2>
<table>
<thead>
<tr>
<th>Test</th>
<th>Duration</th>
<th>Result</th>
</tr>
</thead>
<tr>
<td class="success">롬복_기능_테스트</td>
<td class="success">0.001s</td>
<td class="success">passed</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 6.5</a> at 2020. 11. 30. 오후 3:14:11</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.banjjoknim.book.springboot.domain.posts</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.banjjoknim.book.springboot.domain.posts</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.banjjoknim.book.springboot.domain.posts</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">2</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.162s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest.html">PostsRepositoryTest</a>
</td>
<td>2</td>
<td>0</td>
<td>0</td>
<td>0.162s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 6.5</a> at 2020. 11. 30. 오후 3:14:11</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="x-ua-compatible" content="IE=edge"/>
<title>Test results - Package com.banjjoknim.book.springboot.web.dto</title>
<link href="../css/base-style.css" rel="stylesheet" type="text/css"/>
<link href="../css/style.css" rel="stylesheet" type="text/css"/>
<script src="../js/report.js" type="text/javascript"></script>
</head>
<body>
<div id="content">
<h1>Package com.banjjoknim.book.springboot.web.dto</h1>
<div class="breadcrumbs">
<a href="../index.html">all</a> &gt; com.banjjoknim.book.springboot.web.dto</div>
<div id="summary">
<table>
<tr>
<td>
<div class="summaryGroup">
<table>
<tr>
<td>
<div class="infoBox" id="tests">
<div class="counter">1</div>
<p>tests</p>
</div>
</td>
<td>
<div class="infoBox" id="failures">
<div class="counter">0</div>
<p>failures</p>
</div>
</td>
<td>
<div class="infoBox" id="ignored">
<div class="counter">0</div>
<p>ignored</p>
</div>
</td>
<td>
<div class="infoBox" id="duration">
<div class="counter">0.001s</div>
<p>duration</p>
</div>
</td>
</tr>
</table>
</div>
</td>
<td>
<div class="infoBox success" id="successRate">
<div class="percent">100%</div>
<p>successful</p>
</div>
</td>
</tr>
</table>
</div>
<div id="tabs">
<ul class="tabLinks">
<li>
<a href="#tab0">Classes</a>
</li>
</ul>
<div id="tab0" class="tab">
<h2>Classes</h2>
<table>
<thread>
<tr>
<th>Class</th>
<th>Tests</th>
<th>Failures</th>
<th>Ignored</th>
<th>Duration</th>
<th>Success rate</th>
</tr>
</thread>
<tr>
<td class="success">
<a href="../classes/com.banjjoknim.book.springboot.web.dto.HelloResponseDtoTest.html">HelloResponseDtoTest</a>
</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0.001s</td>
<td class="success">100%</td>
</tr>
</table>
</div>
</div>
<div id="footer">
<p>
<div>
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off"/>
</label>
</div>Generated by
<a href="http://www.gradle.org">Gradle 6.5</a> at 2020. 11. 30. 오후 3:14:11</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,5 @@
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.h2.console.enabled=true
spring.profiles.include=oauth
spring.session.store-type=jdbc

View File

@@ -0,0 +1,74 @@
var main = {
init: function () {
var _this = this;
$('#btn-save').on('click', function () {
_this.save();
});
$('#btn-update').on('click', function () {
_this.update();
});
$('#btn-delete').on('click', function () {
_this.delete();
});
},
save: function () {
var data = {
title: $('#title').val(),
author: $('#author').val(),
content: $('#content').val()
};
$.ajax({
type: 'POST',
url: '/api/v1/posts',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(data)
}).done(function () {
alert('글이 등록되었습니다.');
window.location.href = '/';
}).fail(function (error) {
alert(JSON.stringify(error));
});
},
update: function () {
var data = {
title: $('#title').val(),
content: $('#content').val()
};
var id = $('#id').val();
$.ajax({
type: 'PUT',
url: '/api/v1/posts/' + id,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(data)
}).done(function () {
alert('글이 수정되었습니다.');
window.location.href = '/';
}).fail(function (error) {
alert(JSON.stringify(error));
});
},
delete: function () {
var id = $('#id').val();
$.ajax({
type: 'DELETE',
url: '/api/v1/posts/' + id,
dataType: 'json',
contentType: 'application/json; charset=utf-8'
}).done(function () {
alert('글이 삭제되었습니다.');
window.location.href = '/';
}).fail(function (error) {
alert(JSON.stringify(error));
})
}
};
main.init();

View File

@@ -0,0 +1,44 @@
{{>layout/header}}
<h1>스프링 부트로 시작하는 웹 서비스</h1>
<div class="col-md-12">
<!--로그인 기능 영역-->
<div class="row">
<div class="col-md-6">
<a href="/posts/save" role="button" class="btn btn-primary">글 등록</a>
{{#userName}}
Logged in as : <span id="user">{{username}}</span>
<a href="/logout" class="btn btn-info active" role="button">Logout</a>
{{/userName}}
{{^userName}}
<a href="/oauth2/authorization/google" class="btn btn-success active" role="button">Google Login</a>
<a href="/oauth2/authorization/naver" class="btn btn-secondary active" role="button">Naver Login</a>
{{/userName}}
</div>
</div>
</div>
<br>
<!-- 목록 출력 영역 -->
<table class="table table-horizontal table-bordered">
<thead class="thead-strong">
<tr>
<th>게시글번호</th>
<th>제목</th>
<th>작성자</th>
<th>최종수정일</th>
</tr>
</thead>
<tbody id="tbody">
{{#posts}}
<tr>
<td>{{id}}</td>
<td><a href="/posts/update/{{id}}">{{title}}</a></td>
<td>{{author}}</td>
<td>{{modifiedDate}}</td>
</tr>
{{/posts}}
</tbody>
</table>
</div>
{{>layout/footer}}

View File

@@ -0,0 +1,7 @@
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<!--index.js 추가-->
<script src="/js/app/index.js"></script>
</body>
</html>

View File

@@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<html>
<head>
<title>스프링 부트 웹 서비스</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>

View File

@@ -0,0 +1,26 @@
{{>layout/header}}
<h1>게시글 등록</h1>
<div class="col-md-12">
<div class="col-md-4">
<form>
<div class="form-group">
<label for="title">제목</label>
<input type="text" class="form-control" id="title" placeholder="제목을 입력하세요">
</div>
<div class="form-group">
<label for="author">작성자</label>
<input type="text" class="form-control" id="author" placeholder="작성자를 입력하세요">
</div>
<div class="form-group">
<label for="content">내용</label>
<textarea class="form-control" id="content" placeholder="내용을 입력하세요"></textarea>
</div>
</form>
<a href="/" role="button" class="btn btn-secondary">취소</a>
<button type="button" class="btn btn-primary" id="btn-save">등록</button>
</div>
</div>
{{>layout/footer}}

View File

@@ -0,0 +1,31 @@
{{>layout/header}}
<h1>게시글 수정</h1>
<div class="col-md-12">
<div class="col-md-4">
<form>
<div class="form-group">
<label for="id">글 번호</label>
<input type="text" class="form-control" id="id" value="{{post.id}}" readonly>
</div>
<div class="form-group">
<label for="title">제목</label>
<input type="text" class="form-control" id="title" value="{{post.title}}">
</div>
<div class="form-group">
<label for="author">작성자</label>
<input type="text" class="form-control" id="author" value="{{post.author}}" readonly>
</div>
<div class="form-group">
<label for="content">내용</label>
<textarea class="form-control" id="content">{{post.content}}</textarea>
</div>
</form>
<a href="/" role="button" class="btn btn-secondary">취소</a>
<button type="button" class="btn btn-primary" id="btn-update">수정 완료</button>
<button type="button" class="btn btn-danger" id="btn-delete">삭제</button>
</div>
</div>
{{>layout/footer}}

View File

@@ -0,0 +1,9 @@
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.h2.console.enabled=true
spring.session.store-type=jdbc
# Test OAuth
spring.security.oauth2.client.registration.google.client-id=test
spring.security.oauth2.client.registration.google.client-secret=test
spring.security.oauth2.client.registration.google.scope=profile,email

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest" tests="2" skipped="0" failures="0" errors="0" timestamp="2020-11-30T06:14:09" hostname="DESKTOP-FSO9NHB" time="0.162">
<properties/>
<testcase name="게시글저장_불러오기" classname="com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest" time="0.149"/>
<testcase name="BaseTimeEntity_등록" classname="com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest" time="0.013"/>
<system-out><![CDATA[2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest], using SpringBootContextLoader
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] o.s.t.c.support.AbstractContextLoader : Could not detect default resource locations for test class [com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest]: PostsRepositoryTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.banjjoknim.book.springboot.Application for test class com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.security.test.context.support.ReactorContextTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
2020-11-30 15:14:06.005 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@494eea6b, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@ad78062, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@70262cf, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@78856d4d, org.springframework.test.context.support.DirtiesContextTestExecutionListener@46a6dd84, org.springframework.test.context.transaction.TransactionalTestExecutionListener@70c481a2, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@6444816f, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@377877af, org.springframework.security.test.context.support.ReactorContextTestExecutionListener@47c2c639, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@135f86f2, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@53d0220f, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@27e1e2d5, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@76c30b1e, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@19c47b22]
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.7.RELEASE)
2020-11-30 15:14:06.020 INFO 10792 --- [ Test worker] c.b.b.s.d.posts.PostsRepositoryTest : Starting PostsRepositoryTest on DESKTOP-FSO9NHB with PID 10792 (started by User in C:\Users\User\IdeaProjects\TIL(Today-I-Learned)\WebServiceBySpringBootAndAWS)
2020-11-30 15:14:06.036 INFO 10792 --- [ Test worker] c.b.b.s.d.posts.PostsRepositoryTest : No active profile set, falling back to default profiles: default
2020-11-30 15:14:06.333 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2020-11-30 15:14:06.380 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 47ms. Found 2 repository interfaces.
2020-11-30 15:14:06.583 INFO 10792 --- [ Test worker] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$d029599b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-11-30 15:14:06.723 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2020-11-30 15:14:06.879 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2020-11-30 15:14:06.942 INFO 10792 --- [ Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2020-11-30 15:14:07.020 INFO 10792 --- [ Test worker] org.hibernate.Version : HHH000412: Hibernate Core {5.3.10.Final}
2020-11-30 15:14:07.020 INFO 10792 --- [ Test worker] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2020-11-30 15:14:07.067 INFO 10792 --- [ Test worker] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.4.Final}
2020-11-30 15:14:07.223 INFO 10792 --- [ Test worker] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Hibernate: drop table if exists posts
Hibernate: drop table if exists user
Hibernate: create table posts (id bigint not null auto_increment, created_date datetime, modified_date datetime, author varchar(255), content TEXT not null, title varchar(500) not null, primary key (id)) engine=InnoDB
Hibernate: create table user (id bigint not null auto_increment, created_date datetime, modified_date datetime, email varchar(255) not null, name varchar(255) not null, picture varchar(255), role varchar(255) not null, primary key (id)) engine=InnoDB
2020-11-30 15:14:07.739 INFO 10792 --- [ Test worker] o.h.t.schema.internal.SchemaCreatorImpl : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@69028332'
2020-11-30 15:14:07.739 INFO 10792 --- [ Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-11-30 15:14:08.145 INFO 10792 --- [ Test worker] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2020-11-30 15:14:08.410 INFO 10792 --- [ Test worker] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@585acae0, org.springframework.security.web.context.SecurityContextPersistenceFilter@1f9038fa, org.springframework.security.web.header.HeaderWriterFilter@707a5e43, org.springframework.security.web.authentication.logout.LogoutFilter@6938b66c, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@3f52e612, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@5f02912e, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@77710790, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@27a49d1f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@1d81f472, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@3f2b39c7, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5efb96f4, org.springframework.security.web.session.SessionManagementFilter@3f0ee399, org.springframework.security.web.access.ExceptionTranslationFilter@1572fc36, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@2626e73f]
2020-11-30 15:14:08.676 INFO 10792 --- [ Test worker] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-11-30 15:14:08.692 WARN 10792 --- [ Test worker] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-11-30 15:14:08.723 INFO 10792 --- [ Test worker] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2020-11-30 15:14:09.051 INFO 10792 --- [ Test worker] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2020-11-30 15:14:09.066 INFO 10792 --- [ Test worker] c.b.b.s.d.posts.PostsRepositoryTest : Started PostsRepositoryTest in 3.061 seconds (JVM running for 6.138)
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
>>>>>>>>>> createDate=2020-11-30T15:14:09.223147, modifiedDate=2020-11-30T15:14:09.223147
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.banjjoknim.book.springboot.web.IndexControllerTest" tests="1" skipped="0" failures="0" errors="0" timestamp="2020-11-30T06:14:10" hostname="DESKTOP-FSO9NHB" time="0.135">
<properties/>
<testcase name="메인페이지_로딩" classname="com.banjjoknim.book.springboot.web.IndexControllerTest" time="0.135"/>
<system-out><![CDATA[2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.banjjoknim.book.springboot.web.IndexControllerTest], using SpringBootContextLoader
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] o.s.t.c.support.AbstractContextLoader : Could not detect default resource locations for test class [com.banjjoknim.book.springboot.web.IndexControllerTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.banjjoknim.book.springboot.web.IndexControllerTest]: IndexControllerTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.banjjoknim.book.springboot.Application for test class com.banjjoknim.book.springboot.web.IndexControllerTest
2020-11-30 15:14:09.238 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.security.test.context.support.ReactorContextTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
2020-11-30 15:14:09.254 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4ce9a2ca, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@55512e1b, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@6b3616af, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@59b63904, org.springframework.test.context.support.DirtiesContextTestExecutionListener@58c82f0a, org.springframework.test.context.transaction.TransactionalTestExecutionListener@435f3fe, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@5fed0eb9, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@37fb7259, org.springframework.security.test.context.support.ReactorContextTestExecutionListener@2e52abd3, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@5d317e4, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@32fc5921, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@5ef98c9d, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@65ceb8a2, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@78bfefc8]
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.7.RELEASE)
2020-11-30 15:14:09.270 INFO 10792 --- [ Test worker] c.b.b.s.web.IndexControllerTest : Starting IndexControllerTest on DESKTOP-FSO9NHB with PID 10792 (started by User in C:\Users\User\IdeaProjects\TIL(Today-I-Learned)\WebServiceBySpringBootAndAWS)
2020-11-30 15:14:09.270 INFO 10792 --- [ Test worker] c.b.b.s.web.IndexControllerTest : No active profile set, falling back to default profiles: default
2020-11-30 15:14:09.426 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2020-11-30 15:14:09.441 INFO 10792 --- [ Test worker] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 15ms. Found 2 repository interfaces.
2020-11-30 15:14:09.504 INFO 10792 --- [ Test worker] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$d029599b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-11-30 15:14:09.691 INFO 10792 --- [ Test worker] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 0 (http)
2020-11-30 15:14:09.723 INFO 10792 --- [ Test worker] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-11-30 15:14:09.723 INFO 10792 --- [ Test worker] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.22]
2020-11-30 15:14:09.848 INFO 10792 --- [ Test worker] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-11-30 15:14:09.848 INFO 10792 --- [ Test worker] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 578 ms
2020-11-30 15:14:09.988 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting...
2020-11-30 15:14:09.988 INFO 10792 --- [ Test worker] com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed.
2020-11-30 15:14:10.004 INFO 10792 --- [ Test worker] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2020-11-30 15:14:10.019 INFO 10792 --- [ Test worker] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Hibernate: drop table if exists posts
Hibernate: drop table if exists user
Hibernate: create table posts (id bigint not null auto_increment, created_date datetime, modified_date datetime, author varchar(255), content TEXT not null, title varchar(500) not null, primary key (id)) engine=InnoDB
Hibernate: create table user (id bigint not null auto_increment, created_date datetime, modified_date datetime, email varchar(255) not null, name varchar(255) not null, picture varchar(255), role varchar(255) not null, primary key (id)) engine=InnoDB
2020-11-30 15:14:10.051 INFO 10792 --- [ Test worker] o.h.t.schema.internal.SchemaCreatorImpl : HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@69028332'
2020-11-30 15:14:10.051 INFO 10792 --- [ Test worker] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-11-30 15:14:10.269 INFO 10792 --- [ Test worker] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2020-11-30 15:14:10.379 INFO 10792 --- [ Test worker] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: any request, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@7e9435ed, org.springframework.security.web.context.SecurityContextPersistenceFilter@2a1f931, org.springframework.security.web.header.HeaderWriterFilter@5b9e89ac, org.springframework.security.web.authentication.logout.LogoutFilter@434ac8c5, org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@6c4232aa, org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@5c7374b4, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@4eafc850, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@5ee6f3c6, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3942deec, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@163ef381, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@23cc4dd2, org.springframework.security.web.session.SessionManagementFilter@a4a4066, org.springframework.security.web.access.ExceptionTranslationFilter@2523df66, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@4c0d9bf2]
2020-11-30 15:14:10.504 INFO 10792 --- [ Test worker] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-11-30 15:14:10.504 WARN 10792 --- [ Test worker] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2020-11-30 15:14:10.535 INFO 10792 --- [ Test worker] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page template: index
2020-11-30 15:14:10.722 INFO 10792 --- [ Test worker] s.a.ScheduledAnnotationBeanPostProcessor : No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
2020-11-30 15:14:10.738 INFO 10792 --- [ Test worker] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 12582 (http) with context path ''
2020-11-30 15:14:10.738 INFO 10792 --- [ Test worker] c.b.b.s.web.IndexControllerTest : Started IndexControllerTest in 1.484 seconds (JVM running for 7.815)
2020-11-30 15:14:10.800 INFO 10792 --- [o-auto-1-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-11-30 15:14:10.800 INFO 10792 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-11-30 15:14:10.816 INFO 10792 --- [o-auto-1-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 16 ms
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_ order by posts0_.id DESC
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.banjjoknim.book.springboot.web.PostsApiControllerTest" tests="2" skipped="0" failures="0" errors="0" timestamp="2020-11-30T06:14:10" hostname="DESKTOP-FSO9NHB" time="0.08">
<properties/>
<testcase name="Posts_등록된다" classname="com.banjjoknim.book.springboot.web.PostsApiControllerTest" time="0.055"/>
<testcase name="Posts_수정된다" classname="com.banjjoknim.book.springboot.web.PostsApiControllerTest" time="0.025"/>
<system-out><![CDATA[2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.banjjoknim.book.springboot.web.PostsApiControllerTest], using SpringBootContextLoader
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] o.s.t.c.support.AbstractContextLoader : Could not detect default resource locations for test class [com.banjjoknim.book.springboot.web.PostsApiControllerTest]: no resource found for suffixes {-context.xml, Context.groovy}.
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] t.c.s.AnnotationConfigContextLoaderUtils : Could not detect default configuration classes for test class [com.banjjoknim.book.springboot.web.PostsApiControllerTest]: PostsApiControllerTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Found @SpringBootConfiguration com.banjjoknim.book.springboot.Application for test class com.banjjoknim.book.springboot.web.PostsApiControllerTest
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.security.test.context.support.ReactorContextTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
2020-11-30 15:14:10.879 INFO 10792 --- [ Test worker] .b.t.c.SpringBootTestContextBootstrapper : Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@54b84a95, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@5f2e478d, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@329252bb, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@5f6bd033, org.springframework.test.context.support.DirtiesContextTestExecutionListener@4991d5a9, org.springframework.test.context.transaction.TransactionalTestExecutionListener@64aee139, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@4489609d, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@4562ca77, org.springframework.security.test.context.support.ReactorContextTestExecutionListener@29963ef, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@112dfdac, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@1eafea9c, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@4dcdba4c, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@4023e01, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@7a3c73b0]
2020-11-30 15:14:10.894 INFO 10792 --- [ Test worker] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring TestDispatcherServlet ''
2020-11-30 15:14:10.894 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2020-11-30 15:14:10.894 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 0 ms
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
2020-11-30 15:14:10.941 INFO 10792 --- [ Test worker] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring TestDispatcherServlet ''
2020-11-30 15:14:10.941 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Initializing Servlet ''
2020-11-30 15:14:10.941 INFO 10792 --- [ Test worker] o.s.t.web.servlet.TestDispatcherServlet : Completed initialization in 0 ms
Hibernate: insert into posts (created_date, modified_date, author, content, title) values (?, ?, ?, ?, ?)
Hibernate: select posts0_.id as id1_0_0_, posts0_.created_date as created_2_0_0_, posts0_.modified_date as modified3_0_0_, posts0_.author as author4_0_0_, posts0_.content as content5_0_0_, posts0_.title as title6_0_0_ from posts posts0_ where posts0_.id=?
Hibernate: update posts set created_date=?, modified_date=?, author=?, content=?, title=? where id=?
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: select posts0_.id as id1_0_, posts0_.created_date as created_2_0_, posts0_.modified_date as modified3_0_, posts0_.author as author4_0_, posts0_.content as content5_0_, posts0_.title as title6_0_ from posts posts0_
Hibernate: delete from posts where id=?
]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuite name="com.banjjoknim.book.springboot.web.dto.HelloResponseDtoTest" tests="1" skipped="0" failures="0" errors="0" timestamp="2020-11-30T06:14:09" hostname="DESKTOP-FSO9NHB" time="0.001">
<properties/>
<testcase name="롬복_기능_테스트" classname="com.banjjoknim.book.springboot.web.dto.HelloResponseDtoTest" time="0.001"/>
<system-out><![CDATA[]]></system-out>
<system-err><![CDATA[]]></system-err>
</testsuite>

View File

@@ -0,0 +1,53 @@
com/banjjoknim/book/springboot/config/auth/LoginUserArgumentResolver.java
com.banjjoknim.book.springboot.config.auth.LoginUserArgumentResolver
com/banjjoknim/book/springboot/web/IndexController.java
com.banjjoknim.book.springboot.web.IndexController
com/banjjoknim/book/springboot/web/dto/PostsResponseDto.java
com.banjjoknim.book.springboot.web.dto.PostsResponseDto
com/banjjoknim/book/springboot/domain/posts/Posts.java
com.banjjoknim.book.springboot.domain.posts.Posts
com.banjjoknim.book.springboot.domain.posts.Posts$PostsBuilder
com/banjjoknim/book/springboot/web/dto/PostsUpdateRequestDto.java
com.banjjoknim.book.springboot.web.dto.PostsUpdateRequestDto
com.banjjoknim.book.springboot.web.dto.PostsUpdateRequestDto$PostsUpdateRequestDtoBuilder
com/banjjoknim/book/springboot/domain/BaseTimeEntity.java
com.banjjoknim.book.springboot.domain.BaseTimeEntity
com/banjjoknim/book/springboot/domain/user/Role.java
com.banjjoknim.book.springboot.domain.user.Role
com/banjjoknim/book/springboot/web/dto/HelloResponseDto.java
com.banjjoknim.book.springboot.web.dto.HelloResponseDto
com/banjjoknim/book/springboot/service/PostsService.java
com.banjjoknim.book.springboot.service.PostsService
com/banjjoknim/book/springboot/config/auth/dto/OAuthAttributes.java
com.banjjoknim.book.springboot.config.auth.dto.OAuthAttributes
com.banjjoknim.book.springboot.config.auth.dto.OAuthAttributes$OAuthAttributesBuilder
com/banjjoknim/book/springboot/config/auth/LoginUser.java
com.banjjoknim.book.springboot.config.auth.LoginUser
com/banjjoknim/book/springboot/web/dto/PostsSaveRequestDto.java
com.banjjoknim.book.springboot.web.dto.PostsSaveRequestDto
com.banjjoknim.book.springboot.web.dto.PostsSaveRequestDto$PostsSaveRequestDtoBuilder
com/banjjoknim/book/springboot/config/auth/dto/SessionUser.java
com.banjjoknim.book.springboot.config.auth.dto.SessionUser
com/banjjoknim/book/springboot/config/WebConfig.java
com.banjjoknim.book.springboot.config.WebConfig
com/banjjoknim/book/springboot/web/HelloController.java
com.banjjoknim.book.springboot.web.HelloController
com/banjjoknim/book/springboot/domain/user/UserRepository.java
com.banjjoknim.book.springboot.domain.user.UserRepository
com/banjjoknim/book/springboot/domain/posts/PostsRepository.java
com.banjjoknim.book.springboot.domain.posts.PostsRepository
com/banjjoknim/book/springboot/web/PostsApiController.java
com.banjjoknim.book.springboot.web.PostsApiController
com/banjjoknim/book/springboot/config/auth/CustomOAuth2UserService.java
com.banjjoknim.book.springboot.config.auth.CustomOAuth2UserService
com/banjjoknim/book/springboot/domain/user/User.java
com.banjjoknim.book.springboot.domain.user.User
com.banjjoknim.book.springboot.domain.user.User$UserBuilder
com/banjjoknim/book/springboot/web/dto/PostsListResponseDto.java
com.banjjoknim.book.springboot.web.dto.PostsListResponseDto
com/banjjoknim/book/springboot/config/auth/SecurityConfig.java
com.banjjoknim.book.springboot.config.auth.SecurityConfig
com/banjjoknim/book/springboot/Application.java
com.banjjoknim.book.springboot.Application
com/banjjoknim/book/springboot/config/JpaConfig.java
com.banjjoknim.book.springboot.config.JpaConfig

View File

@@ -0,0 +1,10 @@
com/banjjoknim/book/springboot/web/dto/HelloResponseDtoTest.java
com.banjjoknim.book.springboot.web.dto.HelloResponseDtoTest
com/banjjoknim/book/springboot/web/IndexControllerTest.java
com.banjjoknim.book.springboot.web.IndexControllerTest
com/banjjoknim/book/springboot/web/PostsApiControllerTest.java
com.banjjoknim.book.springboot.web.PostsApiControllerTest
com/banjjoknim/book/springboot/domain/posts/PostsRepositoryTest.java
com.banjjoknim.book.springboot.domain.posts.PostsRepositoryTest
com/banjjoknim/book/springboot/web/HelloControllerTest.java
com.banjjoknim.book.springboot.web.HelloControllerTest

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@EnableJpaAuditing // JPA Auditing 활성화 // @EnableJpaAuditing 가 삭제됨
@SpringBootApplication @SpringBootApplication
public class Application { public class Application {
public static void main(String[] args) { public static void main(String[] args) {

View File

@@ -0,0 +1,9 @@
package com.banjjoknim.book.springboot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Configuration
@EnableJpaAuditing // JPA Auditing 활성화
public class JpaConfig {
}

View File

@@ -0,0 +1,20 @@
package com.banjjoknim.book.springboot.config;
import com.banjjoknim.book.springboot.config.auth.LoginUserArgumentResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final LoginUserArgumentResolver loginUserArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginUserArgumentResolver);
}
}

View File

@@ -0,0 +1,57 @@
package com.banjjoknim.book.springboot.config.auth;
import com.banjjoknim.book.springboot.config.auth.dto.OAuthAttributes;
import com.banjjoknim.book.springboot.config.auth.dto.SessionUser;
import com.banjjoknim.book.springboot.domain.user.User;
import com.banjjoknim.book.springboot.domain.user.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpSession;
import java.util.Collections;
@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
private final UserRepository userRepository;
private final HttpSession httpSession;
@Override
public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
OAuth2UserService delegate = new DefaultOAuth2UserService();
OAuth2User oAuth2User = delegate.loadUser(userRequest);
String registrationId = userRequest.getClientRegistration()
.getRegistrationId();
String userNameAttributeName = userRequest.getClientRegistration()
.getProviderDetails()
.getUserInfoEndpoint()
.getUserNameAttributeName();
OAuthAttributes attributes = OAuthAttributes.
of(registrationId, userNameAttributeName, oAuth2User.getAttributes());
User user = saveOrUpdate(attributes);
httpSession.setAttribute("user", new SessionUser(user));
return new DefaultOAuth2User(
Collections.singleton(new SimpleGrantedAuthority(user.getRoleKey())),
attributes.getAttributes(),
attributes.getNameAttributeKey());
}
private User saveOrUpdate(OAuthAttributes attributes) {
User user = userRepository.findByEmail(attributes.getEmail())
.map(entity -> entity.update(attributes.getName(), attributes.getPicture()))
.orElse(attributes.toEntity());
return userRepository.save(user);
}
}

View File

@@ -0,0 +1,11 @@
package com.banjjoknim.book.springboot.config.auth;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}

View File

@@ -0,0 +1,32 @@
package com.banjjoknim.book.springboot.config.auth;
import com.banjjoknim.book.springboot.config.auth.dto.SessionUser;
import lombok.RequiredArgsConstructor;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpSession;
@RequiredArgsConstructor
@Component
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {
private final HttpSession httpSession;
@Override
public boolean supportsParameter(MethodParameter parameter) {
boolean isLoginUserAnnotation = parameter.getParameterAnnotation(LoginUser.class) != null;
boolean isUserClass = SessionUser.class.equals(parameter.getParameterType());
return isLoginUserAnnotation && isUserClass;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return httpSession.getAttribute("user");
}
}

View File

@@ -0,0 +1,30 @@
package com.banjjoknim.book.springboot.config.auth;
import com.banjjoknim.book.springboot.domain.user.Role;
import lombok.RequiredArgsConstructor;
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.WebSecurityConfigurerAdapter;
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomOAuth2UserService customOAuth2UserService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/", "/css/**", "/images/**", "/js/**", "/h2-console/**").permitAll()
.antMatchers("/api/v1/**").hasRole(Role.USER.name())
.anyRequest().authenticated()
.and()
.logout().logoutSuccessUrl("/")
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService);
}
}

View File

@@ -0,0 +1,66 @@
package com.banjjoknim.book.springboot.config.auth.dto;
import com.banjjoknim.book.springboot.domain.user.Role;
import com.banjjoknim.book.springboot.domain.user.User;
import lombok.Builder;
import lombok.Getter;
import java.util.Map;
@Getter
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String name;
private String email;
private String picture;
@Builder
public OAuthAttributes(Map<String, Object> attributes, String nameAttributeKey, String name, String email, String picture) {
this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
this.picture = picture;
}
public static OAuthAttributes of(String registrationId, String userNameAttributeName, Map<String, Object> attributes) {
if ("naver".equals(registrationId)) {
return ofNaver("id", attributes);
}
return ofGoogle(userNameAttributeName, attributes);
}
private static OAuthAttributes ofNaver(String userNameAttributeName, Map<String, Object> attributes) {
Map<String, Object> response = (Map<String, Object>) attributes.get("response");
return OAuthAttributes.builder()
.name((String) response.get("name"))
.email((String) response.get("email"))
.picture((String) response.get("profile_image"))
.attributes(response)
.nameAttributeKey(userNameAttributeName)
.build();
}
private static OAuthAttributes ofGoogle(String userNameAttributeName, Map<String, Object> attributes) {
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email((String) attributes.get("email"))
.picture((String) attributes.get("picture"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
public User toEntity() {
return User.builder()
.name(name)
.email(email)
.picture(picture)
.role(Role.GUEST)
.build();
}
}

View File

@@ -0,0 +1,19 @@
package com.banjjoknim.book.springboot.config.auth.dto;
import com.banjjoknim.book.springboot.domain.user.User;
import lombok.Getter;
import java.io.Serializable;
@Getter
public class SessionUser implements Serializable {
private String name;
private String email;
private String picture;
public SessionUser(User user) {
this.name = user.getName();
this.email = user.getEmail();
this.picture = user.getPicture();
}
}

View File

@@ -0,0 +1,15 @@
package com.banjjoknim.book.springboot.domain.user;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum Role {
GUEST("ROLE_GUEST", "손님"),
USER("ROLE_USER", "일반 사용자");
private final String key;
private final String title;
}

View File

@@ -0,0 +1,50 @@
package com.banjjoknim.book.springboot.domain.user;
import com.banjjoknim.book.springboot.domain.BaseTimeEntity;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor
@Entity
public class User extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String email;
@Column
private String picture;
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Role role;
@Builder
public User(String name, String email, String picture, Role role) {
this.name = name;
this.email = email;
this.picture = picture;
this.role = role;
}
public User update(String name, String picture) {
this.name = name;
this.picture = picture;
return this;
}
public String getRoleKey() {
return this.role.getKey();
}
}

View File

@@ -0,0 +1,10 @@
package com.banjjoknim.book.springboot.domain.user;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}

View File

@@ -1,5 +1,7 @@
package com.banjjoknim.book.springboot.web; package com.banjjoknim.book.springboot.web;
import com.banjjoknim.book.springboot.config.auth.LoginUser;
import com.banjjoknim.book.springboot.config.auth.dto.SessionUser;
import com.banjjoknim.book.springboot.service.PostsService; import com.banjjoknim.book.springboot.service.PostsService;
import com.banjjoknim.book.springboot.web.dto.PostsResponseDto; import com.banjjoknim.book.springboot.web.dto.PostsResponseDto;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@@ -8,15 +10,22 @@ import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import javax.servlet.http.HttpSession;
@RequiredArgsConstructor @RequiredArgsConstructor
@Controller @Controller
public class IndexController { public class IndexController {
private final PostsService postsService; private final PostsService postsService;
private final HttpSession httpSession;
@GetMapping("/") @GetMapping("/")
public String index(Model model) { public String index(Model model, @LoginUser SessionUser user) {
model.addAttribute("posts", postsService.findAllDesc()); model.addAttribute("posts", postsService.findAllDesc());
if (user != null) {
model.addAttribute("userName", user.getName());
}
return "index"; return "index";
} }

View File

@@ -1,3 +1,5 @@
spring.jpa.show-sql=true spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.h2.console.enabled=true spring.h2.console.enabled=true
spring.profiles.include=oauth
spring.session.store-type=jdbc

View File

@@ -1,14 +1,24 @@
{{>layout/header}} {{>layout/header}}
<h1>스프링 부트로 시작하는 웹 서비스 Ver.2</h1> <h1>스프링 부트로 시작하는 웹 서비스</h1>
<div class="col-md-12"> <div class="col-md-12">
<!--로그인 기능 영역-->
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<a href="/posts/save" role="button" class="btn btn-primary">글 등록</a> <a href="/posts/save" role="button" class="btn btn-primary">글 등록</a>
{{#userName}}
Logged in as : <span id="user">{{username}}</span>
<a href="/logout" class="btn btn-info active" role="button">Logout</a>
{{/userName}}
{{^userName}}
<a href="/oauth2/authorization/google" class="btn btn-success active" role="button">Google Login</a>
<a href="/oauth2/authorization/naver" class="btn btn-secondary active" role="button">Naver Login</a>
{{/userName}}
</div> </div>
</div> </div>
<br> </div>
<!--목록 출력 영역--> <br>
<!-- 목록 출력 영역 -->
<table class="table table-horizontal table-bordered"> <table class="table table-horizontal table-bordered">
<thead class="thead-strong"> <thead class="thead-strong">
<tr> <tr>

View File

@@ -1,9 +1,13 @@
package com.banjjoknim.book.springboot.web; package com.banjjoknim.book.springboot.web;
import com.banjjoknim.book.springboot.config.auth.SecurityConfig;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
@@ -12,12 +16,15 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@WebMvcTest(controllers = HelloController.class) @WebMvcTest(controllers = HelloController.class, excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class)
})
public class HelloControllerTest { public class HelloControllerTest {
@Autowired @Autowired
private MockMvc mvc; private MockMvc mvc;
@Test @Test
@WithMockUser(roles = "USER")
public void hello가_리턴된다() throws Exception { public void hello가_리턴된다() throws Exception {
String hello = "hello"; String hello = "hello";
@@ -27,6 +34,7 @@ public class HelloControllerTest {
} }
@Test @Test
@WithMockUser(roles = "USER")
public void helloDto가_리턴된다() throws Exception { public void helloDto가_리턴된다() throws Exception {
String name = "hello"; String name = "hello";
int amount = 1000; int amount = 1000;

View File

@@ -4,7 +4,9 @@ import com.banjjoknim.book.springboot.domain.posts.Posts;
import com.banjjoknim.book.springboot.domain.posts.PostsRepository; import com.banjjoknim.book.springboot.domain.posts.PostsRepository;
import com.banjjoknim.book.springboot.web.dto.PostsSaveRequestDto; import com.banjjoknim.book.springboot.web.dto.PostsSaveRequestDto;
import com.banjjoknim.book.springboot.web.dto.PostsUpdateRequestDto; import com.banjjoknim.book.springboot.web.dto.PostsUpdateRequestDto;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.After; import org.junit.After;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -12,14 +14,20 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort; import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod; import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus; import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import java.util.List; import java.util.List;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@@ -40,8 +48,22 @@ public class PostsApiControllerTest {
postsRepository.deleteAll(); postsRepository.deleteAll();
} }
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setUp() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
}
@Test @Test
public void Posts_등록된다() { @WithMockUser(roles = "USER")
public void Posts_등록된다() throws Exception {
// given // given
String title = "title"; String title = "title";
String content = "content"; String content = "content";
@@ -54,19 +76,21 @@ public class PostsApiControllerTest {
String url = "http://localhost:" + port + "/api/v1/posts"; String url = "http://localhost:" + port + "/api/v1/posts";
// when // when
ResponseEntity<Long> responseEntity = restTemplate.postForEntity(url, requestDto, Long.class); mvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(new ObjectMapper().writeValueAsString(requestDto)))
.andExpect(status().isOk());
// then // then
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(responseEntity.getBody()).isGreaterThan(0L);
List<Posts> all = postsRepository.findAll(); List<Posts> all = postsRepository.findAll();
assertThat(all.get(0).getTitle()).isEqualTo(title); assertThat(all.get(0).getTitle()).isEqualTo(title);
assertThat(all.get(0).getContent()).isEqualTo(content); assertThat(all.get(0).getContent()).isEqualTo(content);
} }
@Test @Test
public void Posts_수정된다() { @WithMockUser(roles = "USER")
public void Posts_수정된다() throws Exception {
// given // given
Posts savedPosts = postsRepository.save(Posts.builder() Posts savedPosts = postsRepository.save(Posts.builder()
@@ -89,12 +113,12 @@ public class PostsApiControllerTest {
HttpEntity<PostsUpdateRequestDto> requestEntity = new HttpEntity<>(requestDto); HttpEntity<PostsUpdateRequestDto> requestEntity = new HttpEntity<>(requestDto);
// when // when
ResponseEntity<Long> responseEntity = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, Long.class); mvc.perform(put(url)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(new ObjectMapper().writeValueAsString(requestDto)))
.andExpect(status().isOk());
// then // then
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(responseEntity.getBody()).isGreaterThan(0L);
List<Posts> all = postsRepository.findAll(); List<Posts> all = postsRepository.findAll();
assertThat(all.get(0).getTitle()).isEqualTo(expectedTitle); assertThat(all.get(0).getTitle()).isEqualTo(expectedTitle);
assertThat(all.get(0).getContent()).isEqualTo(expectedContent); assertThat(all.get(0).getContent()).isEqualTo(expectedContent);

View File

@@ -0,0 +1,9 @@
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.h2.console.enabled=true
spring.session.store-type=jdbc
# Test OAuth
spring.security.oauth2.client.registration.google.client-id=test
spring.security.oauth2.client.registration.google.client-secret=test
spring.security.oauth2.client.registration.google.scope=profile,email