// Copyright � 2002-2007 Canoo Engineering AG, Switzerland.
package com.canoo.webtest.steps.request;
import java.net.SocketTimeoutException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.tools.ant.Project;
import com.agical.rmock.extension.junit.RMockTestCase;
import com.canoo.webtest.engine.Configuration;
import com.canoo.webtest.engine.Context;
import com.canoo.webtest.engine.StepExecutionException;
import com.canoo.webtest.engine.StepFailedException;
import com.canoo.webtest.interfaces.IConnectionInitializer;
import com.canoo.webtest.interfaces.IPropertyHandler;
import com.canoo.webtest.security.ConnectionInitializationException;
import com.canoo.webtest.self.BufferingAppender;
import com.canoo.webtest.self.ContextStub;
import com.canoo.webtest.self.TestBlock;
import com.canoo.webtest.self.ThrowAssert;
import com.canoo.webtest.steps.AbstractBrowserAction;
import com.canoo.webtest.steps.BaseStepTestCase;
import com.canoo.webtest.steps.StepUtil;
import com.gargoylesoftware.htmlunit.DefaultCredentialsProvider;
/**
* Tests for {@link TargetHelper}.
* @author Paul King
* @author Marc Guillemot
*/
public class TargetHelperTest extends RMockTestCase
{
private static final String OK_CUSTOM_INITIALIZER_CLASS_NAME = "com.canoo.webtest.steps.request.TargetHelperTest$NullConnectionInitializer";
private static final String BAD_CUSTOM_INITIALIZER_CLASS_NAME = "com.canoo.webtest.steps.request.TargetHelperTest$ExceptionConnectionInitializer";
private AbstractBrowserAction fBrowserAction = new AbstractBrowserAction()
{
public void doExecute() {}
};
private TargetHelper fTargetHelper = new TargetHelper(fBrowserAction);
private final Context fTestContext = createContextStupWithoutSteps();
private final BufferingAppender fBuffAppender = new BufferingAppender();
static ContextStub createContextStupWithoutSteps()
{
return new ContextStub()
{
protected void initTestStepSequence(Project project) {
// nothing, we want to skip it here
}
};
}
protected void setUp() throws Exception {
final Configuration testConfig = new Configuration();
testConfig.setShowhtmlparseroutput(false);
final IPropertyHandler handler = (IPropertyHandler) mock(IPropertyHandler.class, "handler");
testConfig.setPropertyHandler(handler);
fTestContext.getWebtest().addConfig(testConfig);
BaseStepTestCase.executeStep(fBrowserAction); // coverage
Logger.getRootLogger().setLevel(Level.INFO); // ensure that the logged event we want to catch is not discarded
Logger.getRootLogger().addAppender(fBuffAppender);
}
protected void tearDown() throws Exception {
super.tearDown();
Logger.getRootLogger().removeAppender(fBuffAppender);
}
public void testGotoTargetByUrl() throws Exception {
fTestContext.getWebtest().getConfig().getExternalProperty(TargetHelper.CONNECTION_INITIALIZER_KEY);
modify().returnValue(null);
startVerification();
fBuffAppender.getEvents().clear();
try {
fTargetHelper.getResponse(fTestContext, "targetUrl");
} catch (final Exception e) {
/* ignore */
}
assertTrue("should be called by url", fBuffAppender.allMessagesToString().indexOf("url") > -1);
}
/**
* Tests that SocketTimeoutException is catched and that a StepFailedException is rethrown
* @throws Exception
*/
public void testSocketTimeoutException() throws Exception {
final String message = ThrowAssert.assertThrows(StepFailedException.class, new TestBlock()
{
public void call() throws Exception {
final Throwable t = new SocketTimeoutException("blah SocketTimeoutException message");
StepUtil.handleException(t);
}
});
assertEquals("Server took to long to answer: blah SocketTimeoutException message", message);
}
public void testInvokeCustomInitializer() throws Exception {
ThrowAssert.assertThrows(StepExecutionException.class, new TestBlock()
{
public void call() throws Exception {
fTargetHelper.invokeCustomInitializer(fTestContext, "no.such.class");
}
});
final String message = ThrowAssert.assertThrows(StepExecutionException.class, new TestBlock()
{
public void call() throws Exception {
fTargetHelper.invokeCustomInitializer(fTestContext, BAD_CUSTOM_INITIALIZER_CLASS_NAME);
}
});
assertTrue(message.startsWith("ConnectionInitializer raised exception"));
}
public void testPrepareConversationWithProperCustomInitializer() throws Exception {
final IPropertyHandler customHandler = (IPropertyHandler) mock(IPropertyHandler.class, "customHandler");
customHandler.getProperty(TargetHelper.CONNECTION_INITIALIZER_KEY);
modify().returnValue(OK_CUSTOM_INITIALIZER_CLASS_NAME);
startVerification();
fTestContext.getConfig().setPropertyHandler(customHandler);
ThrowAssert.assertPasses("normal pass", new TestBlock()
{
public void call() throws Exception {
fTargetHelper.prepareConversationIfNeeded(fTestContext);
}
});
}
public static class ExceptionConnectionInitializer implements IConnectionInitializer
{
public void initializeConnection(final Configuration config) throws ConnectionInitializationException {
throw new ConnectionInitializationException("xxx");
}
}
public static class NullConnectionInitializer implements IConnectionInitializer
{
public void initializeConnection(final Configuration config) throws ConnectionInitializationException {
// just pass
}
}
/**
* There is a bug in HtmlUnit where addCredentials doesn't necessary overwrite old ones.
* Once this has been fixed, we can remove TargetHelper.WTCredentials.
* @throws Exception
*/
public void testDefaultCredentialsProvider() throws Exception {
final DefaultCredentialsProvider credentialsProvider = new DefaultCredentialsProvider();
credentialsProvider.addCredentials("userName", "password");
final UsernamePasswordCredentials cred = (UsernamePasswordCredentials) credentialsProvider.getCredentials(new AuthScope("myHost", 80));
assertEquals("userName", cred.getUserName());
assertEquals("password", cred.getPassword());
credentialsProvider.addCredentials("userName", "new password");
final UsernamePasswordCredentials cred2 = (UsernamePasswordCredentials) credentialsProvider.getCredentials(new AuthScope("myHost", 80));
assertEquals("userName", cred2.getUserName());
assertEquals("new password", cred2.getPassword());
}
}