1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps.assertions.basic;
14
15 import java.awt.BorderLayout;
16 import java.awt.Dimension;
17 import java.awt.event.ActionEvent;
18 import java.awt.event.WindowAdapter;
19 import java.awt.event.WindowEvent;
20 import java.util.ArrayList;
21 import java.util.List;
22
23 import javax.swing.AbstractAction;
24 import javax.swing.Action;
25 import javax.swing.BorderFactory;
26 import javax.swing.JButton;
27 import javax.swing.JCheckBox;
28 import javax.swing.JDialog;
29 import javax.swing.JPanel;
30 import javax.swing.JScrollPane;
31 import javax.swing.JSplitPane;
32 import javax.swing.JTextArea;
33 import javax.swing.SwingUtilities;
34
35 import junit.framework.ComparisonFailure;
36
37 import org.apache.log4j.Logger;
38 import org.apache.xmlbeans.XmlAnySimpleType;
39 import org.apache.xmlbeans.XmlCursor;
40 import org.apache.xmlbeans.XmlObject;
41 import org.apache.xmlbeans.XmlOptions;
42 import org.apache.xmlbeans.XmlQName;
43 import org.apache.xmlbeans.impl.values.XmlValueDisconnectedException;
44 import org.custommonkey.xmlunit.Diff;
45 import org.custommonkey.xmlunit.Difference;
46 import org.custommonkey.xmlunit.DifferenceEngine;
47 import org.custommonkey.xmlunit.DifferenceListener;
48 import org.custommonkey.xmlunit.XMLAssert;
49 import org.w3c.dom.Attr;
50 import org.w3c.dom.Element;
51 import org.w3c.dom.Node;
52
53 import com.eviware.soapui.SoapUI;
54 import com.eviware.soapui.config.TestAssertionConfig;
55 import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
56 import com.eviware.soapui.impl.wsdl.WsdlInterface;
57 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
58 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathImpl;
59 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
60 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
61 import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
62 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
63 import com.eviware.soapui.impl.wsdl.teststeps.assertions.AbstractTestAssertionFactory;
64 import com.eviware.soapui.model.TestModelItem;
65 import com.eviware.soapui.model.iface.MessageExchange;
66 import com.eviware.soapui.model.iface.SubmitContext;
67 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
68 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
69 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
70 import com.eviware.soapui.model.support.XPathReference;
71 import com.eviware.soapui.model.support.XPathReferenceContainer;
72 import com.eviware.soapui.model.support.XPathReferenceImpl;
73 import com.eviware.soapui.model.testsuite.Assertable;
74 import com.eviware.soapui.model.testsuite.AssertionError;
75 import com.eviware.soapui.model.testsuite.AssertionException;
76 import com.eviware.soapui.model.testsuite.RequestAssertion;
77 import com.eviware.soapui.model.testsuite.ResponseAssertion;
78 import com.eviware.soapui.model.testsuite.TestProperty;
79 import com.eviware.soapui.model.testsuite.TestStep;
80 import com.eviware.soapui.support.StringUtils;
81 import com.eviware.soapui.support.UISupport;
82 import com.eviware.soapui.support.components.JUndoableTextArea;
83 import com.eviware.soapui.support.components.JXToolBar;
84 import com.eviware.soapui.support.types.StringList;
85 import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
86 import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
87 import com.eviware.soapui.support.xml.XmlUtils;
88 import com.jgoodies.forms.builder.ButtonBarBuilder;
89
90 /***
91 * Assertion that matches a specified XPath expression and its expected result
92 * against the associated WsdlTestRequests response message
93 *
94 * @author Ole.Matzura
95 */
96
97 public class XPathContainsAssertion extends WsdlMessageAssertion implements RequestAssertion, ResponseAssertion,
98 XPathReferenceContainer
99 {
100 private final static Logger log = Logger.getLogger( XPathContainsAssertion.class );
101 private String expectedContent;
102 private String path;
103 private JDialog configurationDialog;
104 private JTextArea pathArea;
105 private JTextArea contentArea;
106 private boolean configureResult;
107 private boolean allowWildcards;
108 private boolean ignoreNamespaceDifferences;
109
110 public static final String ID = "XPath Match";
111 public static final String LABEL = "XPath Match";
112 private JCheckBox allowWildcardsCheckBox;
113 private JCheckBox ignoreNamespaceDifferencesCheckBox;
114
115 public XPathContainsAssertion( TestAssertionConfig assertionConfig, Assertable assertable )
116 {
117 super( assertionConfig, assertable, true, true, true, true );
118
119 XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( getConfiguration() );
120 path = reader.readString( "path", null );
121 expectedContent = reader.readString( "content", null );
122 allowWildcards = reader.readBoolean( "allowWildcards", false );
123 ignoreNamespaceDifferences = reader.readBoolean( "ignoreNamspaceDifferences", false );
124 }
125
126 public String getExpectedContent()
127 {
128 return expectedContent;
129 }
130
131 public void setExpectedContent( String expectedContent )
132 {
133 this.expectedContent = expectedContent;
134 setConfiguration( createConfiguration() );
135 }
136
137 /***
138 * @deprecated
139 */
140
141 @Deprecated
142 public void setContent( String content )
143 {
144 setExpectedContent( content );
145 }
146
147 public String getPath()
148 {
149 return path;
150 }
151
152 public void setPath( String path )
153 {
154 this.path = path;
155 setConfiguration( createConfiguration() );
156 }
157
158 public boolean isAllowWildcards()
159 {
160 return allowWildcards;
161 }
162
163 public void setAllowWildcards( boolean allowWildcards )
164 {
165 this.allowWildcards = allowWildcards;
166 setConfiguration( createConfiguration() );
167 }
168
169 public boolean isIgnoreNamespaceDifferences()
170 {
171 return ignoreNamespaceDifferences;
172 }
173
174 public void setIgnoreNamespaceDifferences( boolean ignoreNamespaceDifferences )
175 {
176 this.ignoreNamespaceDifferences = ignoreNamespaceDifferences;
177 setConfiguration( createConfiguration() );
178 }
179
180 @Override
181 protected String internalAssertResponse( MessageExchange messageExchange, SubmitContext context )
182 throws AssertionException
183 {
184 if( !messageExchange.hasResponse() )
185 return "Missing Response";
186 else
187 return assertContent( messageExchange.getResponseContentAsXml(), context, "Response" );
188 }
189
190 public String assertContent( String response, SubmitContext context, String type ) throws AssertionException
191 {
192 try
193 {
194 if( path == null )
195 return "Missing path for XPath assertion";
196 if( expectedContent == null )
197 return "Missing content for XPath assertion";
198
199 XmlObject xml = XmlObject.Factory.parse( response );
200 String expandedPath = PropertyExpander.expandProperties( context, path );
201 XmlObject[] items = xml.selectPath( expandedPath );
202 AssertedXPathsContainer assertedXPathsContainer = ( AssertedXPathsContainer )context
203 .getProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY );
204
205 XmlObject contentObj = null;
206 String expandedContent = PropertyExpander.expandProperties( context, expectedContent );
207
208
209
210
211 if( !expandedPath.endsWith( "text()" ) )
212 {
213 try
214 {
215 contentObj = XmlObject.Factory.parse( expandedContent );
216 }
217 catch( Exception e )
218 {
219
220
221
222
223 }
224 }
225
226 if( items.length == 0 )
227 throw new Exception( "Missing content for xpath [" + path + "] in " + type );
228
229 XmlOptions options = new XmlOptions();
230 options.setSavePrettyPrint();
231 options.setSaveOuter();
232
233 for( int c = 0; c < items.length; c++ )
234 {
235 try
236 {
237 AssertedXPathImpl assertedXPathImpl = null;
238 if( assertedXPathsContainer != null )
239 {
240 String xpath = XmlUtils.createAbsoluteXPath( items[c].getDomNode() );
241 if( xpath != null )
242 {
243 XmlObject xmlObj = items[c];
244
245
246
247 assertedXPathImpl = new AssertedXPathImpl( this, xpath, xmlObj );
248 assertedXPathsContainer.addAssertedXPath( assertedXPathImpl );
249 }
250 }
251
252 if( contentObj == null )
253 {
254 if( items[c] instanceof XmlAnySimpleType && !( items[c] instanceof XmlQName ) )
255 {
256 String value = ( ( XmlAnySimpleType )items[c] ).getStringValue();
257 String expandedValue = PropertyExpander.expandProperties( context, value );
258 XMLAssert.assertEquals( expandedContent, expandedValue );
259 }
260 else
261 {
262 Node domNode = items[c].getDomNode();
263 if( domNode.getNodeType() == Node.ELEMENT_NODE )
264 {
265 String expandedValue = PropertyExpander.expandProperties( context, XmlUtils
266 .getElementText( ( Element )domNode ) );
267 XMLAssert.assertEquals( expandedContent, expandedValue );
268 }
269 else
270 {
271 String expandedValue = PropertyExpander.expandProperties( context, domNode.getNodeValue() );
272 XMLAssert.assertEquals( expandedContent, expandedValue );
273 }
274 }
275 }
276 else
277 {
278 compareValues( contentObj.xmlText( options ), items[c].xmlText( options ), items[c] );
279 }
280
281 break;
282 }
283 catch( Throwable e )
284 {
285 if( c == items.length - 1 )
286 throw e;
287 }
288 }
289 }
290 catch( Throwable e )
291 {
292 String msg = "";
293
294 if( e instanceof ComparisonFailure )
295 {
296 ComparisonFailure cf = ( ComparisonFailure )e;
297 String expected = cf.getExpected();
298 String actual = cf.getActual();
299
300
301
302
303
304
305
306 msg = "XPathContains comparison failed, expecting [" + expected + "], actual was [" + actual + "]";
307 }
308 else
309 {
310 msg = "XPathContains assertion failed for path [" + path + "] : " + e.getClass().getSimpleName() + ":"
311 + e.getMessage();
312 }
313
314 throw new AssertionException( new AssertionError( msg ) );
315 }
316
317 return type + " matches content for [" + path + "]";
318 }
319
320 private void compareValues( String expandedContent, String expandedValue, XmlObject object ) throws Exception
321 {
322 Diff diff = new Diff( expandedContent, expandedValue );
323 InternalDifferenceListener internalDifferenceListener = new InternalDifferenceListener();
324 diff.overrideDifferenceListener( internalDifferenceListener );
325
326 if( !diff.identical() )
327 throw new Exception( diff.toString() );
328
329 StringList nodesToRemove = internalDifferenceListener.getNodesToRemove();
330
331 if( !nodesToRemove.isEmpty() )
332 {
333 for( String node : nodesToRemove )
334 {
335 if( node == null )
336 continue;
337
338 int ix = node.indexOf( "\n/" );
339 if( ix != -1 )
340 node = node.substring( 0, ix + 1 ) + "./" + node.substring( ix + 1 );
341 else if( node.startsWith( "/" ) )
342 node = "/" + node;
343
344 XmlObject[] paths = object.selectPath( node );
345 if( paths.length > 0 )
346 {
347 Node domNode = paths[0].getDomNode();
348 if( domNode.getNodeType() == Node.ATTRIBUTE_NODE )
349 ( ( Attr )domNode ).getOwnerElement().removeAttributeNode( ( Attr )domNode );
350 else
351 domNode.getParentNode().removeChild( domNode );
352
353 try
354 {
355 object.set( object.copy() );
356 }
357 catch( XmlValueDisconnectedException e )
358 {
359
360 return;
361 }
362 }
363 }
364 }
365 }
366
367 @Override
368 public boolean configure()
369 {
370 if( configurationDialog == null )
371 buildConfigurationDialog();
372
373 pathArea.setText( path );
374 contentArea.setText( expectedContent );
375 allowWildcardsCheckBox.setSelected( allowWildcards );
376 ignoreNamespaceDifferencesCheckBox.setSelected( ignoreNamespaceDifferences );
377
378 UISupport.showDialog( configurationDialog );
379 return configureResult;
380 }
381
382 protected void buildConfigurationDialog()
383 {
384 configurationDialog = new JDialog( UISupport.getMainFrame() );
385 configurationDialog.setTitle( "XPath Match configuration" );
386 configurationDialog.addWindowListener( new WindowAdapter()
387 {
388 @Override
389 public void windowOpened( WindowEvent event )
390 {
391 SwingUtilities.invokeLater( new Runnable()
392 {
393 public void run()
394 {
395 pathArea.requestFocusInWindow();
396 }
397 } );
398 }
399 } );
400
401 JPanel contentPanel = new JPanel( new BorderLayout() );
402 contentPanel.add( UISupport.buildDescription( "Specify xpath expression and expected result",
403 "declare namespaces with <code>declare namespace <prefix>='<namespace>';</code>", null ),
404 BorderLayout.NORTH );
405
406 JSplitPane splitPane = UISupport.createVerticalSplit();
407
408 pathArea = new JUndoableTextArea();
409 pathArea.setToolTipText( "Specifies the XPath expression to select from the message for validation" );
410
411 JPanel pathPanel = new JPanel( new BorderLayout() );
412 JXToolBar pathToolbar = UISupport.createToolbar();
413 addPathEditorActions( pathToolbar );
414
415 pathPanel.add( pathToolbar, BorderLayout.NORTH );
416 pathPanel.add( new JScrollPane( pathArea ), BorderLayout.CENTER );
417
418 splitPane.setTopComponent( UISupport.addTitledBorder( pathPanel, "XPath Expression" ) );
419
420 contentArea = new JUndoableTextArea();
421 contentArea.setToolTipText( "Specifies the expected result of the XPath expression" );
422
423 JPanel matchPanel = new JPanel( new BorderLayout() );
424 JXToolBar contentToolbar = UISupport.createToolbar();
425 addMatchEditorActions( contentToolbar );
426
427 matchPanel.add( contentToolbar, BorderLayout.NORTH );
428 matchPanel.add( new JScrollPane( contentArea ), BorderLayout.CENTER );
429
430 splitPane.setBottomComponent( UISupport.addTitledBorder( matchPanel, "Expected Result" ) );
431 splitPane.setDividerLocation( 150 );
432 splitPane.setBorder( BorderFactory.createEmptyBorder( 0, 1, 0, 1 ) );
433
434 contentPanel.add( splitPane, BorderLayout.CENTER );
435
436 ButtonBarBuilder builder = new ButtonBarBuilder();
437
438 ShowOnlineHelpAction showOnlineHelpAction = new ShowOnlineHelpAction( HelpUrls.XPATHASSERTIONEDITOR_HELP_URL );
439 builder.addFixed( UISupport.createToolbarButton( showOnlineHelpAction ) );
440 builder.addGlue();
441
442 JButton okButton = new JButton( new OkAction() );
443 builder.addFixed( okButton );
444 builder.addRelatedGap();
445 builder.addFixed( new JButton( new CancelAction() ) );
446
447 builder.setBorder( BorderFactory.createEmptyBorder( 1, 5, 5, 5 ) );
448
449 contentPanel.add( builder.getPanel(), BorderLayout.SOUTH );
450
451 configurationDialog.setContentPane( contentPanel );
452 configurationDialog.setSize( 600, 500 );
453 configurationDialog.setModal( true );
454 UISupport.initDialogActions( configurationDialog, showOnlineHelpAction, okButton );
455 }
456
457 protected void addPathEditorActions( JXToolBar toolbar )
458 {
459 toolbar.addFixed( new JButton( new DeclareNamespacesFromCurrentAction() ) );
460 }
461
462 protected void addMatchEditorActions( JXToolBar toolbar )
463 {
464 toolbar.addFixed( new JButton( new SelectFromCurrentAction() ) );
465 toolbar.addRelatedGap();
466 toolbar.addFixed( new JButton( new TestPathAction() ) );
467 allowWildcardsCheckBox = new JCheckBox( "Allow Wildcards" );
468
469 Dimension dim = new Dimension( 100, 20 );
470
471 allowWildcardsCheckBox.setSize( dim );
472 allowWildcardsCheckBox.setPreferredSize( dim );
473
474 allowWildcardsCheckBox.setOpaque( false );
475 toolbar.addRelatedGap();
476 toolbar.addFixed( allowWildcardsCheckBox );
477
478 Dimension largerDim = new Dimension( 200, 20 );
479 ignoreNamespaceDifferencesCheckBox = new JCheckBox( "Ignore namespace prefixes" );
480 ignoreNamespaceDifferencesCheckBox.setSize( largerDim );
481 ignoreNamespaceDifferencesCheckBox.setPreferredSize( largerDim );
482 ignoreNamespaceDifferencesCheckBox.setOpaque( false );
483 toolbar.addRelatedGap();
484 toolbar.addFixed( ignoreNamespaceDifferencesCheckBox );
485 }
486
487 public XmlObject createConfiguration()
488 {
489 XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
490 builder.add( "path", path );
491 builder.add( "content", expectedContent );
492 builder.add( "allowWildcards", allowWildcards );
493 builder.add( "ignoreNamspaceDifferences", ignoreNamespaceDifferences );
494 return builder.finish();
495 }
496
497 public void selectFromCurrent()
498 {
499 XmlCursor cursor = null;
500
501 try
502 {
503 String assertableContent = getAssertable().getAssertableContent();
504 if( assertableContent == null || assertableContent.trim().length() == 0 )
505 {
506 UISupport.showErrorMessage( "Missing content to select from" );
507 return;
508 }
509
510 XmlObject xml = XmlObject.Factory.parse( assertableContent );
511
512 String txt = pathArea == null || !pathArea.isVisible() ? getPath() : pathArea.getSelectedText();
513 if( txt == null )
514 txt = pathArea == null ? "" : pathArea.getText();
515
516 WsdlTestRunContext context = new WsdlTestRunContext( ( TestStep )getAssertable().getModelItem() );
517
518 String expandedPath = PropertyExpander.expandProperties( context, txt.trim() );
519
520 if( contentArea != null && contentArea.isVisible() )
521 contentArea.setText( "" );
522
523 cursor = xml.newCursor();
524 cursor.selectPath( expandedPath );
525 if( !cursor.toNextSelection() )
526 {
527 UISupport.showErrorMessage( "No match in current response" );
528 }
529 else if( cursor.hasNextSelection() )
530 {
531 UISupport.showErrorMessage( "More than one match in current response" );
532 }
533 else
534 {
535 String stringValue = XmlUtils.getValueForMatch( cursor );
536
537 if( contentArea != null && contentArea.isVisible() )
538 contentArea.setText( stringValue );
539 else
540 setExpectedContent( stringValue );
541 }
542 }
543 catch( Throwable e )
544 {
545 UISupport.showErrorMessage( e.toString() );
546 SoapUI.logError( e );
547 }
548 finally
549 {
550 if( cursor != null )
551 cursor.dispose();
552 }
553 }
554
555 private final class InternalDifferenceListener implements DifferenceListener
556 {
557 private StringList nodesToRemove = new StringList();
558
559 public int differenceFound( Difference diff )
560 {
561 if( allowWildcards
562 && ( diff.getId() == DifferenceEngine.TEXT_VALUE.getId() || diff.getId() == DifferenceEngine.ATTR_VALUE
563 .getId() ) )
564 {
565 if( diff.getControlNodeDetail().getValue().equals( "*" ) )
566 {
567 Node node = diff.getTestNodeDetail().getNode();
568 String xp = XmlUtils.createAbsoluteXPath( node.getNodeType() == Node.ATTRIBUTE_NODE ? node : node
569 .getParentNode() );
570 nodesToRemove.add( xp );
571 return Diff.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
572 }
573 }
574 else if( ignoreNamespaceDifferences && diff.getId() == DifferenceEngine.NAMESPACE_PREFIX_ID )
575 {
576 return Diff.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
577 }
578
579 return Diff.RETURN_ACCEPT_DIFFERENCE;
580 }
581
582 public void skippedComparison( Node arg0, Node arg1 )
583 {
584
585 }
586
587 public StringList getNodesToRemove()
588 {
589 return nodesToRemove;
590 }
591 }
592
593 public class OkAction extends AbstractAction
594 {
595 public OkAction()
596 {
597 super( "Save" );
598 }
599
600 public void actionPerformed( ActionEvent arg0 )
601 {
602 setPath( pathArea.getText().trim() );
603 setExpectedContent( contentArea.getText() );
604 setAllowWildcards( allowWildcardsCheckBox.isSelected() );
605 setIgnoreNamespaceDifferences( ignoreNamespaceDifferencesCheckBox.isSelected() );
606 setConfiguration( createConfiguration() );
607 configureResult = true;
608 configurationDialog.setVisible( false );
609 }
610 }
611
612 public class CancelAction extends AbstractAction
613 {
614 public CancelAction()
615 {
616 super( "Cancel" );
617 }
618
619 public void actionPerformed( ActionEvent arg0 )
620 {
621 configureResult = false;
622 configurationDialog.setVisible( false );
623 }
624 }
625
626 public class DeclareNamespacesFromCurrentAction extends AbstractAction
627 {
628 public DeclareNamespacesFromCurrentAction()
629 {
630 super( "Declare" );
631 putValue( Action.SHORT_DESCRIPTION, "Add namespace declaration from current message to XPath expression" );
632 }
633
634 public void actionPerformed( ActionEvent arg0 )
635 {
636 try
637 {
638 String content = getAssertable().getAssertableContent();
639 if( content != null && content.trim().length() > 0 )
640 {
641 pathArea.setText( XmlUtils.declareXPathNamespaces( content ) + pathArea.getText() );
642 }
643 else if( UISupport.confirm( "Declare namespaces from schema instead?", "Missing Response" ) )
644 {
645 pathArea.setText( XmlUtils.declareXPathNamespaces( ( WsdlInterface )getAssertable().getInterface() )
646 + pathArea.getText() );
647 }
648 }
649 catch( Exception e )
650 {
651 log.error( e.getMessage() );
652 }
653 }
654 }
655
656 public class TestPathAction extends AbstractAction
657 {
658 public TestPathAction()
659 {
660 super( "Test" );
661 putValue( Action.SHORT_DESCRIPTION,
662 "Tests the XPath expression for the current message against the Expected Content field" );
663 }
664
665 public void actionPerformed( ActionEvent arg0 )
666 {
667 String oldPath = getPath();
668 String oldContent = getExpectedContent();
669 boolean oldAllowWildcards = isAllowWildcards();
670
671 setPath( pathArea.getText().trim() );
672 setExpectedContent( contentArea.getText() );
673 setAllowWildcards( allowWildcardsCheckBox.isSelected() );
674 setIgnoreNamespaceDifferences( ignoreNamespaceDifferencesCheckBox.isSelected() );
675
676 try
677 {
678 String msg = assertContent( getAssertable().getAssertableContent(), new WsdlTestRunContext(
679 ( TestStep )getAssertable().getModelItem() ), "Response" );
680 UISupport.showInfoMessage( msg, "Success" );
681 }
682 catch( AssertionException e )
683 {
684 UISupport.showErrorMessage( e.getMessage() );
685 }
686
687 setPath( oldPath );
688 setExpectedContent( oldContent );
689 setAllowWildcards( oldAllowWildcards );
690 }
691 }
692
693 public class SelectFromCurrentAction extends AbstractAction
694 {
695 public SelectFromCurrentAction()
696 {
697 super( "Select from current" );
698 putValue( Action.SHORT_DESCRIPTION,
699 "Selects the XPath expression from the current message into the Expected Content field" );
700 }
701
702 public void actionPerformed( ActionEvent arg0 )
703 {
704 selectFromCurrent();
705 }
706 }
707
708 @Override
709 protected String internalAssertRequest( MessageExchange messageExchange, SubmitContext context )
710 throws AssertionException
711 {
712 if( !messageExchange.hasRequest( true ) )
713 return "Missing Request";
714 else
715 return assertContent( messageExchange.getRequestContent(), context, "Request" );
716 }
717
718 public JTextArea getContentArea()
719 {
720 return contentArea;
721 }
722
723 public JTextArea getPathArea()
724 {
725 return pathArea;
726 }
727
728 @Override
729 public PropertyExpansion[] getPropertyExpansions()
730 {
731 List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
732
733 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( getAssertable().getModelItem(), this,
734 "expectedContent" ) );
735 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( getAssertable().getModelItem(), this, "path" ) );
736
737 return result.toArray( new PropertyExpansion[result.size()] );
738 }
739
740 public XPathReference[] getXPathReferences()
741 {
742 List<XPathReference> result = new ArrayList<XPathReference>();
743
744 if( StringUtils.hasContent( getPath() ) )
745 {
746 TestModelItem testStep = ( TestModelItem )getAssertable().getModelItem();
747 TestProperty property = testStep instanceof WsdlTestRequestStep ? testStep.getProperty( "Response" )
748 : testStep.getProperty( "Request" );
749 result.add( new XPathReferenceImpl( "XPath for " + getName() + " XPathContainsAssertion in "
750 + testStep.getName(), property, this, "path" ) );
751 }
752
753 return result.toArray( new XPathReference[result.size()] );
754 }
755
756 public static class Factory extends AbstractTestAssertionFactory
757 {
758 public Factory()
759 {
760 super( XPathContainsAssertion.ID, XPathContainsAssertion.LABEL, XPathContainsAssertion.class );
761 }
762
763 @Override
764 public Class<? extends WsdlMessageAssertion> getAssertionClassType()
765 {
766 return XPathContainsAssertion.class;
767 }
768 }
769 }