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">
-
+
+
+