From c70ded821f0313f8cf80a93a5b71e416dcfb5ec3 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Fri, 24 Jul 2015 22:18:27 +0200
Subject: [PATCH] no-jira: selenium test for access rules in course

---
 .../ConditionConfigEasyController.java        |   4 +
 .../editor/_content/visibilityedit.html       |   2 +-
 .../ui/main/EditMembershipController.java     |  12 +-
 .../java/org/olat/selenium/CourseTest.java    | 138 ++++++++++++++++++
 .../page/core/MenuTreePageFragment.java       |  31 ++++
 .../page/course/CourseEditorPageFragment.java |   6 +
 .../page/course/EasyConditionConfigPage.java  |  98 +++++++++++++
 .../page/group/MembersWizardPage.java         |   7 +
 8 files changed, 292 insertions(+), 6 deletions(-)
 create mode 100644 src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java

diff --git a/src/main/java/org/olat/course/condition/ConditionConfigEasyController.java b/src/main/java/org/olat/course/condition/ConditionConfigEasyController.java
index 8b68d223aec..febe6ed97df 100644
--- a/src/main/java/org/olat/course/condition/ConditionConfigEasyController.java
+++ b/src/main/java/org/olat/course/condition/ConditionConfigEasyController.java
@@ -1109,6 +1109,7 @@ public class ConditionConfigEasyController extends FormBasicController implement
 		 * yes / no chooser defines if learner do not see the building block at all
 		 */
 		coachExclusive = uifactory.addCheckboxesHorizontal("coachExclusive", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.coachExclusive") });
+		coachExclusive.setElementCssClass("o_sel_condition_coach_exclusive");
 		boolean coachesAndAdminsInitValue = validatedCondition.isEasyModeCoachesAndAdmins();
 		coachExclusive.select("ison", coachesAndAdminsInitValue);
 		
@@ -1201,6 +1202,7 @@ public class ConditionConfigEasyController extends FormBasicController implement
 		String areaInitVal = getAreaNames(areaKeyList);
 
 		groupSwitch = uifactory.addCheckboxesHorizontal("groupSwitch", null, formLayout, new String[] { "ison" }, new String[] { translate("form.easy.groupSwitch") });
+		groupSwitch.setElementCssClass("o_sel_condition_groups");
 		// initialize selection
 		if (!groupKeyList.isEmpty() || !areaKeyList.isEmpty()) {
 			groupSwitch.select("ison", true);
@@ -1217,7 +1219,9 @@ public class ConditionConfigEasyController extends FormBasicController implement
 		easyGroupList.setUserObject(groupKeyList);
 
 		chooseGroupsLink = uifactory.addFormLink("choose", groupChooseSubContainer, "o_form_groupchooser");
+		chooseGroupsLink.setElementCssClass("o_sel_condition_choose_groups");
 		createGroupsLink = uifactory.addFormLink("create", groupChooseSubContainer, "o_form_groupchooser");	
+		createGroupsLink.setElementCssClass("o_sel_condition_create_groups");
 		
 		//areas
 		areaChooseSubContainer = FormLayoutContainer.createDefaultFormLayout("areaChooseSubContainer", getTranslator());
diff --git a/src/main/java/org/olat/course/editor/_content/visibilityedit.html b/src/main/java/org/olat/course/editor/_content/visibilityedit.html
index 315a83b92ad..93ee6447611 100644
--- a/src/main/java/org/olat/course/editor/_content/visibilityedit.html
+++ b/src/main/java/org/olat/course/editor/_content/visibilityedit.html
@@ -1,4 +1,4 @@
-<fieldset class="o_form form-horizontal">
+<fieldset class="o_form form-horizontal o_sel_course_visibility_condition_form">
 	<legend>$r.contextHelpWithWrapper("org.olat.course.editor","ced-vis.html","help.hover.vis")
 	$r.translate("condition.visibility.title")</legend>
 	$r.render("visibilityCondition")
diff --git a/src/main/java/org/olat/group/ui/main/EditMembershipController.java b/src/main/java/org/olat/group/ui/main/EditMembershipController.java
index 9502d44e01f..29c5b34b4ab 100644
--- a/src/main/java/org/olat/group/ui/main/EditMembershipController.java
+++ b/src/main/java/org/olat/group/ui/main/EditMembershipController.java
@@ -26,6 +26,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
+import org.olat.basesecurity.GroupRoles;
 import org.olat.core.commons.persistence.PersistenceHelper;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.EscapeMode;
@@ -192,21 +193,22 @@ public class EditMembershipController extends FormBasicController {
 			boolean managed = BusinessGroupManagedFlag.isManaged(group.getManagedFlags(), BusinessGroupManagedFlag.membersmanagement);
 			MemberOption option = new MemberOption(group);
 			BGPermission bgPermission = PermissionHelper.getPermission(group.getKey(), memberToLoad, groupMemberships);
-			option.setTutor(createSelection(bgPermission.isTutor(), !managed));
-			option.setParticipant(createSelection(bgPermission.isParticipant() || defaultMembership, !managed));
+			option.setTutor(createSelection(bgPermission.isTutor(), !managed, GroupRoles.coach.name()));
+			option.setParticipant(createSelection(bgPermission.isParticipant() || defaultMembership, !managed, GroupRoles.participant.name()));
 			boolean waitingListEnable = !managed && group.getWaitingListEnabled() != null && group.getWaitingListEnabled().booleanValue();
-			option.setWaiting(createSelection(bgPermission.isWaitingList(), waitingListEnable));
+			option.setWaiting(createSelection(bgPermission.isWaitingList(), waitingListEnable, GroupRoles.waiting.name()));
 			options.add(option);
 		}
 		
 		tableDataModel.setObjects(options);
 	}
 	
-	private MultipleSelectionElement createSelection(boolean selected, boolean enabled) {
+	private MultipleSelectionElement createSelection(boolean selected, boolean enabled, String role) {
 		String name = "cb" + UUID.randomUUID().toString().replace("-", "");
 		MultipleSelectionElement selection = new MultipleSelectionElementImpl(name, Layout.horizontal);
+		selection.setElementCssClass("o_sel_role");
 		selection.addActionListener(FormEvent.ONCHANGE);
-		selection.setKeysAndValues(keys, values);
+		selection.setKeysAndValues(keys, values, new String[]{ "o_sel_role_".concat(role) }, null);
 		flc.add(name, selection);
 		selection.select(keys[0], selected);
 		selection.setEnabled(enabled);
diff --git a/src/test/java/org/olat/selenium/CourseTest.java b/src/test/java/org/olat/selenium/CourseTest.java
index 3e69beda06b..a8a2f60814d 100644
--- a/src/test/java/org/olat/selenium/CourseTest.java
+++ b/src/test/java/org/olat/selenium/CourseTest.java
@@ -47,10 +47,12 @@ import org.olat.selenium.page.Student;
 import org.olat.selenium.page.User;
 import org.olat.selenium.page.core.BookingPage;
 import org.olat.selenium.page.core.MenuTreePageFragment;
+import org.olat.selenium.page.course.AssessmentCEConfigurationPage;
 import org.olat.selenium.page.course.CourseEditorPageFragment;
 import org.olat.selenium.page.course.CoursePageFragment;
 import org.olat.selenium.page.course.CourseWizardPage;
 import org.olat.selenium.page.course.InfoMessageCEPage;
+import org.olat.selenium.page.course.MembersPage;
 import org.olat.selenium.page.course.PublisherPageFragment;
 import org.olat.selenium.page.course.RemindersPage;
 import org.olat.selenium.page.course.PublisherPageFragment.Access;
@@ -1257,4 +1259,140 @@ public class CourseTest {
 			.flatView()
 			.waitMessageBody(reiReply);
 	}
+	
+	/**
+	 * An author creates a course with 4 course elements. A folder
+	 * which is visible to group, a forum which is visible to coaches,
+	 * an assessment and an info visible to the students which passed
+	 * the assessment above.<br>
+	 * a student come and checks what it can see, the author make it
+	 * pass the assessment and the student sees the info.
+	 * 
+	 * @param loginPage
+	 * @param kanuBrowser
+	 * @param reiBrowser
+	 * @throws IOException
+	 * @throws URISyntaxException
+	 */
+	@Test
+	@RunAsClient
+	public void courseAccessRules(@InitialPage LoginPage loginPage,
+			@Drone @Student WebDriver reiBrowser)
+	throws IOException, URISyntaxException {
+		UserVO author = new UserRestClient(deploymentUrl).createAuthor();
+		UserVO rei = new UserRestClient(deploymentUrl).createRandomUser("rei");
+		loginPage.loginAs(author.getLogin(), author.getPassword());
+		
+		//create a course
+		String courseTitle = "Course FO " + UUID.randomUUID();
+		navBar
+			.openAuthoringEnvironment()
+			.createCourse(courseTitle)
+			.clickToolbarBack();
+	
+		//go the authoring environment to create a forum
+		String bcTitle = "BC - " + UUID.randomUUID();
+		String foTitle = "FO - " + UUID.randomUUID();
+		String msTitle = "MS - " + UUID.randomUUID();
+		String infoTitle = "Info - " + UUID.randomUUID();
+		
+		String groupName = "Students";
+		
+		CourseEditorPageFragment courseEditor = CoursePageFragment.getCourse(browser)
+			.edit();
+		//folder is group protected
+		courseEditor
+			.createNode("bc")
+			.nodeTitle(bcTitle)
+			.selectTabVisibility()
+			.setGroupCondition()
+			.createBusinessGroup(groupName);
+		//forum is coach exclusive
+		courseEditor
+			.createNode("fo")
+			.nodeTitle(foTitle)
+			.selectTabVisibility()
+			.setCoachExclusive()
+			.save();
+		//assessment is open
+		courseEditor
+			.createNode("ms")
+			.nodeTitle(msTitle);
+		//configure assessment
+		AssessmentCEConfigurationPage assessmentConfig = new AssessmentCEConfigurationPage(browser);
+		assessmentConfig
+			.selectConfiguration()
+			.setScoreAuto(0.0f, 6.0f, 4.0f);
+		
+		//wiki is assessment dependent
+		courseEditor
+			.createNode("info")
+			.nodeTitle(infoTitle)
+			.selectTabVisibility()
+			.setAssessmentCondition(1)
+			.save();
+
+		courseEditor
+			.publish()
+			.quickPublish(Access.membersOnly);
+		courseEditor
+			.clickToolbarBack();
+		
+		//add a member to the group we create above
+		MembersPage members = CoursePageFragment
+			.getCourse(browser)
+			.members();
+		members
+			.addMember()
+			.searchMember(rei, true)
+			.next()
+			.next()
+			.selectGroupAsParticipant(groupName)
+			.next()
+			.finish();
+		
+		//participant search the course
+		LoginPage.getLoginPage(reiBrowser, deploymentUrl)
+			.loginAs(rei)
+			.resume();
+		NavigationPage reiNavBar = new NavigationPage(reiBrowser);
+		reiNavBar
+			.openMyCourses()
+			.select(courseTitle);
+		
+		MenuTreePageFragment reiTree = new MenuTreePageFragment(reiBrowser);
+		reiTree
+			.assertWithTitle(bcTitle.substring(0, 20))
+			.assertWithTitle(msTitle.substring(0, 20))
+			.assertTitleNotExists(foTitle.substring(0, 20))
+			.assertTitleNotExists(infoTitle.substring(0, 20));
+		
+		//author set assessment to passed
+		members
+			.clickToolbarBack()
+			.assessmentTool()
+			.users()
+			.assertOnUsers(rei)
+			.selectUser(rei)
+			.selectCourseNode(msTitle.substring(0, 20))
+			.setAssessmentScore(5.5f)
+			.assertUserPassedCourseNode(msTitle.substring(0, 20));
+		
+		//student can see info
+		reiTree
+			.selectRoot()
+			.assertWithTitle(bcTitle.substring(0, 20))
+			.assertWithTitle(msTitle.substring(0, 20))
+			.assertTitleNotExists(foTitle.substring(0, 20))
+			.assertWithTitle(infoTitle.substring(0, 20));
+		
+		//author can see all
+		members
+			.clickToolbarBack()
+			.clickTree()
+			.assertWithTitle(bcTitle.substring(0, 20))
+			.assertWithTitle(msTitle.substring(0, 20))
+			.assertWithTitle(foTitle.substring(0, 20))
+			.assertWithTitle(infoTitle.substring(0, 20));
+	}
 }
diff --git a/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java b/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java
index 3bd21b5aff4..f25705c9a38 100644
--- a/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java
+++ b/src/test/java/org/olat/selenium/page/core/MenuTreePageFragment.java
@@ -83,5 +83,36 @@ public class MenuTreePageFragment {
 		Assert.assertTrue("Link not found with title: " + title, found);
 		return this;
 	}
+	
+
+	public MenuTreePageFragment assertWithTitle(String title) {
+		boolean found = false;
+		By titleBy = By.cssSelector(".o_tree li>div>span.o_tree_link>a");
+		List<WebElement> nodeLinks = browser.findElements(titleBy);
+		for(WebElement nodeLink:nodeLinks) {
+			String text = nodeLink.getText();
+			if(text.contains(title)) {
+				found = true;
+			}
+		}
+		
+		Assert.assertTrue("Link not found with title: " + title, found);
+		return this;
+	}
 
+	public MenuTreePageFragment assertTitleNotExists(String title) {
+		boolean found = false;
+		WebElement tree = browser.findElement(treeBy);
+		List<WebElement> nodeLinks = tree.findElements(By.cssSelector("li>div>span.o_tree_link>a"));
+		for(WebElement nodeLink:nodeLinks) {
+			String text = nodeLink.getText();
+			if(text.contains(title)) {
+				OOGraphene.waitBusy(browser);
+				found = true;
+			}
+		}
+		
+		Assert.assertFalse("Link found with title: " + title, found);
+		return this;
+	}
 }
diff --git a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
index cdd8e6f71e5..4f96250cc15 100644
--- a/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
+++ b/src/test/java/org/olat/selenium/page/course/CourseEditorPageFragment.java
@@ -99,6 +99,12 @@ public class CourseEditorPageFragment {
 		return this;
 	}
 	
+	public EasyConditionConfigPage selectTabVisibility() {
+		By passwordTabBy = By.cssSelector("fieldset.o_sel_course_visibility_condition_form");
+		selectTab(passwordTabBy);
+		return new EasyConditionConfigPage(browser);
+	}
+	
 	/**
 	 * Select the tab where the password setting are
 	 * @return
diff --git a/src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java b/src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java
new file mode 100644
index 00000000000..3f0fb75f827
--- /dev/null
+++ b/src/test/java/org/olat/selenium/page/course/EasyConditionConfigPage.java
@@ -0,0 +1,98 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.selenium.page.course;
+
+import org.olat.selenium.page.graphene.OOGraphene;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.Select;
+
+/**
+ * 
+ * Initial date: 24.07.2015<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class EasyConditionConfigPage {
+	
+	private WebDriver browser;
+	
+	public EasyConditionConfigPage(WebDriver browser) {
+		this.browser = browser;
+	}
+	
+	public EasyConditionConfigPage setCoachExclusive() {
+		By coacheExclsuiveBy = By.cssSelector("input[name='coachExclusive'][type='checkbox']");
+		browser.findElement(coacheExclsuiveBy).click();
+		OOGraphene.waitBusy(browser);
+		return this;
+	}
+	
+	public EasyConditionConfigPage setGroupCondition() {
+		By groupSwitchBy = By.cssSelector("input[name='groupSwitch'][type='checkbox']");
+		browser.findElement(groupSwitchBy).click();
+		OOGraphene.waitBusy(browser);
+		return this;
+	}
+	
+	public EasyConditionConfigPage createBusinessGroup(String name) {
+		By createBy = By.cssSelector("a.o_sel_condition_create_groups");
+		browser.findElement(createBy).click();
+		OOGraphene.waitBusy(browser);
+		
+		//fill the form
+		By nameBy = By.cssSelector(".o_sel_group_edit_title input[type='text']");
+		WebElement nameEl = browser.findElement(nameBy);
+		nameEl.sendKeys(name);
+
+		//save
+		By submitBy = By.cssSelector(".o_sel_group_edit_group_form button.btn-primary");
+		WebElement submitButton = browser.findElement(submitBy);
+		submitButton.click();
+		OOGraphene.waitBusy(browser);
+		
+		return this;
+	}
+	
+	public EasyConditionConfigPage setAssessmentCondition(int nodeIndex) {
+		By assessmentSwitchBy = By.cssSelector("input[name='assessmentSwitch'][type='checkbox']");
+		browser.findElement(assessmentSwitchBy).click();
+		OOGraphene.waitBusy(browser);
+		
+		By assessmentPassedTypeSwitchBy = By.cssSelector("input[name='assessmentTypeSwitch'][type='radio']");
+		browser.findElement(assessmentPassedTypeSwitchBy).click();
+		OOGraphene.waitBusy(browser);
+		
+		By selectBy = By.cssSelector("fieldset.o_sel_course_visibility_condition_form select");
+		new Select(browser.findElement(selectBy)).selectByIndex(nodeIndex);
+		OOGraphene.waitBusy(browser);
+		
+		return this;
+	}
+	
+	public EasyConditionConfigPage save() {
+		By saveBy = By.cssSelector("fieldset.o_sel_course_visibility_condition_form button.btn-primary");
+		browser.findElement(saveBy).click();
+		OOGraphene.waitBusy(browser);
+		return this;
+	}
+
+}
diff --git a/src/test/java/org/olat/selenium/page/group/MembersWizardPage.java b/src/test/java/org/olat/selenium/page/group/MembersWizardPage.java
index d304b2c2632..8259de53675 100644
--- a/src/test/java/org/olat/selenium/page/group/MembersWizardPage.java
+++ b/src/test/java/org/olat/selenium/page/group/MembersWizardPage.java
@@ -107,4 +107,11 @@ public class MembersWizardPage {
 		OOGraphene.textarea(importAreaEl, sb.toString(), browser);
 		return this;
 	}
+	
+	public MembersWizardPage selectGroupAsParticipant(String groupName) {
+		By rolesBy = By.xpath("//div[contains(@class,'o_table_wrapper')]//table//tr[td[text()='" + groupName + "']]//label[contains(@class,'o_sel_role_participant')]/input");
+		List<WebElement> roleEls = browser.findElements(rolesBy);
+		roleEls.get(0).click();
+		return this;
+	}
 }
-- 
GitLab