mirror of
https://github.com/moodle/moodle.git
synced 2025-04-14 13:02:07 +02:00
Merge branch 'MDL-72178-master' of https://github.com/NoelDeMartin/moodle
This commit is contained in:
commit
31e05de8fc
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user