diff --git a/mock/soap/src/main/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Parser.kt b/mock/soap/src/main/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Parser.kt index 9525643cc..9ce2f3e2c 100644 --- a/mock/soap/src/main/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Parser.kt +++ b/mock/soap/src/main/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Parser.kt @@ -152,7 +152,7 @@ class Wsdl2Parser( expressionTemplate = "./wsdl:operation[@name='%s']", name = operationName ) - return operation?.let { parseOperation(operationName, operation) } + return operation?.let { parseOperation(operationName, interfaceNode, operation) } } private fun getInterfaceNode(interfaceName: String): Element? { @@ -163,13 +163,16 @@ class Wsdl2Parser( ) } - private fun parseOperation(operationName: String, operation: Element): WsdlOperation { + private fun parseOperation(operationName: String, iface: Element, operation: Element): WsdlOperation { val soapOperation = selectSingleNode(operation, "./soap:operation") ?: throw IllegalStateException( "Unable to find soap:operation for operation $operationName" ) val input = getMessage(operation, "./wsdl:input", required = true) val output = getMessage(operation, "./wsdl:output", required = true) + + // fall back to fault defined at interface level val fault = getMessage(operation, "./wsdl:fault", required = false) + ?: getMessage(iface, "./wsdl:fault", required = false) return WsdlOperation( name = operation.getAttributeValue("name"), diff --git a/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap11ParserTest.kt b/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap11ParserTest.kt index 2723b0f85..825717dc6 100644 --- a/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap11ParserTest.kt +++ b/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap11ParserTest.kt @@ -86,7 +86,7 @@ class Wsdl1Soap11ParserTest { } @Test - fun getBinding() { + fun `get SOAP binding, getPetById operation`() { val binding = parser.getBinding("SoapBinding") assertNotNull("SoapBinding should not be null", binding) @@ -102,7 +102,10 @@ class Wsdl1Soap11ParserTest { operation!! assertEquals("getPetById", operation.name) assertEquals("getPetById", operation.soapAction) + + // operation style defined at operation level in this service assertEquals("document", operation.style) + assertEquals( QName("urn:com:example:petstore", "getPetByIdRequest"), (operation.inputRef as ElementOperationMessage).elementName, @@ -111,11 +114,45 @@ class Wsdl1Soap11ParserTest { QName("urn:com:example:petstore", "getPetByIdResponse"), (operation.outputRef as ElementOperationMessage).elementName, ) + assertEquals( + QName("urn:com:example:petstore", "getPetFault"), + (operation.faultRef as ElementOperationMessage?)?.elementName, + ) + } + + @Test + fun `get HTTP binding, getPetByName operation`() { + val binding = parser.getBinding("HttpBinding") + assertNotNull("HttpBinding should not be null", binding) + + binding!! + assertEquals("HttpBinding", binding.name) + assertEquals(BindingType.HTTP, binding.type) + assertEquals("tns:PetPortType", binding.interfaceRef) + + assertEquals(2, binding.operations.size) + val operation = binding.operations.find { it.name == "getPetByName" } + assertNotNull("getPetByName operation should not be null", operation) + + operation!! + assertEquals("getPetByName", operation.name) + assertEquals("getPetByName", operation.soapAction) // operation style should fall back to binding style in WSDL 1.x - val petNameOp = binding.operations.find { it.name == "getPetByName" } - assertNotNull(petNameOp) - assertEquals("document", petNameOp?.style) + assertEquals("document", operation.style) + + assertEquals( + QName("urn:com:example:petstore", "getPetByNameRequest"), + (operation.inputRef as ElementOperationMessage).elementName, + ) + assertEquals( + QName("urn:com:example:petstore", "getPetByNameResponse"), + (operation.outputRef as ElementOperationMessage).elementName, + ) + assertEquals( + QName("urn:com:example:petstore", "getPetFault"), + (operation.faultRef as ElementOperationMessage?)?.elementName, + ) } @Test diff --git a/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap12ParserTest.kt b/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap12ParserTest.kt index 23571e1da..65e4d3191 100644 --- a/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap12ParserTest.kt +++ b/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl1Soap12ParserTest.kt @@ -86,7 +86,7 @@ class Wsdl1Soap12ParserTest { } @Test - fun getBinding() { + fun `get SOAP binding, getPetById operation`() { val binding = parser.getBinding("SoapBinding") assertNotNull("SoapBinding should not be null", binding) @@ -102,7 +102,10 @@ class Wsdl1Soap12ParserTest { operation!! assertEquals("getPetById", operation.name) assertEquals("getPetById", operation.soapAction) + + // operation style defined at operation level in this service assertEquals("document", operation.style) + assertEquals( QName("urn:com:example:petstore","getPetByIdRequest"), (operation.inputRef as ElementOperationMessage).elementName, @@ -111,11 +114,45 @@ class Wsdl1Soap12ParserTest { QName("urn:com:example:petstore","getPetByIdResponse"), (operation.outputRef as ElementOperationMessage).elementName, ) + assertEquals( + QName("urn:com:example:petstore", "getPetFault"), + (operation.faultRef as ElementOperationMessage?)?.elementName, + ) + } + + @Test + fun `get HTTP binding, getPetByName operation`() { + val binding = parser.getBinding("HttpBinding") + assertNotNull("HttpBinding should not be null", binding) + + binding!! + assertEquals("HttpBinding", binding.name) + assertEquals(BindingType.HTTP, binding.type) + assertEquals("tns:PetPortType", binding.interfaceRef) + + assertEquals(2, binding.operations.size) + val operation = binding.operations.find { it.name == "getPetByName" } + assertNotNull("getPetByName operation should not be null", operation) + + operation!! + assertEquals("getPetByName", operation.name) + assertEquals("getPetByName", operation.soapAction) // operation style should fall back to binding style in WSDL 1.x - val petNameOp = binding.operations.find { it.name == "getPetByName" } - assertNotNull(petNameOp) - assertEquals("document", petNameOp?.style) + assertEquals("document", operation.style) + + assertEquals( + QName("urn:com:example:petstore","getPetByNameRequest"), + (operation.inputRef as ElementOperationMessage).elementName, + ) + assertEquals( + QName("urn:com:example:petstore","getPetByNameResponse"), + (operation.outputRef as ElementOperationMessage).elementName, + ) + assertEquals( + QName("urn:com:example:petstore", "getPetFault"), + (operation.faultRef as ElementOperationMessage?)?.elementName, + ) } @Test diff --git a/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Soap12ParserTest.kt b/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Soap12ParserTest.kt index 5463bad1f..400ea68db 100644 --- a/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Soap12ParserTest.kt +++ b/mock/soap/src/test/java/io/gatehill/imposter/plugin/soap/parser/Wsdl2Soap12ParserTest.kt @@ -86,7 +86,7 @@ class Wsdl2Soap12ParserTest { } @Test - fun getBinding() { + fun `get SOAP binding, getPetById operation`() { val binding = parser.getBinding("SoapBinding") assertNotNull("SoapBinding should not be null", binding) @@ -111,6 +111,46 @@ class Wsdl2Soap12ParserTest { QName("urn:com:example:petstore", "getPetByIdResponse"), (operation.outputRef as ElementOperationMessage).elementName, ) + + // fault defined at interface level + assertEquals( + QName("urn:com:example:petstore", "getPetFault"), + (operation.faultRef as ElementOperationMessage?)?.elementName, + ) + } + + @Test + fun `get HTTP binding, getPetByName operation`() { + val binding = parser.getBinding("HttpBinding") + assertNotNull("HttpBinding should not be null", binding) + + binding!! + assertEquals("HttpBinding", binding.name) + assertEquals(BindingType.HTTP, binding.type) + assertEquals("tns:PetInterface", binding.interfaceRef) + + assertEquals(2, binding.operations.size) + val operation = binding.operations.find { it.name == "getPetByName" } + assertNotNull("getPetByName operation should not be null", operation) + + operation!! + assertEquals("getPetByName", operation.name) + assertEquals("getPetByName", operation.soapAction) + assertEquals("document", operation.style) + assertEquals( + QName("urn:com:example:petstore", "getPetByNameRequest"), + (operation.inputRef as ElementOperationMessage).elementName, + ) + assertEquals( + QName("urn:com:example:petstore", "getPetByNameResponse"), + (operation.outputRef as ElementOperationMessage).elementName, + ) + + // fault defined in operation + assertEquals( + QName("urn:com:example:petstore", "getPetFault"), + (operation.faultRef as ElementOperationMessage?)?.elementName, + ) } @Test diff --git a/mock/soap/src/test/resources/wsdl1-soap11-document-bare/schema.xsd b/mock/soap/src/test/resources/wsdl1-soap11-document-bare/schema.xsd index 18698a618..ce0722429 100644 --- a/mock/soap/src/test/resources/wsdl1-soap11-document-bare/schema.xsd +++ b/mock/soap/src/test/resources/wsdl1-soap11-document-bare/schema.xsd @@ -9,6 +9,13 @@ + + + + + + + @@ -27,5 +34,5 @@ - + diff --git a/mock/soap/src/test/resources/wsdl1-soap11-document-bare/service.wsdl b/mock/soap/src/test/resources/wsdl1-soap11-document-bare/service.wsdl index 48ffea79a..4f983579e 100644 --- a/mock/soap/src/test/resources/wsdl1-soap11-document-bare/service.wsdl +++ b/mock/soap/src/test/resources/wsdl1-soap11-document-bare/service.wsdl @@ -105,16 +105,21 @@ + + + + + @@ -130,6 +135,9 @@ + + + @@ -139,6 +147,9 @@ + + + @@ -154,6 +165,9 @@ + + + @@ -165,6 +179,9 @@ + + + diff --git a/mock/soap/src/test/resources/wsdl1-soap12/schema.xsd b/mock/soap/src/test/resources/wsdl1-soap12/schema.xsd index 18698a618..ce0722429 100644 --- a/mock/soap/src/test/resources/wsdl1-soap12/schema.xsd +++ b/mock/soap/src/test/resources/wsdl1-soap12/schema.xsd @@ -9,6 +9,13 @@ + + + + + + + @@ -27,5 +34,5 @@ - + diff --git a/mock/soap/src/test/resources/wsdl1-soap12/service.wsdl b/mock/soap/src/test/resources/wsdl1-soap12/service.wsdl index 30c345f1c..f79915c7b 100644 --- a/mock/soap/src/test/resources/wsdl1-soap12/service.wsdl +++ b/mock/soap/src/test/resources/wsdl1-soap12/service.wsdl @@ -104,16 +104,21 @@ + + + + + @@ -129,6 +134,9 @@ + + + @@ -138,6 +146,9 @@ + + + @@ -153,6 +164,9 @@ + + + @@ -164,6 +178,9 @@ + + + diff --git a/mock/soap/src/test/resources/wsdl2-soap12/schema.xsd b/mock/soap/src/test/resources/wsdl2-soap12/schema.xsd index 18698a618..ce0722429 100644 --- a/mock/soap/src/test/resources/wsdl2-soap12/schema.xsd +++ b/mock/soap/src/test/resources/wsdl2-soap12/schema.xsd @@ -9,6 +9,13 @@ + + + + + + + @@ -27,5 +34,5 @@ - + diff --git a/mock/soap/src/test/resources/wsdl2-soap12/service.wsdl b/mock/soap/src/test/resources/wsdl2-soap12/service.wsdl index 5531b3877..9f134a13b 100644 --- a/mock/soap/src/test/resources/wsdl2-soap12/service.wsdl +++ b/mock/soap/src/test/resources/wsdl2-soap12/service.wsdl @@ -94,19 +94,21 @@ http://www.w3.org/ns/wsdl/soap http://www.w3.org/2002/ws/desc/ns/soap.xsd"> - + + +