/*
* #!
* Ontopia Access Control webapplication
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.topicmaps.nav2.webapps.accessctl;
//import net.ontopia.topicmaps.webed.test.AbstractWebBasedTestCase;
import com.meterware.httpunit.Button;
import com.meterware.httpunit.HTMLElement;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebResponse;
import java.io.IOException;
import java.util.Random;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import net.ontopia.utils.StringUtils;
import net.ontopia.topicmaps.webed.AbstractWebBasedTestCase;
import org.junit.Test;
/**
* INTERNAL.
* Tests the web application accessctl, located in:
* src/java/j2ee/webapps/accessctl
* Visits the index.jsp webpage and from there navigates from webpage to
* webpage, sometimes changing fields and checkboxes on those webpages.
* Stops after visiting as many webpages as specified by VISIT_LIMIT.
*/
public class AccessctlRandomizedTest extends AbstractWebBasedTestCase {
// initialization of logging facility
private static Logger log = LoggerFactory.getLogger(AccessctlRandomizedTest.class.getName());
// The number of webpages visited so far.
protected int visitCount;
// The maximum number of webpages to visit.
public static int VISIT_LIMIT = 100000;
// The number of privileges, users and user groups that was last seen.
protected int privileges;
protected int users;
protected int userGroups;
// Decides what do do next at any given moment (e.g. which link to click).
protected Random random;
private WebResponse resp;
/**
* Create a new tester.
* @param aName
*/
public AccessctlRandomizedTest(String aName) {
super(aName);
visitCount = 0;
random = new Random();
log.debug("Started");
privileges = 0;
users = 0;
userGroups = 0;
}
protected void setUp() throws Exception {
super.setUp();
// different webapp default
webedTestApplication = System.getProperty("net.ontopia.webed.test.testApplicationPath", "/accessctl");
webedTestLocation = System.getProperty("net.ontopia.webed.test.testServerLocation", "http://127.0.0.1:8080") + webedTestApplication;
}
/**
* Moves from webpage to webpage, possibly filling modifying fields and
* checkboxes on those pages. Stops after visiting VISIT_LIMIT webpages.
* @throws IOException
* @throws SAXException
*/
@Test
public void testAtRandom () throws IOException, SAXException {
// Maintain old user group
getPage("index.jsp");
while (visitCount <= VISIT_LIMIT)
visitCurrentPage();
log.debug("Finished");
}
/**
* Choose which actions to take for the current page based on its URL.
* Also keep track of how many webpages have been visited.
* @throws IOException
* @throws SAXException
*/
public void visitCurrentPage () throws IOException, SAXException {
visitCount++;
String pageName = resp.getURL().getPath().toString();
pageName = pageName.substring(pageName.lastIndexOf('/') + 1);
log.debug("Visiting " + pageName);
if (pageName.equals("index.jsp"))
visitIndex();
else if (pageName.equals("main.jsp"))
visitMain();
else if (pageName.equals("password.jsp"))
visitPassword();
else if (pageName.equals("privilege.jsp"))
visitPrivilege();
else if (pageName.equals("privileges.jsp"))
visitPrivileges();
else if (pageName.equals("user.jsp"))
visitUser();
else if (pageName.equals("users.jsp"))
visitUsers();
else if (pageName.equals("userGroup.jsp"))
visitUserGroup();
else if (pageName.equals("userGroups.jsp"))
visitUserGroups();
else
log.debug("Don't recognize " + pageName);
}
/**
*
* @throws IOException
* @throws SAXException
*/
public void visitIndex () throws IOException, SAXException {
if (random.nextBoolean())
clickLinkNumber(0);
else
clickRandomLink();
login();
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitMain () throws IOException, SAXException {
log.debug("Main - Links: " + resp.getLinks().length);
int choice = random.nextInt(100);
if (choice < 30)
clickButton("privilegeCreation", "createNewPrivilege");
else if (choice < 60)
clickButton("userCreation", "createNewUser");
else if (choice < 90)
clickButton("userGroupCreation", "createNewUserGroup");
else
clickRandomLinkOrButton();
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitPassword () throws IOException, SAXException {
clickRandomButton();
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitPrivilege () throws IOException, SAXException {
changeField("enterName", StringUtils.makeRandomId(2 + random.nextInt(10)));
changeField("enterSI", StringUtils.makeRandomId(2 + random.nextInt(4)) + "://"
+ StringUtils.makeRandomId(2 + random.nextInt(15)));
clickRandomButton();
}
/**
* @return
* @throws SAXException
*/
public int getButtonCount() throws SAXException {
WebForm forms[] = resp.getForms();
assertTrue(forms.length > 0);
WebForm form = forms[0];
return form.getButtons().length;
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitPrivileges () throws IOException, SAXException {
int buttonCount = getButtonCount();
if (buttonCount > privileges) {
log.debug("Privileges: " + ": " + privileges);
privileges = buttonCount;
}
int choice = random.nextInt(100);
if (choice < 95)
clickButton("create");
else
clickRandomLinkOrButton();
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitUser () throws IOException, SAXException {
if (random.nextBoolean())
changeField("enterName", StringUtils.makeRandomId(2 + random.nextInt(10)));
if (random.nextBoolean())
changeField("enterUsername", StringUtils.makeRandomId(2 + random.nextInt(10)));
if (random.nextBoolean())
changeField("enterPassword", StringUtils.makeRandomId(2 + random.nextInt(10)));
clickRandomButton();
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitUsers () throws IOException, SAXException {
int buttonCount = getButtonCount();
if (buttonCount > users) {
log.debug("Users: " + ": " + users);
users = buttonCount;
}
int choice = random.nextInt(100);
if (choice < 95)
clickButton("create");
else
clickRandomLinkOrButton();
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitUserGroup () throws IOException, SAXException {
if (random.nextBoolean())
changeField("enterName", StringUtils.makeRandomId(2 + random.nextInt(10)));
clickRandomButton();
}
/**
* @throws IOException
* @throws SAXException
*/
public void visitUserGroups () throws IOException, SAXException {
int buttonCount = getButtonCount();
if (buttonCount > userGroups) {
log.debug("User Groups: " + ": " + userGroups);
userGroups = buttonCount;
}
int choice = random.nextInt(100);
if (choice < 95)
clickButton("create");
else
clickRandomLinkOrButton();
}
/**
* @throws IOException
* @throws SAXException
*/
public void clickRandomLinkOrButton () throws IOException, SAXException {
if (random.nextBoolean())
clickRandomLink();
else
clickRandomButton();
}
/**
* Clicks a random link on the current page.
* @throws Exception
*/
public void clickRandomLink () throws IOException, SAXException {
WebLink links[] = resp.getLinks();
int choice = random.nextInt(links.length);
WebLink link = links[choice];
if (!(link == null || link.getURLString().startsWith("http://"))) {
log.debug("Clicking Link: " + link.asText());
clickFiltered(link);
}
}
/**
* @param link
* @throws IOException
* @throws SAXException
*/
public void clickFiltered(WebLink link) throws IOException, SAXException {
String text = link.asText();
if (!(text.equals("John Doe") || text.equals("Gold Users")
|| text.equals("Private Administrative Users"))) {
log.debug("Clicing Link: " + text);
link.click();
resp = wc.getCurrentPage();
}
}
/**
* Clicks the link at a given index position.
* @param index The index position of the link.
* @throws IOException
* @throws SAXException
*/
public void clickLinkNumber (int index) throws IOException, SAXException {
log.debug("Clicking link number: " + index);
WebLink links[] = resp.getLinks();
log.debug("Links: " + links.length);
if (index >= links.length)
index = links.length - 1;
WebLink link = links[index];
log.debug("Index: " + index + " text: " + link.getName());
if (!(link == null || link.getURLString().startsWith("http://"))) {
clickFiltered(link);
}
}
/**
* @throws IOException
* @throws SAXException
*/
public void clickRandomButton () throws IOException, SAXException {
WebForm forms[] = resp.getForms();
WebForm form = forms[random.nextInt(forms.length)];
Button buttons[] = form.getButtons();
Button button = buttons[random.nextInt(buttons.length)];
button.click();
log.debug("Clicked Button: " + button.getID());
resp = wc.getCurrentPage();
}
/**
* Change the contents of a given input field.
* @param fieldID The ID of the field.
* @param newValue The new value to put in the input field.
* @throws SAXException
*/
protected void changeField(String fieldID, String newValue)
throws SAXException {
HTMLElement field = resp.getElementWithID(fieldID);
assertNotNull(field);
WebForm forms[] = resp.getForms();
assertTrue(forms.length > 0);
WebForm form = forms[0];
form.setParameter(field.getName(), newValue);
log.debug("Changed Field: fieldID=" + fieldID + " newValue=" + newValue);
}
/**
* Click on the link with a given text.
* @param linkText The text of the link.
* @throws SAXException
* @throws IOException
*/
protected void clickOn(String linkText) throws SAXException, IOException {
WebLink link = resp.getLinkWith(linkText);
assertNotNull(link);
clickFiltered(link);
}
/**
* Click on the button with a given ID within the first form.
* @param buttonID The id of the button to click.
* @throws SAXException
* @throws IOException
*/
protected void clickButton(String buttonID) throws SAXException, IOException {
log.debug("Clicking Button: " + buttonID);
WebForm forms[] = resp.getForms();
assertTrue(forms.length > 0);
WebForm form = forms[0];
Button button = form.getButtonWithID(buttonID);
assertNotNull(button);
button.click();
resp = wc.getCurrentPage();
}
/**
* Click on the button with a given ID within a given form.
* @param formID The id of the form with the button.
* @param buttonID The id of the button to click.
* @throws SAXException
* @throws IOException
*/
protected void clickButton(String formID, String buttonID) throws SAXException, IOException {
log.debug("Clicking Button: " + buttonID + " formID=" + formID);
WebForm form = resp.getFormWithID(formID);
assertNotNull(form);
Button button = form.getButtonWithID(buttonID);
assertNotNull(button);
button.click();
resp = wc.getCurrentPage();
}
/**
* Make the page of a path relative to the test location the active page.
* @param relativePath The path, relative to webedTestLocation.
* @throws SAXException
* @throws IOException
*/
protected void getPage(String relativePath) throws SAXException, IOException {
resp = wc.getResponse(webedTestLocation + "/" + relativePath);
}
/**
* Faced with the login form, perform the necessary steps to log in.
* @throws IOException
* @throws SAXException
*/
protected void login() throws IOException, SAXException {
// If required to log in, then do so.
if (resp.getElementWithID("name") != null && resp.getElementWithID("passw") != null) {
changeField("name", "johndoe");
changeField("passw", "secret");
clickButton("submit");
}
}
}