Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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 customfield_textarea;
18
 
19
use core_customfield_generator;
20
use core_customfield_test_instance_form;
21
use context_user;
22
use context_course;
23
use context_system;
24
 
25
/**
26
 * Functional test for customfield_textarea
27
 *
28
 * @package    customfield_textarea
29
 * @copyright  2019 Marina Glancy
30
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31
 * @covers     \customfield_textarea\field_controller
32
 * @covers     \customfield_textarea\data_controller
33
 */
1441 ariadna 34
final class plugin_test extends \advanced_testcase {
1 efrain 35
 
36
    /** @var \stdClass[] */
37
    private $courses = [];
38
    /** @var \core_customfield\category_controller */
39
    private $cfcat;
40
    /** @var \core_customfield\field_controller[] */
41
    private $cfields;
42
    /** @var \core_customfield\data_controller[] */
43
    private $cfdata;
44
 
45
    /**
46
     * Tests set up.
47
     */
48
    public function setUp(): void {
1441 ariadna 49
        parent::setUp();
1 efrain 50
        $this->resetAfterTest();
51
 
52
        $this->cfcat = $this->get_generator()->create_category();
53
 
54
        $this->cfields[1] = $this->get_generator()->create_field(
55
            ['categoryid' => $this->cfcat->get('id'), 'shortname' => 'myfield1', 'type' => 'textarea']);
56
        $this->cfields[2] = $this->get_generator()->create_field(
57
            ['categoryid' => $this->cfcat->get('id'), 'shortname' => 'myfield2', 'type' => 'textarea',
58
                'configdata' => ['required' => 1]]);
59
        $this->cfields[3] = $this->get_generator()->create_field(
60
            ['categoryid' => $this->cfcat->get('id'), 'shortname' => 'myfield3', 'type' => 'textarea',
61
                'configdata' => ['defaultvalue' => 'Value3', 'defaultvalueformat' => FORMAT_MOODLE]]);
62
 
63
        $this->courses[1] = $this->getDataGenerator()->create_course();
64
        $this->courses[2] = $this->getDataGenerator()->create_course();
65
        $this->courses[3] = $this->getDataGenerator()->create_course();
66
 
67
        $this->cfdata[1] = $this->get_generator()->add_instance_data($this->cfields[1], $this->courses[1]->id,
68
            ['text' => 'Value1', 'format' => FORMAT_MOODLE]);
69
        $this->cfdata[2] = $this->get_generator()->add_instance_data($this->cfields[1], $this->courses[2]->id,
70
            ['text' => '<br />', 'format' => FORMAT_MOODLE]);
71
 
72
        $this->setUser($this->getDataGenerator()->create_user());
73
    }
74
 
75
    /**
76
     * Get generator
77
     * @return core_customfield_generator
78
     */
79
    protected function get_generator(): core_customfield_generator {
80
        return $this->getDataGenerator()->get_plugin_generator('core_customfield');
81
    }
82
 
83
    /**
84
     * Test for initialising field and data controllers
85
     */
11 efrain 86
    public function test_initialise(): void {
1 efrain 87
        $f = \core_customfield\field_controller::create($this->cfields[1]->get('id'));
88
        $this->assertTrue($f instanceof field_controller);
89
 
90
        $f = \core_customfield\field_controller::create(0, (object)['type' => 'textarea'], $this->cfcat);
91
        $this->assertTrue($f instanceof field_controller);
92
 
93
        $d = \core_customfield\data_controller::create($this->cfdata[1]->get('id'));
94
        $this->assertTrue($d instanceof data_controller);
95
 
96
        $d = \core_customfield\data_controller::create(0, null, $this->cfields[1]);
97
        $this->assertTrue($d instanceof data_controller);
98
    }
99
 
100
    /**
101
     * Test for configuration form functions
102
     *
103
     * Create a configuration form and submit it with the same values as in the field
104
     */
11 efrain 105
    public function test_config_form(): void {
1 efrain 106
        $this->setAdminUser();
107
        $submitdata = (array)$this->cfields[3]->to_record();
108
        $submitdata['configdata'] = $this->cfields[3]->get('configdata');
109
 
110
        $submitdata = \core_customfield\field_config_form::mock_ajax_submit($submitdata);
111
        $form = new \core_customfield\field_config_form(null, null, 'post', '', null, true,
112
            $submitdata, true);
113
        $form->set_data_for_dynamic_submission();
114
        $this->assertTrue($form->is_validated());
115
        $form->process_dynamic_submission();
116
    }
117
 
118
    /**
119
     * Test for instance form functions
120
     */
11 efrain 121
    public function test_instance_form(): void {
1 efrain 122
        global $CFG;
123
        require_once($CFG->dirroot . '/customfield/tests/fixtures/test_instance_form.php');
124
        $this->setAdminUser();
125
        $handler = $this->cfcat->get_handler();
126
 
127
        // First try to submit without required field.
128
        $submitdata = (array)$this->courses[1];
129
        core_customfield_test_instance_form::mock_submit($submitdata, []);
130
        $form = new core_customfield_test_instance_form('POST',
131
            ['handler' => $handler, 'instance' => $this->courses[1]]);
132
        $this->assertFalse($form->is_validated());
133
 
134
        // Now with required field.
135
        $submitdata['customfield_myfield2_editor'] = ['text' => 'Some text', 'format' => FORMAT_HTML];
136
        core_customfield_test_instance_form::mock_submit($submitdata, []);
137
        $form = new core_customfield_test_instance_form('POST',
138
            ['handler' => $handler, 'instance' => $this->courses[1]]);
139
        $this->assertTrue($form->is_validated());
140
 
141
        $data = $form->get_data();
142
        $this->assertNotEmpty($data->customfield_myfield1_editor);
143
        $this->assertNotEmpty($data->customfield_myfield2_editor);
144
        $handler->instance_form_save($data);
145
    }
146
 
147
    /**
148
     * Test that instance form save empties the field content for blank values
149
     */
150
    public function test_instance_form_save_clear(): void {
151
        global $CFG;
152
 
153
        require_once("{$CFG->dirroot}/customfield/tests/fixtures/test_instance_form.php");
154
 
155
        $this->setAdminUser();
156
 
157
        $handler = $this->cfcat->get_handler();
158
 
159
        // Set our custom field to a known value.
160
        $submitdata = (array) $this->courses[1] + [
161
            'customfield_myfield1_editor' => ['text' => 'I can see it in your eyes', 'format' => FORMAT_HTML],
162
            'customfield_myfield2_editor' => ['text' => 'I can see it in your smile', 'format' => FORMAT_HTML],
163
        ];
164
 
165
        core_customfield_test_instance_form::mock_submit($submitdata, []);
166
        $form = new core_customfield_test_instance_form('post', ['handler' => $handler, 'instance' => $this->courses[1]]);
167
        $handler->instance_form_save($form->get_data());
168
 
169
        $this->assertEquals($submitdata['customfield_myfield1_editor']['text'],
170
            \core_customfield\data_controller::create($this->cfdata[1]->get('id'))->export_value());
171
 
172
        // Now empty our non-required field.
173
        $submitdata['customfield_myfield1_editor']['text'] = '';
174
 
175
        core_customfield_test_instance_form::mock_submit($submitdata, []);
176
        $form = new core_customfield_test_instance_form('post', ['handler' => $handler, 'instance' => $this->courses[1]]);
177
        $handler->instance_form_save($form->get_data());
178
 
179
        $this->assertNull(\core_customfield\data_controller::create($this->cfdata[1]->get('id'))->export_value());
180
    }
181
 
182
    /**
183
     * Test for data_controller::get_value and export_value
184
     */
11 efrain 185
    public function test_get_export_value(): void {
1 efrain 186
        $this->assertEquals('Value1', $this->cfdata[1]->get_value());
187
        $this->assertEquals('<div class="text_to_html">Value1</div>', $this->cfdata[1]->export_value());
188
 
189
        // Field with empty data.
190
        $this->assertNull($this->cfdata[2]->export_value());
191
 
192
        // Field without data but with a default value.
193
        $d = \core_customfield\data_controller::create(0, null, $this->cfields[3]);
194
        $this->assertEquals('Value3', $d->get_value());
195
        $this->assertEquals('<div class="text_to_html">Value3</div>', $d->export_value());
196
    }
197
 
198
    /**
199
     * Deleting fields and data
200
     */
11 efrain 201
    public function test_delete(): void {
1 efrain 202
        $this->cfcat->get_handler()->delete_all();
203
    }
204
 
205
    /**
206
     * Test embedded file backup and restore.
207
     *
208
     * @covers \customfield_textarea\data_controller::backup_define_structure
209
     * @covers \customfield_textarea\data_controller::backup_restore_structure
210
     */
211
    public function test_embedded_file_backup_and_restore(): void {
212
        global $CFG, $USER, $DB;
213
        require_once($CFG->dirroot . '/customfield/tests/fixtures/test_instance_form.php');
214
        $this->setAdminUser();
215
        $handler = $this->cfcat->get_handler();
216
 
217
        // Create a file.
218
        $fs = get_file_storage();
219
        $filerecord = [
220
            'contextid' => context_user::instance($USER->id)->id,
221
            'component' => 'user',
222
            'filearea' => 'draft',
223
            'itemid' => file_get_unused_draft_itemid(),
224
            'filepath' => '/',
225
            'filename' => 'mytextfile.txt',
226
        ];
227
        $fs->create_file_from_string($filerecord, 'Some text contents');
228
 
229
        // Add the file to the custom field.
230
        $submitdata = (array) $this->courses[1];
231
        $submitdata['customfield_myfield1_editor'] = [
232
            'text' => 'Here is a file: @@PLUGINFILE@@/mytextfile.txt',
233
            'format' => FORMAT_HTML,
234
            'itemid' => $filerecord['itemid'],
235
        ];
236
 
237
        // Set the required field and submit.
238
        $submitdata['customfield_myfield2_editor'] = ['text' => 'Some text', 'format' => FORMAT_HTML];
239
        core_customfield_test_instance_form::mock_submit($submitdata, []);
240
        $form = new core_customfield_test_instance_form('POST',
241
            ['handler' => $handler, 'instance' => $this->courses[1]]);
242
        $this->assertTrue($form->is_validated());
243
 
244
        $data = $form->get_data();
245
        $this->assertNotEmpty($data->customfield_myfield1_editor);
246
        $this->assertNotEmpty($data->customfield_myfield2_editor);
247
        $handler->instance_form_save($data);
248
 
249
        // Check if the draft file exists.
250
        $context = context_course::instance($this->courses[1]->id);
251
        $file = $fs->get_file($filerecord['contextid'], $filerecord['component'], $filerecord['filearea'], $filerecord['itemid'],
252
            $filerecord['filepath'], $filerecord['filename']);
253
        $this->assertNotEmpty($file);
254
 
255
        // Check if the permanent file exists.
256
        $file = $fs->get_file($context->id, 'customfield_textarea', 'value', $this->cfdata[1]->get('id'), '/', 'mytextfile.txt');
257
        $this->assertNotEmpty($file);
258
 
259
        // Backup and restore the course.
260
        $backupid = $this->backup($this->courses[1]);
261
        $newcourseid = $this->restore($backupid, $this->courses[1], '_copy');
262
 
263
        $newcontext = context_course::instance($newcourseid);
264
 
265
        $newcfdata = $DB->get_record('customfield_data', ['instanceid' => $newcourseid, 'fieldid' => $this->cfields[1]->get('id')]);
266
 
267
        // Check if the permanent file exists in the new course after restore.
268
        $file = $fs->get_file($newcontext->id, 'customfield_textarea', 'value', $newcfdata->id, '/', 'mytextfile.txt');
269
        $this->assertNotEmpty($file);
270
    }
271
 
272
    /**
273
     * Backs a course up to temp directory.
274
     *
275
     * @param \stdClass $course Course object to backup
276
     * @return string ID of backup
277
     */
278
    protected function backup($course): string {
279
        global $USER, $CFG;
280
        require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
281
 
282
        // Turn off file logging, otherwise it can't delete the file (Windows).
283
        $CFG->backup_file_logger_level = \backup::LOG_NONE;
284
 
285
        // Do backup with default settings. MODE_IMPORT means it will just
286
        // create the directory and not zip it.
287
        $bc = new \backup_controller(\backup::TYPE_1COURSE, $course->id,
288
            \backup::FORMAT_MOODLE, \backup::INTERACTIVE_NO, \backup::MODE_IMPORT,
289
            $USER->id);
290
        $bc->get_plan()->get_setting('users')->set_status(\backup_setting::NOT_LOCKED);
291
        $bc->get_plan()->get_setting('users')->set_value(true);
292
        $bc->get_plan()->get_setting('logs')->set_value(true);
293
        $backupid = $bc->get_backupid();
294
 
295
        $bc->execute_plan();
296
        $bc->destroy();
297
        return $backupid;
298
    }
299
 
300
    /**
301
     * Restores a course from temp directory.
302
     *
303
     * @param string $backupid Backup id
304
     * @param \stdClass $course Original course object
305
     * @param string $suffix Suffix to add after original course shortname and fullname
306
     * @return int New course id
307
     * @throws \restore_controller_exception
308
     */
309
    protected function restore(string $backupid, $course, string $suffix): int {
310
        global $USER, $CFG;
311
        require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
312
 
313
        // Do restore to new course with default settings.
314
        $newcourseid = \restore_dbops::create_new_course(
315
            $course->fullname . $suffix, $course->shortname . $suffix, $course->category);
316
        $rc = new \restore_controller($backupid, $newcourseid,
317
            \backup::INTERACTIVE_NO, \backup::MODE_GENERAL, $USER->id,
318
            \backup::TARGET_NEW_COURSE);
319
        $rc->get_plan()->get_setting('logs')->set_value(true);
320
        $rc->get_plan()->get_setting('users')->set_value(true);
321
 
322
        $this->assertTrue($rc->execute_precheck());
323
        $rc->execute_plan();
324
        $rc->destroy();
325
 
326
        return $newcourseid;
327
    }
328
}