├── .gitignore
├── .travis.yml
├── README.md
├── backend
├── .gitignore
├── build.gradle
└── src
│ ├── main
│ ├── java
│ │ └── io
│ │ │ └── codechobostudy
│ │ │ └── common
│ │ │ └── RequireJSController.java
│ ├── resources
│ │ ├── application.yml
│ │ ├── static
│ │ │ ├── js
│ │ │ │ ├── app.js
│ │ │ │ └── views
│ │ │ │ │ └── app.view.js
│ │ │ └── styles
│ │ │ │ └── .gitkeep
│ │ └── templates
│ │ │ └── index.html
│ └── scala
│ │ └── io
│ │ └── codechobostudy
│ │ ├── Application.scala
│ │ ├── config
│ │ ├── SimpleCORSFilter.scala
│ │ └── WebConfig.scala
│ │ ├── home
│ │ └── controller
│ │ │ └── HomeController.scala
│ │ └── sample
│ │ ├── controller
│ │ └── SampleController.scala
│ │ ├── domain
│ │ ├── BaseEntity.scala
│ │ └── SampleDomain.scala
│ │ ├── repository
│ │ └── SampleRepository.scala
│ │ └── service
│ │ └── SampleService.scala
│ └── test
│ └── scala
│ └── io
│ └── codechobostudy
│ └── sample
│ ├── controller
│ └── SampleControllerTest.java
│ ├── domain
│ └── SampleDomainDomainTest.java
│ ├── fixture
│ └── SampleBuilder.java
│ ├── repository
│ └── SampleRepositoryTest.java
│ └── service
│ └── SampleServiceTest.java
├── build.gradle
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | .idea
3 | build
4 | gradle
5 | out
6 | gradlew
7 | gradlew.bat
8 | *.iml
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 | script: "gradle build"
5 | branches:
6 | only:
7 | - develop
8 | env:
9 | - TERM=dumb
10 | after_success:
11 | - gradle cobertura coveralls
12 | notifications:
13 | slack: codechobostudy:7xxE3u0mOPli3DRz6cKiIz51
14 | email:
15 | - changhwaoh.co@gmail.com
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # code-chobo-study
2 | [](https://travis-ci.org/codechobostudy/code-chobo-study)[](https://coveralls.io/r/codechobostudy/code-chobo-study?branch=develop)
3 | 코드초보스터디 사이트 개편 프로젝트
4 |
5 | #### Requirement
6 | 1. JDK 1.8
7 | 2. scala 2.11.x
8 | 3. gradle 2.x
9 |
10 | #### 실행방법
11 | ```
12 | # 프로젝트 루트 폴더에서 해당 명령어 실행
13 | gradle bootRun 또는 gradle backend:bootRun
14 | ```
15 |
16 | #### Git 브랜치 전략 및 참여방법
17 | ----
18 | ##### Branch
19 | 1. master는 태그처럼 관리하며 사이클(주기) 별로 배포된다.
20 | 2. develop 브랜치는 개발서버로 배포되는 브랜치이다.
21 | 3. feature 브랜치는 각 기능이 개발되는 브랜치이다.
22 | 4. bugfix 브랜치는 develop, master 브랜치에서 생성될 수 있고 버그 수정이다.
23 | 5. release 브랜치는 사용유무는 회의를 통해 결정한다.
24 |
25 | ##### 참여방법
26 | 1. develop 브랜치를 기준으로 각 feature 브랜치를 생성한다.
27 | 2. 또는 develop 브랜치로 Fork를 한다.
28 | 3. github이슈에 자신을 등록하고 ing 라벨을 붙인다.
29 | 4. 개발이 완료 되면 develop 브랜치로 Pull Request를 보낸다.
30 | 5. 반드시 최소 2인 이상의 TF,명예팀 코드리뷰를 통과해야한다
31 | 만약 TF, 명예팀이 보낸 Pull Request는 본인을 제외한 2인이다.
32 | 6. 브랜치를 병합하고 삭제한다.
33 | 7. develop 브랜치에 병합되면 정상적으로 동작하는지 확인한다.
34 | 8. 완류 후 이슈를 close 하고 ing 라벨을 제거한다.
35 | 9. 가능한 pull 을 받는 경우는 --rebase 옵션을 활용한다.
36 | 10. 그외 방법은 [angularjs Contribute Guide](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#submitting-a-pull-request) 를 참고한다.
37 |
38 | ##### 커밋로그작성방법
39 | 1. 기본형태
40 | ```
41 | commit type (관련 기능, 이슈번호등) : 요약메세지 (짧을 경우 전체기입가능)
42 | 1. 자세한 메세지 내용
43 | 2. 자세한 메세지 내용
44 | 3. 자세한 메세지 내용
45 |
46 | ex) 회원기능의 CRUD 개발 후 메세지
47 | feature(user) : 회원 CRUD 개발
48 | 1. 회원가입,수정,탈퇴
49 | 2. 스프링 시큐리티 설정
50 | ```
51 | 2. 가능한 커밋은 해당 메세지에 해당하는 항목만 커밋되도록한다. (커밋합치기, 쪼개기 활용)
52 | 3. 경우에 따라 리뷰시 커밋관련 메세지나 잘못끼어든 파일등으로 반려될 수 있다.
53 | 4. 커밋타입은 다음과 같다. (필요에 따라 추가될 수 있다.)
54 | - feature : 기능
55 | - bugfix : 버그 패치
56 | - doc : 문서가 변경된 경우
57 | - style : 코드 영향을 주지 않는 공백, 코드스타일 등을 수정한 경우
58 | - refactor : 코드 리팩토링
59 | - test : 테스트코드를 추가할때 (가능한 커밋시 테스트코드는 따로 하지말고 같이보낸다)
60 | - enhancement : 개발완료된 기능을 개선하는 경우 (성능등)
61 | - framework : 프레임워크 관련 수정 또는 프로젝트 설정 수정등
62 |
--------------------------------------------------------------------------------
/backend/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | build
3 | out
4 | .DS_Store
5 | **/.DS_Store
--------------------------------------------------------------------------------
/backend/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenLocal()
4 | mavenCentral()
5 | }
6 | dependencies {
7 | classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE")
8 | classpath 'net.saliman:gradle-cobertura-plugin:2.2.8'
9 | classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.3.1'
10 | }
11 | }
12 |
13 | apply plugin: 'spring-boot'
14 | apply plugin: 'war'
15 | apply plugin: 'scala'
16 |
17 | apply plugin: 'net.saliman.cobertura'
18 | apply plugin: 'com.github.kt3k.coveralls'
19 |
20 | dependencies {
21 | compile 'org.scala-lang:scala-library:2.11.6'
22 | compile 'org.springframework.boot:spring-boot-starter-web'
23 | compile 'org.springframework.boot:spring-boot-starter-jdbc'
24 | compile 'org.springframework.boot:spring-boot-starter-data-jpa'
25 | compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
26 | compile 'com.h2database:h2'
27 | compile 'com.zaxxer:HikariCP'
28 | compile 'mysql:mysql-connector-java'
29 | compile 'org.projectlombok:lombok:1.16.4'
30 |
31 | testCompile 'org.springframework.boot:spring-boot-starter-test'
32 | compile 'com.jayway.restassured:rest-assured:2.4.1'
33 | runtime 'net.sourceforge.nekohtml:nekohtml:1.9.21'
34 | compile 'org.codehaus.groovy:groovy-all:2.4.3'
35 |
36 |
37 | //webjars
38 | compile 'org.webjars:jquery:1.11.3'
39 | compile 'org.webjars:underscorejs:1.8.3'
40 | compile 'org.webjars:backbonejs:1.1.2-4'
41 | compile 'org.webjars:bootstrap:3.3.4'
42 | compile 'org.webjars:requirejs:2.1.17'
43 | compile 'org.webjars:webjars-locator:0.21'
44 |
45 | }
46 |
47 | sourceSets {
48 | main {
49 | scala {
50 | srcDirs = ['src/main/scala']
51 | }
52 | }
53 | test {
54 | scala {
55 | srcDirs = ['src/test/scala']
56 | }
57 | }
58 | }
59 |
60 | cobertura {
61 | coverageFormats = ['html', 'xml'] // coveralls plugin depends on xml format report
62 | coverageExcludes = ['.*common\\.RequireJSController.*'
63 | ,'.*config\\.SimpleCORSFilter.*'
64 | ,'.*config\\.WebConfig.*'
65 | ,'.*home\\.*controller\\.HomeController.*'
66 | ,'.*codechobostudy\\.Application.*']
67 | }
68 |
69 |
70 | war{
71 | baseName = 'sample'
72 | version = '1.0'
73 | }
74 |
75 | springBoot {
76 | mainClass = 'io.codechobostudy.Application'
77 | }
--------------------------------------------------------------------------------
/backend/src/main/java/io/codechobostudy/common/RequireJSController.java:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.common;
2 |
3 | import org.springframework.core.io.ClassPathResource;
4 | import org.springframework.http.HttpStatus;
5 | import org.springframework.http.ResponseEntity;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.web.bind.annotation.PathVariable;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.ResponseBody;
10 | import org.springframework.web.servlet.HandlerMapping;
11 | import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
12 | import org.webjars.RequireJS;
13 | import org.webjars.WebJarAssetLocator;
14 |
15 | import javax.servlet.http.HttpServletRequest;
16 |
17 | @Controller
18 | public class RequireJSController extends ResourceHttpRequestHandler {
19 |
20 | private WebJarAssetLocator assetLocator = new WebJarAssetLocator();
21 |
22 | @ResponseBody
23 | @RequestMapping(value = "/webjarsjs", produces = "application/javascript")
24 | public String webjarjs() {
25 | return RequireJS.getSetupJavaScript("/webjars/");
26 | }
27 |
28 | @ResponseBody
29 | @RequestMapping("/webjarslocator/{webjar}/**")
30 | public ResponseEntity locateWebjarAsset(@PathVariable String webjar, HttpServletRequest request) {
31 | try {
32 | String mvcPrefix = "/webjarslocator/" + webjar + "/"; // This prefix must match the mapping path!
33 | String mvcPath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
34 | String fullPath = assetLocator.getFullPath(webjar, mvcPath.substring(mvcPrefix.length()));
35 | return new ResponseEntity(new ClassPathResource(fullPath), HttpStatus.OK);
36 | } catch (Exception e) {
37 | return new ResponseEntity<>(HttpStatus.NOT_FOUND);
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/backend/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring.thymeleaf.cache: false
2 | spring.template.cache: false
3 | spring.thymeleaf.mode: LEGACYHTML5
4 |
5 | webjars.requirejs.newModules:
6 |
7 | app:
8 | version: de4db33f
--------------------------------------------------------------------------------
/backend/src/main/resources/static/js/app.js:
--------------------------------------------------------------------------------
1 | require([
2 | 'backbone',
3 | 'views/app.view'
4 | ], function (Backbone, AppView) {
5 | /*jshint nonew:false*/
6 | Backbone.history.start();
7 | new AppView();
8 | });
9 |
--------------------------------------------------------------------------------
/backend/src/main/resources/static/js/views/app.view.js:
--------------------------------------------------------------------------------
1 | /*global define*/
2 | define([
3 | 'jquery',
4 | 'underscore',
5 | 'backbone'
6 | ], function ($, _, Backbone) {
7 | 'use strict';
8 |
9 | var AppView = Backbone.View.extend({
10 |
11 | el: '#content',
12 |
13 | initialize: function(){
14 | this.render();
15 | },
16 |
17 | render: function(){
18 | this.$el.html($("#message").val());
19 | }
20 | });
21 |
22 | return AppView;
23 | });
24 |
--------------------------------------------------------------------------------
/backend/src/main/resources/static/styles/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codechobostudy/code-chobo-study/07a1a52203ef6e077089729e2a232d7039472127/backend/src/main/resources/static/styles/.gitkeep
--------------------------------------------------------------------------------
/backend/src/main/resources/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Getting Started: Spring Boot CLI + Javascript
5 |
6 |
7 |
8 |
9 |
10 |
11 | Gooooood!
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/Application.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper
4 | import org.springframework.boot.SpringApplication
5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration
6 | import org.springframework.boot.builder.SpringApplicationBuilder
7 | import org.springframework.boot.context.web.SpringBootServletInitializer
8 | import org.springframework.context.annotation.{Bean, ComponentScan, Configuration}
9 | import org.springframework.web.WebApplicationInitializer
10 |
11 | object Application extends App {
12 | SpringApplication.run(classOf[Application])
13 | }
14 |
15 | @Configuration
16 | @EnableAutoConfiguration
17 | @ComponentScan
18 | class Application extends SpringBootServletInitializer with WebApplicationInitializer {
19 |
20 | protected override def configure(application: SpringApplicationBuilder): SpringApplicationBuilder = {
21 | application.sources(classOf[Application])
22 | }
23 |
24 | @Bean
25 | def objectMapper() : ObjectMapper = {
26 | return new ObjectMapper()
27 | }
28 | }
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/config/SimpleCORSFilter.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.config
2 |
3 | import javax.servlet.http.HttpServletResponse
4 | import javax.servlet._
5 |
6 | import org.springframework.context.annotation.Profile
7 | import org.springframework.stereotype.Component
8 |
9 | @Component
10 | @Profile(Array("dev"))
11 | class SimpleCORSFilter extends Filter {
12 |
13 | def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
14 | val response = res.asInstanceOf[HttpServletResponse]
15 | response.setHeader("Access-Control-Allow-Origin", "*")
16 | response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE")
17 | response.setHeader("Access-Control-Max-Age", "3600")
18 | response.setHeader("Access-Control-Allow-Headers", "origin, x-requested-with, content-type, accept")
19 | chain.doFilter(req, res)
20 | }
21 |
22 | def init(filterConfig: FilterConfig) {
23 | }
24 |
25 | def destroy() {
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/config/WebConfig.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.config
2 |
3 | import org.springframework.beans.factory.annotation.{Autowired, Value}
4 | import org.springframework.context.annotation.{Bean, ComponentScan, Configuration}
5 | import org.springframework.core.env.Environment
6 | import org.springframework.web.servlet.config.annotation.{ResourceHandlerRegistry, ViewControllerRegistry, WebMvcConfigurerAdapter}
7 | import org.springframework.web.servlet.resource.{AppCacheManifestTransformer, ResourceUrlEncodingFilter, VersionResourceResolver}
8 |
9 | @Configuration
10 | @ComponentScan
11 | class WebConfig extends WebMvcConfigurerAdapter {
12 |
13 | private var environment: Environment = _
14 |
15 | @Value("${app.version:}")
16 | private var appVersion: String = _
17 |
18 |
19 | override def addViewControllers(registry: ViewControllerRegistry) {
20 | registry.addViewController("/").setViewName("index")
21 | }
22 |
23 | @Bean
24 | def resourceUrlEncodingFilter: ResourceUrlEncodingFilter = {
25 | new ResourceUrlEncodingFilter
26 | }
27 |
28 | override def addResourceHandlers(registry: ResourceHandlerRegistry ) {
29 |
30 | val isDevMode = environment.acceptsProfiles("dev")
31 | val pathPatterns = "/**"
32 | var cachePeriod: java.lang.Integer = null
33 | var useResourceCache = false
34 |
35 | val locations = "classpath:static/"
36 |
37 | if (isDevMode) {
38 | cachePeriod = 0
39 | useResourceCache = true
40 | }
41 |
42 | val appCacheTransformer = new AppCacheManifestTransformer
43 | val versionResolver = new VersionResourceResolver()
44 | //.addFixedVersionStrategy(getApplicationVersion, "/**/*.js", "/**/*.map")
45 | .addContentVersionStrategy("/**")
46 |
47 | registry.addResourceHandler(pathPatterns)
48 | .addResourceLocations(locations)
49 | .setCachePeriod(cachePeriod)
50 | .resourceChain(useResourceCache)
51 | .addResolver(versionResolver)
52 | .addTransformer(appCacheTransformer)
53 | }
54 |
55 | def getApplicationVersion : String = {
56 | return if (environment.acceptsProfiles("dev")) "dev" else appVersion
57 | }
58 |
59 | @Autowired
60 | def setEnvironment(environment: Environment) {
61 | this.environment = environment
62 | }
63 | }
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/home/controller/HomeController.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.home.controller
2 |
3 | import org.springframework.ui.Model
4 | import org.springframework.web.bind.annotation.{RequestMapping, RestController}
5 |
6 | @RestController
7 | class HomeController {
8 |
9 | @RequestMapping(Array("/index"))
10 | def home (model: Model) = {
11 | model.addAttribute("message", "Hello World")
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/sample/controller/SampleController.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.controller
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper
4 | import io.codechobostudy.sample.domain.SampleDomain
5 | import io.codechobostudy.sample.service.SampleService
6 | import org.springframework.beans.factory.annotation.Autowired
7 | import org.springframework.web.bind.annotation.{RequestMethod, RequestBody, RequestMapping, RestController}
8 |
9 | @RestController
10 | @RequestMapping(Array("/api/sample"))
11 | class SampleController {
12 |
13 | @Autowired
14 | private var objectMapper: ObjectMapper = _
15 |
16 | @Autowired
17 | private var categoryService: SampleService = _
18 |
19 | @RequestMapping(value = Array( "/create"), method = Array(RequestMethod.POST))
20 | def create(@RequestBody category: SampleDomain): String = {
21 | objectMapper.writeValueAsString(categoryService.create(category))
22 | }
23 |
24 | @RequestMapping(value = Array("/update"), method = Array(RequestMethod.PUT))
25 | def update(@RequestBody category: SampleDomain): String = {
26 | val updateCategory = categoryService.update(category)
27 | objectMapper.writeValueAsString(updateCategory)
28 | }
29 |
30 | @RequestMapping(Array("/"))
31 | def getAllCategory: String = {
32 | objectMapper.writeValueAsString(categoryService.getAllCategory)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/sample/domain/BaseEntity.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.domain
2 |
3 | import java.util.Date
4 | import javax.persistence._
5 |
6 | import com.fasterxml.jackson.annotation.JsonFormat
7 |
8 | import scala.beans.BeanProperty
9 |
10 | @MappedSuperclass
11 | class BaseEntity {
12 |
13 | @Id
14 | @GeneratedValue(strategy = GenerationType.AUTO)
15 | @BeanProperty
16 | var id: Long = _
17 |
18 | @Column(name = "created_at")
19 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
20 | @BeanProperty
21 | var createdAt: Date = _
22 |
23 | @Column(name = "updated_at")
24 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
25 | @BeanProperty
26 | var updatedAt: Date = _
27 |
28 | @PrePersist
29 | def created = {
30 | this.updatedAt = new Date()
31 | this.createdAt = this.updatedAt
32 | }
33 |
34 | @PreUpdate
35 | def updated = {
36 | this.updatedAt = new Date()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/sample/domain/SampleDomain.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.domain
2 |
3 | import javax.persistence.Entity
4 | import scala.beans.BeanProperty
5 |
6 |
7 | @Entity
8 | class SampleDomain extends BaseEntity{
9 |
10 | @BeanProperty
11 | var categoryName: String = _
12 |
13 | @BeanProperty
14 | var categoryDesc: String = _
15 | }
16 |
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/sample/repository/SampleRepository.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.repository
2 |
3 | import io.codechobostudy.sample.domain.SampleDomain
4 | import org.springframework.data.jpa.repository.JpaRepository
5 | import java.lang.Long
6 | import java.util.List
7 |
8 | trait SampleRepository extends JpaRepository[SampleDomain, Long]{
9 |
10 | def findByCategoryName(categoryName: String) : List[SampleDomain]
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/backend/src/main/scala/io/codechobostudy/sample/service/SampleService.scala:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.service
2 |
3 | import io.codechobostudy.sample.domain.SampleDomain
4 | import io.codechobostudy.sample.repository.SampleRepository
5 | import org.springframework.beans.factory.annotation.Autowired
6 | import org.springframework.stereotype.Service
7 | import org.springframework.transaction.annotation.Transactional
8 |
9 | @Service
10 | @Transactional
11 | class SampleService {
12 |
13 | @Autowired
14 | private var categoryRepository: SampleRepository = _
15 |
16 | def create(category: SampleDomain): SampleDomain = {
17 | categoryRepository.save(category)
18 | }
19 |
20 | def update(category: SampleDomain): SampleDomain = {
21 | val updateCategory = categoryRepository.findOne(category.getId)
22 | updateCategory.setCategoryName(category.categoryName)
23 | updateCategory.setCategoryDesc(category.categoryDesc)
24 |
25 | categoryRepository.save(updateCategory)
26 | }
27 |
28 | def getAllCategory: java.util.List[SampleDomain] = {
29 | categoryRepository.findAll()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/backend/src/test/scala/io/codechobostudy/sample/controller/SampleControllerTest.java:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.controller;
2 |
3 | import io.codechobostudy.sample.domain.SampleDomain;
4 | import io.codechobostudy.sample.repository.SampleRepository;
5 | import io.codechobostudy.sample.fixture.SampleBuilder;
6 | import io.codechobostudy.Application;
7 |
8 | import org.apache.http.HttpStatus;
9 | import org.junit.Before;
10 | import org.junit.Test;
11 | import org.junit.runner.RunWith;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.beans.factory.annotation.Value;
14 | import org.springframework.boot.test.IntegrationTest;
15 | import org.springframework.boot.test.SpringApplicationConfiguration;
16 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
17 | import org.springframework.test.context.web.WebAppConfiguration;
18 |
19 | import com.jayway.restassured.RestAssured;
20 |
21 | import static com.jayway.restassured.RestAssured.given;
22 | import static org.hamcrest.CoreMatchers.containsString;
23 |
24 | @RunWith(SpringJUnit4ClassRunner.class)
25 | @SpringApplicationConfiguration(classes = Application.class)
26 | @WebAppConfiguration
27 | @IntegrationTest("server.port:0")
28 | public class SampleControllerTest {
29 |
30 | @Autowired
31 | private SampleRepository sampleRepository;
32 |
33 | private static final String apiPrefixUrl = "/api/sample";
34 | private static final String contentType = "application/json";
35 |
36 | @Value("${local.server.port}")
37 | private int port;
38 |
39 | private SampleDomain paramSampleDomain;
40 |
41 | @Before
42 | public void setup(){
43 | RestAssured.port = port;
44 |
45 | paramSampleDomain = SampleBuilder.anCategory()
46 | .withCategoryName("Test Category")
47 | .withCategoryDesc("Test Category Desc")
48 | .build();
49 | }
50 |
51 | @Test
52 | public void test_sample_create(){
53 |
54 | given()
55 | .contentType(contentType)
56 | .body(paramSampleDomain)
57 | .when()
58 | .post(apiPrefixUrl + "/create")
59 | .then()
60 | .statusCode(HttpStatus.SC_OK)
61 | .body(containsString(paramSampleDomain.getCategoryName()));
62 | }
63 |
64 | @Test
65 | public void test_sample_update(){
66 |
67 | SampleDomain sampleDomain = sampleRepository.save(paramSampleDomain);
68 | sampleDomain.setCategoryName("Update Category");
69 |
70 | given()
71 | .contentType(contentType)
72 | .body(sampleDomain)
73 | .when()
74 | .put(apiPrefixUrl + "/update")
75 | .then()
76 | .statusCode(HttpStatus.SC_OK)
77 | .body(containsString("Update Category"));
78 | }
79 |
80 | @Test
81 | public void test_sample_get_all(){
82 |
83 | sampleRepository.save(paramSampleDomain);
84 |
85 | given()
86 | .when()
87 | .get(apiPrefixUrl+"/")
88 | .then()
89 | .statusCode(HttpStatus.SC_OK);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/backend/src/test/scala/io/codechobostudy/sample/domain/SampleDomainDomainTest.java:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.domain;
2 |
3 | import io.codechobostudy.sample.domain.SampleDomain;
4 | import org.junit.Test;
5 | import static org.hamcrest.CoreMatchers.is;
6 | import static org.junit.Assert.*;
7 |
8 | public class SampleDomainDomainTest {
9 |
10 | @Test
11 | public void test_get_set_domain(){
12 |
13 | SampleDomain sampleDomain = new SampleDomain();
14 | sampleDomain.setId(1L);
15 | sampleDomain.setCategoryName("TEST");
16 |
17 | assertThat(sampleDomain.getId(), is(1L));
18 | assertThat(sampleDomain.getCategoryName(), is("TEST"));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/backend/src/test/scala/io/codechobostudy/sample/fixture/SampleBuilder.java:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.fixture;
2 |
3 | import io.codechobostudy.sample.domain.SampleDomain;
4 |
5 | public class SampleBuilder {
6 |
7 | private String categoryName;
8 | private String categoryDesc;
9 |
10 | public static SampleBuilder anCategory(){
11 | return new SampleBuilder();
12 | }
13 |
14 | public SampleBuilder withCategoryName(String categoryName){
15 | this.categoryName = categoryName;
16 | return this;
17 | }
18 |
19 | public SampleBuilder withCategoryDesc(String categoryDesc){
20 | this.categoryDesc = categoryDesc;
21 | return this;
22 | }
23 |
24 | public SampleDomain build(){
25 | SampleDomain sampleDomain = new SampleDomain();
26 | sampleDomain.setCategoryName(this.categoryName);
27 | sampleDomain.setCategoryDesc(this.categoryDesc);
28 | return sampleDomain;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/backend/src/test/scala/io/codechobostudy/sample/repository/SampleRepositoryTest.java:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.repository;
2 |
3 | import io.codechobostudy.Application;
4 | import io.codechobostudy.sample.domain.SampleDomain;
5 | import io.codechobostudy.sample.fixture.SampleBuilder;
6 | import io.codechobostudy.sample.repository.SampleRepository;
7 | import org.junit.Before;
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.boot.test.SpringApplicationConfiguration;
12 | import org.springframework.test.annotation.Rollback;
13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
14 | import org.springframework.transaction.annotation.Transactional;
15 |
16 | import java.util.List;
17 |
18 | import static org.hamcrest.CoreMatchers.is;
19 | import static org.junit.Assert.*;
20 |
21 | @RunWith(SpringJUnit4ClassRunner.class)
22 | @SpringApplicationConfiguration(classes = Application.class)
23 | @Transactional
24 | public class SampleRepositoryTest {
25 |
26 | @Autowired
27 | private SampleRepository sampleRepository;
28 |
29 | SampleDomain sampleDomain1;
30 | SampleDomain sampleDomain2;
31 |
32 | @Before
33 | public void setup(){
34 |
35 | sampleDomain1 = SampleBuilder
36 | .anCategory()
37 | .withCategoryName("Test")
38 | .withCategoryDesc("Test sample")
39 | .build();
40 |
41 | sampleDomain2 = SampleBuilder
42 | .anCategory()
43 | .withCategoryName("Test2")
44 | .withCategoryDesc("Test sample")
45 | .build();
46 | }
47 |
48 | @Test
49 | @Rollback
50 | public void test_sample_save(){
51 |
52 | //when
53 | SampleDomain resultSampleDomain = sampleRepository.save(sampleDomain1);
54 |
55 | //then
56 | assertNotNull(resultSampleDomain.getId());
57 | assertNotNull(resultSampleDomain.getCreatedAt());
58 | assertThat(resultSampleDomain.getCategoryName(), is(sampleDomain1.getCategoryName()));
59 | }
60 |
61 | @Test
62 | @Rollback
63 | public void test_sample_update(){
64 |
65 | //given
66 | SampleDomain sampleDomain = sampleRepository.save(sampleDomain1);
67 | Long categoryId = sampleDomain.getId();
68 |
69 | //when
70 | sampleDomain.setCategoryName("UpdateName");
71 | sampleRepository.save(sampleDomain1);
72 |
73 | //then
74 | assertThat(sampleDomain.getId(), is(categoryId));
75 | assertThat(sampleDomain.getCategoryName(), is("UpdateName"));
76 | }
77 |
78 | @Test
79 | @Rollback
80 | public void test_find_by_name_one(){
81 |
82 | //given
83 | sampleRepository.save(sampleDomain1);
84 |
85 | //when
86 | List categories = sampleRepository.findByCategoryName(sampleDomain1.getCategoryName());
87 |
88 | //then
89 | assertThat(categories.size(), is(1));
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/backend/src/test/scala/io/codechobostudy/sample/service/SampleServiceTest.java:
--------------------------------------------------------------------------------
1 | package io.codechobostudy.sample.service;
2 |
3 | import io.codechobostudy.Application;
4 | import io.codechobostudy.sample.domain.SampleDomain;
5 | import io.codechobostudy.sample.repository.SampleRepository;
6 | import io.codechobostudy.sample.fixture.SampleBuilder;
7 | import io.codechobostudy.sample.service.SampleService;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 | import org.junit.runner.RunWith;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.boot.test.SpringApplicationConfiguration;
13 | import org.springframework.test.annotation.Rollback;
14 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
15 | import org.springframework.transaction.annotation.Transactional;
16 |
17 | import java.util.List;
18 |
19 | import static org.hamcrest.CoreMatchers.is;
20 | import static org.junit.Assert.assertNotNull;
21 | import static org.junit.Assert.assertThat;
22 |
23 | @RunWith(SpringJUnit4ClassRunner.class)
24 | @SpringApplicationConfiguration(classes = Application.class)
25 | @Transactional
26 | public class SampleServiceTest {
27 |
28 | @Autowired
29 | private SampleService sampleService;
30 |
31 | @Autowired
32 | private SampleRepository sampleRepository;
33 |
34 | private SampleDomain sampleDomain1;
35 |
36 | @Before
37 | public void setup(){
38 |
39 | sampleDomain1 = SampleBuilder
40 | .anCategory()
41 | .withCategoryName("Test")
42 | .withCategoryDesc("Test Category")
43 | .build();
44 | }
45 |
46 | @Test
47 | @Rollback
48 | public void test_sample_save(){
49 |
50 | //when
51 | SampleDomain resultSampleDomain = sampleService.create(sampleDomain1);
52 |
53 | //then
54 | assertNotNull(resultSampleDomain.getId());
55 | assertNotNull(resultSampleDomain.getCreatedAt());
56 | assertThat(resultSampleDomain.getCategoryName(), is(sampleDomain1.getCategoryName()));
57 | }
58 |
59 | @Test
60 | @Rollback
61 | public void test_sample_update(){
62 |
63 | //given
64 | SampleDomain saveSampleDomain = sampleRepository.save(sampleDomain1);
65 | saveSampleDomain.setCategoryName("Update Category");
66 |
67 | //when
68 | SampleDomain resultSampleDomain = sampleService.update(saveSampleDomain);
69 |
70 | //then
71 | assertThat(resultSampleDomain.getCategoryName(), is(saveSampleDomain.getCategoryName()));
72 | }
73 |
74 | @Test
75 | public void test_get_all_sample(){
76 |
77 | //given
78 | sampleRepository.save(sampleDomain1);
79 |
80 | //when
81 | List categories = sampleService.getAllCategory();
82 |
83 | //then
84 | assertThat(categories.size(), is(1));
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 |
2 |
3 | buildscript {
4 | repositories {
5 | mavenLocal()
6 | mavenCentral()
7 | }
8 | dependencies {
9 | classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE")
10 | }
11 | }
12 |
13 | configurations {
14 | providedRuntime
15 | }
16 |
17 | configure(allprojects) { project ->
18 |
19 | apply plugin: 'java'
20 | apply plugin: 'idea'
21 | apply plugin: 'eclipse-wtp'
22 |
23 | sourceCompatibility = 1.8
24 | compileJava.options.encoding = 'UTF-8'
25 |
26 | configurations {
27 | all*.exclude module: 'commons-logging'
28 | }
29 | repositories {
30 | mavenLocal()
31 | mavenCentral()
32 | }
33 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'codechobostudy'
2 |
3 | include 'backend'
4 |
--------------------------------------------------------------------------------