package com.github.kongchen.smp.integration;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import static com.github.kongchen.smp.integration.utils.TestUtils.YamlToJson;
import static com.github.kongchen.smp.integration.utils.TestUtils.changeDescription;
import static com.github.kongchen.smp.integration.utils.TestUtils.createTempDirPath;
import static com.github.kongchen.smp.integration.utils.TestUtils.setCustomReader;
import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo;
import com.github.kongchen.swagger.docgen.mavenplugin.ApiSource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import junitx.framework.FileAssert;
import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
import net.javacrumbs.jsonunit.core.Configuration;
import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.yaml.snakeyaml.Yaml;
/**
* @author chekong on 8/15/14.
*/
public class SpringMvcTest extends AbstractMojoTestCase {
private File swaggerOutputDir = new File(getBasedir(), "generated/swagger-ui-spring");
private File docOutput = new File(getBasedir(), "generated/document-spring.html");
private ApiDocumentMojo mojo;
@BeforeMethod
protected void setUp() throws Exception {
super.setUp();
try {
FileUtils.deleteDirectory(swaggerOutputDir);
FileUtils.forceDelete(docOutput);
} catch (Exception e) {
//ignore
}
File testPom = new File(getBasedir(), "target/test-classes/plugin-config-springmvc.xml");
mojo = (ApiDocumentMojo) lookupMojo("generate", testPom);
}
@Test
public void testGeneratedSwaggerSpecJson() throws Exception {
assertGeneratedSwaggerSpecJson("This is a sample.");
}
@Test
public void testGeneratedSwaggerSpecYaml() throws Exception {
assertGeneratedSwaggerSpecYaml("This is a sample.");
}
@Test
public void testSwaggerCustomReaderJson() throws Exception {
setCustomReader(mojo, "com.wordnik.springmvc.CustomSpringMvcReader");
assertGeneratedSwaggerSpecJson("Processed with CustomSpringMvcReader");
}
@Test
public void testSwaggerCustomReaderYaml() throws Exception {
setCustomReader(mojo, "com.wordnik.springmvc.CustomSpringMvcReader");
assertGeneratedSwaggerSpecYaml("Processed with CustomSpringMvcReader");
}
@Test
public void testInvalidCustomReaderJson() throws Exception {
String className = "com.wordnik.nonexisting.Class";
setCustomReader(mojo, className);
try {
testGeneratedSwaggerSpecJson();
} catch (MojoFailureException e) {
assertEquals(String.format("Cannot load Swagger API reader: %s", className), e.getMessage());
}
}
@Test
public void testInvalidCustomReaderYaml() throws Exception {
String className = "com.wordnik.nonexisting.Class";
setCustomReader(mojo, className);
try {
testGeneratedSwaggerSpecJson();
} catch (MojoFailureException e) {
assertEquals(String.format("Cannot load Swagger API reader: %s", className), e.getMessage());
}
}
@Test
public void testGeneratedDoc() throws Exception {
mojo.execute();
BufferedReader actualReader = null;
BufferedReader expectReader = null;
FileInputStream swaggerJson = null;
BufferedReader swaggerReader = null;
try {
File actual = docOutput;
File expected = new File(this.getClass().getResource("/sample-springmvc.html").getFile());
FileAssert.assertEquals(expected, actual);
swaggerJson = new FileInputStream(new File(swaggerOutputDir, "swagger.json"));
swaggerReader = new BufferedReader(new InputStreamReader(swaggerJson));
String s = swaggerReader.readLine();
while (s != null) {
if (s.contains("\"parameters\" : [ ],")) {
assertFalse("should not have null parameters", true);
}
s = swaggerReader.readLine();
}
} finally {
if (actualReader != null) {
actualReader.close();
}
if (expectReader != null) {
expectReader.close();
}
if (swaggerJson != null) {
swaggerJson.close();
}
if (swaggerReader != null) {
swaggerReader.close();
}
}
}
@Test
public void testGeneratedDocWithJsonExampleValues() throws Exception {
List<ApiSource> apisources = (List<ApiSource>) getVariableValueFromObject(mojo, "apiSources");
ApiSource apiSource = apisources.get(0);
// Force serialization of example values as json raw values
apiSource.setJsonExampleValues(true);
// exclude part of the model when not compliant with jev option (e.g. example expressed as plain string)
apiSource.setApiModelPropertyExclusions(Collections.singletonList("exclude-when-jev-option-set"));
mojo.execute();
// check generated swagger json file
ObjectMapper mapper = new ObjectMapper();
JsonNode actualJson = mapper.readTree(new File(swaggerOutputDir, "swagger.json"));
JsonNode expectJson = mapper.readTree(this.getClass().getResourceAsStream("/options/jsonExampleValues/expected/swagger-spring.json"));
JsonNode actualUserNode = actualJson.path("definitions").path("User");
JsonNode expectUserNode = expectJson.path("definitions").path("User");
// Cannot test full node equality since tags order is not guaranteed in generated json
Assert.assertEquals(actualUserNode, expectUserNode);
}
@Test
public void testNullSwaggerOutput() throws Exception {
List<ApiSource> apisources = (List<ApiSource>) getVariableValueFromObject(mojo, "apiSources");
apisources.get(0).setSwaggerDirectory(null);
setVariableValueToObject(mojo, "apiSources", apisources);
mojo.execute();
Assert.assertFalse(swaggerOutputDir.exists());
}
@Test
public void testNullMustacheOutput() throws Exception {
List<ApiSource> apisources = (List<ApiSource>) getVariableValueFromObject(mojo, "apiSources");
apisources.get(0).setTemplatePath(null);
setVariableValueToObject(mojo, "apiSources", apisources);
mojo.execute();
Assert.assertFalse(docOutput.exists());
}
@DataProvider
private Iterator<Object[]> pathProvider() throws Exception {
String tempDirPath = createTempDirPath();
List<Object[]> dataToBeReturned = new ArrayList<Object[]>();
dataToBeReturned.add(new String[]{tempDirPath + "foo" + File.separator + "bar" + File.separator + "test.html"});
dataToBeReturned.add(new String[]{tempDirPath + File.separator + "bar" + File.separator + "test.html"});
dataToBeReturned.add(new String[]{tempDirPath + File.separator + "test.html"});
dataToBeReturned.add(new String[]{"test.html"});
return dataToBeReturned.iterator();
}
@Test(enabled = false, dataProvider = "pathProvider")
public void testExecuteDirectoryCreated(String path) throws Exception {
mojo.getApiSources().get(0).setOutputPath(path);
File file = new File(path);
mojo.execute();
Assert.assertTrue(file.exists());
if (file.getParentFile() != null) {
FileUtils.deleteDirectory(file.getParentFile());
}
}
private void assertGeneratedSwaggerSpecJson(String description) throws MojoExecutionException, MojoFailureException, IOException {
mojo.execute();
ObjectMapper mapper = new ObjectMapper();
JsonNode actualJson = mapper.readTree(new File(swaggerOutputDir, "swagger.json"));
JsonNode expectJson = mapper.readTree(this.getClass().getResourceAsStream("/expectedOutput/swagger-spring.json"));
changeDescription(expectJson, description);
assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER));
}
private void assertGeneratedSwaggerSpecYaml(String description) throws MojoExecutionException, MojoFailureException, IOException {
mojo.getApiSources().get(0).setOutputFormats("yaml");
mojo.execute();
String actualYaml = io.swagger.util.Yaml.pretty().writeValueAsString(
new Yaml().load(FileUtils.readFileToString(new File(swaggerOutputDir, "swagger.yaml"))));
String expectYaml = io.swagger.util.Yaml.pretty().writeValueAsString(
new Yaml().load(this.getClass().getResourceAsStream("/expectedOutput/swagger-spring.yaml")));
ObjectMapper mapper = new ObjectMapper();
JsonNode actualJson = mapper.readTree(YamlToJson(actualYaml));
JsonNode expectJson = mapper.readTree(YamlToJson(expectYaml));
changeDescription(expectJson, description);
assertJsonEquals(expectJson, actualJson, Configuration.empty().when(IGNORING_ARRAY_ORDER));
}
}