1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.config.*;
17 import com.eviware.soapui.impl.wsdl.*;
18 import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
19 import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
20 import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
21 import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner;
22 import com.eviware.soapui.impl.wsdl.mock.dispatch.QueryMatchMockOperationDispatcher;
23 import com.eviware.soapui.impl.wsdl.panels.mockoperation.WsdlMockResultMessageExchange;
24 import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
25 import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
26 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
27 import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
28 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
29 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
30 import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry;
31 import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
32 import com.eviware.soapui.model.ModelItem;
33 import com.eviware.soapui.model.iface.Interface;
34 import com.eviware.soapui.model.iface.Operation;
35 import com.eviware.soapui.model.iface.SubmitContext;
36 import com.eviware.soapui.model.mock.MockResult;
37 import com.eviware.soapui.model.mock.MockRunner;
38 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
39 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
40 import com.eviware.soapui.model.support.*;
41 import com.eviware.soapui.model.testsuite.*;
42 import com.eviware.soapui.model.testsuite.AssertionError;
43 import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
44 import com.eviware.soapui.support.StringUtils;
45 import com.eviware.soapui.support.resolver.ChangeOperationResolver;
46 import com.eviware.soapui.support.resolver.ImportInterfaceResolver;
47 import com.eviware.soapui.support.resolver.RemoveTestStepResolver;
48 import com.eviware.soapui.support.resolver.ResolveContext;
49 import com.eviware.soapui.support.resolver.ResolveContext.PathToResolve;
50 import com.eviware.soapui.support.types.StringToStringMap;
51 import org.apache.log4j.Logger;
52
53 import javax.swing.*;
54 import java.beans.PropertyChangeEvent;
55 import java.beans.PropertyChangeListener;
56 import java.util.*;
57
58 public class WsdlMockResponseTestStep extends WsdlTestStepWithProperties implements OperationTestStep,
59 PropertyChangeListener, Assertable
60 {
61 private final static Logger log = Logger.getLogger( WsdlMockResponseTestStep.class );
62
63 public static final String STATUS_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@status";
64 public static final String TIMEOUT_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@timeout";
65
66 private MockResponseStepConfig mockResponseStepConfig;
67 private MockResponseConfig mockResponseConfig;
68 private WsdlMockOperation mockOperation;
69 private WsdlTestMockService mockService;
70 private WsdlMockRunner mockRunner;
71 private WsdlMockResponse mockResponse;
72
73 private AssertionsSupport assertionsSupport;
74 private InternalMockRunListener mockRunListener;
75
76 private final InternalProjectListener projectListener = new InternalProjectListener();
77 private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
78 private final InternalTestRunListener testRunListener = new InternalTestRunListener();
79 private WsdlInterface iface;
80 private AssertionStatus oldStatus;
81
82 private ModelItemIconAnimator<WsdlMockResponseTestStep> iconAnimator;
83 private WsdlMockResponse testMockResponse;
84 private WsdlTestStep startTestStep;
85
86 public WsdlMockResponseTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
87 {
88 super( testCase, config, true, forLoadTest );
89
90 if( config.getConfig() != null )
91 {
92 mockResponseStepConfig = (MockResponseStepConfig) config.getConfig().changeType( MockResponseStepConfig.type );
93 mockResponseConfig = mockResponseStepConfig.getResponse();
94 }
95 else
96 {
97 mockResponseStepConfig = (MockResponseStepConfig) config.addNewConfig()
98 .changeType( MockResponseStepConfig.type );
99 mockResponseConfig = mockResponseStepConfig.addNewResponse();
100 }
101
102 initAssertions();
103 initMockObjects( testCase );
104
105 if( !forLoadTest )
106 {
107 if( iface != null )
108 {
109 iface.getProject().addProjectListener( projectListener );
110 iface.addInterfaceListener( interfaceListener );
111 }
112
113 iconAnimator = new ModelItemIconAnimator<WsdlMockResponseTestStep>( this, "/mockResponseStep.gif",
114 "/exec_mockResponse", 4, "gif" );
115 }
116
117
118 initProperties();
119
120 testCase.addTestRunListener( testRunListener );
121
122 startTestStep = testCase.getTestStepByName( getStartStep() );
123 if( startTestStep != null )
124 {
125 startTestStep.addPropertyChangeListener( this );
126 }
127
128 testCase.addPropertyChangeListener( this );
129 }
130
131 private void initProperties()
132 {
133 if( mockResponse != null )
134 {
135 addProperty( new TestStepBeanProperty( "Response", false, mockResponse, "responseContent", this ) );
136 }
137
138 addProperty( new DefaultTestStepProperty( "Request", true, new DefaultTestStepProperty.PropertyHandlerAdapter()
139 {
140 public String getValue( DefaultTestStepProperty property )
141 {
142 WsdlMockResult mockResult = mockResponse == null ? null : mockResponse.getMockResult();
143 return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
144 }
145 }, this ) );
146 }
147
148 @Override
149 public ImageIcon getIcon()
150 {
151 return iconAnimator == null ? null : iconAnimator.getIcon();
152 }
153
154 private void initAssertions()
155 {
156 assertionsSupport = new AssertionsSupport( this, new AssertableConfig()
157 {
158
159 public TestAssertionConfig addNewAssertion()
160 {
161 return mockResponseStepConfig.addNewAssertion();
162 }
163
164 public List<TestAssertionConfig> getAssertionList()
165 {
166 return mockResponseStepConfig.getAssertionList();
167 }
168
169 public void removeAssertion( int ix )
170 {
171 mockResponseStepConfig.removeAssertion( ix );
172 }
173 } );
174 }
175
176 private void initMockObjects( WsdlTestCase testCase )
177 {
178 MockServiceConfig mockServiceConfig = MockServiceConfig.Factory.newInstance();
179 mockServiceConfig.setPath( mockResponseStepConfig.getPath() );
180 mockServiceConfig.setPort( mockResponseStepConfig.getPort() );
181
182 mockService = new WsdlTestMockService( this, mockServiceConfig );
183 mockService.setName( getName() );
184
185 iface = (WsdlInterface) testCase.getTestSuite().getProject().getInterfaceByName(
186 mockResponseStepConfig.getInterface() );
187 if( iface == null )
188 {
189 }
190 else
191 {
192 iface.addInterfaceListener( interfaceListener );
193
194 mockOperation = mockService.addNewMockOperation( iface
195 .getOperationByName( mockResponseStepConfig.getOperation() ) );
196
197 if( mockResponseStepConfig.getHandleFault() )
198 mockService.setFaultMockOperation( mockOperation );
199
200 if( mockResponseStepConfig.getHandleResponse() )
201 mockService.setDispatchResponseMessages( true );
202
203 mockResponse = mockOperation.addNewMockResponse( "MockResponse", false );
204 mockResponse.setConfig( mockResponseConfig );
205
206 mockOperation.setDefaultResponse( mockResponse.getName() );
207
208 mockResponse.addPropertyChangeListener( this );
209 }
210 }
211
212 public void resetConfigOnMove( TestStepConfig config )
213 {
214 super.resetConfigOnMove( config );
215
216 mockResponseStepConfig = (MockResponseStepConfig) config.getConfig().changeType( MockResponseStepConfig.type );
217 mockResponseConfig = mockResponseStepConfig.getResponse();
218 mockResponse.setConfig( mockResponseConfig );
219 assertionsSupport.refresh();
220 }
221
222 @Override
223 public boolean cancel()
224 {
225 if( mockRunner != null )
226 {
227 mockRunner.stop();
228 mockRunner = null;
229 }
230
231 if( mockRunListener != null )
232 mockRunListener.cancel();
233
234 return true;
235 }
236
237 @Override
238 public void prepare( TestRunner testRunner, TestRunContext testRunContext ) throws Exception
239 {
240 super.prepare( testRunner, testRunContext );
241
242 LoadTestRunner loadTestRunner = (LoadTestRunner) testRunContext.getProperty( TestRunContext.LOAD_TEST_RUNNER );
243 mockRunListener = new InternalMockRunListener();
244
245 if( loadTestRunner == null )
246 {
247 mockService.addMockRunListener( mockRunListener );
248 mockRunner = mockService.start( (WsdlTestRunContext) testRunContext );
249 }
250 else
251 {
252 synchronized( STATUS_PROPERTY )
253 {
254 mockRunner = (WsdlMockRunner) testRunContext.getProperty( "sharedMockServiceRunner" );
255 if( mockRunner == null )
256 {
257 mockService.addMockRunListener( mockRunListener );
258 mockRunner = mockService.start( (WsdlTestRunContext) testRunContext );
259 }
260 else
261 {
262 mockRunner.getMockService().addMockRunListener( mockRunListener );
263 }
264 }
265 }
266 }
267
268 protected void initTestMockResponse( TestRunContext testRunContext )
269 {
270 if( StringUtils.hasContent( getQuery() ) && StringUtils.hasContent( getMatch() ) )
271 {
272 testMockResponse = mockOperation.addNewMockResponse( "MockResponse" + Math.random(), false );
273 testMockResponse.setConfig( mockResponse.getConfig() );
274
275 QueryMatchMockOperationDispatcher dispatcher = (QueryMatchMockOperationDispatcher) mockOperation.setDispatchStyle( MockOperationDispatchStyleConfig.QUERY_MATCH.toString() );
276 QueryMatchMockOperationDispatcher.Query query = dispatcher.addQuery( "Match" );
277 query.setQuery( PropertyExpansionUtils.expandProperties( testRunContext, getQuery() ) );
278 query.setMatch( PropertyExpansionUtils.expandProperties( testRunContext, getMatch() ) );
279 query.setResponse( testMockResponse.getName() );
280 }
281 else
282 {
283 testMockResponse = mockResponse;
284 }
285 }
286
287 public TestStepResult run( TestRunner testRunner, TestRunContext context )
288 {
289 LoadTestRunner loadTestRunner = (LoadTestRunner) context.getProperty( TestRunContext.LOAD_TEST_RUNNER );
290 if( loadTestRunner == null )
291 {
292 return internalRun( (WsdlTestRunContext) context );
293 }
294 else
295 {
296
297 synchronized( STATUS_PROPERTY )
298 {
299 if( loadTestRunner.getStatus() == LoadTestRunner.Status.RUNNING )
300 {
301 return internalRun( (WsdlTestRunContext) context );
302 }
303 else
304 {
305 WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult( this );
306 result.setStatus( TestStepStatus.UNKNOWN );
307 return result;
308 }
309 }
310 }
311 }
312
313 private TestStepResult internalRun( WsdlTestRunContext context )
314 {
315 iconAnimator.start();
316 WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult( this );
317
318 try
319 {
320 if( !mockRunListener.hasResult() )
321 {
322 if( testMockResponse == null )
323 initTestMockResponse( context );
324
325 result.startTimer();
326
327 long timeout = getTimeout();
328 synchronized( mockRunListener )
329 {
330 mockRunListener.waitForRequest( timeout );
331 }
332 }
333
334 result.stopTimer();
335
336 AssertedWsdlMockResultMessageExchange messageExchange = new AssertedWsdlMockResultMessageExchange( mockRunListener
337 .getResult() );
338 result.setMessageExchange( messageExchange );
339
340 if( mockRunListener.getResult() != null )
341 {
342 context.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, messageExchange );
343 assertResult( mockRunListener.getResult(), context );
344 }
345
346 if( mockRunListener.getResult() == null )
347 {
348 if( mockRunListener.isCanceled() )
349 {
350 result.setStatus( TestStepStatus.CANCELED );
351 }
352 else
353 {
354 result.setStatus( TestStepStatus.FAILED );
355 result.addMessage( "Timeout occured after " + getTimeout() + " milliseconds" );
356 }
357 }
358 else
359 {
360 AssertionStatus status = getAssertionStatus();
361 if( status == AssertionStatus.FAILED )
362 {
363 result.setStatus( TestStepStatus.FAILED );
364
365 if( getAssertionCount() == 0 )
366 {
367 result.addMessage( "Invalid/empty request" );
368 }
369 else
370 for( int c = 0; c < getAssertionCount(); c++ )
371 {
372 AssertionError[] errors = getAssertionAt( c ).getErrors();
373 if( errors != null )
374 {
375 for( AssertionError error : errors )
376 {
377 result.addMessage( error.getMessage() );
378 }
379 }
380 }
381 }
382 else
383 {
384 result.setStatus( TestStepStatus.OK );
385 }
386
387 mockRunListener.setResult( null );
388 }
389 }
390 catch( Exception e )
391 {
392 result.stopTimer();
393 result.setStatus( TestStepStatus.FAILED );
394 result.setError( e );
395 SoapUI.logError( e );
396 }
397 finally
398 {
399 iconAnimator.stop();
400 }
401
402 return result;
403 }
404
405 private void assertResult( WsdlMockResult result, SubmitContext context )
406 {
407 if( oldStatus == null )
408 oldStatus = getAssertionStatus();
409
410 for( int c = 0; c < getAssertionCount(); c++ )
411 {
412 WsdlMessageAssertion assertion = getAssertionAt( c );
413 if( !assertion.isDisabled() )
414 {
415 assertion.assertRequest( new WsdlMockResultMessageExchange( result, getMockResponse() ), context );
416 }
417 }
418
419 AssertionStatus newStatus = getAssertionStatus();
420 if( newStatus != oldStatus )
421 {
422 notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
423 oldStatus = newStatus;
424 }
425 }
426
427 @Override
428 public void finish( TestRunner testRunner, TestRunContext testRunContext )
429 {
430 if( mockRunListener != null )
431 {
432 mockService.removeMockRunListener( mockRunListener );
433 mockRunListener = null;
434 }
435
436 if( testMockResponse != null )
437 {
438 if( testMockResponse != mockResponse )
439 {
440 mockOperation.removeMockResponse( testMockResponse );
441 }
442
443 testMockResponse = null;
444 }
445
446 if( mockRunner != null )
447 {
448 if( mockRunner.isRunning() )
449 {
450 mockRunner.stop();
451 }
452
453 mockRunner = null;
454 }
455 }
456
457 public class InternalMockRunListener extends MockRunListenerAdapter
458 {
459 private WsdlMockResult result;
460 private boolean canceled;
461 private boolean waiting;
462
463 public void onMockResult( MockResult result )
464 {
465
466 if( this.result == null && waiting && result.getMockResponse() == testMockResponse )
467 {
468
469 this.setResult( (WsdlMockResult) result );
470
471
472 mockRunner.stop();
473
474 if( waiting )
475 {
476 synchronized( this )
477 {
478 notifyAll();
479 }
480 }
481 }
482 }
483
484 public void cancel()
485 {
486 canceled = true;
487
488 }
489
490 private void setResult( WsdlMockResult result )
491 {
492 this.result = result;
493 }
494
495 public WsdlMockResult getResult()
496 {
497 return result;
498 }
499
500 public boolean isCanceled()
501 {
502 return canceled;
503 }
504
505 public boolean hasResult()
506 {
507 return result != null;
508 }
509
510 public boolean isWaiting()
511 {
512 return waiting;
513 }
514
515 public void setWaiting( boolean waiting )
516 {
517 this.waiting = waiting;
518 }
519
520 public void waitForRequest( long timeout ) throws InterruptedException
521 {
522 waiting = true;
523 wait( timeout );
524 }
525
526 @Override
527 public void onMockRunnerStart( MockRunner mockRunner )
528 {
529 waiting = false;
530 result = null;
531 canceled = false;
532 }
533 }
534
535 public WsdlMockResponse getMockResponse()
536 {
537 return mockResponse;
538 }
539
540 public void setPort( int port )
541 {
542 int old = getPort();
543 mockService.setPort( port );
544 mockResponseStepConfig.setPort( port );
545 notifyPropertyChanged( "port", old, port );
546 }
547
548 public String getPath()
549 {
550 return mockResponseStepConfig.getPath();
551 }
552
553 public long getContentLength()
554 {
555 return mockResponse == null ? 0 : mockResponse.getContentLength();
556 }
557
558 public int getPort()
559 {
560 return mockResponseStepConfig.getPort();
561 }
562
563 public String getEncoding()
564 {
565 return mockResponse.getEncoding();
566 }
567
568 public void setEncoding( String encoding )
569 {
570 String old = getEncoding();
571 mockResponse.setEncoding( encoding );
572 notifyPropertyChanged( "encoding", old, encoding );
573 }
574
575 public boolean isMtomEnabled()
576 {
577 return mockResponse.isMtomEnabled();
578 }
579
580 public void setMtomEnabled( boolean enabled )
581 {
582 if( isMtomEnabled() == enabled )
583 return;
584 mockResponse.setMtomEnabled( enabled );
585
586 notifyPropertyChanged( "mtomEnabled", !enabled, enabled );
587 }
588
589 public String getOutgoingWss()
590 {
591 return mockResponse.getOutgoingWss();
592 }
593
594 public void setOutgoingWss( String outgoingWss )
595 {
596 String old = getOutgoingWss();
597 mockResponse.setOutgoingWss( outgoingWss );
598 notifyPropertyChanged( "outgoingWss", old, outgoingWss );
599 }
600
601 public void setQuery( String s )
602 {
603 String old = getQuery();
604 mockResponseStepConfig.setQuery( s );
605 notifyPropertyChanged( "query", old, s );
606 }
607
608 public String getQuery()
609 {
610 return mockResponseStepConfig.getQuery();
611 }
612
613 public String getMatch()
614 {
615 return mockResponseStepConfig.getMatch();
616 }
617
618 public void setMatch( String s )
619 {
620 String old = getMatch();
621 mockResponseStepConfig.setMatch( s );
622 notifyPropertyChanged( "match", old, s );
623 }
624
625 public boolean isForceMtom()
626 {
627 return mockResponse.isForceMtom();
628 }
629
630 public void setForceMtom( boolean forceMtom )
631 {
632 mockResponse.setForceMtom( forceMtom );
633 }
634
635 public boolean isInlineFilesEnabled()
636 {
637 return mockResponse.isInlineFilesEnabled();
638 }
639
640 public void setInlineFilesEnabled( boolean inlineFilesEnabled )
641 {
642 mockResponse.setInlineFilesEnabled( inlineFilesEnabled );
643 }
644
645 public String getStartStep()
646 {
647 return startTestStep == null ? "" : startTestStep.getName();
648 }
649
650 public void setStartStep( String startStep )
651 {
652 String old = getStartStep();
653 if( startTestStep != null )
654 {
655 startTestStep.removePropertyChangeListener( this );
656 startTestStep = null;
657 }
658
659 if( startStep != null )
660 {
661 startTestStep = getTestCase().getTestStepByName( startStep );
662 if( startTestStep != null )
663 {
664 startTestStep.addPropertyChangeListener( this );
665 }
666 }
667
668 mockResponseStepConfig.setStartStep( startStep );
669 notifyPropertyChanged( "startStep", old, startStep );
670 }
671
672 public boolean isMultipartEnabled()
673 {
674 return mockResponse.isMultipartEnabled();
675 }
676
677 public void setMultipartEnabled( boolean enabled )
678 {
679 mockResponse.setMultipartEnabled( enabled );
680 }
681
682 public boolean isHandleFault()
683 {
684 return mockResponseStepConfig.getHandleFault();
685 }
686
687 public void setHandleFault( boolean handleFault )
688 {
689 mockResponseStepConfig.setHandleFault( handleFault );
690 if( mockService != null )
691 mockService.setFaultMockOperation( handleFault ? mockOperation : null );
692 }
693
694 public boolean isHandleResponse()
695 {
696 return mockResponseStepConfig.getHandleResponse();
697 }
698
699 public void setHandleResponse( boolean handleResponse )
700 {
701 mockResponseStepConfig.setHandleResponse( handleResponse );
702 if( mockService != null )
703 mockService.setDispatchResponseMessages( handleResponse );
704 }
705
706 public long getResponseDelay()
707 {
708 return mockResponse.getResponseDelay();
709 }
710
711 public void setResponseDelay( long delay )
712 {
713 mockResponse.setResponseDelay( delay );
714 }
715
716 public String getResponseHttpStatus()
717 {
718 return mockResponse.getResponseHttpStatus();
719 }
720
721 public void setResponseHttpStatus( String httpStatus )
722 {
723 mockResponse.setResponseHttpStatus( httpStatus );
724 }
725
726 public boolean isEncodeAttachments()
727 {
728 return mockResponse.isEncodeAttachments();
729 }
730
731 public boolean isRemoveEmptyContent()
732 {
733 return mockResponse.isRemoveEmptyContent();
734 }
735
736 public boolean isStripWhitespaces()
737 {
738 return mockResponse.isStripWhitespaces();
739 }
740
741 public void setEncodeAttachments( boolean encodeAttachments )
742 {
743 mockResponse.setEncodeAttachments( encodeAttachments );
744 }
745
746 public void setRemoveEmptyContent( boolean removeEmptyContent )
747 {
748 mockResponse.setRemoveEmptyContent( removeEmptyContent );
749 }
750
751 public void setStripWhitespaces( boolean stripWhitespaces )
752 {
753 mockResponse.setStripWhitespaces( stripWhitespaces );
754 }
755
756 public void setPath( String path )
757 {
758 mockService.setPath( path );
759 mockResponseStepConfig.setPath( path );
760 }
761
762 public void propertyChange( PropertyChangeEvent evt )
763 {
764 if( evt.getSource() == mockResponse )
765 {
766 mockResponseConfig.set( mockResponse.getConfig() );
767 notifyPropertyChanged( evt.getPropertyName(), evt.getOldValue(), evt.getNewValue() );
768 }
769 else if( evt.getSource() == getTestCase() && evt.getPropertyName().equals( "testSteps" ) &&
770 evt.getNewValue() == null && evt.getOldValue() == startTestStep && startTestStep != null )
771 {
772 setStartStep( null );
773 }
774 else if( evt.getSource() == startTestStep && evt.getPropertyName().equals( WsdlTestStep.NAME_PROPERTY ))
775 {
776 mockResponseStepConfig.setStartStep( String.valueOf( evt.getNewValue() ) );
777 }
778 }
779
780 public WsdlMessageAssertion addAssertion( String assertionName )
781 {
782 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
783
784 try
785 {
786 TestAssertionConfig assertionConfig = mockResponseStepConfig.addNewAssertion();
787 assertionConfig.setType( TestAssertionRegistry.getInstance().getAssertionTypeForName( assertionName ) );
788
789 WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionConfig );
790 assertionsSupport.fireAssertionAdded( assertion );
791
792 if( getMockResponse().getMockResult() != null )
793 {
794 assertion.assertRequest( new WsdlMockResultMessageExchange( getMockResponse().getMockResult(),
795 getMockResponse() ), new WsdlSubmitContext( this ) );
796 notifier.notifyChange();
797 }
798
799 return assertion;
800 }
801 catch( Exception e )
802 {
803 SoapUI.logError( e );
804 return null;
805 }
806 }
807
808 public void addAssertionsListener( AssertionsListener listener )
809 {
810 assertionsSupport.addAssertionsListener( listener );
811 }
812
813 public WsdlMessageAssertion getAssertionAt( int c )
814 {
815 return assertionsSupport.getAssertionAt( c );
816 }
817
818 public int getAssertionCount()
819 {
820 return assertionsSupport.getAssertionCount();
821 }
822
823 public void removeAssertionsListener( AssertionsListener listener )
824 {
825 assertionsSupport.removeAssertionsListener( listener );
826 }
827
828 public AssertionStatus getAssertionStatus()
829 {
830 AssertionStatus currentStatus = AssertionStatus.UNKNOWN;
831 int cnt = getAssertionCount();
832 if( cnt == 0 )
833 return currentStatus;
834
835 if( mockResponse.getMockResult() != null )
836 {
837 if( mockResponse.getMockResult().getMockRequest() == null )
838 {
839 currentStatus = AssertionStatus.FAILED;
840 }
841 }
842 else
843 return currentStatus;
844
845 for( int c = 0; c < cnt; c++ )
846 {
847 WsdlMessageAssertion assertion = getAssertionAt( c );
848 if( assertion.isDisabled() )
849 continue;
850
851 if( assertion.getStatus() == AssertionStatus.FAILED )
852 {
853 currentStatus = AssertionStatus.FAILED;
854 break;
855 }
856 }
857
858 if( currentStatus == AssertionStatus.UNKNOWN )
859 currentStatus = AssertionStatus.VALID;
860
861 return currentStatus;
862 }
863
864 public void removeAssertion( TestAssertion assertion )
865 {
866 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
867
868 try
869 {
870 assertionsSupport.removeAssertion( (WsdlMessageAssertion) assertion );
871 }
872 finally
873 {
874 ( (WsdlMessageAssertion) assertion ).release();
875 notifier.notifyChange();
876 }
877 }
878
879 public String getAssertableContent()
880 {
881 WsdlMockResult mockResult = getMockResponse().getMockResult();
882 return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
883 }
884
885 public TestStep getTestStep()
886 {
887 return this;
888 }
889
890 @Override
891 public void setName( String name )
892 {
893 super.setName( name );
894 if( mockService != null )
895 mockService.setName( getName() );
896 }
897
898 public WsdlInterface getInterface()
899 {
900 return getOperation().getInterface();
901 }
902
903 public WsdlOperation getOperation()
904 {
905 return getMockResponse().getMockOperation().getOperation();
906 }
907
908 public void setInterface( String string )
909 {
910 WsdlInterface iface = (WsdlInterface) getTestCase().getTestSuite().getProject().getInterfaceByName( string );
911 if( iface != null )
912 {
913 mockResponseStepConfig.setInterface( iface.getName() );
914 WsdlOperation operation = iface.getOperationAt( 0 );
915 mockResponseStepConfig.setOperation( operation.getName() );
916 mockOperation.setOperation( operation );
917 }
918 }
919
920 public void setOperation( String string )
921 {
922 WsdlOperation operation = getInterface().getOperationByName( string );
923 if( operation != null )
924 {
925 mockResponseStepConfig.setOperation( string );
926 mockOperation.setOperation( operation );
927 }
928 }
929
930 private class PropertyChangeNotifier
931 {
932 private AssertionStatus oldStatus;
933 private ImageIcon oldIcon;
934
935 public PropertyChangeNotifier()
936 {
937 oldStatus = getAssertionStatus();
938 oldIcon = getIcon();
939 }
940
941 public void notifyChange()
942 {
943 AssertionStatus newStatus = getAssertionStatus();
944 ImageIcon newIcon = getIcon();
945
946 if( oldStatus != newStatus )
947 notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
948
949 if( oldIcon != newIcon )
950 notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
951 }
952 }
953
954 @Override
955 public void release()
956 {
957 super.release();
958 assertionsSupport.release();
959
960 if( mockResponse != null )
961 mockResponse.removePropertyChangeListener( this );
962
963 if( mockService != null )
964 mockService.release();
965
966 if( iface != null )
967 {
968 iface.getProject().removeProjectListener( projectListener );
969 iface.removeInterfaceListener( interfaceListener );
970 }
971
972 getTestCase().removeTestRunListener( testRunListener );
973 getTestCase().removePropertyChangeListener( this );
974 }
975
976 public AssertableType getAssertableType()
977 {
978 return AssertableType.REQUEST;
979 }
980
981 @Override
982 public Collection<WsdlInterface> getRequiredInterfaces()
983 {
984 ArrayList<WsdlInterface> result = new ArrayList<WsdlInterface>();
985 result.add( getInterface() );
986 return result;
987 }
988
989 public String getDefaultSourcePropertyName()
990 {
991 return "Response";
992 }
993
994 public String getDefaultTargetPropertyName()
995 {
996 return "Request";
997 }
998
999 @Override
1000 public void beforeSave()
1001 {
1002 super.beforeSave();
1003
1004 if( mockResponse != null )
1005 {
1006 mockResponse.beforeSave();
1007 mockResponseConfig.set( mockResponse.getConfig() );
1008 }
1009 }
1010
1011 public long getTimeout()
1012 {
1013 return mockResponseStepConfig.getTimeout();
1014 }
1015
1016 public void setTimeout( long timeout )
1017 {
1018 long old = getTimeout();
1019 mockResponseStepConfig.setTimeout( timeout );
1020 notifyPropertyChanged( TIMEOUT_PROPERTY, old, timeout );
1021 }
1022
1023 @Override
1024 public boolean dependsOn( AbstractWsdlModelItem<?> modelItem )
1025 {
1026 return modelItem == getOperation().getInterface();
1027 }
1028
1029 public class InternalProjectListener extends ProjectListenerAdapter
1030 {
1031 public void interfaceRemoved( Interface iface )
1032 {
1033 if( getOperation() != null && getOperation().getInterface().equals( iface ) )
1034 {
1035 log.debug( "Removing test step due to removed interface" );
1036 ( getTestCase() ).removeTestStep( WsdlMockResponseTestStep.this );
1037 }
1038 }
1039 }
1040
1041 public class InternalInterfaceListener extends InterfaceListenerAdapter
1042 {
1043 public void operationRemoved( Operation operation )
1044 {
1045 if( operation == getOperation() )
1046 {
1047 log.debug( "Removing test step due to removed operation" );
1048 ( getTestCase() ).removeTestStep( WsdlMockResponseTestStep.this );
1049 }
1050 }
1051
1052 @Override
1053 public void operationUpdated( Operation operation )
1054 {
1055 if( operation == getOperation() )
1056 {
1057 setOperation( operation.getName() );
1058 }
1059 }
1060 }
1061
1062 public WsdlMessageAssertion cloneAssertion( TestAssertion source, String name )
1063 {
1064 TestAssertionConfig conf = mockResponseStepConfig.addNewAssertion();
1065 conf.set( ( (WsdlMessageAssertion) source ).getConfig() );
1066 conf.setName( name );
1067
1068 WsdlMessageAssertion result = assertionsSupport.addWsdlAssertion( conf );
1069 assertionsSupport.fireAssertionAdded( result );
1070 return result;
1071 }
1072
1073 public List<TestAssertion> getAssertionList()
1074 {
1075 return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
1076 }
1077
1078 @Override
1079 public List<? extends ModelItem> getChildren()
1080 {
1081 return assertionsSupport.getAssertionList();
1082 }
1083
1084 public PropertyExpansion[] getPropertyExpansions()
1085 {
1086 List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
1087
1088 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, mockResponse, "responseContent" ) );
1089
1090 StringToStringMap responseHeaders = mockResponse.getResponseHeaders();
1091 for( String key : responseHeaders.keySet() )
1092 {
1093 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, new ResponseHeaderHolder( responseHeaders,
1094 key ), "value" ) );
1095 }
1096
1097 return result.toArray( new PropertyExpansion[result.size()] );
1098 }
1099
1100 public class ResponseHeaderHolder
1101 {
1102 private final StringToStringMap valueMap;
1103 private final String key;
1104
1105 public ResponseHeaderHolder( StringToStringMap valueMap, String key )
1106 {
1107 this.valueMap = valueMap;
1108 this.key = key;
1109 }
1110
1111 public String getValue()
1112 {
1113 return valueMap.get( key );
1114 }
1115
1116 public void setValue( String value )
1117 {
1118 valueMap.put( key, value );
1119 mockResponse.setResponseHeaders( valueMap );
1120 }
1121 }
1122
1123 public WsdlMessageAssertion getAssertionByName( String name )
1124 {
1125 return assertionsSupport.getAssertionByName( name );
1126 }
1127
1128 public Map<String, TestAssertion> getAssertions()
1129 {
1130 Map<String, TestAssertion> result = new HashMap<String, TestAssertion>();
1131
1132 for( TestAssertion assertion : getAssertionList() )
1133 result.put( assertion.getName(), assertion );
1134
1135 return result;
1136 }
1137
1138 private class AssertedWsdlMockResultMessageExchange extends WsdlMockResultMessageExchange implements
1139 RequestAssertedMessageExchange, AssertedXPathsContainer
1140 {
1141 private List<AssertedXPath> assertedXPaths;
1142
1143 public AssertedWsdlMockResultMessageExchange( WsdlMockResult mockResult )
1144 {
1145 super( mockResult, mockResult == null ? null : mockResult.getMockResponse() );
1146 }
1147
1148 public AssertedXPath[] getAssertedXPathsForRequest()
1149 {
1150 return assertedXPaths == null ? new AssertedXPath[0] : assertedXPaths.toArray( new AssertedXPath[assertedXPaths
1151 .size()] );
1152 }
1153
1154 public void addAssertedXPath( AssertedXPath assertedXPath )
1155 {
1156 if( assertedXPaths == null )
1157 assertedXPaths = new ArrayList<AssertedXPath>();
1158
1159 assertedXPaths.add( assertedXPath );
1160 }
1161 }
1162
1163 public String getDefaultAssertableContent()
1164 {
1165 return getOperation().createRequest( true );
1166 }
1167
1168 @SuppressWarnings( "unchecked" )
1169 @Override
1170 public void resolve( ResolveContext context )
1171 {
1172 super.resolve( context );
1173
1174 if( mockOperation == null )
1175 {
1176 if( context.hasThisModelItem( this, "Missing Operation in Project", mockResponseStepConfig.getInterface() + "/"
1177 + mockResponseStepConfig.getOperation() ) )
1178 return;
1179 context.addPathToResolve( this, "Missing Operation in Project",
1180 mockResponseStepConfig.getInterface() + "/" + mockResponseStepConfig.getOperation() ).addResolvers(
1181 new RemoveTestStepResolver( this ), new ImportInterfaceResolver( this )
1182 {
1183
1184 @Override
1185 protected boolean update()
1186 {
1187 initMockObjects( getTestCase() );
1188 initProperties();
1189 setDisabled( false );
1190 return true;
1191 }
1192 }, new ChangeOperationResolver( this, "Operation" )
1193 {
1194
1195 @Override
1196 public boolean update()
1197 {
1198 WsdlOperation operation = (WsdlOperation) getSelectedOperation();
1199 setInterface( operation.getInterface().getName() );
1200 setOperation( operation.getName() );
1201 initMockObjects( getTestCase() );
1202 initProperties();
1203 setDisabled( false );
1204 return true;
1205 }
1206
1207 protected Interface[] getInterfaces( WsdlProject project )
1208 {
1209 List<WsdlInterface> interfaces = ModelSupport.getChildren( project, WsdlInterface.class );
1210 return interfaces.toArray( new Interface[interfaces.size()] );
1211
1212 }
1213
1214 } );
1215 }
1216 else
1217 {
1218 mockOperation.resolve( context );
1219 if( context.hasThisModelItem( this, "Missing Operation in Project", mockResponseStepConfig.getInterface() + "/"
1220 + mockResponseStepConfig.getOperation() ) )
1221 {
1222 PathToResolve path = context.getPath( this, "Missing Operation in Project", mockResponseStepConfig.getInterface() + "/"
1223 + mockResponseStepConfig.getOperation() );
1224 path.setSolved( true );
1225 }
1226 }
1227 }
1228
1229 private class InternalTestRunListener extends TestRunListenerAdapter
1230 {
1231 @Override
1232 public void beforeStep( TestRunner testRunner, TestRunContext runContext )
1233 {
1234 if( runContext.getCurrentStep() == startTestStep && testMockResponse == null )
1235 {
1236 initTestMockResponse( runContext );
1237 mockRunListener.setWaiting( true );
1238 }
1239 }
1240 }
1241
1242 }