diff --git a/.travis.yml b/.travis.yml index 3cdee28..1c84452 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,24 @@ language: java +jdk: + - oraclejdk8 cache: directories: - $HOME/.gradle +addons: + chrome: stable + +dist: trusty +services: + - xvfb + +before_install: + - # start your web application and listen on `localhost` + - "/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --headless --disable-gpu --remote-debugging-port=8080 http://localhost &" + + script: - - ./gradlew build \ No newline at end of file + - gradle bootRun & + - gradle test + - gradle --stop \ No newline at end of file diff --git a/build.gradle b/build.gradle index dd94235..944f9da 100644 --- a/build.gradle +++ b/build.gradle @@ -1,61 +1,50 @@ + buildscript { - ext { - springBootVersion = '2.0.0.RELEASE' - seleniumVersion = '3.0.1' - } - repositories { - mavenCentral() - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") - } + ext { + springBootVersion = '2.0.0.RELEASE' + seleniumVersion = '3.141.59' + } + repositories { + mavenCentral() + maven { url 'http://dl.bintray.com/vermeulen-mp/gradle-plugins' } + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") + classpath 'com.wiredforcode:gradle-spawn-plugin:0.8.0' + } + } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' +apply plugin: 'com.wiredforcode.spawn' group = 'com.pillar' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { - mavenCentral() + mavenCentral() } dependencies { - compile('org.springframework.boot:spring-boot-starter-data-jpa') - compile('org.springframework.boot:spring-boot-starter-web') - compile(group: 'com.h2database', name: 'h2', version: '1.4.194') - - compile(group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf') - - runtime('mysql:mysql-connector-java') - testCompile('org.springframework.boot:spring-boot-starter-test') - testCompile('org.thymeleaf:thymeleaf-testing:3.0.3.RELEASE') - testCompile('org.gebish:geb-junit4:2.1') - testCompile("org.seleniumhq.selenium:selenium-chrome-driver:${seleniumVersion}") - - testCompile("io.github.bonigarcia:webdrivermanager:1.5.0") { - exclude group: 'org.seleniumhq.selenium' - } -} - -task bootRunTest(type: org.springframework.boot.gradle.tasks.run.BootRun, dependsOn: build) { - group= 'Application' - doFirst() { - main = bootJar.mainClassName - classpath = sourceSets.main.runtimeClasspath - systemProperty 'spring.profiles.active', 'test' - } + compile('org.springframework.boot:spring-boot-starter-data-jpa') + compile('org.springframework.boot:spring-boot-starter-web') + compile(group: 'com.h2database', name: 'h2', version: '1.4.194') + compile(group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf') + compile('org.apache.ivy:ivy:2.4.0') + + runtime('mysql:mysql-connector-java') + testCompile('org.springframework.boot:spring-boot-starter-test') + testCompile('org.thymeleaf:thymeleaf-testing:3.0.3.RELEASE') + testCompile('org.gebish:geb-junit4:2.3') + testCompile("org.seleniumhq.selenium:selenium-java:${seleniumVersion}") + testCompile("org.seleniumhq.selenium:selenium-chrome-driver:${seleniumVersion}") + + testCompile("io.github.bonigarcia:webdrivermanager:3.4.0") { + exclude group: 'org.seleniumhq.selenium' + } } -task bootRunProd(type: org.springframework.boot.gradle.tasks.run.BootRun, dependsOn: build) { - group= 'Application' - doFirst() { - main = bootJar.mainClassName - classpath = sourceSets.main.runtimeClasspath - systemProperty 'spring.profiles.active', 'prod' - } -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3bba7fc..83eafb6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Mar 09 11:01:42 CST 2018 +#Tue Apr 23 14:06:00 EDT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/src/main/java/com/pillar/pillarLearningCenter/controller/PostController.java b/src/main/java/com/pillar/pillarLearningCenter/controller/PostController.java index 6e2eaef..e2b2faf 100644 --- a/src/main/java/com/pillar/pillarLearningCenter/controller/PostController.java +++ b/src/main/java/com/pillar/pillarLearningCenter/controller/PostController.java @@ -1,7 +1,8 @@ package com.pillar.pillarLearningCenter.controller; import com.pillar.pillarLearningCenter.model.Post; -import com.pillar.pillarLearningCenter.service.PostService; +//import com.pillar.pillarLearningCenter.service.PostService; +import com.pillar.pillarLearningCenter.repository.PostRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -13,11 +14,11 @@ public class PostController { @Autowired - private PostService postService; + private PostRepository postService; @GetMapping("/posts") public String posts(Model model) { - List allPosts = postService.getAllPosts(); + List allPosts = postService.findAll(); model.addAttribute("postList", allPosts); return "posts"; } @@ -30,7 +31,7 @@ public String postsNew(Model model) { @PostMapping("/posts/new") public String submitPost(@ModelAttribute Post post) { - postService.createPost(post); + postService.save(post); return "redirect:/posts"; } diff --git a/src/main/java/com/pillar/pillarLearningCenter/model/Post.java b/src/main/java/com/pillar/pillarLearningCenter/model/Post.java index f5bdba8..f6bf398 100644 --- a/src/main/java/com/pillar/pillarLearningCenter/model/Post.java +++ b/src/main/java/com/pillar/pillarLearningCenter/model/Post.java @@ -1,6 +1,7 @@ package com.pillar.pillarLearningCenter.model; import javax.persistence.*; +import java.util.Objects; @Entity @Table(name = "posts") @@ -14,6 +15,9 @@ public class Post { @Column(name = "title") public String title; + @Column(name = "username") + public String username; + @Column(name = "content") public String content; @@ -25,6 +29,12 @@ public String getTitle() { return title; } + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() {return username;} + public Long getId() { return id; } @@ -41,17 +51,16 @@ public void setContent(String content) { this.content = content; } + @Override public boolean equals(Object o) { - if(o == this) { - return true; - } - - if (!(o instanceof Post)) { - return false; - } - - Post post2 = (Post) o; - return post2.getId() == this.getId() && post2.getTitle().equals(this.getTitle()) && post2.getContent().equals(this.getContent()); + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Post post = (Post) o; + return Objects.equals(id, post.id) && + Objects.equals(title, post.title) && + Objects.equals(username, post.username) && + Objects.equals(content, post.content); } + } \ No newline at end of file diff --git a/src/main/java/com/pillar/pillarLearningCenter/repository/PostRepository.java b/src/main/java/com/pillar/pillarLearningCenter/repository/PostRepository.java index f7a2838..5dd7fd7 100644 --- a/src/main/java/com/pillar/pillarLearningCenter/repository/PostRepository.java +++ b/src/main/java/com/pillar/pillarLearningCenter/repository/PostRepository.java @@ -6,6 +6,5 @@ @Repository public interface PostRepository extends JpaRepository{ - //public Post getOne(Long id); - public Post save(Post post); + } \ No newline at end of file diff --git a/src/main/java/com/pillar/pillarLearningCenter/service/PostService.java b/src/main/java/com/pillar/pillarLearningCenter/service/PostService.java deleted file mode 100644 index bff8d6c..0000000 --- a/src/main/java/com/pillar/pillarLearningCenter/service/PostService.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.pillar.pillarLearningCenter.service; - -import com.pillar.pillarLearningCenter.model.Post; - -import java.util.List; - -public interface PostService { - public List getAllPosts(); - - //public Post getPostById(Long id); - - public void createPost(Post post); -} diff --git a/src/main/java/com/pillar/pillarLearningCenter/service/PostServiceImpl.java b/src/main/java/com/pillar/pillarLearningCenter/service/PostServiceImpl.java deleted file mode 100644 index 0315ab3..0000000 --- a/src/main/java/com/pillar/pillarLearningCenter/service/PostServiceImpl.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.pillar.pillarLearningCenter.service; - -import com.pillar.pillarLearningCenter.model.Post; -import com.pillar.pillarLearningCenter.repository.PostRepository; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -public class PostServiceImpl implements PostService { - - @Autowired - private PostRepository postRepository; - - @Override - public List getAllPosts() { - return postRepository.findAll(); - } - - /*public Post getPostById(Long id) { - return postRepository.getOne(id); - }*/ - - @Override - public void createPost(Post post){ postRepository.save(post); } -} \ No newline at end of file diff --git a/src/main/resources/templates/new.html b/src/main/resources/templates/new.html index efbb67f..0be2219 100644 --- a/src/main/resources/templates/new.html +++ b/src/main/resources/templates/new.html @@ -2,6 +2,7 @@

Create a New Post!

+
diff --git a/src/main/resources/templates/posts.html b/src/main/resources/templates/posts.html index 5c4ea88..5601d83 100644 --- a/src/main/resources/templates/posts.html +++ b/src/main/resources/templates/posts.html @@ -2,6 +2,8 @@

Posts

+

+
diff --git a/src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTest.java b/src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTest.java new file mode 100644 index 0000000..26cdd68 --- /dev/null +++ b/src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTest.java @@ -0,0 +1,54 @@ +package com.pillar.pillarLearningCenter.endToEndTests; + +import io.github.bonigarcia.wdm.WebDriverManager; +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; + + + +import java.util.List; + +public class CreatePostTest { + private WebDriver driver; + private ChromeOptions options = new ChromeOptions().addArguments("--headless"); + + @BeforeClass + public static void setupClass() { + WebDriverManager.chromedriver().setup(); + } + + @Before + public void setupTest() { + driver = new ChromeDriver(options); + } + + @After + public void teardown() { + if (driver != null) { + driver.quit(); + } + } + + @Test + public void ThisThingCreatesAPost() { + driver.navigate().to("http://localhost:8080/posts/new"); + driver.findElement(By.name("title")).sendKeys("New Title - in memory"); + driver.findElement(By.name("content")).sendKeys("Content here"); + driver.findElement(By.name("username")).sendKeys("Max"); + driver.findElement(By.name("submit")).click(); + + List results = driver.findElements(By.xpath("//h1")); + String result = results.get(1).getText(); + + assertEquals("New Title - in memory", result); + } +} diff --git a/src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTest.groovy b/src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTestDEAD.groovy similarity index 87% rename from src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTest.groovy rename to src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTestDEAD.groovy index c034ece..dd4c6de 100644 --- a/src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTest.groovy +++ b/src/test/java/com/pillar/pillarLearningCenter/endToEndTests/CreatePostTestDEAD.groovy @@ -1,12 +1,13 @@ package com.pillar.pillarLearningCenter.endToEndTests + import geb.junit4.GebTest import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 @RunWith(JUnit4) -class CreatePostTest extends GebTest { +class CreatePostTestDEAD extends GebTest { //teardown method here /* @Autowired private TestEntityManager entityManager; @@ -22,11 +23,13 @@ class CreatePostTest extends GebTest { $("form").title = "New Title - in memory" $("form").content = "Content here" + $("form").username = "Max" $("input", value: "Submit").click() assert $("h1")[0].text() == "Posts" assert $("div h1")[-1].text() == "New Title - in memory" assert $("div p")[-1].text() == "Content here" + assert $("div h3")[-1].text() == "Max" //teardown() } } diff --git a/src/test/java/com/pillar/pillarLearningCenter/unitTest/controller/PostControllerTest.java b/src/test/java/com/pillar/pillarLearningCenter/unitTest/controller/PostControllerTest.java index 73b82b2..00d3b1e 100644 --- a/src/test/java/com/pillar/pillarLearningCenter/unitTest/controller/PostControllerTest.java +++ b/src/test/java/com/pillar/pillarLearningCenter/unitTest/controller/PostControllerTest.java @@ -2,7 +2,7 @@ import com.pillar.pillarLearningCenter.controller.PostController; import com.pillar.pillarLearningCenter.model.Post; -import com.pillar.pillarLearningCenter.service.PostService; +import com.pillar.pillarLearningCenter.repository.PostRepository; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,7 +28,7 @@ public class PostControllerTest { private PostController postController; @Mock - private PostService postService; + private PostRepository postService; private Model model = new ExtendedModelMap(); @@ -42,12 +42,14 @@ public void initMocks(){ public void posts_ShouldPopulateModelWithPostData_WhenServiceReturnsPostData() { Post onePost = new Post(); onePost.setTitle("Title One"); + onePost.setUsername("Max"); Post twoPost = new Post(); twoPost.setTitle("Title Two"); + twoPost.setUsername("Max"); List expected = new ArrayList<>(); expected.add(onePost); expected.add(twoPost); - Mockito.when(postService.getAllPosts()).thenReturn(expected); + Mockito.when(postService.findAll()).thenReturn(expected); postController.posts(model); @@ -91,7 +93,7 @@ public void submitPost_ShouldUseServiceToCreatePost_WhenCalled(){ post.setTitle("Dummy Title"); post.setContent("Dummy Content"); postController.submitPost(post); - Mockito.verify(postService).createPost(post); + Mockito.verify(postService).save(post); } } \ No newline at end of file diff --git a/src/test/java/com/pillar/pillarLearningCenter/unitTest/service/ServiceTest.java b/src/test/java/com/pillar/pillarLearningCenter/unitTest/service/ServiceTest.java index d30fee8..f269a9e 100644 --- a/src/test/java/com/pillar/pillarLearningCenter/unitTest/service/ServiceTest.java +++ b/src/test/java/com/pillar/pillarLearningCenter/unitTest/service/ServiceTest.java @@ -1,14 +1,14 @@ package com.pillar.pillarLearningCenter.unitTest.service; import com.pillar.pillarLearningCenter.model.Post; -import com.pillar.pillarLearningCenter.service.PostService; +import com.pillar.pillarLearningCenter.repository.PostRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; import org.springframework.test.context.junit4.SpringRunner; - +import javax.persistence.EntityNotFoundException; import java.util.List; import static org.junit.Assert.assertEquals; @@ -17,11 +17,57 @@ @DataJpaTest public class ServiceTest { @Autowired - PostService postService; + PostRepository postService; @Autowired private TestEntityManager entityManager; + @Test + public void testGetPostById(){ + Post post = new Post(); + post.setTitle("Title One"); + post.setContent("Content is Here"); + + entityManager.persist(post); + entityManager.flush(); + + Post postSaved = postService.getOne(1L); + + assertEquals(post, postSaved); + } + + @Test + public void getPostAndThenDeletePostRemovesPostFromList() { + Post post = new Post(); + post.setTitle("Title One"); + post.setContent("Content is Here"); + Post post2 = new Post(); + post2.setTitle("Title 2"); + post2.setContent("Content 2 is Here"); + entityManager.persist(post); + entityManager.persist(post2); + entityManager.flush(); + List postList = postService.findAll(); + + postService.deleteById(postList.get(0).getId()); + List postListAfterDelete = postService.findAll(); + + assertEquals(postList.size() - 1, postListAfterDelete.size()); + } + + @Test + public void getPostByIdThrowsExceptionWhenPostNotFound() { + String message = ""; + try { + Post postSaved = postService.getOne(1L); + assertEquals(postSaved, 0); + } catch (EntityNotFoundException e) { + message = e.getMessage(); + } + assertEquals("Unable to find com.pillar.pillarLearningCenter.model.Post with id 1", message); + } + + @Test public void testGetAllPosts(){ Post post = new Post(); @@ -34,7 +80,7 @@ public void testGetAllPosts(){ entityManager.persist(post2); entityManager.flush(); - List postList = postService.getAllPosts(); + List postList = postService.findAll(); assertEquals(postList.get(0), post); assertEquals(postList.get(1), post2); @@ -45,12 +91,14 @@ public void testCreatePost(){ Post post = new Post(); post.setTitle("Title One"); post.setContent("Content is Here"); + post.setUsername("max"); - postService.createPost(post); + postService.save(post); Post resultPost = entityManager.find(Post.class, post.getId()); assertEquals(resultPost, post); } + } diff --git a/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/CreatePostViewTest.java b/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/CreatePostViewTest.java index ee39615..5922e54 100644 --- a/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/CreatePostViewTest.java +++ b/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/CreatePostViewTest.java @@ -1,7 +1,7 @@ package com.pillar.pillarLearningCenter.unitTest.view; import com.pillar.pillarLearningCenter.controller.PostController; -import com.pillar.pillarLearningCenter.service.PostService; +import com.pillar.pillarLearningCenter.repository.PostRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -22,7 +22,7 @@ public class CreatePostViewTest { MockMvc mockMvc; @MockBean - PostService postServiceMock; + PostRepository postServiceMock; @Test public void testPostNewRouteLoadsSuccessfully() throws Exception { diff --git a/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/PostViewTest.java b/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/PostViewTest.java index d60c4db..9593d91 100644 --- a/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/PostViewTest.java +++ b/src/test/java/com/pillar/pillarLearningCenter/unitTest/view/PostViewTest.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.pillar.pillarLearningCenter.controller.PostController; -import com.pillar.pillarLearningCenter.service.PostServiceImpl; +import com.pillar.pillarLearningCenter.repository.PostRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -23,7 +23,7 @@ public class PostViewTest { MockMvc mockMvc; @MockBean - PostServiceImpl postServiceMock; + PostRepository postServiceMock; @Autowired ObjectMapper objectMapper; diff --git a/src/test/resources/GebConfig.groovy b/src/test/resources/GebConfig.groovy index 0cd397f..78f28bc 100644 --- a/src/test/resources/GebConfig.groovy +++ b/src/test/resources/GebConfig.groovy @@ -1,5 +1,7 @@ -import io.github.bonigarcia.wdm.ChromeDriverManager + +import io.github.bonigarcia.wdm.WebDriverManager import org.openqa.selenium.chrome.ChromeDriver +import static io.github.bonigarcia.wdm.DriverManagerType.CHROME // Location where Geb saves the screenshots and HTML dumps at the end of each test reportsDir = 'build/test-reports' @@ -9,7 +11,8 @@ atCheckWaiting = true // Run tests in Chrome by default driver = { // Download and configure Marionette using https://github.com/bonigarcia/webdrivermanager - ChromeDriverManager.getInstance().setup() +// WebDriverManager.chromedriver().setup() + WebDriverManager.getInstance(CHROME).setup() new ChromeDriver() } diff --git a/src/test/resources/posts/new.thtest b/src/test/resources/posts/new.thtest index 8175011..63fa7d1 100644 --- a/src/test/resources/posts/new.thtest +++ b/src/test/resources/posts/new.thtest @@ -5,6 +5,7 @@

Create a New Post!

+
diff --git a/src/test/resources/posts/posts.thtest b/src/test/resources/posts/posts.thtest index 82ddfac..89cd917 100644 --- a/src/test/resources/posts/posts.thtest +++ b/src/test/resources/posts/posts.thtest @@ -1,9 +1,11 @@ %CONTEXT postOne = new com.pillar.pillarLearningCenter.model.Post() postOne.title = 'Title' +postOne.username = 'Max' postOne.content = 'Content' postTwo = new com.pillar.pillarLearningCenter.model.Post() postTwo.title = 'Title Two' +postTwo.username = 'Max' postTwo.content = 'Content Two' postList = {postOne, postTwo} %INPUT (classpath:templates/posts.html) @@ -12,10 +14,14 @@ postList = {postOne, postTwo}

Posts

Title

+

Max

Content

+

Title Two

+

Max

Content Two

+
\ No newline at end of file