Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace gradepenalty_duedate;
18
 
19
use cm_info;
20
use context_course;
21
use context_module;
22
use context_system;
23
use core\plugininfo\gradepenalty;
24
use core_grades\penalty_manager;
25
use grade_item;
26
use gradepenalty_duedate\tests\penalty_testcase;
27
 
28
/**
29
 * Test for penalty calculator.
30
 *
31
 * @package   gradepenalty_duedate
32
 * @copyright 2024 Catalyst IT Australia Pty Ltd
33
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34
 * @covers \gradepenalty_duedate\penalty_calculator
35
 */
36
final class penalty_calculator_test extends penalty_testcase {
37
    /**
38
     * Data provider for test_calculate_penalty.
39
     */
40
    public static function calculate_penalty_provider(): array {
41
        return [
42
            // Submission date, due date and expected grade.
43
            // No penalty.
44
            [0, 0, 100],
45
            // One day late.
46
            [1, 0, 90],
47
            [DAYSECS, 0, 90],
48
            // Two day late.
49
            [DAYSECS + 1, 0, 80],
50
            [DAYSECS * 2, 0, 80],
51
            // Three day late.
52
            [DAYSECS * 2 + 1, 0, 70],
53
            [DAYSECS * 3, 0, 70],
54
            // Four day late.
55
            [DAYSECS * 3 + 1, 0, 60],
56
            [DAYSECS * 4, 0, 60],
57
            // Five day late.
58
            [DAYSECS * 4 + 1, 0, 50],
59
            [DAYSECS * 5, 0, 50],
60
            // Six day late. Same penalty as five day late.
61
            [DAYSECS * 5 + 1, 0, 50],
62
            [DAYSECS * 6, 0, 50],
63
        ];
64
    }
65
 
66
    /**
67
     * Test calculate penalty.
68
     *
69
     * @dataProvider calculate_penalty_provider
70
     *
71
     * @param int $submissiondate The submission date.
72
     * @param int $duedate The due date.
73
     * @param int $expectedgrade The expected grade.
74
     */
75
    public function test_calculate_penalty(int $submissiondate, int $duedate, int $expectedgrade): void {
76
        $this->resetAfterTest();
77
 
78
        // Create a course and an assignment.
79
        $user = $this->getDataGenerator()->create_user();
80
        $course = $this->getDataGenerator()->create_course();
81
        $assignment = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
82
 
83
        // Create sample rules.
84
        $this->create_sample_rules();
85
 
86
        // Enable grade penalty.
87
        penalty_manager::enable_modules(['quiz', 'assign']);
88
        gradepenalty::enable_plugin('duedate', true);
89
 
90
        // Add a grade.
91
        grade_update(
92
            'mod/assign',
93
            $course->id,
94
            'mod',
95
            'assign',
96
            $assignment->id,
97
            0,
98
            ['userid' => $user->id, 'rawgrade' => 100],
99
        );
100
 
101
        // Get grade item.
102
        $gradeitemparams = [
103
            'courseid' => $course->id,
104
            'itemtype' => 'mod',
105
            'itemmodule' => 'assign',
106
            'iteminstance' => $assignment->id,
107
            'itemnumber' => 0,
108
        ];
109
        $gradeitem = grade_item::fetch($gradeitemparams);
110
 
111
        // Apply penalty.
112
        penalty_manager::apply_grade_penalty_to_user($user->id, $gradeitem, $submissiondate, $duedate);
113
 
114
        // Check the grade.
115
        $this->assertEquals($expectedgrade, $gradeitem->get_final($user->id)->finalgrade);
116
    }
117
 
118
    /**
119
     * Rules set at different contexts.
120
     */
121
    public function test_find_effective_penalty_rules(): void {
122
        global $DB;
123
        $this->resetAfterTest();
124
 
125
        // Create a course and an assignment.
126
        $course = $this->getDataGenerator()->create_course();
127
        $assignment = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
128
        $cm = get_coursemodule_from_instance('assign', $assignment->id, $course->id);
129
        $cm = cm_info::create($cm);
130
 
131
        // Create a penalty rule at the system context.
132
        $systemcontext = context_system::instance();
133
        $systemrule = [
134
            'contextid' => $systemcontext->id,
135
            'overdueby' => 1,
136
            'penalty' => 10,
137
            'sortorder' => 1,
138
        ];
139
        $DB->insert_record('gradepenalty_duedate_rule', (object)$systemrule);
140
        // The penalty should be 10%.
141
        $this->assertEquals(10, penalty_calculator::get_penalty_from_rules($cm, DAYSECS, 0));
142
 
143
        // Create a penalty rule at the course context.
144
        $coursecontext = context_course::instance($course->id);
145
        $courserule = [
146
            'contextid' => $coursecontext->id,
147
            'overdueby' => 1,
148
            'penalty' => 20,
149
            'sortorder' => 1,
150
        ];
151
        $DB->insert_record('gradepenalty_duedate_rule', (object)$courserule);
152
        // The penalty should be 20%.
153
        $this->assertEquals(20, penalty_calculator::get_penalty_from_rules($cm, DAYSECS, 0));
154
 
155
        // Create a penalty rule at the module context.
156
        $cm = get_coursemodule_from_instance('assign', $assignment->id, $course->id);
157
        $cm = cm_info::create($cm);
158
        $modulecontext = context_module::instance($cm->id);
159
        $modulerule = [
160
            'contextid' => $modulecontext->id,
161
            'overdueby' => 1,
162
            'penalty' => 30,
163
            'sortorder' => 1,
164
        ];
165
        $DB->insert_record('gradepenalty_duedate_rule', (object)$modulerule);
166
        // The penalty should be 30%.
167
        $this->assertEquals(30, penalty_calculator::get_penalty_from_rules($cm, DAYSECS, 0));
168
    }
169
}