first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Step definition to generate database fixtures for learning plan system.
*
* @package tool_lp
* @category test
* @copyright 2016 Issam Taboubi <issam.taboubi@umontreal.ca>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php');
/**
* Step definition for learning plan system.
*
* @package tool_lp
* @category test
* @copyright 2016 Issam Taboubi <issam.taboubi@umontreal.ca>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_tool_lp extends behat_base {
/**
* Click on an entry in the edit menu.
*
* @When /^I click on "([^"]*)" of edit menu in the "([^"]*)" row$/
*
* @param string $nodetext
* @param string $rowname
*/
public function click_on_edit_menu_of_the_row($nodetext, $rowname) {
$xpathtarget = "//ul//li//ul//li[contains(concat(' ', @class, ' '), ' tool-lp-menu-item ')]//a[contains(.,'" . $nodetext . "')]";
$this->execute('behat_general::i_click_on_in_the', [get_string('edit'), 'link', $this->escape($rowname), 'table_row']);
$this->execute('behat_general::i_click_on_in_the', [$xpathtarget, 'xpath_element', $this->escape($rowname), 'table_row']);
}
/**
* Click on competency in the tree.
*
* @Given /^I select "([^"]*)" of the competency tree$/
*
* @param string $competencyname
*/
public function select_of_the_competency_tree($competencyname) {
$xpathtarget = "//li[@role='tree-item']//span[contains(.,'" . $competencyname . "')]";
$this->execute('behat_general::i_click_on', [$xpathtarget, 'xpath_element']);
}
/**
* Convert page names to URLs for steps like 'When I am on the "[identifier]" "[page type]" page'.
*
* Recognised page names are:
* | pagetype | name meaning | description |
* | Course competencies | Course name | The course competencies page |
*
* @param string $page identifies which type of page this is, e.g. 'Course competencies'.
* @param string $identifier identifies the particular page, e.g. 'C1'.
* @return moodle_url the corresponding URL.
* @throws Exception with a meaningful error message if the specified page cannot be found.
*/
protected function resolve_page_instance_url(string $page, string $identifier): moodle_url {
switch (strtolower($page)) {
case 'course competencies':
$courseid = $this->get_course_id($identifier);
return new moodle_url('/admin/tool/lp/coursecompetencies.php', [
'courseid' => $courseid,
]);
default:
throw new Exception("Unrecognised page type '{$page}'");
}
}
/**
* Return a list of the exact named selectors for the component.
*
* @return behat_component_named_selector[]
*/
public static function get_exact_named_selectors(): array {
return [
new behat_component_named_selector('competency', [
"//*[@data-region='coursecompetencies']//table[contains(@class,'managecompetencies')]".
"//tr[contains(., //a[@title='View details'][contains(., %locator%)])]",
]),
new behat_component_named_selector('learning plan', [
"//*[@data-region='plan-competencies']//table[contains(@class,'managecompetencies')]".
"//tr[@data-node='user-competency'][contains(., //a[@data-usercompetency='true'][contains(., %locator%)])]",
]),
new behat_component_named_selector('competency description', [
"//td/p[contains(., %locator%)]",
]),
new behat_component_named_selector('competency grade', [
"//span[contains(concat(' ', normalize-space(@class), ' '), ' badge ')][contains(., %locator%)]",
]),
new behat_component_named_selector('learning plan rating', [
"//td[position()=2][contains(., %locator%)]",
]),
new behat_component_named_selector('learning plan proficiency', [
"//td[position()=3][contains(., %locator%)]",
]),
new behat_component_named_selector('competency page proficiency', [
"//dt[contains(., 'Proficient')]/following-sibling::dd[1][contains(., %locator%)]",
]),
new behat_component_named_selector('competency page rating', [
"//dt[contains(., 'Rating')]/following-sibling::dd[1][contains(., %locator%)]",
]),
new behat_component_named_selector('competency page related competency', [
"//*[@data-region='relatedcompetencies']//a[contains(., %locator%)]",
]),
];
}
}
@@ -0,0 +1,362 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Step definition to generate database fixtures for learning plan system.
*
* @package tool_lp
* @category test
* @copyright 2016 Issam Taboubi <issam.taboubi@umontreal.ca>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../../../lib/behat/behat_base.php');
use Behat\Gherkin\Node\TableNode as TableNode;
use Behat\Behat\Tester\Exception\PendingException as PendingException;
use core_competency\competency;
use core_competency\competency_framework;
use core_competency\plan;
use core_competency\user_evidence;
/**
* Step definition to generate database fixtures for learning plan system.
*
* @package tool_lp
* @category test
* @copyright 2016 Issam Taboubi <issam.taboubi@umontreal.ca>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_tool_lp_data_generators extends behat_base {
/**
* @var tool_lp data generator
*/
protected $datageneratorlp;
/**
* Each element specifies:
* - The data generator sufix used.
* - The required fields.
* - The mapping between other elements references and database field names.
* @var array
*/
protected static $elements = array(
'frameworks' => array(
'datagenerator' => 'framework',
'required' => array()
),
'templates' => array(
'datagenerator' => 'template',
'required' => array()
),
'plans' => array(
'datagenerator' => 'plan',
'required' => array('user')
),
'competencies' => array(
'datagenerator' => 'competency',
'required' => array('framework')
),
'userevidence' => array(
'datagenerator' => 'user_evidence',
'required' => array('user')
),
'plancompetencies' => array(
'datagenerator' => 'plan_competency',
'required' => array('plan', 'competency')
),
'userevidencecompetencies' => array(
'datagenerator' => 'user_evidence_competency',
'required' => array('userevidence', 'competency')
),
'usercompetencies' => array(
'datagenerator' => 'user_competency',
'required' => array('user', 'competency')
),
'usercompetencyplans' => array(
'datagenerator' => 'user_competency_plan',
'required' => array('user', 'competency', 'plan')
)
);
/**
* Creates the specified element. More info about available elements in https://moodledev.io/general/development/tools/behat.
*
* @Given /^the following lp "(?P<element_string>(?:[^"]|\\")*)" exist:$/
*
* @throws Exception
* @throws PendingException
* @param string $elementname The name of the entity to add
* @param TableNode $data
*/
public function the_following_lp_exist($elementname, TableNode $data) {
// Now that we need them require the data generators.
require_once(__DIR__.'/../../../../../lib/phpunit/classes/util.php');
if (empty(self::$elements[$elementname])) {
throw new PendingException($elementname . ' data generator is not implemented');
}
$datagenerator = testing_util::get_data_generator();
$this->datageneratorlp = $datagenerator->get_plugin_generator('core_competency');
$elementdatagenerator = self::$elements[$elementname]['datagenerator'];
$requiredfields = self::$elements[$elementname]['required'];
if (!empty(self::$elements[$elementname]['switchids'])) {
$switchids = self::$elements[$elementname]['switchids'];
}
foreach ($data->getHash() as $elementdata) {
// Check if all the required fields are there.
foreach ($requiredfields as $requiredfield) {
if (!isset($elementdata[$requiredfield])) {
throw new Exception($elementname . ' requires the field ' . $requiredfield . ' to be specified');
}
}
// Switch from human-friendly references to ids.
if (isset($switchids)) {
foreach ($switchids as $element => $field) {
$methodname = 'get_' . $element . '_id';
// Not all the switch fields are required, default vars will be assigned by data generators.
if (isset($elementdata[$element])) {
// Temp $id var to avoid problems when $element == $field.
$id = $this->{$methodname}($elementdata[$element]);
unset($elementdata[$element]);
$elementdata[$field] = $id;
}
}
}
// Preprocess the entities that requires a special treatment.
if (method_exists($this, 'preprocess_' . $elementdatagenerator)) {
$elementdata = $this->{'preprocess_' . $elementdatagenerator}($elementdata);
}
// Creates element.
$methodname = 'create_' . $elementdatagenerator;
if (method_exists($this->datageneratorlp, $methodname)) {
// Using data generators directly.
$this->datageneratorlp->{$methodname}($elementdata);
} else if (method_exists($this, 'process_' . $elementdatagenerator)) {
// Using an alternative to the direct data generator call.
$this->{'process_' . $elementdatagenerator}($elementdata);
} else {
throw new PendingException($elementname . ' data generator is not implemented');
}
}
}
/**
* Adapt creating competency from framework idnumber or frameworkid.
*
* @param array $data
* @return array
*/
protected function preprocess_competency($data) {
if (isset($data['framework'])) {
$framework = competency_framework::get_record(array('idnumber' => $data['framework']));
if ($framework) {
$data['competencyframeworkid'] = $framework->get('id');
} else {
$framework = competency_framework::get_record(array('id' => $data['framework']));
if ($framework) {
$data['competencyframeworkid'] = $framework->get('id');
} else {
throw new Exception('Could not resolve framework with idnumber or id : "' . $data['category'] . '"');
}
}
}
unset($data['framework']);
return $data;
}
/**
* Adapt creating plan from user username.
*
* @param array $data
* @return array
*/
protected function preprocess_plan($data) {
global $DB;
if (isset($data['user'])) {
$user = $DB->get_record('user', array('username' => $data['user']), '*', MUST_EXIST);
$data['userid'] = $user->id;
}
unset($data['user']);
if (isset($data['reviewer'])) {
if (is_number($data['reviewer'])) {
$data['reviewerid'] = $data['reviewer'];
} else {
$user = $DB->get_record('user', array('username' => $data['reviewer']), '*', MUST_EXIST);
$data['reviewerid'] = $user->id;
}
unset($data['reviewer']);
}
if (isset($data['status'])) {
switch ($data['status']) {
case 'draft':
$status = plan::STATUS_DRAFT;
break;
case 'in review':
$status = plan::STATUS_IN_REVIEW;
break;
case 'waiting for review':
$status = plan::STATUS_WAITING_FOR_REVIEW;
break;
case 'active':
$status = plan::STATUS_ACTIVE;
break;
case 'complete':
$status = plan::STATUS_COMPLETE;
break;
default:
throw new Exception('Could not resolve plan status with: "' . $data['status'] . '"');
break;
}
$data['status'] = $status;
}
return $data;
}
/**
* Adapt creating user_evidence from user username.
*
* @param array $data
* @return array
*/
protected function preprocess_user_evidence($data) {
global $DB;
if (isset($data['user'])) {
$user = $DB->get_record('user', array('username' => $data['user']), '*', MUST_EXIST);
$data['userid'] = $user->id;
}
unset($data['user']);
return $data;
}
/**
* Adapt creating plan_competency from plan name and competency shortname.
*
* @param array $data
* @return array
*/
protected function preprocess_plan_competency($data) {
global $DB;
if (isset($data['plan'])) {
$plan = $DB->get_record(plan::TABLE, array('name' => $data['plan']), '*', MUST_EXIST);
$data['planid'] = $plan->id;
}
unset($data['plan']);
if (isset($data['competency'])) {
$competency = $DB->get_record(competency::TABLE, array('shortname' => $data['competency']), '*', MUST_EXIST);
$data['competencyid'] = $competency->id;
}
unset($data['competency']);
return $data;
}
/**
* Adapt creating plan_competency from user evidence name and competency shortname.
*
* @param array $data
* @return array
*/
protected function preprocess_user_evidence_competency($data) {
global $DB;
if (isset($data['userevidence'])) {
$userevidence = $DB->get_record(user_evidence::TABLE, array('name' => $data['userevidence']), '*', MUST_EXIST);
$data['userevidenceid'] = $userevidence->id;
}
unset($data['userevidence']);
if (isset($data['competency'])) {
$competency = $DB->get_record(competency::TABLE, array('shortname' => $data['competency']), '*', MUST_EXIST);
$data['competencyid'] = $competency->id;
}
unset($data['competency']);
return $data;
}
/**
* Adapt creating user_competency from user name and competency shortname.
*
* @param array $data
* @return array
*/
protected function preprocess_user_competency($data) {
global $DB;
if (isset($data['user'])) {
$user = $DB->get_record('user', array('username' => $data['user']), '*', MUST_EXIST);
$data['userid'] = $user->id;
}
unset($data['user']);
if (isset($data['competency'])) {
$competency = $DB->get_record(competency::TABLE, array('shortname' => $data['competency']), '*', MUST_EXIST);
$data['competencyid'] = $competency->id;
}
unset($data['competency']);
return $data;
}
/**
* Adapt creating user_competency_plan from user name, competency shortname and plan name.
*
* @param array $data
* @return array
*/
protected function preprocess_user_competency_plan($data) {
global $DB;
if (isset($data['user'])) {
$user = $DB->get_record('user', array('username' => $data['user']), '*', MUST_EXIST);
$data['userid'] = $user->id;
}
unset($data['user']);
if (isset($data['competency'])) {
$competency = $DB->get_record(competency::TABLE, array('shortname' => $data['competency']), '*', MUST_EXIST);
$data['competencyid'] = $competency->id;
}
unset($data['competency']);
if (isset($data['plan'])) {
$plan = $DB->get_record(plan::TABLE, array('name' => $data['plan']), '*', MUST_EXIST);
$data['planid'] = $plan->id;
}
unset($data['plan']);
return $data;
}
}
@@ -0,0 +1,62 @@
@report @javascript @tool_lp
Feature: See the competencies for an activity on the course competencies page.
As a student
In order to see only the competencies for an activity in the course competencies page.
Background:
Given the following lp "frameworks" exist:
| shortname | idnumber |
| Test-Framework | ID-FW1 |
And the following lp "competencies" exist:
| shortname | framework |
| Test-Comp1 | ID-FW1 |
| Test-Comp2 | ID-FW1 |
Given the following "courses" exist:
| shortname | fullname | enablecompletion |
| C1 | Course 1 | 1 |
And the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
And the following "activities" exist:
| activity | name | intro | course | idnumber | completion | completionview |
| page | PageName1 | PageDesc1 | C1 | PAGE1 | 1 | 1 |
| page | PageName2 | PageDesc2 | C1 | PAGE2 | 1 | 1 |
And I am on the "Course 1" course page logged in as admin
And I navigate to "Competencies" in current page administration
And I press "Add competencies to course"
And "Competency picker" "dialogue" should be visible
And I select "Test-Comp1" of the competency tree
And I click on "Add" "button" in the "Competency picker" "dialogue"
And I press "Add competencies to course"
And "Competency picker" "dialogue" should be visible
And I select "Test-Comp2" of the competency tree
And I click on "Add" "button" in the "Competency picker" "dialogue"
And I am on the PageName1 "page activity editing" page
And I click on "Expand all" "link" in the "region-main" "region"
And I set the field "Course competencies" to "Test-Comp1"
And I press "Save and return to course"
And I log out
@javascript
Scenario: Go to the competency course competencies page.
Given I am on the "Course 1" course page logged in as student1
When I follow "Competencies"
Then I should see "Test-Comp1"
And I should see "Test-Comp2"
And I set the field "Filter competencies by resource or activity" to "PageName1"
And I press the enter key
And I should see "Test-Comp1"
And I should not see "Test-Comp2"
And I set the field "Filter competencies by resource or activity" to "PageName2"
And I press the enter key
And I should not see "Test-Comp1"
And I should not see "Test-Comp2"
And I should see "No competencies have been linked to this activity or resource."
@javascript
Scenario: None course competencies page.
When I am on the PageName1 "page activity" page logged in as student1
Then I should see "Test page content"
@@ -0,0 +1,145 @@
@tool @javascript @tool_lp @tool_lp_framework
Feature: Manage competency frameworks
As a competency framework admin
In order to perform CRUD operations on competency framework
I need to create, update and delete competency framework
Background:
Given I log in as "admin"
And I change window size to "small"
And I am on site homepage
Scenario: Create a new framework
Given I navigate to "Competencies > Competency frameworks" in site administration
And I should see "List of competency frameworks"
And I click on "Add new competency framework" "button"
And I should see "General"
And I should see "Taxonomies"
And I set the field "Name" to "Science Year-1"
And I set the field "ID number" to "Comp-frm-1"
And I press "Save changes"
And I should see "The scale needs to be configured by selecting default and proficient items."
And "Configure scales" "button" should be visible
And I press "Configure scales"
And I click on "//input[@data-field='tool_lp_scale_default_1']" "xpath_element"
And I click on "//input[@data-field='tool_lp_scale_proficient_1']" "xpath_element"
And I click on "//input[@value='Close']" "xpath_element"
When I press "Save changes"
Then I should see "Competency framework created"
And I should see "Science Year-1"
Scenario: Read a framework
Given the following lp "frameworks" exist:
| shortname | idnumber |
| Science Year-2 | sc-y-2 |
And I navigate to "Competencies > Competency frameworks" in site administration
And I should see "Science Year-2"
When I click on "Science Year-2" "link"
Then I should see "Science Year-2"
Scenario: Edit a framework
Given the following lp "frameworks" exist:
| shortname | idnumber |
| Science Year-3 | sc-y-3 |
And I navigate to "Competencies > Competency frameworks" in site administration
And I should see "Science Year-3"
And I click on "Edit" of edit menu in the "Science Year-3" row
And the field "Name" matches value "Science Year-3 "
And I set the field "Name" to "Science Year-3 Edited"
When I press "Save changes"
Then I should see "Competency framework updated"
And I should see "Science Year-3 Edited"
And I should see "sc-y-3"
Scenario: Delete a framework
Given the following lp "frameworks" exist:
| shortname | idnumber |
| Science Year-4 | sc-y-4 |
And I navigate to "Competencies > Competency frameworks" in site administration
And I should see "Science Year-4"
And I should see "sc-y-4"
And I click on "Delete" of edit menu in the "Science Year-4" row
And "Confirm" "dialogue" should be visible
And "Delete" "button" should exist in the "Confirm" "dialogue"
And "Cancel" "button" should exist in the "Confirm" "dialogue"
And I click on "Cancel" "button" in the "Confirm" "dialogue"
And I click on "Delete" of edit menu in the "Science Year-4" row
And "Confirm" "dialogue" should be visible
When I click on "Delete" "button" in the "Confirm" "dialogue"
Then I should not see "Science Year-4"
And I should not see "sc-y-4"
Scenario: Edit a framework with competencies in user competency
Given the following lp "frameworks" exist:
| shortname | idnumber |
| Science Year-5 | sc-y-5 |
And the following lp "competencies" exist:
| shortname | framework |
| Comp1 | sc-y-5 |
| Comp2 | sc-y-5 |
And the following lp "plans" exist:
| name | user | description |
| Plan Science-5 | admin | Plan description |
And the following lp "plancompetencies" exist:
| plan | competency |
| Plan Science-5 | Comp1 |
| Plan Science-5 | Comp2 |
And the following lp "usercompetencies" exist:
| user | competency |
| admin | Comp1 |
| admin | Comp2 |
And I navigate to "Competencies > Competency frameworks" in site administration
And I should see "Science Year-5"
And I click on "Edit" of edit menu in the "Science Year-5" row
And the field "Name" matches value "Science Year-5 "
And I set the field "Name" to "Science Year-5 Edited"
And the "scaleid" "select" should be readonly
When I press "Save changes"
Then I should see "Competency framework updated"
And I should see "Science Year-5 Edited"
And I should see "sc-y-5"
Scenario: Edit a framework with competencies in user competency plan
Given the following lp "frameworks" exist:
| shortname | idnumber |
| Science Year-6 | sc-y-6 |
And the following lp "competencies" exist:
| shortname | framework |
| Comp1 | sc-y-6 |
| Comp2 | sc-y-6 |
And the following lp "plans" exist:
| name | user | description |
| Plan Science-6 | admin | Plan description |
And the following lp "plancompetencies" exist:
| plan | competency |
| Plan Science-6 | Comp1 |
| Plan Science-6 | Comp2 |
And the following lp "usercompetencyplans" exist:
| user | competency | plan |
| admin | Comp1 | Plan Science-6 |
| admin | Comp2 | Plan Science-6 |
And I navigate to "Competencies > Competency frameworks" in site administration
And I should see "Science Year-6"
And I click on "Edit" of edit menu in the "Science Year-6" row
And the field "Name" matches value "Science Year-6 "
And I set the field "Name" to "Science Year-6 Edited"
And the "scaleid" "select" should be readonly
When I press "Save changes"
Then I should see "Competency framework updated"
And I should see "Science Year-6 Edited"
And I should see "sc-y-6"
Scenario: Duplicate a competency framework
Given the following lp "frameworks" exist:
| shortname | idnumber |
| CF1 | CF1 |
And the following lp "competencies" exist:
| shortname | framework |
| C1 | CF1 |
And I navigate to "Competencies > Competency frameworks" in site administration
# Duplicate the selected competency framework
When I click on "Duplicate" of edit menu in the "CF1" row
# Confirm that the selected framework was duplicated by clicking on the link
And I click on "CF1 (copy) (CF1_1)" "link"
# Confirm that the corresponding competency also exists in the duplicated framework
Then I should see "C1"
+161
View File
@@ -0,0 +1,161 @@
@tool @javascript @tool_lp @tool_lp_plan
Feature: Manage plearning plan
As a learning plan admin
In order to perform CRUD operations on learning plan
I need to create, update and delete learning plan
Background:
Given I log in as "admin"
And I am on site homepage
When I follow "Profile" in the user menu
Then I should see "Learning plans"
Scenario: Create a new learning plan
Given I follow "Learning plans"
And I should see "List of learning plan"
And I click on "Add new learning plan" "button"
And I should see "Add new learning plan"
And I set the field "Name" to "Science plan"
And I set the field "Description" to "Here description of learning plan"
When I press "Save changes"
Then I should see "Learning plan created"
And I should see "Science plan"
Scenario: Create a learning plan based on template
Given the following lp "templates" exist:
| shortname | description |
| Science template | science template description |
And I am on homepage
And I navigate to "Competencies > Learning plan templates" in site administration
And I click on ".template-userplans" "css_element" in the "Science template" "table_row"
And I open the autocomplete suggestions list
And I click on "Admin User" item in the autocomplete list
And I press the escape key
When I click on "Create learning plans" "button"
Then I should see "A learning plan was created"
And I should see "Admin User" in the "Science template" "table_row"
Scenario: Create a learning plan from template cohort
Given the following lp "templates" exist:
| shortname | description |
| Science template cohort | science template description |
And the following "users" exist:
| username | firstname | lastname | email |
| student-plan1 | Student | 1 | studentplan1@example.com |
| student-plan2 | Student | 2 | studentplan2@example.com |
And the following "cohorts" exist:
| name | idnumber |
| cohort plan | COHORTPLAN |
And the following "cohort members" exist:
| user | cohort |
| student-plan1 | COHORTPLAN |
| student-plan2 | COHORTPLAN |
And I am on homepage
And I navigate to "Competencies > Learning plan templates" in site administration
And I click on ".template-cohorts" "css_element" in the "Science template cohort" "table_row"
And I set the field "Select cohorts to sync" to "cohort plan"
When I click on "Add cohorts" "button"
Then I should see "2 learning plans were created."
And I navigate to "Competencies > Learning plan templates" in site administration
And I click on ".template-userplans" "css_element" in the "Science template cohort" "table_row"
And I should see "Student 1"
And I should see "Student 2"
Scenario: Read a learning plan
Given the following lp "plans" exist:
| name | user | description |
| Science plan Year-1 | admin | science plan description |
And I follow "Learning plans"
And I should see "Science plan Year-1"
When I click on "Science plan Year-1" "link"
Then I should see "Science plan Year-1"
And I should see "Learning plan competencies"
Scenario: Manage a learning plan competencies
Given the following lp "plans" exist:
| name | user | description |
| Science plan Year-manage | admin | science plan description |
And the following lp "frameworks" exist:
| shortname | idnumber |
| Framework 1 | sc-y-2 |
And the following lp "competencies" exist:
| shortname | framework |
| comp1 | sc-y-2 |
| comp2 | sc-y-2 |
And I follow "Learning plans"
And I should see "Science plan Year-manage"
And I follow "Science plan Year-manage"
And I should see "Add competency"
And I press "Add competency"
And "Competency picker" "dialogue" should be visible
And I select "comp1" of the competency tree
When I click on "Add" "button" in the "Competency picker" "dialogue"
Then "comp1" "table_row" should exist
And I click on "Delete" of edit menu in the "comp1" row
And "Confirm" "dialogue" should be visible
And I click on "Confirm" "button"
And I wait until the page is ready
And "comp1" "table_row" should not exist
Scenario: Edit a learning plan
Given the following lp "plans" exist:
| name | user | description |
| Science plan Year-2 | admin | science plan description |
| Science plan Year-3 | admin | science plan description |
And I follow "Learning plans"
And I should see "Science plan Year-2"
And I should see "Science plan Year-3"
And I click on "Edit" of edit menu in the "Science plan Year-3" row
And the field "Name" matches value "Science plan Year-3"
And I set the field "Name" to "Science plan Year-3 Edited"
When I press "Save changes"
Then I should see "Learning plan updated"
And I should see "Science plan Year-3 Edited"
Scenario: Delete a learning plan
Given the following lp "plans" exist:
| name | user | description |
| Science plan Year-4 | admin | science plan description |
And I follow "Learning plans"
And I should see "Science plan Year-4"
And I click on "Delete" of edit menu in the "Science plan Year-4" row
And "Confirm" "dialogue" should be visible
And "Delete" "button" should exist in the "Confirm" "dialogue"
And "Cancel" "button" should exist in the "Confirm" "dialogue"
And I click on "Cancel" "button" in the "Confirm" "dialogue"
And I click on "Delete" of edit menu in the "Science plan Year-4" row
And "Confirm" "dialogue" should be visible
When I click on "Delete" "button" in the "Confirm" "dialogue"
And I wait until the page is ready
Then I should not see "Science plan Year-4"
Scenario: See a learning plan from a course
Given the following lp "plans" exist:
| name | user | description |
| Science plan Year-manage | admin | science plan description |
And the following lp "frameworks" exist:
| shortname | idnumber |
| Framework 1 | sc-y-2 |
And the following lp "competencies" exist:
| shortname | framework |
| comp1 | sc-y-2 |
| comp2 | sc-y-2 |
And I follow "Learning plans"
And I should see "Science plan Year-manage"
And I follow "Science plan Year-manage"
And I should see "Add competency"
And I press "Add competency"
And "Competency picker" "dialogue" should be visible
And I select "comp1" of the competency tree
When I click on "Add" "button" in the "Competency picker" "dialogue"
Then "comp1" "table_row" should exist
And I create a course with:
| Course full name | New course fullname |
| Course short name | New course shortname |
And I navigate to "Competencies" in current page administration
And I press "Add competencies to course"
And "Competency picker" "dialogue" should be visible
And I select "comp1" of the competency tree
And I click on "Add" "button" in the "Competency picker" "dialogue"
And I should see "Learning plans"
And I should see "Science plan Year-manage"
@@ -0,0 +1,190 @@
@tool @javascript @tool_lp @tool_lp_plan_workflow
Feature: Manage plan workflow
As a user
In order to change the status of plan
I need to be able to change the status of a plan
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| user1 | User | 1 | user1@example.com |
| user2 | User | 2 | user2@example.com |
| manager1 | Manager | 1 | manager@example.com |
And the following "roles" exist:
| shortname | name | archetype |
| usermanageowndraftplan | User manage own draft plan role | user |
| usermanageownplan | User manage own plan role | user |
| manageplan | Manager all plans role | manager |
And the following "role capabilities" exist:
| role | moodle/competency:planmanageowndraft | moodle/competency:planmanageown |
| usermanageowndraftplan | allow | |
| usermanageownplan | allow | allow |
| manageplan | allow | allow |
And the following "role capability" exists:
| role | manageplan |
| moodle/competency:planmanage | allow |
| moodle/competency:planview | allow |
| moodle/competency:planreview | allow |
| moodle/competency:planrequestreview | allow |
And the following "role assigns" exist:
| user | role | contextlevel | reference |
| user1 | usermanageowndraftplan | System | |
| user2 | usermanageownplan | System | |
| manager1 | manageplan | System | |
And the following lp "frameworks" exist:
| shortname | idnumber |
| Test-Framework | ID-FW1 |
And the following lp "competencies" exist:
| shortname | framework |
| Test-Comp1 | ID-FW1 |
| Test-Comp2 | ID-FW1 |
And the following lp "plans" exist:
| name | user | description |
| Test-Plan1 | user1 | Description of plan for user 1 |
| Test-Plan2 | user2 | Description of plan for user 2 |
And the following lp "plancompetencies" exist:
| plan | competency |
| Test-Plan1 | Test-Comp1 |
| Test-Plan1 | Test-Comp2 |
| Test-Plan2 | Test-Comp1 |
| Test-Plan2 | Test-Comp2 |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| lp | System | 1 | my-index | content |
Scenario: User can manages his own plan draft
Given I log in as "user1"
And I follow "Profile" in the user menu
When I follow "Learning plans"
Then I should see "List of learning plans"
And I should see "Test-Plan1"
And I should not see "Test-Plan2"
And I click on "Request review" of edit menu in the "Test-Plan1" row
And I should see "Waiting for review"
And I click on "Cancel review" of edit menu in the "Test-Plan1" row
And I should see "Draft"
And I log out
Scenario: User can manages his own plan
Given I log in as "user2"
And I follow "Profile" in the user menu
When I follow "Learning plans"
Then I should see "List of learning plans"
And I should see "Test-Plan2"
And I should not see "Test-Plan1"
And I click on "Request review" of edit menu in the "Test-Plan2" row
And I should see "Waiting for review"
And I click on "Start review" of edit menu in the "Test-Plan2" row
And I should see "In review"
And I click on "Finish review" of edit menu in the "Test-Plan2" row
And I should see "Draft"
And I click on "Make active" of edit menu in the "Test-Plan2" row
And I should see "Active"
And I click on "Complete this learning plan" of edit menu in the "Test-Plan2" row
And I click on "Complete this learning plan" "button" in the "Confirm" "dialogue"
And I should see "Complete"
And I click on "Reopen this learning plan" of edit menu in the "Test-Plan2" row
And I click on "Reopen this learning plan" "button" in the "Confirm" "dialogue"
And I should see "Active"
And I log out
Scenario: Manager can see learning plan with status waiting for review
Given the following lp "plans" exist:
| name | user | description | status |
| Test-Plan3 | user2 | Description of plan 3 for user 1 | waiting for review |
| Test-Plan4 | user1 | Description of plan 3 for user 1 | draft |
When I log in as "manager1"
Then I should see "Test-Plan3"
And I should not see "Test-Plan4"
And I log out
Scenario: Manager can start review of learning plan with status waiting for review
Given the following lp "plans" exist:
| name | user | description | status |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | waiting for review |
And I log in as "manager1"
And I follow "Test-Plan3"
And I should see "User 1"
And I should see "Test-Plan3"
When I follow "Start review"
Then I should see "In review"
And I log out
Scenario: Manager can reject a learning plan with status in review
Given the following lp "plans" exist:
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | in review | manager1 |
And I log in as "manager1"
And I follow "Test-Plan3"
And I should see "User 1"
And I should see "Test-Plan3"
And I should see "In review"
When I follow "Finish review"
Then I should see "Draft"
And I log out
Scenario: Manager can accept a learning plan with status in review
Given the following lp "plans" exist:
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | in review | manager1 |
And I log in as "manager1"
And I follow "Test-Plan3"
And I should see "User 1"
And I should see "Test-Plan3"
And I should see "In review"
When I follow "Make active"
Then I should see "Active"
And I log out
Scenario: Manager send back to draft an active learning plan
Given the following lp "plans" exist:
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
When I click on "Send back to draft" of edit menu in the "Test-Plan3" row
And I follow "Test-Plan4"
And I follow "Send back to draft"
And I follow "Learning plans"
Then I should see "Draft"
And I should not see "Active"
And I log out
Scenario: Manager change an active learning plan to completed
Given the following lp "plans" exist:
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | active | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | active | manager1 |
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
When I click on "Complete this learning plan" of edit menu in the "Test-Plan3" row
And I click on "Complete this learning plan" "button" in the "Confirm" "dialogue"
And I wait until the page is ready
And I follow "Test-Plan4"
And I follow "Complete this learning plan"
And I click on "Complete this learning plan" "button" in the "Confirm" "dialogue"
And I follow "Learning plans"
Then I should see "Complete"
And I should not see "Active"
And I log out
Scenario: Manager reopen a complete learning plan
Given the following lp "plans" exist:
| name | user | description | status | reviewer |
| Test-Plan3 | user1 | Description of plan 3 for user 1 | complete | manager1 |
| Test-Plan4 | user1 | Description of plan 4 for user 1 | complete | manager1 |
And I am on the "user1" "user > profile" page logged in as "manager1"
And I follow "Learning plans"
And I should see "List of learning plans"
When I click on "Reopen this learning plan" of edit menu in the "Test-Plan3" row
And I click on "Reopen this learning plan" "button" in the "Confirm" "dialogue"
And I follow "Test-Plan4"
And I follow "Reopen this learning plan"
And I click on "Reopen this learning plan" "button" in the "Confirm" "dialogue"
And I follow "Learning plans"
Then I should see "Active"
And I should not see "Complete"
And I log out
@@ -0,0 +1,61 @@
@tool @javascript @tool_lp @tool_lp_template
Feature: Manage plearning plan templates
As a learning plan admin
In order to perform CRUD operations on learning plan template
I need to create, update and delete learning plan temlate
Background:
Given I log in as "admin"
And I change window size to "small"
And I am on site homepage
Scenario: Create a new learning plan template
Given I navigate to "Competencies > Learning plan templates" in site administration
And I should see "List of learning plan templates"
And I click on "Add new learning plan template" "button"
And I should see "Add new learning plan template"
And I set the field "Name" to "Science template"
And I set the field "Description" to "Here description of learning plan template"
When I press "Save changes"
Then I should see "Learning plan template created"
And I should see "Science template"
Scenario: Read a learning plan template
Given the following lp "templates" exist:
| shortname | description |
| Science template Year-2 | science template description |
And I navigate to "Competencies > Learning plan templates" in site administration
And I should see "Science template Year-2"
When I click on "Science template Year-2" "link"
Then I should see "Science template Year-2"
And I should see "Learning plan template competencies"
Scenario: Edit a learning plan template
Given the following lp "templates" exist:
| shortname | description |
| Science template Year-3 | science template description |
And I navigate to "Competencies > Learning plan templates" in site administration
And I should see "Science template Year-3"
And I click on "Edit" of edit menu in the "Science template Year-3" row
And the field "Name" matches value "Science template Year-3"
And I set the field "Name" to "Science template Year-3 Edited"
When I press "Save changes"
Then I should see "Learning plan template updated"
And I should see "Science template Year-3 Edited"
Scenario: Delete a learning plan template
Given the following lp "templates" exist:
| shortname | description |
| Science template Year-4 | science template description |
And I navigate to "Competencies > Learning plan templates" in site administration
And I should see "Science template Year-4"
And I click on "Delete" of edit menu in the "Science template Year-4" row
And "Confirm" "dialogue" should be visible
And "Delete" "button" should exist in the "Confirm" "dialogue"
And "Cancel" "button" should exist in the "Confirm" "dialogue"
And I click on "Cancel" "button" in the "Confirm" "dialogue"
And I click on "Delete" of edit menu in the "Science template Year-4" row
And "Confirm" "dialogue" should be visible
When I click on "Delete" "button" in the "Confirm" "dialogue"
And I wait until the page is ready
Then I should not see "Science template Year-4"
@@ -0,0 +1,72 @@
@tool @javascript @tool_lp @tool_lp_user_evidence_comp_link
Feature: Manage competencies linked to evidence of prior learning
To link or unlink competency to evidence of prior learning
As learning plan admin
I need to link and unlink competencies from evidence of prior learning
Background:
Given the following lp "frameworks" exist:
| shortname | idnumber |
| Test-Framework | ID-FW1 |
And the following lp "competencies" exist:
| shortname | framework |
| Test-Comp1 | ID-FW1 |
| Test-Comp2 | ID-FW1 |
And the following lp "plans" exist:
| name | user | description |
| Test-Plan | admin | Plan description |
And the following lp "plancompetencies" exist:
| plan | competency |
| Test-Plan | Test-Comp1 |
| Test-Plan | Test-Comp2 |
And the following lp "userevidence" exist:
| name | description | user |
| Test-Evidence | Description evidence | admin |
When I log in as "admin"
And I follow "Profile" in the user menu
And I follow "Learning plans"
Then I should see "Evidence of prior learning"
Scenario: Link competency to evidence of prior learning from page
Given I follow "Evidence of prior learning"
And I should see "List of evidence"
And I should see "Test-Evidence"
And I click on "Test-Evidence" "link"
And I should see "Linked competencies"
And I press "Link competencies"
And "Competency picker" "dialogue" should be visible
And I select "Test-Comp1" of the competency tree
When I click on "Add" "button" in the "Competency picker" "dialogue"
Then "Test-Comp1" "table_row" should exist
Scenario: Link competency to evidence of prior learning from list
Given I follow "Evidence of prior learning"
And I change window size to "large"
And I should see "List of evidence"
And I should see "Test-Evidence"
And I click on "Link" of edit menu in the "Test-Evidence" row
And "Competency picker" "dialogue" should be visible
And I select "Test-Comp2" of the competency tree
When I click on "Add" "button" in the "Competency picker" "dialogue"
Then "Test-Comp2" "table_row" should exist
Scenario: Unlink competency from evidence of prior learning
Given the following lp "userevidencecompetencies" exist:
| userevidence | competency |
| Test-Evidence | Test-Comp1 |
| Test-Evidence | Test-Comp2 |
Given the following lp "usercompetencies" exist:
| user | competency |
| admin | Test-Comp1 |
| admin | Test-Comp2 |
And I follow "Evidence of prior learning"
And I should see "List of evidence"
And I should see "Test-Evidence"
And I click on "Test-Evidence" "link"
And I should see "Linked competencies"
And I should see "Test-Comp1"
And I should see "Test-Comp2"
When I click on "Delete" "link" in the "Test-Comp1" "table_row"
And I wait until the page is ready
Then I should not see "Test-Comp1"
And I should see "Test-Comp2"
@@ -0,0 +1,81 @@
@tool @javascript @tool_lp @tool_lp_user_evidence
Feature: Manage evidence of prior learning
In order to perform CRUD operations on evidence of prior learning
As a user
I need to create, update and delete evidence of prior learning
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
|user1 | User | 1 | user1@example.com |
When I log in as "user1"
And I follow "Profile" in the user menu
And I follow "Learning plans"
Then I should see "Evidence of prior learning"
Scenario: Create a new evidence of prior learning
Given I follow "Evidence of prior learning"
And I should see "List of evidence"
When I click on "Add new evidence" "button"
And I set the field "Name" to "Evidence-1"
And I set the field "Description" to "Evidence-1 description"
And I press "Save changes"
Then I should see "Evidence of prior learning created"
And I should see "Evidence-1"
Scenario: Read an evidence of prior learning
Given the following lp "userevidence" exist:
| name | description | user |
| Evidence-2 | Evidence-2 description | user1 |
And I follow "Evidence of prior learning"
And I should see "List of evidence"
And I should see "Evidence-2"
When I click on "Evidence-2" "link"
Then I should see "Evidence-2"
Scenario: Edit an evidence of prior learning
Given the following lp "userevidence" exist:
| name | description | user |
| Evidence-3 | Evidence-3 description | user1 |
And I follow "Evidence of prior learning"
And I should see "List of evidence"
And I click on "Edit" of edit menu in the "Evidence-3" row
And the field "Name" matches value "Evidence-3"
When I set the field "Name" to "Evidence-3 Edited"
And I press "Save changes"
Then I should see "Evidence of prior learning updated"
And I should see "Evidence-3 Edited"
Scenario: Delete an evidence of prior learning
Given the following lp "userevidence" exist:
| name | description | user |
| Evidence-4 | Evidence-4 description | user1 |
And I follow "Evidence of prior learning"
And I should see "List of evidence"
And I click on "Delete" of edit menu in the "Evidence-4" row
And I click on "Cancel" "button" in the "Confirm" "dialogue"
And I click on "Delete" of edit menu in the "Evidence-4" row
And "Confirm" "dialogue" should be visible
When I click on "Delete" "button" in the "Confirm" "dialogue"
And I wait until the page is ready
Then I should not see "Evidence-4"
Scenario: List evidences of prior learning
Given the following "users" exist:
| username | firstname | lastname | email |
|user2 | User | 2 | user2@example.com |
And the following lp "userevidence" exist:
| name | description | user |
| Evidence-5 | Evidence-5 description | user1 |
| Evidence-6 | Evidence-6 description | user2 |
And I follow "Evidence of prior learning"
And I should see "List of evidence"
And I should see "Evidence-5"
When I log out
And I log in as "user2"
And I follow "Profile" in the user menu
And I follow "Learning plans"
And I follow "Evidence of prior learning"
Then I should see "List of evidence"
And I should see "Evidence-6"
And I should not see "Evidence-5"
@@ -0,0 +1,187 @@
@tool @tool_lp @javascript
Feature: View competencies
In order to access competency information
As a user
I need to view user competencies
Background:
Given the following "users" exist:
| username | firstname | lastname |
| student1 | Student | first |
| teacher1 | Teacher | first |
And the following "system role assigns" exist:
| user | role | contextlevel |
| teacher1 | editingteacher | System |
And the following "permission overrides" exist:
| capability | permission | role | contextlevel | reference |
| moodle/competency:planview | Allow | editingteacher | System | |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
And the following "scales" exist:
| name | scale |
| Test Scale | Bad, Good, Great |
And the following "core_competency > frameworks" exist:
| shortname | idnumber | scale |
| Cookery | cookery | Test Scale |
| Literacy | literacy | Test Scale |
And the following "core_competency > competencies" exist:
| shortname | idnumber | description | competencyframework |
| Salads | salads | Salads are important | cookery |
| Desserts | desserts | Desserts are important | cookery |
| Cakes | cakes | Cakes are important | cookery |
| Reading | reading | Reading is important | literacy |
| Writing | writing | Writing is important | literacy |
And the following "core_competency > related_competencies" exist:
| competency | relatedcompetency |
| desserts | cakes |
And the following "core_competency > plans" exist:
| name | description | competencies | user |
| Cookery | Cookery is important | salads, desserts, cakes | student1 |
| Literacy | Literacy is important | reading, writing | student1 |
And the following "core_competency > course_competencies" exist:
| course | competency |
| C1 | salads |
| C1 | desserts |
| C1 | cakes |
| C1 | reading |
| C1 | writing |
And the following "core_competency > user_competency" exist:
| competency | user | grade |
| salads | student1 | Good |
| desserts | student1 | Great |
| cakes | student1 | Great |
And the following "core_competency > user_competency_courses" exist:
| course | competency | user | grade |
| C1 | salads | student1 | Good |
| C1 | desserts | student1 | Great |
| C1 | cakes | student1 | Great |
Scenario: Student view
# Course competencies
Given I am on the "C1" "tool_lp > course competencies" page logged in as "student1"
Then I should see "You are proficient in 3 out of 5 competencies in this course"
And "Salads are important" "tool_lp > competency description" should exist in the "Salads" "tool_lp > competency"
And "Good" "tool_lp > competency grade" should exist in the "Salads" "tool_lp > competency"
And "Desserts are important" "tool_lp > competency description" should exist in the "Desserts" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should exist in the "Desserts" "tool_lp > competency"
And "Cakes are important" "tool_lp > competency description" should exist in the "Cakes" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should exist in the "Cakes" "tool_lp > competency"
And "Reading is important" "tool_lp > competency description" should exist in the "Reading" "tool_lp > competency"
And "Good" "tool_lp > competency grade" should not exist in the "Reading" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should not exist in the "Reading" "tool_lp > competency"
And "Bad" "tool_lp > competency grade" should not exist in the "Reading" "tool_lp > competency"
And "Writing is important" "tool_lp > competency description" should exist in the "Writing" "tool_lp > competency"
And "Good" "tool_lp > competency grade" should not exist in the "Writing" "tool_lp > competency"
And "Great" "tool_lp > competency grade" should not exist in the "Writing" "tool_lp > competency"
And "Bad" "tool_lp > competency grade" should not exist in the "Writing" "tool_lp > competency"
# Course competencies details
And I click on "Desserts" "link" in the "Desserts" "tool_lp > competency"
And I should see "Desserts are important"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Course competencies summary
And I click on "Cakes" "link"
And I should see "Cakes are important"
# Learning plans
And I click on "Close" "button" in the "Cakes" "dialogue"
And I follow "Profile" in the user menu
And I click on "Learning plans" "link"
And I should see "Cookery"
And I should see "Literacy"
# Learning plans details
And I click on "Cookery" "link"
And I should see "Cookery is important"
And I should see "3 out of 3 competencies are proficient"
And "Good" "tool_lp > learning plan rating" should exist in the "Salads" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Salads" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Desserts" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Desserts" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Cakes" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Cakes" "tool_lp > learning plan"
And I should not see "Literacy"
And I should not see "Reading"
And I should not see "Writing"
# Learning plans competency details
And I click on "Desserts" "link" in the "Desserts" "tool_lp > learning plan"
And I should see "Desserts are important"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Learning plans competency summary
And I click on "Cakes cakes" "link"
And I should see "Cakes are important"
Scenario: Teacher view
# Participant competencies
Given I am on the "C1" "report_competency > breakdown" page logged in as "teacher1"
Then I should see "Student first"
And "Good" "report_competency > breakdown rating" should exist in the "Salads" "report_competency > breakdown"
And "Great" "report_competency > breakdown rating" should exist in the "Desserts" "report_competency > breakdown"
And "Great" "report_competency > breakdown rating" should exist in the "Cakes" "report_competency > breakdown"
And "Not rated" "report_competency > breakdown rating" should exist in the "Reading" "report_competency > breakdown"
And "Not rated" "report_competency > breakdown rating" should exist in the "Writing" "report_competency > breakdown"
# Participant competencies details
And I click on "Great" "report_competency > breakdown rating" in the "Desserts" "report_competency > breakdown"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Participant competencies summary
And I click on "Cakes" "tool_lp > competency page related competency"
And I should see "Cakes are important"
# Participant learning plans
And I click on "Close" "button" in the "Cakes" "dialogue"
And I click on "Close" "button" in the "User competency summary" "dialogue"
And I navigate to course participants
And I click on "Student first" "link"
And I click on "Learning plans" "link"
And I should see "Cookery"
And I should see "Literacy"
# Participant learning plans details
And I click on "Cookery" "link"
And I should see "Cookery is important"
And I should see "3 out of 3 competencies are proficient"
And "Good" "tool_lp > learning plan rating" should exist in the "Salads" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Salads" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Desserts" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Desserts" "tool_lp > learning plan"
And "Great" "tool_lp > learning plan rating" should exist in the "Cakes" "tool_lp > learning plan"
And "Yes" "tool_lp > learning plan proficiency" should exist in the "Cakes" "tool_lp > learning plan"
And I should not see "Literacy"
And I should not see "Reading"
And I should not see "Writing"
# Learning plans competency details
And I click on "Desserts" "link"
And I should see "Desserts are important"
And "Yes" "tool_lp > competency page proficiency" should exist
And "Great" "tool_lp > competency page rating" should exist
# Learning plans competency summary
And I click on "Cakes" "tool_lp > competency page related competency"
And I should see "Cakes are important"
+478
View File
@@ -0,0 +1,478 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_lp;
use core_competency\api;
use core_external\external_api;
use externallib_advanced_testcase;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* External learning plans webservice API tests.
*
* @package tool_lp
* @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class externallib_test extends externallib_advanced_testcase {
/** @var \stdClass $creator User with enough permissions to create insystem context. */
protected $creator = null;
/** @var \stdClass $catcreator User with enough permissions to create incategory context. */
protected $catcreator = null;
/** @var \stdClass $category Category */
protected $category = null;
/** @var \stdClass $category Category */
protected $othercategory = null;
/** @var \stdClass $user User with enough permissions to view insystem context */
protected $user = null;
/** @var \stdClass $catuser User with enough permissions to view incategory context */
protected $catuser = null;
/** @var int Creator role id */
protected $creatorrole = null;
/** @var int User role id */
protected $userrole = null;
/**
* Setup function- we will create a course and add an assign instance to it.
*/
protected function setUp(): void {
global $DB, $CFG;
$this->resetAfterTest(true);
// Create some users.
$creator = $this->getDataGenerator()->create_user();
$user = $this->getDataGenerator()->create_user();
$catuser = $this->getDataGenerator()->create_user();
$catcreator = $this->getDataGenerator()->create_user();
$category = $this->getDataGenerator()->create_category();
$othercategory = $this->getDataGenerator()->create_category();
$syscontext = \context_system::instance();
$catcontext = \context_coursecat::instance($category->id);
// Fetching default authenticated user role.
$authrole = $DB->get_record('role', array('id' => $CFG->defaultuserroleid));
// Reset all default authenticated users permissions.
unassign_capability('moodle/competency:competencygrade', $authrole->id);
unassign_capability('moodle/competency:competencymanage', $authrole->id);
unassign_capability('moodle/competency:competencyview', $authrole->id);
unassign_capability('moodle/competency:planmanage', $authrole->id);
unassign_capability('moodle/competency:planmanagedraft', $authrole->id);
unassign_capability('moodle/competency:planmanageown', $authrole->id);
unassign_capability('moodle/competency:planview', $authrole->id);
unassign_capability('moodle/competency:planviewdraft', $authrole->id);
unassign_capability('moodle/competency:planviewown', $authrole->id);
unassign_capability('moodle/competency:planviewowndraft', $authrole->id);
unassign_capability('moodle/competency:templatemanage', $authrole->id);
unassign_capability('moodle/competency:templateview', $authrole->id);
unassign_capability('moodle/cohort:manage', $authrole->id);
unassign_capability('moodle/competency:coursecompetencyconfigure', $authrole->id);
// Creating specific roles.
$this->creatorrole = create_role('Creator role', 'lpcreatorrole', 'learning plan creator role description');
$this->userrole = create_role('User role', 'lpuserrole', 'learning plan user role description');
assign_capability('moodle/competency:competencymanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:coursecompetencyconfigure', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planmanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planmanagedraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planmanageown', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planview', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:planviewdraft', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:templatemanage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:competencygrade', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/cohort:manage', CAP_ALLOW, $this->creatorrole, $syscontext->id);
assign_capability('moodle/competency:competencyview', CAP_ALLOW, $this->userrole, $syscontext->id);
assign_capability('moodle/competency:templateview', CAP_ALLOW, $this->userrole, $syscontext->id);
assign_capability('moodle/competency:planviewown', CAP_ALLOW, $this->userrole, $syscontext->id);
assign_capability('moodle/competency:planviewowndraft', CAP_ALLOW, $this->userrole, $syscontext->id);
role_assign($this->creatorrole, $creator->id, $syscontext->id);
role_assign($this->creatorrole, $catcreator->id, $catcontext->id);
role_assign($this->userrole, $user->id, $syscontext->id);
role_assign($this->userrole, $catuser->id, $catcontext->id);
$this->creator = $creator;
$this->catcreator = $catcreator;
$this->user = $user;
$this->catuser = $catuser;
$this->category = $category;
$this->othercategory = $othercategory;
accesslib_clear_all_caches_for_unit_testing();
}
public function test_search_users_by_capability(): void {
global $CFG;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$ux = $dg->create_user();
$u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan',
'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing',
'institution' => 'HQ'));
// First we search with no capability assigned.
$this->setUser($ux);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(0, $result['users']);
$this->assertEquals(0, $result['count']);
// Now we assign a different capability.
$usercontext = \context_user::instance($u1->id);
$systemcontext = \context_system::instance();
$customrole = $this->assignUserCapability('moodle/competency:planview', $usercontext->id);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(0, $result['users']);
$this->assertEquals(0, $result['count']);
// Now we assign a matching capability in the same role.
$usercontext = \context_user::instance($u1->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $customrole);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now assign another role with the same capability (test duplicates).
role_assign($this->creatorrole, $ux->id, $usercontext->id);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now lets try a different user with only the role at system level.
$ux2 = $dg->create_user();
role_assign($this->creatorrole, $ux2->id, $systemcontext->id);
$this->setUser($ux2);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now lets try a different user with only the role at user level.
$ux3 = $dg->create_user();
role_assign($this->creatorrole, $ux3->id, $usercontext->id);
$this->setUser($ux3);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Switch back.
$this->setUser($ux);
// Now add a prevent override (will change nothing because we still have an ALLOW).
assign_capability('moodle/competency:planmanage', CAP_PREVENT, $customrole, $usercontext->id);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
// Now change to a prohibit override (should prevent access).
assign_capability('moodle/competency:planmanage', CAP_PROHIBIT, $customrole, $usercontext->id);
$result = external::search_users('yyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
}
/**
* Ensures that overrides, as well as system permissions, are respected.
*/
public function test_search_users_by_capability_the_comeback(): void {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$master = $dg->create_user();
$manager = $dg->create_user();
$slave1 = $dg->create_user(array('lastname' => 'MOODLER'));
$slave2 = $dg->create_user(array('lastname' => 'MOODLER'));
$slave3 = $dg->create_user(array('lastname' => 'MOODLER'));
$syscontext = \context_system::instance();
$slave1context = \context_user::instance($slave1->id);
$slave2context = \context_user::instance($slave2->id);
$slave3context = \context_user::instance($slave3->id);
// Creating a role giving the site config.
$roleid = $dg->create_role();
assign_capability('moodle/site:config', CAP_ALLOW, $roleid, $syscontext->id, true);
// Create a role override for slave 2.
assign_capability('moodle/site:config', CAP_PROHIBIT, $roleid, $slave2context->id, true);
// Assigning the role.
// Master -> System context.
// Manager -> User context.
role_assign($roleid, $master->id, $syscontext);
role_assign($roleid, $manager->id, $slave1context);
// Flush accesslib.
accesslib_clear_all_caches_for_unit_testing();
// Confirm.
// Master has system permissions.
$this->setUser($master);
$this->assertTrue(has_capability('moodle/site:config', $syscontext));
$this->assertTrue(has_capability('moodle/site:config', $slave1context));
$this->assertFalse(has_capability('moodle/site:config', $slave2context));
$this->assertTrue(has_capability('moodle/site:config', $slave3context));
// Manager only has permissions in slave 1.
$this->setUser($manager);
$this->assertFalse(has_capability('moodle/site:config', $syscontext));
$this->assertTrue(has_capability('moodle/site:config', $slave1context));
$this->assertFalse(has_capability('moodle/site:config', $slave2context));
$this->assertFalse(has_capability('moodle/site:config', $slave3context));
// Now do the test.
$this->setUser($master);
$result = external::search_users('MOODLER', 'moodle/site:config');
$this->assertCount(2, $result['users']);
$this->assertEquals(2, $result['count']);
$this->assertArrayHasKey($slave1->id, $result['users']);
$this->assertArrayHasKey($slave3->id, $result['users']);
$this->setUser($manager);
$result = external::search_users('MOODLER', 'moodle/site:config');
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
$this->assertArrayHasKey($slave1->id, $result['users']);
}
public function test_search_users(): void {
global $CFG;
$this->resetAfterTest(true);
$dg = $this->getDataGenerator();
$ux = $dg->create_user();
$u1 = $dg->create_user(array('idnumber' => 'Cats', 'firstname' => 'Bob', 'lastname' => 'Dyyylan',
'email' => 'bobbyyy@dyyylan.com', 'phone1' => '123456', 'phone2' => '78910', 'department' => 'Marketing',
'institution' => 'HQ'));
$u2 = $dg->create_user(array('idnumber' => 'Dogs', 'firstname' => 'Alice', 'lastname' => 'Dyyylan',
'email' => 'alyyyson@dyyylan.com', 'phone1' => '33333', 'phone2' => '77777', 'department' => 'Development',
'institution' => 'O2'));
$u3 = $dg->create_user(array('idnumber' => 'Fish', 'firstname' => 'Thomas', 'lastname' => 'Xow',
'email' => 'fishyyy@moodle.com', 'phone1' => '77777', 'phone2' => '33333', 'department' => 'Research',
'institution' => 'Bob'));
// We need to give the user the capability we are searching for on each of the test users.
$this->setAdminUser();
$usercontext = \context_user::instance($u1->id);
$dummyrole = $this->assignUserCapability('moodle/competency:planmanage', $usercontext->id);
$usercontext = \context_user::instance($u2->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$usercontext = \context_user::instance($u3->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$this->setUser($ux);
$usercontext = \context_user::instance($u1->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$usercontext = \context_user::instance($u2->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$usercontext = \context_user::instance($u3->id);
$this->assignUserCapability('moodle/competency:planmanage', $usercontext->id, $dummyrole);
$this->setAdminUser();
// No identity fields.
$CFG->showuseridentity = '';
$result = external::search_users('cats', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(0, $result['users']);
$this->assertEquals(0, $result['count']);
// Filter by name.
$CFG->showuseridentity = '';
$result = external::search_users('dyyylan', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(2, $result['users']);
$this->assertEquals(2, $result['count']);
$this->assertEquals($u2->id, $result['users'][0]['id']);
$this->assertEquals($u1->id, $result['users'][1]['id']);
// Filter by institution and name.
$CFG->showuseridentity = 'institution';
$result = external::search_users('bob', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(2, $result['users']);
$this->assertEquals(2, $result['count']);
$this->assertEquals($u1->id, $result['users'][0]['id']);
$this->assertEquals($u3->id, $result['users'][1]['id']);
// Filter by id number.
$CFG->showuseridentity = 'idnumber';
$result = external::search_users('cats', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
$this->assertEquals($u1->id, $result['users'][0]['id']);
$this->assertEquals($u1->idnumber, $result['users'][0]['idnumber']);
$this->assertEmpty($result['users'][0]['email']);
$this->assertEmpty($result['users'][0]['phone1']);
$this->assertEmpty($result['users'][0]['phone2']);
$this->assertEmpty($result['users'][0]['department']);
$this->assertEmpty($result['users'][0]['institution']);
// Filter by email.
$CFG->showuseridentity = 'email';
$result = external::search_users('yyy', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(3, $result['users']);
$this->assertEquals(3, $result['count']);
$this->assertEquals($u2->id, $result['users'][0]['id']);
$this->assertEquals($u2->email, $result['users'][0]['email']);
$this->assertEquals($u1->id, $result['users'][1]['id']);
$this->assertEquals($u1->email, $result['users'][1]['email']);
$this->assertEquals($u3->id, $result['users'][2]['id']);
$this->assertEquals($u3->email, $result['users'][2]['email']);
// Filter by any.
$CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution';
$result = external::search_users('yyy', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(3, $result['users']);
$this->assertEquals(3, $result['count']);
$this->assertArrayHasKey('idnumber', $result['users'][0]);
$this->assertArrayHasKey('email', $result['users'][0]);
$this->assertArrayHasKey('phone1', $result['users'][0]);
$this->assertArrayHasKey('phone2', $result['users'][0]);
$this->assertArrayHasKey('department', $result['users'][0]);
$this->assertArrayHasKey('institution', $result['users'][0]);
// Switch to a user that cannot view identity fields.
$this->setUser($ux);
$CFG->showuseridentity = 'idnumber,email,phone1,phone2,department,institution';
// Only names are included.
$result = external::search_users('fish');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(0, $result['users']);
$this->assertEquals(0, $result['count']);
$result = external::search_users('bob', 'moodle/competency:planmanage');
$result = external_api::clean_returnvalue(external::search_users_returns(), $result);
$this->assertCount(1, $result['users']);
$this->assertEquals(1, $result['count']);
$this->assertEquals($u1->id, $result['users'][0]['id']);
$this->assertEmpty($result['users'][0]['idnumber']);
$this->assertEmpty($result['users'][0]['email']);
$this->assertEmpty($result['users'][0]['phone1']);
$this->assertEmpty($result['users'][0]['phone2']);
$this->assertEmpty($result['users'][0]['department']);
$this->assertEmpty($result['users'][0]['institution']);
}
public function test_data_for_user_competency_summary_in_plan(): void {
global $CFG;
$this->setUser($this->creator);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$tpl = $lpg->create_template();
$lpg->create_template_competency(array('templateid' => $tpl->get('id'), 'competencyid' => $c1->get('id')));
$plan = $lpg->create_plan(array('userid' => $this->user->id, 'templateid' => $tpl->get('id'), 'name' => 'Evil'));
$uc = $lpg->create_user_competency(array('userid' => $this->user->id, 'competencyid' => $c1->get('id')));
$evidence = \core_competency\external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 1, true);
$evidence = \core_competency\external::grade_competency_in_plan($plan->get('id'), $c1->get('id'), 2, true);
$summary = external::data_for_user_competency_summary_in_plan($c1->get('id'), $plan->get('id'));
$this->assertTrue($summary->usercompetencysummary->cangrade);
$this->assertEquals('Evil', $summary->plan->name);
$this->assertEquals('B', $summary->usercompetencysummary->usercompetency->gradename);
$this->assertEquals('B', $summary->usercompetencysummary->evidence[0]->gradename);
$this->assertEquals('A', $summary->usercompetencysummary->evidence[1]->gradename);
}
public function test_data_for_user_competency_summary(): void {
$this->setUser($this->creator);
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 1, true);
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 2, true);
$summary = external::data_for_user_competency_summary($this->user->id, $c1->get('id'));
$this->assertTrue($summary->cangrade);
$this->assertEquals('B', $summary->usercompetency->gradename);
$this->assertEquals('B', $summary->evidence[0]->gradename);
$this->assertEquals('A', $summary->evidence[1]->gradename);
}
public function test_data_for_course_competency_page(): void {
$this->setAdminUser();
$dg = $this->getDataGenerator();
$lpg = $dg->get_plugin_generator('core_competency');
$f1 = $lpg->create_framework();
$c1 = $lpg->create_competency(array('competencyframeworkid' => $f1->get('id')));
$course1 = $dg->create_course(array('category' => $this->category->id));
$cc = api::add_competency_to_course($course1->id, $c1->get('id'));
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 1, true);
$evidence = \core_competency\external::grade_competency($this->user->id, $c1->get('id'), 2, true);
$pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
$page = $pagegenerator->create_instance(array('course' => $course1->id));
$page2 = $pagegenerator->create_instance(array('course' => $course1->id));
$cm = get_coursemodule_from_instance('page', $page->id);
$cm2 = get_coursemodule_from_instance('page', $page2->id);
// Add the competency to the course module.
$ccm = api::add_competency_to_course_module($cm, $c1->get('id'));
$summary = external::data_for_course_competencies_page($course1->id, 0);
$summary2 = external::data_for_course_competencies_page($course1->id, $cm->id);
$summary3 = external::data_for_course_competencies_page($course1->id, $cm2->id);
$this->assertEquals(count($summary->competencies), 1);
$this->assertEquals(count($summary->competencies), count($summary2->competencies));
$this->assertEquals(count($summary3->competencies), 0);
}
}