package io.swagger.parser.util; import io.swagger.models.Model; import io.swagger.models.ModelImpl; import io.swagger.models.auth.AuthorizationValue; import io.swagger.models.refs.RefFormat; import io.swagger.parser.processors.ExternalRefProcessor; import mockit.Injectable; import mockit.Mocked; import mockit.StrictExpectations; import org.apache.commons.io.IOUtils; import org.junit.Test; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; public class RefUtilsTest { @Test public void testComputeDefinitionName() throws Exception { //URL refs doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.json", "file"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.json#/foo", "foo"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.json#/foo/bar", "bar"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.json#/foo/bar/hello", "hello"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file", "file"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file#/foo", "foo"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file#/foo/bar", "bar"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file#/foo/bar/hello", "hello"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.yaml", "file"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.yaml#/foo", "foo"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.yaml#/foo/bar", "bar"); doComputeDefinitionNameTestCase("http://my.company.com/path/to/file.yaml#/foo/bar/hello", "hello"); //Relative file refs doComputeDefinitionNameTestCase("./path/to/file.json", "file"); doComputeDefinitionNameTestCase("./path/to/file.json#/foo", "foo"); doComputeDefinitionNameTestCase("./path/to/file.json#/foo/bar", "bar"); doComputeDefinitionNameTestCase("./path/to/file.json#/foo/bar/hello", "hello"); doComputeDefinitionNameTestCase("./path/to/file.yaml", "file"); doComputeDefinitionNameTestCase("./path/to/file.yaml#/foo", "foo"); doComputeDefinitionNameTestCase("./path/to/file.yaml#/foo/bar", "bar"); doComputeDefinitionNameTestCase("./path/to/file.yaml#/foo/bar/hello", "hello"); doComputeDefinitionNameTestCase("./path/to/file", "file"); doComputeDefinitionNameTestCase("./path/to/file#/foo", "foo"); doComputeDefinitionNameTestCase("./path/to/file#/foo/bar", "bar"); doComputeDefinitionNameTestCase("./path/to/file#/foo/bar/hello", "hello"); } private void doComputeDefinitionNameTestCase(String ref, String expectedDefinitionName) { assertEquals(expectedDefinitionName, RefUtils.computeDefinitionName(ref)); } private Map<String, Model> createMap(String... keys) { Map<String, Model> definitionMap = new HashMap<>(); for (String key : keys) { definitionMap.put(key, new ModelImpl()); } return definitionMap; } @Test public void testIsAnExternalRefFormat() throws Exception { final RefFormat[] values = RefFormat.values(); for (RefFormat value : values) { switch (value) { case URL: case RELATIVE: assertTrue(RefUtils.isAnExternalRefFormat(value)); break; case INTERNAL: assertFalse(RefUtils.isAnExternalRefFormat(value)); break; default: fail("Unhandled RefFormat condition: " + value); } } } @Test public void testReadExternalRef_UrlFormat(@Injectable final List<AuthorizationValue> auths, @Mocked RemoteUrl remoteUrl ) throws Exception { final String url = "http://my.company.com/path/to/file.json"; final String expectedResult = "really good json"; new StrictExpectations() {{ RemoteUrl.urlToString(url, auths); times = 1; result = expectedResult; }}; String actualResult = RefUtils.readExternalRef(url, RefFormat.URL, auths, null); assertEquals(expectedResult, actualResult); } @Test public void testReadExternalRef_UrlFormat_ExceptionThrown(@Injectable final List<AuthorizationValue> auths, @Injectable final Exception mockedException, @Mocked RemoteUrl remoteUrl ) throws Exception { final String url = "http://my.company.com/path/to/file.json"; new StrictExpectations() {{ RemoteUrl.urlToString(url, auths); times = 1; result = mockedException; }}; try { RefUtils.readExternalRef(url, RefFormat.URL, auths, null); fail("Should have thrown an exception"); } catch (RuntimeException e) { assertEquals(mockedException, e.getCause()); } } @Test public void testReadExternalRef_RelativeFileFormat(@Injectable final List<AuthorizationValue> auths, @Mocked IOUtils ioUtils, @Mocked final FileInputStream fileInputStream, @Mocked Files files, @Injectable final Path parentDirectory, @Injectable final Path pathToUse, @Injectable final File file ) throws Exception { final String filePath = "./path/to/file.json"; final String expectedResult = "really good json"; setupRelativeFileExpectations(fileInputStream, parentDirectory, pathToUse, file, filePath); new StrictExpectations() {{ IOUtils.toString(fileInputStream, "UTF-8"); times = 1; result = expectedResult; }}; String actualResult = RefUtils.readExternalRef(filePath, RefFormat.RELATIVE, auths, parentDirectory); assertEquals(expectedResult, actualResult); } private void setupRelativeFileExpectations(@Mocked final FileInputStream fileInputStream, @Injectable final Path parentDirectory, @Injectable final Path pathToUse, @Injectable final File file, final String filePath) throws Exception { new StrictExpectations() {{ parentDirectory.resolve(filePath).normalize(); times = 1; result = pathToUse; Files.exists(pathToUse); times = 1; result = true; pathToUse.toFile(); times = 1; result = file; new FileInputStream(file); times = 1; result = fileInputStream; }}; } @Test public void testReadExternalRef_RelativeFileFormat_ExceptionThrown(@Injectable final List<AuthorizationValue> auths, @Mocked IOUtils ioUtils, @Mocked final FileInputStream fileInputStream, @Mocked Files files, @Injectable final IOException mockedException, @Injectable final Path parentDirectory, @Injectable final Path pathToUse, @Injectable final File file ) throws Exception { final String filePath = "./path/to/file.json"; setupRelativeFileExpectations(fileInputStream, parentDirectory, pathToUse, file, filePath); new StrictExpectations() {{ IOUtils.toString(fileInputStream, "UTF-8"); times = 1; result = mockedException; }}; try { RefUtils.readExternalRef(filePath, RefFormat.RELATIVE, auths, parentDirectory); fail("Should have thrown an exception"); } catch (RuntimeException e) { assertEquals(mockedException, e.getCause()); } } @Test public void testReadExternalRef_InternalFormat(@Injectable final List<AuthorizationValue> auths) throws Exception { final String file = "#/defintiions/foo"; try { RefUtils.readExternalRef(file, RefFormat.INTERNAL, auths, null); fail("Should have thrown an exception"); } catch (RuntimeException e) { } } @Test public void testReadExternalRef_OnClasspath(@Mocked Files files, @Mocked ClasspathHelper classpathHelper, @Injectable final Path parentDirectory, @Injectable final Path pathToUse) throws Exception { final String filePath = "./path/to/file.json"; final String expectedResult = "really good json"; new StrictExpectations() {{ parentDirectory.resolve(filePath).normalize(); times = 1; result = pathToUse; Files.exists(pathToUse); times = 1; result = false; ClasspathHelper.loadFileFromClasspath(filePath); times=1; result=expectedResult; }}; final String actualResult = RefUtils.readExternalRef(filePath, RefFormat.RELATIVE, null, parentDirectory); assertEquals(actualResult, expectedResult); } @Test public void testPathJoin1() { // simple assertEquals(ExternalRefProcessor.join("http://foo.bar.com", "fun"), "http://foo.bar.com/fun"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com/", "fun"), "http://foo.bar.com/fun"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com/", "/fun"), "http://foo.bar.com/fun"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com", "/fun"), "http://foo.bar.com/fun"); // relative to host assertEquals(ExternalRefProcessor.join("http://foo.bar.com/foo/bar", "/fun"), "http://foo.bar.com/fun"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com/foo/bar#/baz/bat", "/fun"), "http://foo.bar.com/fun"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com/foo/bar#/baz/bat", "/fun#for/all"), "http://foo.bar.com/fun#for/all"); // relative assertEquals(ExternalRefProcessor.join("http://foo.bar.com", "./fun"), "http://foo.bar.com/fun"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com/veryFun", "./fun"), "http://foo.bar.com/fun"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com/veryFun/", "../fun#nothing"), "http://foo.bar.com/fun#nothing"); assertEquals(ExternalRefProcessor.join("http://foo.bar.com/veryFun/notFun", "../fun#/it/is/fun"), "http://foo.bar.com/fun#/it/is/fun"); // with file extensions assertEquals(ExternalRefProcessor.join("http://foo.bar.com/baz/bat.yaml", "../fun/times.yaml"), "http://foo.bar.com/fun/times.yaml"); // hashes assertEquals(ExternalRefProcessor.join("http://foo.bar.com/veryFun/", "../fun#/it/is/fun"), "http://foo.bar.com/fun#/it/is/fun"); // relative locations assertEquals(ExternalRefProcessor.join("./foo#/definitions/Foo", "./bar#/definitions/Bar"), "./bar#/definitions/Bar"); } }