/**************************************************************** * Copyright (C) 2006 LAMS Foundation (http://lamsfoundation.org) * ============================================================= * License Information: http://lamsfoundation.org/licensing/lams/2.0/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2.0 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA * * http://www.gnu.org/licenses/gpl.txt * **************************************************************** */ package org.lamsfoundation.testharness.learner; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.websocket.MessageHandler; import org.apache.log4j.Logger; import org.lamsfoundation.testharness.Call; import org.lamsfoundation.testharness.MockUser; import org.lamsfoundation.testharness.TestHarnessException; import org.lamsfoundation.testharness.TestUtil; import org.lamsfoundation.testharness.admin.MockAdmin; import org.xml.sax.SAXException; import com.meterware.httpunit.Button; import com.meterware.httpunit.FormControl; import com.meterware.httpunit.WebForm; import com.meterware.httpunit.WebLink; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; /** * @author Fei Yang, Marcin Cieslak */ public class MockLearner extends MockUser implements Runnable { private static final Logger log = Logger.getLogger(MockLearner.class); public static final String DEFAULT_NAME = "Learner"; private static final String ARBITRARY_TEXT_ALPHABET = "`1234567890-=qwertyuiop[]\\asdfghjkl;'\tzxcvbnm,./ ~!@#$%^&*()_+}{POIUYTREWQASDFGHJKL:\"?> SCRATCHIE_FINISHED_TOOL_CONTENT = new TreeSet(); private static final String CHAT_FINISH_SUBSTRING = "/lams/tool/lachat11/learning.do"; private static final int CHAT_REPLIES = 3; private static final Pattern CHAT_TOOL_SESSION_ID_PATTERN = Pattern.compile("TOOL_SESSION_ID = '(\\d+)'"); private static final String KNOCK_GATE_SUBSTRING = "/lams/learning/gate.do?method=knockGate"; private static final String ASSESSMENT_TOOL_SUBSTRING = "laasse10"; private static final Pattern ASSESSMENT_FINISH_PATTERN = Pattern .compile("'(/lams/tool/laasse10/learning/finish\\.do\\?.*)'"); private static final String ASSESSMENT_HAS_EDIT_RIGHT_SUBSTRING = "hasEditRight=true"; private static final Pattern ASSESSMENT_TOOL_SESSION_ID_PATTERN = Pattern.compile("data: 'toolSessionID=(\\d+)',"); private static final String ASSESSMENT_FINISH_BUTTON_SUBSTRING = "return finishSession()"; private static final Pattern IMAGE_GALLERY_FINISH_PATTERN = Pattern .compile("'(/lams/tool/laimag10/learning/finish\\.do\\?.*)'"); private static final String QA_TOOL_SUBSTRING = "laqa11"; private static final String VIDEORECORDER_TOOL_STRING = "lavidr10"; private static final String TASK_FINISH_SUBSTRING = "/lams/tool/latask10/learning/finish.do"; private static final String VOTE_VIEW_ALL_RESULTS_BUTTON_STRING = "submitMethod('viewAllResults')"; private static final String VOTE_LEARNER_FINISHED_BUTTON_STRING = "submitMethod('learnerFinished')"; private static final String VOTE_MIN_NOMINATION_PARAM = "minNominationCount"; private static final String VOTE_MAX_NOMINATION_PARAM = "maxNominationCount"; private static final String WIKI_EDIT_BUTTON_STRING = "doEditOrAdd('editPage')"; private static final Pattern SHARE_RESOURCES_REDIRECT_PATTERN = Pattern .compile("\"(/lams/tool/larsrc11/pages/learning/learning\\.jsp.*)\""); private static final Pattern SHARE_RESOURCES_VIEW_ITEM_URL_PATTERH = Pattern .compile("\"(/lams/tool/larsrc11/reviewItem\\.do.*)\""); private static final Pattern SHARE_RESOURCES_VIEW_ITEM_PATTERN = Pattern.compile("viewItem\\((\\d+)\\)"); private static final Pattern SUBMIT_FILES_FINISH_PATTERN = Pattern .compile("/lams/tool/lasbmt11/learner\\.do\\?method=finish\\&sessionMapID=sessionMapID-\\d+"); private static final String PEER_REVIEW_SUBSTRING = "/lams/tool/laprev11/"; private static final String PEER_REVIEW_SHOW_RESULTS_SUBSTRING = "/lams/tool/laprev11/learning/showResults.do"; private static final String PEER_REVIEW_FINISH_SUBSTRING = "/lams/tool/laprev11/learning/finish.do"; private static final String SCRIBE_TOOL_SUBSTRING = "/lams/tool/lascrb11/learning.do"; private static final String SCRIBE_SUBMIT_REPORT_SUBSTRING = "javascript:submitReport()"; private static final String SCRIBE_START_ACTIVITY_SUBSTRING = "value=\"startActivity\""; private static final String SCRIBE_FINISH_ACTIVITY_SUBSTRING = "value=\"finishActivity\""; private static final String SCRIBE_DISPLAY_REFLECTION_SUBSTRING = "value=\"openNotebook\""; private static final String SCRIBE_SUBMIT_REFLECTION_SUBSTRING = "value=\"submitReflection\""; private static final Pattern SCRIBE_REPORT_ENTRY_PATTERN = Pattern.compile("id=\"report-(\\d+)\""); private static final Pattern SCRIBE_TOOL_SESSION_ID_PATTERN = Pattern.compile("toolSessionID=' \\+ (\\d+)\\)"); private static final Set SCRIBE_FINISHED_TOOL_CONTENT = new TreeSet(); private static final short SCRIBE_SUBMIT_REPORT_ATTEMPTS = 3; private static int joinLessonUserCount = 0; private static int topJoinLessonUserCount = 0; private boolean finished = false; /** * MockLearner Constructor */ public MockLearner(LearnerTest test, String username, String password, String userId) { super(test, username, password, MockAdmin.LEARNER_ROLE, userId); } private static String[] chooseArbitraryValues(String[] values, boolean unique, Integer minValues, Integer maxValues) { int min = minValues == null ? 1 : minValues; int max = maxValues == null ? values.length : Math.min(maxValues, values.length); int length = min + TestUtil.generateRandomNumber(max); String[] answers = new String[length]; for (int i = 0; i < length; i++) { answers[i] = values[TestUtil.generateRandomNumber(values.length)]; if (unique) { for (int j = 0; j < i; j++) { if (answers[j].equals(answers[i])) { // repeat choice so there are no duplicates i--; break; } } } } return answers; } private static String composeArbitraryText() { int length = 1 + TestUtil.generateRandomNumber(MockLearner.ARBITRARY_TEXT_ALPHABET.length()); StringBuilder text = new StringBuilder(length); for (int i = 0; i < length; i++) { // make the text split into words to comply with Assessment Tool validation if ((i % 3) == 0) { text.append(" "); } text.append(MockLearner.ARBITRARY_TEXT_ALPHABET .charAt(TestUtil.generateRandomNumber(MockLearner.ARBITRARY_TEXT_ALPHABET.length()))); } return text.toString(); } private static String findURLInAHREF(WebResponse resp, String linkSubstring) throws SAXException { WebLink[] links = resp.getLinks(); if (links != null) { for (WebLink link : links) { MockLearner.log.debug("Checking link " + link.getURLString()); if (link.getURLString().indexOf(linkSubstring) != -1) { return link.getURLString(); } } } return null; } private static String findURLInLocationHref(WebResponse resp, String linkSubstring) throws IOException { // an example of matched string: // location.href ='http://localhost/lams/mylinksubstring/learner.do' Pattern linkPattern = Pattern .compile("location\\.href\\s*=\\s*['\"](.*" + Pattern.quote(linkSubstring) + ".*)['\"]"); Matcher m = linkPattern.matcher(resp.getText()); if (m.find()) { String url = m.group(1); MockLearner.log.debug("Found location.href = " + url); return url; } return null; } private static Map> groupButtonsByName(Button[] btns, String buttonType) { Map> buttonGroups = new HashMap>(); if (btns != null) { for (Button btn : btns) { if (buttonType.equals(btn.getType())) { String name = btn.getName(); MockLearner.log.debug("Got " + buttonType + " " + name + " and its value is " + btn.getValue()); if (!buttonGroups.containsKey(name)) { buttonGroups.get(name).add(btn); } else { List