/*******************************************************************************
* Copyright (c) 2010-2013 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.ws.ui.bot.test.rest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hamcrest.core.Is;
import org.hamcrest.core.StringContains;
import org.hamcrest.core.StringStartsWith;
import org.jboss.ide.eclipse.as.reddeer.server.requirement.ServerRequirement.JBossServer;
import org.jboss.reddeer.common.condition.AbstractWaitCondition;
import org.jboss.reddeer.common.exception.WaitTimeoutExpiredException;
import org.jboss.reddeer.common.matcher.RegexMatcher;
import org.jboss.reddeer.common.wait.AbstractWait;
import org.jboss.reddeer.common.wait.TimePeriod;
import org.jboss.reddeer.common.wait.WaitUntil;
import org.jboss.reddeer.common.wait.WaitWhile;
import org.jboss.reddeer.core.condition.JobIsRunning;
import org.jboss.reddeer.core.condition.ShellWithTextIsAvailable;
import org.jboss.reddeer.core.matcher.WithTextMatchers;
import org.jboss.reddeer.eclipse.condition.ExactNumberOfProblemsExists;
import org.jboss.reddeer.eclipse.condition.ProblemExists;
import org.jboss.reddeer.eclipse.core.resources.Project;
import org.jboss.reddeer.eclipse.jdt.ui.ProjectExplorer;
import org.jboss.reddeer.eclipse.ui.perspectives.JavaEEPerspective;
import org.jboss.reddeer.eclipse.ui.problems.ProblemsView.ProblemType;
import org.jboss.reddeer.eclipse.ui.problems.matcher.AbstractProblemMatcher;
import org.jboss.reddeer.eclipse.ui.problems.matcher.ProblemsDescriptionMatcher;
import org.jboss.reddeer.eclipse.ui.problems.matcher.ProblemsPathMatcher;
import org.jboss.reddeer.eclipse.ui.problems.matcher.ProblemsTypeMatcher;
import org.jboss.reddeer.requirements.openperspective.OpenPerspectiveRequirement.OpenPerspective;
import org.jboss.reddeer.requirements.server.ServerReqState;
import org.jboss.reddeer.swt.api.Menu;
import org.jboss.reddeer.swt.impl.menu.ContextMenu;
import org.jboss.reddeer.workbench.impl.editor.TextEditor;
import org.jboss.tools.ws.reddeer.editor.ExtendedTextEditor;
import org.jboss.tools.ws.reddeer.jaxrs.core.RESTfulWebService;
import org.jboss.tools.ws.reddeer.jaxrs.core.RESTfulWebServicesNode;
import org.jboss.tools.ws.reddeer.ui.tester.views.WsTesterView;
import org.jboss.tools.ws.ui.bot.test.WSTestBase;
import org.jboss.tools.ws.ui.bot.test.uiutils.RunOnServerDialog;
import org.jboss.tools.ws.ui.bot.test.utils.ResourceHelper;
import org.junit.Assert;
/**
* Test base for bot tests using RESTFul support
*
* @author jjankovi
*
*/
@JBossServer(state=ServerReqState.STOPPED, cleanup=false)
@OpenPerspective(JavaEEPerspective.class)
public class RESTfulTestBase extends WSTestBase {
public static final String PATH_PARAM_VALID_ERROR = "@PathParam value";
public static final String JAX_RS_PROBLEM = "JAX-RS Problem";
protected final static RESTfulHelper restfulHelper = new RESTfulHelper();
protected RESTfulWebServicesNode restWebServicesNode = null;
protected final String SIMPLE_REST_WS_RESOURCE = "SimpleRestWS.java.ws";
private final TimePeriod WAIT_FOR_PROBLEMS_FALSE_POSItIVE_TIMEOUT = TimePeriod.getCustom(2);
private final TimePeriod WAIT_FOR_PROBLEMS_FALSE_NEGATIVE_TIMEOUT = TimePeriod.getCustom(5);
protected String getWsPackage() {
return "org.rest.test";
}
protected String getWsName() {
return "RestService";
}
@Override
public void setup() {
if (!projectExists(getWsProjectName())) {
importWSTestProject(getWsProjectName());
}
}
@Override
public void cleanup() {
deleteAllProjects();
}
protected void importAndCheckErrors(String projectName) {
importWSTestProject(projectName);
assertCountOfValidationProblemsExists(ProblemType.ERROR, projectName, null, null, 0);
assertCountOfProblemsExists(ProblemType.ERROR, null, null, null, 0);
}
private AbstractProblemMatcher[] getProblemMatchers(String description, String project, String type) {
List<AbstractProblemMatcher> matcherList = new ArrayList<AbstractProblemMatcher>();
if (description != null) {
matcherList.add(new ProblemsDescriptionMatcher(StringContains.containsString(description)));
}
if (project != null) {
matcherList. add(new ProblemsPathMatcher(StringStartsWith.startsWith("/" + project)));
}
if (type != null) {
matcherList.add(new ProblemsTypeMatcher(Is.is(type)));
}
AbstractProblemMatcher[] matchers = new AbstractProblemMatcher[matcherList.size()];
return matchers = matcherList.toArray(matchers);
}
public void assertCountOfProblemsExists(ProblemType problemType, String projectName,
String description, String type, int count) {
AbstractProblemMatcher[] matchers = getProblemMatchers(description, projectName, type);
try {
new WaitUntil(new ExactNumberOfProblemsExists(problemType, count, matchers));
} catch (WaitTimeoutExpiredException ex) {
Assert.fail("There is not " + count + " number of problems matching specified matchers existing.");
}
}
public void assertCountOfProblemsExists(ProblemType problemType, int count) {
assertCountOfProblemsExists(problemType, null, null, null, count);
}
public void assertCountOfValidationProblemsExists(ProblemType problemType, String projectName,
String description, String type, int count) {
AbstractProblemMatcher[] matchers = getProblemMatchers(description, projectName, type);
if(count == 0 && !new ProblemExists(ProblemType.ANY).test()) {//prevent from false positive result when we do not expect errors and there is no error
new WaitWhile(new ExactNumberOfProblemsExists(ProblemType.ERROR, count, matchers),
WAIT_FOR_PROBLEMS_FALSE_POSItIVE_TIMEOUT, false);
} else {//prevent from false negative result
new WaitUntil(new ExactNumberOfProblemsExists(ProblemType.ERROR, count, matchers),
WAIT_FOR_PROBLEMS_FALSE_NEGATIVE_TIMEOUT, false);
}
try {
new WaitUntil(new ExactNumberOfProblemsExists(problemType, count, matchers));
} catch (WaitTimeoutExpiredException ex) {
Assert.fail("There is not " + count + " number of problems matching specified matchers existing.");
}
}
protected void assertCountOfRESTServices(List<RESTfulWebService> restServices,
int expectedCount) {
assertTrue(restServices.size() + " RESTful services"
+ " was found instead of " + expectedCount,
restServices.size() == expectedCount);
}
protected void assertAllRESTServicesInExplorer(List<RESTfulWebService> restServices) {
assertTrue("All RESTful services (GET, DELETE, POST, PUT) "
+ "should be present but they are not\nThere are "
+ Arrays.toString(restServices.toArray()),
allRestServicesArePresent(restServices));
}
protected void assertNotAllRESTServicesInExplorer(List<RESTfulWebService> restServices) {
assertFalse("All RESTful services (GET, DELETE, POST, PUT) "
+ "shouldnt be present but they are"
+ Arrays.toString(restServices.toArray()),
allRestServicesArePresent(restServices));
}
protected void assertExpectedPathOfService(String message,
RESTfulWebService service, String expectedPath) {
assertEquals(message + "Failure when comparing paths\n", expectedPath,
service.getPath());
}
protected void assertExpectedPathOfService(RESTfulWebService service,
String expectedPath) {
assertExpectedPathOfService("", service, expectedPath);
}
protected List<RESTfulWebService> restfulServicesForProject(String projectName) {
restWebServicesNode = new RESTfulWebServicesNode(projectName);
return restWebServicesNode.getWebServices();
}
protected void invokeMethodInWSTester(WsTesterView wsTesterView, WsTesterView.RequestType type) {
wsTesterView.setRequestType(type);
wsTesterView.invoke();
}
protected void copyRestfulResource(String resourceFile, Object... param) {
String streamPath = "/resources/restful/" + resourceFile;
InputStream stream = this.getClass().getResourceAsStream(streamPath);
ResourceHelper.copyResourceToClassWithSave(
stream, true, param);
AbstractWait.sleep(TimePeriod.getCustom(2));
}
private boolean allRestServicesArePresent(List<RESTfulWebService> restServices) {
String[] allRestMethods = {"GET", "POST", "POST", "DELETE"};
for (String restMethod : allRestMethods) {
if(!restServiceIsPresent(restServices, restMethod)) {
return false;
}
}
return true;
}
private boolean restServiceIsPresent(List<RESTfulWebService> restServices, String restMethod) {
for (RESTfulWebService restService : restServices) {
if (restService.getMethod().equals(restMethod)) {
return true;
}
}
return false;
}
protected void runRestServiceOnServer(String restWebServiceMethod) {
runRestServiceOnServer(restWebServicesNode.getWebServiceByMethod(restWebServiceMethod).get(0));
}
protected void runRestServiceOnServer(RESTfulWebService restWebService) {
runRestServiceOnServer(restWebService, getConfiguredServerName());
}
protected void runRestServiceOnServer(RESTfulWebService restWebService, String serverName) {
restWebService.select();
Menu menu = new ContextMenu(
new WithTextMatchers(new RegexMatcher(".*Run.*"),
new RegexMatcher(".*Run on Server.*")).getMatchers());
menu.select();
RunOnServerDialog dialog = new RunOnServerDialog();
String dialogTitle = dialog.getText();
dialog.chooseExistingServer();
dialog.selectServer(serverName);
dialog.finish();
new WaitWhile(new ShellWithTextIsAvailable(dialogTitle), TimePeriod.getCustom(20));
new WaitWhile(new JobIsRunning(), TimePeriod.getCustom(20));
}
protected void prepareSimpleRestService(String pathArgument, String pathParamArgument) {
prepareRestService(getWsProjectName(), SIMPLE_REST_WS_RESOURCE,
pathArgument, pathParamArgument);
}
protected void prepareRestService(String projectName, String resourceFileName,
Object... param) {
openJavaFile(projectName, "org.rest.test", "RestService.java");
Object[] newParam = new Object[2 + (param != null ? param.length : 0)];
newParam[0] = "org.rest.test";
newParam[1] = "RestService";
for(int i=2;i<newParam.length;i++) {
newParam[i] = param[i-2];
}
copyRestfulResource(resourceFileName, newParam);
}
protected void replaceInRestService(String regex, String replacement) {
replaceInRestService(getWsProjectName(), regex, replacement);
}
protected void replaceInRestService(String projectName,
String regex, String replacement) {
openJavaFile(projectName, "org.rest.test", "RestService.java");
ExtendedTextEditor editor = new ExtendedTextEditor();
editor.replace(regex, replacement);
}
protected TextEditor setCursorPositionToLineInTextEditor(String text) {
ExtendedTextEditor editor = new ExtendedTextEditor();
int line = editor.getLineNum(StringContains.containsString(text));
editor.setCursorPosition(line, 0);
return editor;
}
protected TextEditor setCursorPositionToTextInTextEditor(String text) {
ExtendedTextEditor editor = new ExtendedTextEditor();
int line = editor.getLineNum(StringContains.containsString(text));
editor.setCursorPosition(line, editor.getTextAtLine(line).indexOf(text)
+ text.length());
return editor;
}
protected void refreshRestServices(String projectName) {
Project project = new ProjectExplorer().getProject(projectName);
project.getChild("JAX-RS Web Services").refresh();
}
protected class RestServicePathsHaveUpdated extends AbstractWaitCondition {
private String projectName;
private Set<String> previousState = new HashSet<>();
public RestServicePathsHaveUpdated(String projectName) {
this.projectName = projectName;
for (RESTfulWebService service : restfulServicesForProject(projectName)) {
previousState.add(service.getPath());
}
}
@Override
public boolean test() {
Set<String> currentState = new HashSet<>();
for (RESTfulWebService service : restfulServicesForProject(projectName)) {
currentState.add(service.getPath());
}
return !currentState.equals(previousState);
}
}
}