-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SOAP integration: set root element namespace #41 #50
Conversation
|
||
|
||
it 'should require xmlnsAttribute value', -> | ||
assert.equal soap.validate(url: 'http://foo', function: 'whatever', version:'1.1', namespace_prefix: 'tns', xmlnsAttribute_name: 'xmlns:tns'), 'XmlnsAttribute value is required' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want this configuration to be optional.
@@ -189,6 +204,9 @@ requestVariables = -> | |||
{ name: 'url', description: 'WSDL URL', type: 'string', required: true } | |||
{ name: 'function', description: 'Name of the SOAP function to call', type: 'string', required: true } | |||
{ name: 'version', description: 'SOAP version to use: 1.1 or 1.2 (default: 1.1)', type: 'string', required: false } | |||
{ name: 'namespace_prefix', description: 'namespace prefix for the body element', type: 'string', required: true } | |||
{ name: 'xmlnsAttribute_name', description: 'xmlnsAttribute name for the body element', type: 'string', required: true } | |||
{ name: 'xmlnsAttribute_value', description: 'xmlnsAttribute value for the body element', type: 'string', required: true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make the variable name all lower case. Maybe root_xmlns_attribute_name
and root_xmlns_attribute_value
?
re: tests and validations, it seems as per https://www.w3.org/TR/REC-xml-names/ that xml namespaces are URIs. since this checks also, for testing the new attributes, you might want to test that the |
Kelly said:
I came across some of those conflicting things you mentioned on Wikipedia: "In general, however, users should assume that the namespace URI is simply a name, not the address of a document on the Web". For this advanced setting, I think being more lax is better. If someone needs to set up this namespace business, they'll have to enter the value right one way or the other. I'm afraid that as soon as it's validated to be a URI, we'll have a customer that wants to use a non-URI value. Any thoughts, @alexkwolfe ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to this feedback, there are outstanding questions to discuss about URI validation.
<tns:AddLeadResponse xmlns:tns="http://donkey/ws.asmx/"> | ||
<AddLeadXMLResult> | ||
<Response> | ||
<Result>true</Result> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a reason for these tags to be in <
s and >
s, instead of <
s and >
s?
validateVersion = (vars) -> | ||
version = vars.version?.trim() | ||
return unless version? | ||
return 'Must be valid SOAP version: 1.1 or 1.2' unless version == '1.1' or version == '1.2' | ||
|
||
validateXmlnsAttributeValue = (vars) -> | ||
if vars.root_xmlns_attribute_value? | ||
console.log vars.root_xmlns_attribute_value,'validate url result', validate.isValidUrl(vars.root_xmlns_attribute_value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to remove this debugging statement.
@@ -189,6 +198,9 @@ requestVariables = -> | |||
{ name: 'url', description: 'WSDL URL', type: 'string', required: true } | |||
{ name: 'function', description: 'Name of the SOAP function to call', type: 'string', required: true } | |||
{ name: 'version', description: 'SOAP version to use: 1.1 or 1.2 (default: 1.1)', type: 'string', required: false } | |||
{ name: 'root_namespace_prefix', description: 'namespace prefix for the body element', type: 'string', required: false } | |||
{ name: 'root_xmlns_attribute_name', description: 'xmlnsAttribute name for the body element', type: 'string', required: false } | |||
{ name: 'root_xmlns_attribute_value', description: 'xmlnsAttribute value for the body element', type: 'string', required: false } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These variables are presented to the user in the UI in the order they're listed here. I think these new settings won't be very commonly used, so they'd be better at the end of this array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think we can give better information about these (admittedly advanced) settings than "xmlnsAttribute name for the body element".
@@ -24,12 +25,14 @@ describe 'Outbound SOAP', -> | |||
vars = | |||
url: 'http://donkey/login/ws/ws.asmx?WSDL' | |||
function: 'someUnsupportedFunction' | |||
root_xmlns_attribute_name: 'xmlns:tns' | |||
root_xmlns_attribute_value: 'http://skylist.com/services/Soap' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think these new lines are needed.
@@ -41,6 +44,8 @@ describe 'Outbound SOAP', -> | |||
vars = | |||
url: 'http://donkey/login/ws/ws.asmx?WSDL' | |||
function: 'AddLead' | |||
root_xmlns_attribute_name: 'xmlns:tns' | |||
root_xmlns_attribute_value: 'http://donkey/login/ws/ws.asmx?WSDL' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, I don't think these new lines are needed.
done() | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Kelly mentioned previously, there should also be test coverage for when these new variables are not set, to ensure the requests are still constructed correctly.
@cgrayson I agree with being more lax on the namespace. My point of reference was https://www.w3.org/TR/REC-xml-names/#concepts -- with the definition being a URI reference. I did a bit more digging just now and found this unclear documentation as well -- not sure if it's referring to a valid URI format or actual endpoint: https://www.w3.org/TR/REC-xml-names/#ProcessorConformance. So on that note, since namespace validation is pretty unclear, probably best to avoid it after all. |
I vote for omitting URI validation for the namespaces. |
@cgrayson I have made the changes. |
@@ -46,5 +46,3 @@ module.exports = | |||
# ensure that user-specified Content-Type is similar to what's allowed | |||
if headers['content-type']? and !headers['content-type']?.match(new RegExp(contentTypeBase, 'i')) | |||
return "Invalid Content-Type header value" | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These whitespace changes are making this file show as changed when it hasn't, really.
<Result>true</Result> | ||
<Message>some message</Message> | ||
<LeadId>12345</LeadId> | ||
<Empty></Empty> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would normally just be <Empty/>
, as here.
.reply 200, wsdl, 'Content-Type': 'text/xml' | ||
|
||
@service = nock 'http://donkey' | ||
.post '/login/ws/ws.asmx' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test (and the following one) aren't quite sufficient. They're only verifying that a POST is made by the integration to that URL, but not what is posted. This test should verify that the correct SOAP header stuff is added, and the test below should verify that no SOAP header stuff is changed. I think using a regex, as described in the nock docs, would be the way to go.
namespace: vars.root_namespace_prefix | ||
xmlnsAttributes: [ | ||
{ name: vars.root_xmlns_attribute_name, value: vars.root_xmlns_attribute_value } | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you'll find, once tests are more thorough, that these options need to be set only when the vars.root_…
values are present. For example, I think this code will set an attribute like undefined="undefined"
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, as mentioned in discussion on #41, there would ideally be support for multiple name/value pairs here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if you have any questions, or when this is ready to review again
|
||
# prevent root xlmns attribute key and value from being added to the root element when it is undefined | ||
if !vars.root_xlmns_attributes | ||
delete options.overrideRootElement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic would be a little clearer if the options
values were only ever set if needed, rather than always set and then possibly deleted later. E.g., don't declare them at all at first, and then:
if _.isPlainObject(vars.root_xlmns_attributes)
options.overrideRootElement = {}
options.overrideRootElement.namespace = vars.root_namespace_prefix if vars.root_namespace_prefix
for key, value of vars.root_xlmns_attributes
options.overrideRootElement.xmlnsAttributes.push { name: key, value: value }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though, unfortunately, the way you have this set up won't work. vars.root_xmlns_attributes
here is an object, but data isn't addressable like that in LeadConduit. That is, users can't map an object like { 'xmlns:cal': 'http://donkey/ws.asmx/' }
in the LC UI. To support multiples, I think there would need to be an array for root_xmlns_names
, and another matching one for root_xmlns_values
… (unless there's some way I'm not thinking of, @alexkwolfe?).
So, although I think ideally we would allow multiple, for now please step back to one pair, and we'll hope that's enough for the time being.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have edited it. I agree that they should be arrays. The reason why I used wildcard as the type instead of an array is that array is not included as a type in the documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting close, I just have that last concern.
# prevent root xlmns attribute key and value from being added to the root element when it is undefined | ||
if vars.root_xmlns_attribute_name and vars.root_xmlns_attribute_value | ||
options.overrideRootElement = | ||
namespace: vars.root_namespace_prefix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I know this is set up as I suggested 😃 but I think there may be a problem here. If only root_namespace_prefix
is set (and root_xmlns_attribute_name
or …value
isn't), then this namespace
option will never be set. Maybe tests for each combination of values would make sure these cases are covered.
Jumoke, based on what you said in our integrations meeting today, it sounds like maybe you were thinking of implementing an array of namespaces. But it sounds like we're OK just skipping that for now. And the only remaining issue is the one that chris brought up here. |
|
||
# prevent root xlmns attribute key and value from being added to the root element when undefined | ||
if vars.root_xmlns_attribute_name and vars.root_xmlns_attribute_value | ||
options.overrideRootElement['xmlnsAttributes'] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem here is that if vars.root_namespace_prefix
isn't defined, then there is no options.overrideRootElement
. If you add a test with root_xmlns_attribute_name
and root_xmlns_attribute_value
, but no vars.root_namespace_prefix
, you'll see what I mean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise LGTM
options = | ||
valueKey: '#value' | ||
forceSoap12Headers: vars.version?.trim() == '1.2' | ||
disableCache: true | ||
overrideRootElement: | ||
namespace: vars.root_namespace_prefix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though it's evidently not currently causing problems, per your tests, when vars.root_namespace_prefix
isn't set, this code is setting overrideRootElement.namespace
to undefined
, which makes me nervous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the last thing to address before we get this merged?
] | ||
|
||
if !vars.root_namespace_prefix | ||
delete options.overrideRootElement['namespace'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of deleting this property, I think it makes more sense to not set it at all. I know you're running into an error when root_namespace_prefix
isn't defined but the others are, so you could use _.set
around L28 to reduce some of the logic to make sure options.overrideRootElement
is defined:
_.set options, 'overrideRootElement.xmlnsAttributes', [
name: vars.root_xmlns_attribute_name
value: vars.root_xmlns_attribute_value
]
Still LGTM |
cf07cdb
to
026d1f5
Compare
…ce or xmlns attribute name/value pair when specified
026d1f5
to
5c41ff2
Compare
#41