Add html unit tests

This commit integrates with spring-test-htmlunit and provides tests
that use the HTML form.
This commit is contained in:
Stephane Nicoll
2014-08-21 14:09:40 +02:00
parent 985016af9a
commit a1e01fc0ba
6 changed files with 286 additions and 32 deletions

View File

@@ -59,6 +59,10 @@
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test-htmlunit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
@@ -83,6 +87,11 @@
<artifactId>jsonassert</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test-htmlunit</artifactId>
<version>1.0.0.M2</version>
</dependency>
</dependencies>
</dependencyManagement>
@@ -132,4 +141,21 @@
</plugins>
</build>
<profiles>
<profile>
<id>springMilestone</id>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
</project>

View File

@@ -123,7 +123,7 @@
</div>
<div class="row">
<p class="text-center">
<button type="submit" class="btn btn-lg btn-primary" role="button">
<button name="generate-project" type="submit" class="btn btn-lg btn-primary" role="button">
<span class="glyphicon glyphicon-download"></span> Generate Project
</button>
</p>

View File

@@ -16,6 +16,7 @@
package io.spring.initializr.web
import io.spring.initializr.support.ProjectAssert
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
@@ -59,6 +60,42 @@ abstract class AbstractMainControllerIntegrationTests {
restTemplate.exchange(createUrl('/'), HttpMethod.GET, new HttpEntity<Void>(headers), String).body
}
/**
* Return a {@link ProjectAssert} for the following archive content.
*/
ProjectAssert projectAssert(byte[] content, ArchiveType archiveType) {
File archiveFile = writeArchive(content)
def project = folder.newFolder()
switch (archiveType) {
case ArchiveType.ZIP:
new AntBuilder().unzip(dest: project, src: archiveFile)
break
case ArchiveType.TGZ:
new AntBuilder().untar(dest: project, src: archiveFile, compression: 'gzip')
break
}
new ProjectAssert(project)
}
protected File writeArchive(byte[] body) {
def archiveFile = folder.newFile()
def stream = new FileOutputStream(archiveFile)
try {
stream.write(body)
} finally {
stream.close()
}
archiveFile
}
enum ArchiveType {
ZIP,
TGZ
}
@EnableAutoConfiguration
static class Config {}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.initializr.web
import com.gargoylesoftware.htmlunit.WebClient
import com.gargoylesoftware.htmlunit.WebRequest
import com.gargoylesoftware.htmlunit.html.HtmlPage
import io.spring.initializr.support.ProjectAssert
import io.spring.initializr.web.support.HomePage
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.htmlunit.MockMvcWebConnection
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.web.context.WebApplicationContext
/**
*
* @author Stephane Nicoll
*/
@ActiveProfiles('test-default')
class MainControllerFormIntegrationTests extends AbstractMainControllerIntegrationTests {
@Autowired
private WebApplicationContext context
private WebClient webClient
@Before
void setup() {
MockMvc mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.build()
webClient = new WebClient()
webClient.setWebConnection(new MockMvcWebConnection(mockMvc, ''))
}
@After
void cleanup() {
this.webClient.closeAllWindows()
}
@Test
void createDefaultProject() {
HomePage page = home()
ProjectAssert projectAssert = projectAssert(page.generateProject(), ArchiveType.ZIP)
projectAssert.isMavenProject().isJavaProject().hasStaticAndTemplatesResources(false)
.pomAssert().hasDependenciesCount(1).hasSpringBootStarterDependency('test')
}
@Test
void createProjectWithCustomDefaults() {
HomePage page = home()
page.groupId = 'com.acme'
page.artifactId = 'foo-bar'
page.name = 'My project'
page.description = 'A description for my project'
page.dependencies << 'web' << 'data-jpa'
ProjectAssert projectAssert = projectAssert(page.generateProject(), ArchiveType.ZIP)
projectAssert.isMavenProject().isJavaProject().hasStaticAndTemplatesResources(true)
projectAssert.pomAssert().hasGroupId('com.acme').hasArtifactId('foo-bar')
.hasName('My project').hasDescription('A description for my project')
.hasSpringBootStarterDependency('web')
.hasSpringBootStarterDependency('data-jpa')
.hasSpringBootStarterDependency('test')
}
@Test
void createSimpleGradleProject() {
HomePage page = home()
page.type = 'gradle.zip'
page.dependencies << 'data-jpa'
ProjectAssert projectAssert = projectAssert(page.generateProject(), ArchiveType.ZIP)
projectAssert.isGradleProject().isJavaProject().hasStaticAndTemplatesResources(false)
}
@Test
void createWarProject() {
HomePage page = home()
page.packaging = 'war'
ProjectAssert projectAssert = projectAssert(page.generateProject(), ArchiveType.ZIP)
projectAssert.isMavenProject().isJavaWarProject()
.pomAssert().hasPackaging('war').hasDependenciesCount(3)
.hasSpringBootStarterDependency('web') // Added with war packaging
.hasSpringBootStarterDependency('tomcat')
.hasSpringBootStarterDependency('test')
}
HomePage home() {
WebRequest request = new WebRequest(new URL('http://localhost/'), 'text/html')
HtmlPage home = webClient.getPage(request)
return new HomePage(home)
}
}

View File

@@ -40,7 +40,7 @@ class MainControllerIntegrationTests extends AbstractMainControllerIntegrationTe
@Test
void simpleZipProject() {
downloadZip('/starter.zip?style=web&style=jpa').isJavaProject().isMavenProject()
download('/starter.zip?style=web&style=jpa', ArchiveType.ZIP).isJavaProject().isMavenProject()
.hasStaticAndTemplatesResources(true).pomAssert()
.hasDependenciesCount(3)
.hasSpringBootStarterDependency('web')
@@ -50,7 +50,7 @@ class MainControllerIntegrationTests extends AbstractMainControllerIntegrationTe
@Test
void simpleTgzProject() {
downloadTgz('/starter.tgz?style=org.acme:bar').isJavaProject().isMavenProject()
download('/starter.tgz?style=org.acme:bar', ArchiveType.TGZ).isJavaProject().isMavenProject()
.hasStaticAndTemplatesResources(false).pomAssert()
.hasDependenciesCount(2)
.hasDependency('org.acme', 'bar', '2.1.0')
@@ -58,8 +58,8 @@ class MainControllerIntegrationTests extends AbstractMainControllerIntegrationTe
@Test
void gradleWarProject() {
downloadZip('/starter.zip?style=web&style=security&packaging=war&type=gradle.zip').isJavaWarProject()
.isGradleProject()
download('/starter.zip?style=web&style=security&packaging=war&type=gradle.zip', ArchiveType.ZIP)
.isJavaWarProject().isGradleProject()
}
@Test
@@ -167,36 +167,11 @@ class MainControllerIntegrationTests extends AbstractMainControllerIntegrationTe
}
private ProjectAssert downloadZip(String context) {
private ProjectAssert download(String context, ArchiveType archiveType) {
byte[] body = restTemplate.getForObject(createUrl(context), byte[])
File zipFile = writeArchive(body)
def project = folder.newFolder()
new AntBuilder().unzip(dest: project, src: zipFile)
new ProjectAssert(project)
projectAssert(body, archiveType)
}
private ProjectAssert downloadTgz(String context) {
byte[] body = restTemplate.getForObject(createUrl(context), byte[])
File tgzFile = writeArchive(body)
def project = folder.newFolder()
new AntBuilder().untar(dest: project, src: tgzFile, compression: 'gzip')
new ProjectAssert(project)
}
private File writeArchive(byte[] body) {
def archiveFile = folder.newFile()
def stream = new FileOutputStream(archiveFile)
try {
stream.write(body)
} finally {
stream.close()
}
archiveFile
}
private static JSONObject readJson(String version) {
def resource = new ClassPathResource('metadata/test-default-' + version + '.json')
def stream = resource.getInputStream()

View File

@@ -0,0 +1,103 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.initializr.web.support
import com.gargoylesoftware.htmlunit.Page
import com.gargoylesoftware.htmlunit.html.*
import io.spring.initializr.support.ProjectAssert
/**
* Represent the home page of the service.
*
* @author Stephane Nicoll
*/
class HomePage {
String groupId
String artifactId
String name
String description
String packageName
String type
String packaging
List<String> dependencies = []
private final HtmlPage page
HomePage(HtmlPage page) {
this.page = page
}
/**
* Generate a project using the specified temporary directory. Return
* the {@link ProjectAssert} instance.
* @see org.junit.rules.TemporaryFolder
*/
byte[] generateProject() {
setup()
HtmlButton submit = page.getElementByName('generate-project')
Page newMessagePage = submit.click();
newMessagePage.webResponse.contentAsStream.bytes
}
/**
* Setup the {@link HtmlPage} with the customization of this
* instance. Only applied when a non-null value is set
*/
private void setup() {
setTextValue('groupId', groupId)
setTextValue('artifactId', artifactId)
setTextValue('name', name)
setTextValue('description', description)
setTextValue('packageName', packageName)
select('type', type)
select('packaging', packaging)
selectDependencies(dependencies)
}
private void setTextValue(String elementId, String value) {
if (value != null) {
HtmlTextInput input = page.getHtmlElementById(elementId)
input.setValueAttribute(value)
}
}
private void select(String selectId, String value) {
if (value != null) {
HtmlSelect input = page.getHtmlElementById(selectId)
input.setSelectedAttribute(value, true)
}
}
private void selectDependencies(List<String> dependencies) {
List<DomElement> styles = page.getElementsByName("style")
Map<String, HtmlCheckBoxInput> allStyles = new HashMap<>()
for (HtmlCheckBoxInput checkBoxInput : styles) {
allStyles.put(checkBoxInput.getValueAttribute(), checkBoxInput)
}
for (String dependency : dependencies) {
HtmlCheckBoxInput checkBox = allStyles.get(dependency)
if (checkBox != null) {
checkBox.checked = true
} else {
throw new IllegalArgumentException('No dependency with name '
+ dependency + ' was found amongst ' + allStyles.keySet());
}
}
}
}