1   package org.codehaus.ivory;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.net.MalformedURLException;
6   import java.util.HashMap;
7   import java.util.List;
8   import java.util.Map;
9   import org.apache.avalon.framework.service.ServiceManager;
10  import org.apache.axis.MessageContext;
11  import org.apache.axis.server.AxisServer;
12  import org.apache.axis.soap.SOAPConstants;
13  import org.apache.axis.transport.local.LocalTransport;
14  import org.codehaus.ivory.AxisService;
15  import org.codehaus.plexus.PlexusTestCase;
16  import org.dom4j.DocumentHelper;
17  import org.dom4j.Node;
18  import org.dom4j.XPath;
19  import org.dom4j.io.DOMReader;
20  import org.w3c.dom.Document;
21  import org.xml.sax.SAXException;
22  import com.meterware.httpunit.HttpException;
23  import com.meterware.httpunit.HttpUnitOptions;
24  import com.meterware.httpunit.WebConversation;
25  import com.meterware.httpunit.WebRequest;
26  import com.meterware.servletunit.ServletRunner;
27  import com.meterware.servletunit.ServletUnitClient;
28  
29  /***
30   * A generic test-case for testing Ivory and other SOAP services for Plexus.
31   * 
32   * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
33   * @since May 4, 2003
34   */
35  public class IvoryTestCase 
36      extends PlexusTestCase
37  {
38      private ServletRunner sr;
39      
40      private ServiceManager manager;
41      
42      private String services = "http://localhost/services/";
43      
44      private boolean verbose = false;
45      
46      public final static String VERBOSE_KEY = 
47      	"IvoryTestCase.verbose";
48  
49      /*** Namespaces for the XPath expressions. */
50      private Map namespaces = new HashMap();
51      
52      public IvoryTestCase(String name)
53      {
54          super(name);
55      }
56      
57      public void setUp() throws Exception
58      {
59          super.setUp();
60          setVerbose( Boolean.getBoolean( VERBOSE_KEY ) );
61      
62          HttpUnitOptions.setExceptionsThrownOnErrorStatus(true);
63          
64          InputStream is =
65              getClass().getResourceAsStream( "/org/codehaus/ivory/plexus/web.xml");
66      
67          sr = new ServletRunner(is);
68          
69          PlexusTestServlet.Plexus = getContainer();
70          sr.registerServlet("plexus", PlexusTestServlet.class.getName());
71      }
72      
73      protected ServletUnitClient newClient() throws Exception
74      {
75          return sr.newClient();
76      }
77      
78      /***
79       * @return
80       */
81      public boolean isVerbose()
82      {
83      	return verbose;
84      }
85      
86      /***
87       * @param b
88       */
89      public void setVerbose(boolean b)
90      {
91      	verbose = b;
92      }
93      
94      /***
95       * Here we expect an errorCode other than 200, and look for it
96       * checking for text is omitted as it doesnt work. It would never work on
97       * java1.3, but one may have expected java1.4+ to have access to the
98       * error stream in responses. Clearly not.
99       * @param request
100      * @param errorCode
101      * @param errorText optional text string to search for
102      * @throws MalformedURLException
103      * @throws IOException
104      * @throws SAXException
105      */
106     protected void expectErrorCode(
107         WebRequest request,
108         int errorCode,
109         String errorText)
110         throws MalformedURLException, IOException, SAXException
111     {
112         WebConversation session = new WebConversation();
113         String failureText =
114             "Expected error " + errorCode + " from " + request.getURL();
115     
116         try
117         {
118             session.getResponse(request);
119             fail(errorText + " -got success instead");
120         }
121         catch (HttpException e)
122         {
123             assertEquals(failureText, errorCode, e.getResponseCode());
124             /* checking for text omitted as it doesnt work.
125             if(errorText!=null) {
126             	assertTrue(
127             			"Failed to find "+errorText+" in "+ e.getResponseMessage(),
128             			e.getMessage().indexOf(errorText)>=0);
129             }
130             */
131         }
132     }
133     
134     public org.dom4j.Document getWSDL( String serviceName ) throws Exception
135     {
136     	AxisService service = ( AxisService ) lookup( AxisService.ROLE );
137     	AxisServer server = service.getAxisServer();
138     
139     	LocalTransport transport = new LocalTransport(server);
140     
141     	MessageContext msgContext = new MessageContext(server);
142     	msgContext.setSOAPConstants(SOAPConstants.SOAP12_CONSTANTS);
143     	msgContext.setEncodingStyle(SOAPConstants.SOAP12_CONSTANTS.getEncodingURI());
144     
145     	msgContext.setTargetService( serviceName );
146         
147     	// During a real invocation this is set by the handler, however we
148     	// need to set it hear to get the wsdl generation working.
149     	msgContext.setProperty( MessageContext.TRANS_URL, 
150     							services + serviceName );
151     	server.generateWSDL( msgContext );        
152         
153     	// another one of those undocumented "features"
154     	Document doc = (Document) msgContext.getProperty( "WSDL" );
155         
156         DOMReader xmlReader = new DOMReader();
157         return xmlReader.read(doc);
158     }
159     
160     /***
161      * Assert that the following XPath query selects one or more nodes.
162      * 
163      * @param xpath
164      * @throws Exception
165      */
166     public void assertValid( String xpath, Node node )
167         throws Exception
168     {
169         List nodes = createXPath( xpath ).selectNodes( node );
170         
171         if ( nodes.size() == 0 )
172         {
173             throw new Exception( "Failed to select any nodes for expression:.\n" +
174                                  xpath + "\n" +
175                                  node.asXML() );
176         }
177     }
178     
179     /***
180      * Assert that the following XPath query selects no nodes.
181      * 
182      * @param xpath
183      * @throws Exception
184      */
185     public void assertInvalid( String xpath, Node node )
186         throws Exception
187     {
188         List nodes = createXPath( xpath ).selectNodes( node );
189         
190         if ( nodes.size() > 0 )
191         {
192             throw new Exception( "Found multiple nodes for expression:\n" +
193                                  xpath + "\n" +
194                                  node.asXML() );
195         }
196     }
197 
198     /***
199      * Asser that the text of the xpath node retrieved is equal to the
200      * value specified.
201      * 
202      * @param xpath
203      * @param value
204      * @param node
205      * @throws Exception
206      */
207     public void assertXPathEquals( String xpath, String value, Node node )
208         throws Exception
209     {
210         Node n = createXPath( xpath ).selectSingleNode( node );
211         
212         if ( n == null )
213             fail("Couldn't select a valid node.");
214         
215         String value2 = n.getText().trim();
216         assertEquals( value, value2 );
217     }
218 
219     /***
220      * Create the specified XPath expression with the namespaces added
221      * via addNamespace().
222      */
223     protected XPath createXPath( String xpathString )
224     {
225         XPath xpath = DocumentHelper.createXPath( xpathString );
226         xpath.setNamespaceURIs(namespaces);
227         
228         return xpath;
229     }
230 
231     /***
232      * Add a namespace that will be used for XPath expressions.
233      * @param ns Namespace name.
234      * @param uri The namespace uri.
235      */
236     public void addNamespace( String ns, String uri )
237     {
238         namespaces.put(ns, uri);
239     }
240 }