Merge branch 'MDL-72178-master' of https://github.com/NoelDeMartin/moodle

This commit is contained in:
Sara Arjona 2022-08-16 16:58:28 +02:00
commit 31e05de8fc
4 changed files with 261 additions and 63 deletions

View File

@ -154,7 +154,7 @@ abstract class feedback_item_base {
* Prepares the value for exporting to Excel
*
* @param object $item the db-object from feedback_item
* @param string $value a item-related value from feedback_values
* @param object $value object with item-related value from feedback_values in the 'value' property
* @return string
*/
abstract public function get_printval($item, $value);

View File

@ -50,43 +50,28 @@ Feature: Feedbacks in courses with groups
| feedback | Site feedback | Acceptance test site | feedback0 | 2 | 1 | 1 | 1 |
| feedback | Course feedback | C1 | feedback1 | 2 | 1 | 1 | 0 |
| feedback | Course anon feedback | C1 | feedback2 | 1 | 1 | 1 | 0 |
And I am on the "Site feedback" "feedback activity" page logged in as manager
And I click on "Edit questions" "link" in the "[role=main]" "css_element"
And I add a "Multiple choice" question to the feedback with:
| Question | Do you like our site? |
| Label | multichoice2 |
| Multiple choice type | Multiple choice - single answer |
| Hide the "Not selected" option | Yes |
| Multiple choice values | Yes of course\nNot at all\nI don't know |
And I log out
@javascript
Scenario: Non anonymous feedback with groups in a course
Given I am on the "Course feedback" "feedback activity" page logged in as teacher
And I click on "Edit questions" "link" in the "[role=main]" "css_element"
And I add a "Multiple choice" question to the feedback with:
| Question | Do you like this course? |
| Label | multichoice1 |
| Multiple choice type | Multiple choice - single answer |
| Hide the "Not selected" option | Yes |
| Multiple choice values | Yes of course\nNot at all\nI don't know |
And I log out
And I log in as "user1" and complete feedback "Course feedback" in course "Course 1" with:
| Not at all | 1 |
And I log in as "user2" and complete feedback "Course feedback" in course "Course 1" with:
| I don't know | 1 |
And I log in as "user3" and complete feedback "Course feedback" in course "Course 1" with:
| Not at all | 1 |
And I log in as "user4" and complete feedback "Course feedback" in course "Course 1" with:
| Yes of course | 1 |
And I log in as "user5" and complete feedback "Course feedback" in course "Course 1" with:
| Yes of course | 1 |
And I log in as "user6" and complete feedback "Course feedback" in course "Course 1" with:
| Not at all | 1 |
And I log in as "user7" and complete feedback "Course feedback" in course "Course 1" with:
| I don't know | 1 |
Given the following "mod_feedback > question" exists:
| activity | feedback1 |
| name | Do you like this course? |
| questiontype | multichoice |
| label | multichoice1 |
| subtype | r |
| hidenoselect | 1 |
| values | Yes of course\nNot at all\nI don't know |
And the following "mod_feedback > responses" exist:
| activity | user | Do you like this course? |
| feedback1 | user1 | Not at all |
| feedback1 | user2 | I don't know |
| feedback1 | user3 | Not at all |
| feedback1 | user4 | Yes of course |
| feedback1 | user5 | Yes of course |
| feedback1 | user6 | Not at all |
| feedback1 | user7 | I don't know |
# View analysis, user1 should only see one group - group 1
And I am on the "Course feedback" "feedback activity" page logged in as user1
When I am on the "Course feedback" "feedback activity" page logged in as user1
And I follow "Analysis"
And I should see "Separate groups: Group 1"
And I show chart data for the "multichoice1" feedback
@ -152,37 +137,44 @@ Feature: Feedbacks in courses with groups
And I should see "Username 3"
@javascript
Scenario: Anonymous feedback with groups in a course
Given I am on the "Course anon feedback" "feedback activity" page logged in as teacher
And I click on "Edit questions" "link" in the "[role=main]" "css_element"
And I add a "Multiple choice" question to the feedback with:
| Question | Do you like this course? |
| Label | multichoice1 |
| Multiple choice type | Multiple choice - single answer |
| Hide the "Not selected" option | Yes |
| Multiple choice values | Yes of course\nNot at all\nI don't know |
And I log out
And I log in as "user1" and complete feedback "Course anon feedback" in course "Course 1" with:
| Not at all | 1 |
And I am on the "Course anon feedback" "feedback activity" page logged in as user1
Scenario: Anonymous feedback with groups in a course - insufficient responses
Given the following "mod_feedback > question" exists:
| activity | feedback2 |
| name | Do you like this course? |
| questiontype | multichoice |
| label | multichoice1 |
| subtype | r |
| hidenoselect | 1 |
| values | Yes of course\nNot at all\nI don't know |
And the following "mod_feedback > responses" exist:
| activity | user | Do you like this course? |
| feedback2 | user1 | Not at all |
When I am on the "Course anon feedback" "feedback activity" page logged in as user1
And I follow "Analysis"
Then I should not see "Yes of course"
And I should see "There are insufficient responses for this group"
And I should not see "Yes of course"
And I log out
And I log in as "user2" and complete feedback "Course anon feedback" in course "Course 1" with:
| I don't know | 1 |
And I log in as "user3" and complete feedback "Course anon feedback" in course "Course 1" with:
| Not at all | 1 |
And I log in as "user4" and complete feedback "Course anon feedback" in course "Course 1" with:
| Yes of course | 1 |
And I log in as "user5" and complete feedback "Course anon feedback" in course "Course 1" with:
| Yes of course | 1 |
And I log in as "user6" and complete feedback "Course anon feedback" in course "Course 1" with:
| Not at all | 1 |
And I log in as "user7" and complete feedback "Course anon feedback" in course "Course 1" with:
| I don't know | 1 |
@javascript
Scenario: Anonymous feedback with groups in a course
Given the following "mod_feedback > question" exists:
| activity | feedback2 |
| name | Do you like this course? |
| questiontype | multichoice |
| label | multichoice1 |
| subtype | r |
| hidenoselect | 1 |
| values | Yes of course\nNot at all\nI don't know |
And the following "mod_feedback > responses" exist:
| activity | user | Do you like this course? |
| feedback2 | user1 | Not at all |
| feedback2 | user2 | I don't know |
| feedback2 | user3 | Not at all |
| feedback2 | user4 | Yes of course |
| feedback2 | user5 | Yes of course |
| feedback2 | user6 | Not at all |
| feedback2 | user7 | I don't know |
# View analysis, user1 should only see one group - group 1
And I am on the "Course anon feedback" "feedback activity" page logged in as user1
When I am on the "Course anon feedback" "feedback activity" page logged in as user1
And I follow "Analysis"
And I should see "Separate groups: Group 1"
And I show chart data for the "multichoice1" feedback

View File

@ -0,0 +1,49 @@
<?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/>.
/**
* Behat data generator for mod_feedback.
*
* @package mod_feedback
* @category test
* @copyright 2022 Noel De Martin
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_mod_feedback_generator extends behat_generator_base {
/**
* Get a list of the entities that Behat can create using the generator step.
*
* @return array
*/
protected function get_creatable_entities(): array {
return [
'questions' => [
'singular' => 'question',
'datagenerator' => 'question',
'required' => ['activity'],
'switchids' => ['activity' => 'cmid'],
],
'responses' => [
'singular' => 'response',
'datagenerator' => 'response',
'required' => ['activity', 'user'],
'switchids' => ['activity' => 'cmid', 'user' => 'userid'],
],
];
}
}

View File

@ -83,6 +83,97 @@ class mod_feedback_generator extends testing_module_generator {
return parent::create_instance($record, (array)$options);
}
/**
* Create question.
*
* @param array $data Question data
* @return mixed Question instance
*/
public function create_question(array $data) {
global $DB;
$questiontype = $data['questiontype'] ?? 'textfield';
$cm = get_coursemodule_from_id('feedback', $data['cmid']);
$feedback = $DB->get_record('feedback', ['id' => $cm->instance]);
unset($data['questiontype']);
unset($data['cmid']);
if (isset($data['values'])) {
$data['values'] = $this->format_item_values($questiontype, $data['values']);
}
return call_user_func([$this, "create_item_{$questiontype}"], $feedback, $data);
}
/**
* Create response.
*
* @param array $data Response data.
* @return stdClass feedback_completed response instance.
*/
public function create_response(array $data): stdClass {
global $DB;
$userid = $data['userid'];
$responsenumber = null;
$cm = get_coursemodule_from_id('feedback', $data['cmid']);
$feedback = $DB->get_record('feedback', ['id' => $cm->instance]);
$answers = [];
if (isset($data['responsenumber']) && trim($data['responsenumber']) !== '') {
$responsenumber = $data['responsenumber'];
}
if (isset($data['anonymous']) && trim($data['anonymous']) !== '') {
$anonymous = filter_var(trim($data['anonymous']), FILTER_VALIDATE_BOOLEAN);
$feedback->anonymous = $anonymous ? FEEDBACK_ANONYMOUS_YES : FEEDBACK_ANONYMOUS_NO;
}
unset($data['cmid']);
unset($data['userid']);
unset($data['anonymous']);
unset($data['responsenumber']);
foreach ($data as $question => $response) {
$item = $DB->get_record('feedback_item', ['name' => trim($question)], '*', MUST_EXIST);
$answers["{$item->typ}_{$item->id}"] = $this->get_item_response_value($item, $response);
}
$feedbackcompletion = new mod_feedback_completion(
$feedback,
$cm,
$cm->course,
false,
null,
$feedback->anonymous === FEEDBACK_ANONYMOUS_YES ? null : $userid,
$userid
);
if (!$feedbackcompletion->can_complete()) {
throw new coding_exception("User {$userid} cannot complete this feedback activity.");
}
if (!$feedbackcompletion->is_open()) {
throw new coding_exception("This activity is not open.");
}
$feedbackcompletion->set_module_viewed();
$feedbackcompletion->save_response_tmp((object) $answers);
$feedbackcompletion->save_response();
$completed = $feedbackcompletion->get_completed();
if (!is_null($responsenumber)) {
$DB->update_record('feedback_completed', [
'id' => $completed->id,
'random_response' => $responsenumber,
]);
}
return $completed;
}
/**
* Create info question item.
*
@ -392,5 +483,71 @@ class mod_feedback_generator extends testing_module_generator {
return feedback_create_pagebreak($feedback->id);
}
}
/**
* Format feedback item values.
*
* This method will replace newline characters with the proper line separator for each question type.
*
* @param string $questiontype Question types
* @param string $values Values
* @return string Formatted values
*/
protected function format_item_values(string $questiontype, string $values): string {
global $CFG;
if (!file_exists($CFG->dirroot.'/mod/feedback/item/'.$questiontype.'/lib.php')) {
throw new coding_exception("Question type '$questiontype' not found");
}
require_once($CFG->dirroot.'/mod/feedback/item/'.$questiontype.'/lib.php');
$questiontype = strtoupper($questiontype);
if (defined("FEEDBACK_{$questiontype}_LINE_SEP")) {
return implode(constant("FEEDBACK_{$questiontype}_LINE_SEP"), explode('\n', $values));
}
return $values;
}
/**
* Given a response to a feedback item, return its corresponding value.
*
* @param mixed $record Item record
* @param string $response Response name
* @return int|string Response value
*/
protected function get_item_response_value($record, string $response) {
if (strpos($record->typ, 'multichoice') === 0) {
$item = feedback_get_item_class($record->typ);
return $this->get_choice_item_response_value($item, $record, $response);
}
return $response;
}
/**
* Given a response to a feedback choice item, return its corresponding value.
*
* @param feedback_item_base $item Feedback item
* @param mixed $record Item record
* @param string $response Response
* @param int $offset Choice to start looking from
* @return int Response choice index
*/
protected function get_choice_item_response_value(feedback_item_base $item, $record, string $response, int $offset = 1): int {
$printval = $item->get_printval($record, (object) ['value' => $offset]);
if (empty($printval)) {
throw new coding_exception("Value '$offset' not found");
}
if ($printval === $response) {
return $offset;
}
return $this->get_choice_item_response_value($item, $record, $response, $offset + 1);
}
}