Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | 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 core;
18
 
19
use block_contents;
20
use custom_menu;
21
use custom_menu_item;
22
use paging_bar;
23
use renderer_base;
24
use single_button;
25
use single_select;
26
use theme_config;
27
use url_select;
28
use user_picture;
29
 
30
defined('MOODLE_INTERNAL') || die();
31
 
32
global $CFG;
33
require_once($CFG->libdir . '/outputcomponents.php');
34
 
35
/**
36
 * Unit tests for lib/outputcomponents.php.
37
 *
38
 * @package   core
39
 * @category  test
40
 * @copyright 2011 David Mudrak <david@moodle.com>
41
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class outputcomponents_test extends \advanced_testcase {
44
 
45
    /**
46
     * Tests user_picture::fields.
47
     *
48
     * @deprecated since Moodle 3.11 MDL-45242
49
     */
50
    public function test_fields_aliasing() {
51
        $fields = user_picture::fields();
52
        $fields = array_map('trim', explode(',', $fields));
53
        $this->assertTrue(in_array('id', $fields));
54
 
55
        $aliased = array();
56
        foreach ($fields as $field) {
57
            if ($field === 'id') {
58
                $aliased['id'] = 'aliasedid';
59
            } else {
60
                $aliased[$field] = 'prefix'.$field;
61
            }
62
        }
63
 
64
        $returned = user_picture::fields('', array('custom1', 'id'), 'aliasedid', 'prefix');
65
        $returned = array_map('trim', explode(',', $returned));
66
        $this->assertEquals(count($returned), count($fields) + 1); // Only one extra field added.
67
 
68
        foreach ($fields as $field) {
69
            if ($field === 'id') {
70
                $expected = "id AS aliasedid";
71
            } else {
72
                $expected = "$field AS prefix$field";
73
            }
74
            $this->assertContains($expected, $returned, "Expected pattern '$expected' not returned");
75
        }
76
        $this->assertContains("custom1 AS prefixcustom1", $returned, "Expected pattern 'custom1 AS prefixcustom1' not returned");
77
 
78
        // Deprecation warnings for user_picture::fields.
79
        $this->assertDebuggingCalledCount(2);
80
    }
81
 
82
    /**
83
     * Tests user_picture::unalias.
84
     */
85
    public function test_fields_unaliasing() {
86
        $fields = implode(',', \core_user\fields::get_picture_fields());
87
        $fields = array_map('trim', explode(',', $fields));
88
 
89
        $fakerecord = new \stdClass();
90
        $fakerecord->aliasedid = 42;
91
        foreach ($fields as $field) {
92
            if ($field !== 'id') {
93
                $fakerecord->{'prefix'.$field} = "Value of $field";
94
            }
95
        }
96
        $fakerecord->prefixcustom1 = 'Value of custom1';
97
 
98
        $returned = user_picture::unalias($fakerecord, array('custom1'), 'aliasedid', 'prefix');
99
 
100
        $this->assertEquals(42, $returned->id);
101
        foreach ($fields as $field) {
102
            if ($field !== 'id') {
103
                $this->assertSame("Value of $field", $returned->{$field});
104
            }
105
        }
106
        $this->assertSame('Value of custom1', $returned->custom1);
107
    }
108
 
109
    /**
110
     * Tests user_picture::unalias with null values.
111
     */
112
    public function test_fields_unaliasing_null() {
113
        $fields = implode(',', \core_user\fields::get_picture_fields());
114
        $fields = array_map('trim', explode(',', $fields));
115
 
116
        $fakerecord = new \stdClass();
117
        $fakerecord->aliasedid = 42;
118
        foreach ($fields as $field) {
119
            if ($field !== 'id') {
120
                $fakerecord->{'prefix'.$field} = "Value of $field";
121
            }
122
        }
123
        $fakerecord->prefixcustom1 = 'Value of custom1';
124
        $fakerecord->prefiximagealt = null;
125
 
126
        $returned = user_picture::unalias($fakerecord, array('custom1'), 'aliasedid', 'prefix');
127
 
128
        $this->assertEquals(42, $returned->id);
129
        $this->assertNull($returned->imagealt);
130
        foreach ($fields as $field) {
131
            if ($field !== 'id' and $field !== 'imagealt') {
132
                $this->assertSame("Value of $field", $returned->{$field});
133
            }
134
        }
135
        $this->assertSame('Value of custom1', $returned->custom1);
136
    }
137
 
138
    public function test_get_url() {
139
        global $DB, $CFG, $USER;
140
 
141
        $this->resetAfterTest();
142
 
143
        // Verify new install contains expected defaults.
144
        $this->assertSame(theme_config::DEFAULT_THEME, $CFG->theme);
145
        $this->assertEquals(1, $CFG->slasharguments);
146
        $this->assertEquals(1, $CFG->themerev);
147
        $this->assertEquals(0, $CFG->themedesignermode);
148
        $this->assertSame('https://www.example.com/moodle', $CFG->wwwroot);
149
        $this->assertEquals(0, $CFG->enablegravatar);
150
        $this->assertSame('mm', $CFG->gravatardefaulturl);
151
 
152
        // Create some users.
153
        $page = new \moodle_page();
154
        $page->set_url('/user/profile.php');
155
        $page->set_context(\context_system::instance());
156
        $renderer = $page->get_renderer('core');
157
 
158
        $user1 = $this->getDataGenerator()->create_user(array('picture'=>11, 'email'=>'user1@example.com'));
159
        $context1 = \context_user::instance($user1->id);
160
        $user2 = $this->getDataGenerator()->create_user(array('picture'=>0, 'email'=>'user2@example.com'));
161
        $context2 = \context_user::instance($user2->id);
162
 
163
        // User 3 is deleted.
164
        $user3 = $this->getDataGenerator()->create_user(array('picture'=>1, 'deleted'=>1, 'email'=>'user3@example.com'));
165
        $this->assertNotEmpty(\context_user::instance($user3->id));
166
        $this->assertEquals(0, $user3->picture);
167
        $this->assertNotEquals('user3@example.com', $user3->email);
168
 
169
        // User 4 is incorrectly deleted with its context deleted as well (testing legacy code).
170
        $user4 = $this->getDataGenerator()->create_user(['picture' => 1, 'deleted' => 1, 'email' => 'user4@example.com']);
171
        \context_helper::delete_instance(CONTEXT_USER, $user4->id);
172
        $this->assertEquals(0, $user4->picture);
173
        $this->assertNotEquals('user4@example.com', $user4->email);
174
 
175
        // Try legacy picture == 1.
176
        $user1->picture = 1;
177
        $up1 = new user_picture($user1);
178
        $this->assertSame($CFG->wwwroot.'/pluginfile.php/'.$context1->id.'/user/icon/boost/f2?rev=1', $up1->get_url($page, $renderer)->out(false));
179
        $user1->picture = 11;
180
 
181
        // Try valid user with picture when user context is not cached - 1 query expected.
182
        \context_helper::reset_caches();
183
        $reads = $DB->perf_get_reads();
184
        $up1 = new user_picture($user1);
185
        $this->assertEquals($reads, $DB->perf_get_reads());
186
        $this->assertSame($CFG->wwwroot.'/pluginfile.php/'.$context1->id.'/user/icon/boost/f2?rev=11', $up1->get_url($page, $renderer)->out(false));
187
        $this->assertEquals($reads+1, $DB->perf_get_reads());
188
 
189
        // Try valid user with contextid hint - no queries expected.
190
        $user1->contextid = $context1->id;
191
        \context_helper::reset_caches();
192
        $reads = $DB->perf_get_reads();
193
        $up1 = new user_picture($user1);
194
        $this->assertEquals($reads, $DB->perf_get_reads());
195
        $this->assertSame($CFG->wwwroot.'/pluginfile.php/'.$context1->id.'/user/icon/boost/f2?rev=11', $up1->get_url($page, $renderer)->out(false));
196
        $this->assertEquals($reads, $DB->perf_get_reads());
197
 
198
        // Try valid user without image - no queries expected.
199
        \context_helper::reset_caches();
200
        $reads = $DB->perf_get_reads();
201
        $up2 = new user_picture($user2);
202
        $this->assertEquals($reads, $DB->perf_get_reads());
203
        $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up2->get_url($page, $renderer)->out(false));
204
        $this->assertEquals($reads, $DB->perf_get_reads());
205
 
206
        // Try guessing of deleted users - no queries expected.
207
        unset($user3->deleted);
208
        \context_helper::reset_caches();
209
        $reads = $DB->perf_get_reads();
210
        $up3 = new user_picture($user3);
211
        $this->assertEquals($reads, $DB->perf_get_reads());
212
        $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up3->get_url($page, $renderer)->out(false));
213
        $this->assertEquals($reads, $DB->perf_get_reads());
214
 
215
        // Try incorrectly deleted users (with valid email and picture flag, but user context removed) - some DB reads expected.
216
        unset($user4->deleted);
217
        $user4->email = 'user4@example.com';
218
        $user4->picture = 1;
219
        $reads = $DB->perf_get_reads();
220
        $up4 = new user_picture($user4);
221
        $this->assertEquals($reads, $DB->perf_get_reads());
222
        $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up4->get_url($page, $renderer)->out(false));
223
        $this->assertGreaterThan($reads, $DB->perf_get_reads());
224
 
225
        // Test gravatar.
226
        set_config('enablegravatar', 1);
227
 
228
        // Deleted user can not have gravatar.
229
        $user3->email = 'deleted';
230
        $user3->picture = 0;
231
        $up3 = new user_picture($user3);
232
        $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up3->get_url($page, $renderer)->out(false));
233
        $user4->email = 'deleted';
234
        $user4->picture = 0;
235
        $up4 = new user_picture($user4);
236
        $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up4->get_url($page, $renderer)->out(false));
237
 
238
        // Http version.
239
        $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot);
240
 
241
        // Verify defaults to misteryman (mm).
242
        $up2 = new user_picture($user2);
243
        $this->assertSame('http://www.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?s=35&d=mm', $up2->get_url($page, $renderer)->out(false));
244
 
245
        // Without gravatardefaulturl, verify we pick own file.
246
        set_config('gravatardefaulturl', '');
247
        $up2 = new user_picture($user2);
248
        $this->assertSame('http://www.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?s=35&d=http%3A%2F%2Fwww.example.com%2Fmoodle%2Fpix%2Fu%2Ff2.png', $up2->get_url($page, $renderer)->out(false));
249
        // Uploaded image takes precedence before gravatar.
250
        $up1 = new user_picture($user1);
251
        $this->assertSame($CFG->wwwroot.'/pluginfile.php/'.$context1->id.'/user/icon/boost/f2?rev=11', $up1->get_url($page, $renderer)->out(false));
252
 
253
        // Uploaded image with token-based access for current user.
254
        $up1 = new user_picture($user1);
255
        $up1->includetoken = true;
256
        $token = get_user_key('core_files', $USER->id);
257
        $this->assertSame($CFG->wwwroot.'/tokenpluginfile.php/'.$token.'/'.$context1->id.'/user/icon/boost/f2?rev=11', $up1->get_url($page, $renderer)->out(false));
258
 
259
        // Uploaded image with token-based access for other user.
260
        $up1 = new user_picture($user1);
261
        $up1->includetoken = $user2->id;
262
        $token = get_user_key('core_files', $user2->id);
263
        $this->assertSame($CFG->wwwroot.'/tokenpluginfile.php/'.$token.'/'.$context1->id.'/user/icon/boost/f2?rev=11', $up1->get_url($page, $renderer)->out(false));
264
 
265
        // Https version.
266
        $CFG->wwwroot = str_replace('http:', 'https:', $CFG->wwwroot);
267
 
268
        $up1 = new user_picture($user1);
269
        $this->assertSame($CFG->wwwroot.'/pluginfile.php/'.$context1->id.'/user/icon/boost/f2?rev=11', $up1->get_url($page, $renderer)->out(false));
270
 
271
        $up2 = new user_picture($user2);
272
        $this->assertSame('https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?s=35&d=https%3A%2F%2Fwww.example.com%2Fmoodle%2Fpix%2Fu%2Ff2.png', $up2->get_url($page, $renderer)->out(false));
273
 
274
        $up3 = new user_picture($user3);
275
        $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up3->get_url($page, $renderer)->out(false));
276
 
277
        $up4 = new user_picture($user4);
278
        $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up4->get_url($page, $renderer)->out(false));
279
 
280
        // TODO MDL-44792 Rewrite those tests to use a fixture.
281
        // Now test gravatar with one theme having own images (afterburner).
282
        // $this->assertFileExists("$CFG->dirroot/theme/afterburner/config.php");
283
        // set_config('theme', 'afterburner');
284
        // $page = new \moodle_page();
285
        // $page->set_url('/user/profile.php');
286
        // $page->set_context(\context_system::instance());
287
        // $renderer = $page->get_renderer('core');
288
 
289
        // $up2 = new user_picture($user2);
290
        // $this->assertEquals('http://www.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?s=35&d=http%3A%2F%2Fwww.example.com%2Fmoodle%2Ftheme%2Fafterburner%2Fpix_core%2Fu%2Ff2.png', $up2->get_url($page, $renderer)->out(false));
291
 
292
        // $up2 = new user_picture($user2);
293
        // $this->assertSame('https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?s=35&d=https%3A%2F%2Fwww.example.com%2Fmoodle%2Ftheme%2Fafterburner%2Fpix_core%2Fu%2Ff2.png', $up2->get_url($page, $renderer)->out(false));
294
        // End of gravatar tests.
295
 
296
        // Test themed images.
297
        // set_config('enablegravatar', 0);
298
        // $this->assertFileExists("$CFG->dirroot/theme/formal_white/config.php"); // Use any other theme.
299
        // set_config('theme', 'formal_white');
300
        // $page = new \moodle_page();
301
        // $page->set_url('/user/profile.php');
302
        // $page->set_context(\context_system::instance());
303
        // $renderer = $page->get_renderer('core');
304
 
305
        // $up1 = new user_picture($user1);
306
        // $this->assertSame($CFG->wwwroot.'/pluginfile.php/'.$context1->id.'/user/icon/formal_white/f2?rev=11', $up1->get_url($page, $renderer)->out(false));
307
 
308
        // $up2 = new user_picture($user2);
309
        // $this->assertSame($CFG->wwwroot.'/theme/image.php/formal_white/core/1/u/f2', $up2->get_url($page, $renderer)->out(false));
310
 
311
        // Test non-slashargument images.
312
        set_config('theme', 'classic');
313
        $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot);
314
        $CFG->slasharguments = 0;
315
        $page = new \moodle_page();
316
        $page->set_url('/user/profile.php');
317
        $page->set_context(\context_system::instance());
318
        $renderer = $page->get_renderer('core');
319
 
320
        $up3 = new user_picture($user3);
321
        $this->assertSame($CFG->wwwroot.'/theme/image.php?theme=classic&component=core&rev=1&image=u%2Ff2', $up3->get_url($page, $renderer)->out(false));
322
    }
323
 
324
    public function test_empty_menu() {
325
        $emptymenu = new custom_menu();
326
        $this->assertInstanceOf(custom_menu::class, $emptymenu);
327
        $this->assertFalse($emptymenu->has_children());
328
    }
329
 
330
    public function test_basic_syntax() {
331
        $definition = <<<EOF
332
Moodle community|http://moodle.org
333
-Moodle free support|http://moodle.org/support
334
-Moodle development|http://moodle.org/development
335
--Moodle Tracker|http://tracker.moodle.org
336
--Moodle Docs|http://docs.moodle.org
337
-Moodle News|http://moodle.org/news
338
Moodle company||Moodle trust pty
339
-Hosting|http://moodle.com/hosting|Commercial hosting
340
-Support|http://moodle.com/support|Commercial support
341
EOF;
342
 
343
        $menu = new custom_menu($definition);
344
        $this->assertInstanceOf('custom_menu', $menu);
345
        $this->assertTrue($menu->has_children());
346
        $firstlevel = $menu->get_children();
347
        $this->assertTrue(is_array($firstlevel));
348
        $this->assertCount(2, $firstlevel);
349
 
350
        $item = array_shift($firstlevel);
351
        $this->assertInstanceOf('custom_menu_item', $item);
352
        $this->assertTrue($item->has_children());
353
        $this->assertCount(3, $item->get_children());
354
        $this->assertEquals('Moodle community', $item->get_text());
355
        $itemurl = $item->get_url();
356
        $this->assertTrue($itemurl instanceof \moodle_url);
357
        $this->assertEquals('http://moodle.org', $itemurl->out());
358
        $this->assertNull($item->get_title()); // Implicit title.
359
 
360
        /** @var custom_menu_item $item */
361
        $item = array_shift($firstlevel);
362
        $this->assertTrue($item->has_children());
363
        $this->assertCount(2, $item->get_children());
364
        $this->assertSame('Moodle company', $item->get_text());
365
        $this->assertNull($item->get_url());
366
        $this->assertSame('Moodle trust pty', $item->get_title());
367
 
368
        $children = $item->get_children();
369
        $subitem = array_shift($children);
370
        $this->assertFalse($subitem->has_children());
371
        $this->assertSame('Hosting', $subitem->get_text());
372
        $this->assertSame('Commercial hosting', $subitem->get_title());
373
    }
374
 
375
    public function test_custommenu_mulitlang() {
376
        $definition = <<<EOF
377
Start|http://school.info
378
Info
379
-English|http://school.info/en|Information in English|en
380
--Nested under English
381
--I will be lost|||de
382
-Deutsch|http://school.info/de|Informationen in deutscher Sprache|de,de_du,de_kids
383
--Nested under Deutsch
384
--I will be lost|||en
385
kontaktieren Sie uns|contactus.php||de
386
Contact us|contactus.php||en
387
EOF;
388
        $definitionen = <<<EOF
389
Start|http://school.info
390
Info
391
-English|http://school.info/en|Information in English|en
392
--Nested under English
393
Contact us|contactus.php||en
394
EOF;
395
        $definitionde = <<<EOF
396
Start|http://school.info
397
Info
398
-Deutsch|http://school.info/de|Informationen in deutscher Sprache|de,de_du,de_kids
399
--Nested under Deutsch
400
kontaktieren Sie uns|contactus.php||de
401
EOF;
402
 
403
        $definitiondedu = <<<EOF
404
Start|http://school.info
405
Info
406
-Deutsch|http://school.info/de|Informationen in deutscher Sprache|de,de_du,de_kids
407
--Nested under Deutsch
408
EOF;
409
 
410
        $parsed = $this->custommenu_out(new custom_menu($definition));
411
        $parseden = $this->custommenu_out(new custom_menu($definition, 'en'));
412
        $parsedde = $this->custommenu_out(new custom_menu($definition, 'de'));
413
        $parseddedu = $this->custommenu_out(new custom_menu($definition, 'de_du'));
414
 
415
        $actualen = $this->custommenu_out(new custom_menu($definitionen, 'en'));
416
        $actualde = $this->custommenu_out(new custom_menu($definitionde, 'de'));
417
        $actualdedu = $this->custommenu_out(new custom_menu($definitiondedu, 'de_du'));
418
 
419
        $this->assertSame($actualen, $parseden, 'The parsed English menu does not match the expected English menu');
420
        $this->assertSame($actualde, $parsedde, 'The parsed German menu does not match the expected German menu');
421
        $this->assertSame($actualdedu, $parseddedu, 'The parsed German [Du] menu does not match the expected German [Du] menu');
422
 
423
        $this->assertNotSame($parsed, $parsedde, 'The menu without language is the same as the German menu. They should differ!');
424
        $this->assertNotSame($parsed, $parseden, 'The menu without language is the same as the English menu. They should differ!');
425
        $this->assertNotSame($parsed, $parseddedu, 'The menu without language is the same as the German [Du] menu. They should differ!');
426
        $this->assertNotSame($parseden, $parsedde, 'The English menu is the same as the German menu. They should differ!');
427
        $this->assertNotSame($parseden, $parseddedu, 'The English menu is the same as the German [Du] menu. They should differ!');
428
        $this->assertNotSame($parseddedu, $parsedde, 'The German [Du] menu is the same as the German menu. They should differ!');
429
    }
430
 
431
    /**
432
     * Support function that takes a custom_menu_item and converts it to a string.
433
     *
434
     * @param custom_menu_item $item
435
     * @param int $depth
436
     * @return string
437
     */
438
    protected function custommenu_out(custom_menu_item $item, $depth = 0) {
439
        $str = str_repeat('-', $depth);
440
        $str .= $item->get_text();
441
        $str .= '|' . $item->get_url();
442
        $str .= '|' . $item->get_title();
443
        if ($item->has_children()) {
444
            $str .= '|' . count($item->get_children());
445
            foreach ($item->get_children() as $child) {
446
                $str .= "\n" . $this->custommenu_out($child, $depth + 1);
447
            }
448
        }
449
        return $str;
450
    }
451
 
452
    public function test_prepare() {
453
        $expecteda = array('<span class="current-page">1</span>',
454
            '<a href="index.php?page=1">2</a>',
455
            '<a href="index.php?page=2">3</a>',
456
            '<a href="index.php?page=3">4</a>',
457
            '<a href="index.php?page=4">5</a>',
458
            '<a href="index.php?page=5">6</a>',
459
            '<a href="index.php?page=6">7</a>',
460
            '<a href="index.php?page=7">8</a>',
461
        );
462
        $expectedb = array('<a href="page?page=3">4</a>',
463
            '<a href="page?page=4">5</a>',
464
            '<span class="current-page">6</span>',
465
            '<a href="page?page=6">7</a>',
466
            '<a href="page?page=7">8</a>',
467
        );
468
 
469
        $mpage = new \moodle_page();
470
        $rbase = new renderer_base($mpage, "/");
471
        $pbara = new paging_bar(40, 0, 5, 'index.php');
472
        $pbara->prepare($rbase, $mpage, "/");
473
        $pbarb = new paging_bar(100, 5, 5, 'page');
474
        $pbarb->maxdisplay = 5;
475
        $pbarb->prepare($rbase, $mpage, "/");
476
 
477
        $this->assertEquals($expecteda, $pbara->pagelinks);
478
        $this->assertEquals($expectedb, $pbarb->pagelinks);
479
    }
480
 
481
    public function test_pix_icon() {
482
        $this->resetAfterTest();
483
 
484
        $page = new \moodle_page();
485
 
486
        set_config('theme', 'boost');
487
        // Need to reset after changing theme.
488
        $page->reset_theme_and_output();
489
        $renderer = $page->get_renderer('core');
490
 
491
        $reason = 'An icon with no alt text is hidden from screenreaders.';
492
        $this->assertStringContainsString('aria-hidden="true"', $renderer->pix_icon('t/print', ''), $reason);
493
 
494
        $reason = 'An icon with alt text is not hidden from screenreaders.';
495
        $this->assertStringNotContainsString('aria-hidden="true"', $renderer->pix_icon('t/print', 'Print'), $reason);
496
 
497
        // Test another theme with a different icon system.
498
        set_config('theme', 'classic');
499
        // Need to reset after changing theme.
500
        $page->reset_theme_and_output();
501
        $renderer = $page->get_renderer('core');
502
 
503
        $reason = 'An icon with no alt text is hidden from screenreaders.';
504
        $this->assertStringContainsString('aria-hidden="true"', $renderer->pix_icon('t/print', ''), $reason);
505
 
506
        $reason = 'An icon with alt text is not hidden from screenreaders.';
507
        $this->assertStringNotContainsString('aria-hidden="true"', $renderer->pix_icon('t/print', 'Print'), $reason);
508
    }
509
 
510
    /**
511
     * Test for checking the template context data for the single_select element.
512
     */
513
    public function test_single_select() {
514
        global $PAGE;
515
 
516
        $fakename = 'fakename';
517
        $fakeclass = 'fakeclass';
518
        $faketitle = 'faketitle';
519
        $fakedisabled = true;
520
        $fakefor = 'fakefor';
521
 
522
        $someid = 'someid';
523
        $realname = 'realname';
524
        $realclass = 'realclass';
525
        $realtitle = 'realtitle';
526
        $realdisabled = false;
527
        $reallabel = 'Some cool label';
528
        $labelclass = 'somelabelclass';
529
        $labelstyle = 'font-weight: bold';
530
 
531
        $dataaction = 'actiondata';
532
        $dataother = 'otherdata';
533
 
534
        $attributes = [
535
            'id' => $someid,
536
            'class' => $fakeclass,
537
            'title' => $faketitle,
538
            'disabled' => $fakedisabled,
539
            'name' => $fakename,
540
            'data-action' => $dataaction,
541
            'data-other' => $dataother,
542
        ];
543
        $labelattributes = [
544
            'for' => $fakefor,
545
            'class' => $labelclass,
546
            'style' => $labelstyle
547
        ];
548
 
549
        $options = [ "Option A", "Option B", "Option C" ];
550
        $nothing = ['' => 'choosedots'];
551
 
552
        $url = new \moodle_url('/');
553
 
554
        $singleselect = new single_select($url, $realname, $options, null, $nothing, 'someformid');
555
        $singleselect->class = $realclass;
556
        $singleselect->tooltip = $realtitle;
557
        $singleselect->disabled = $realdisabled;
558
        $singleselect->attributes = $attributes;
559
        $singleselect->label = $reallabel;
560
        $singleselect->labelattributes = $labelattributes;
561
 
562
        $renderer = $PAGE->get_renderer('core');
563
        $data = $singleselect->export_for_template($renderer);
564
 
565
        $this->assertEquals($realtitle, $data->title);
566
        $this->assertEquals($singleselect->class, $data->classes);
567
        $this->assertEquals($realname, $data->name);
568
        $this->assertEquals($reallabel, $data->label);
569
        $this->assertEquals($realdisabled, $data->disabled);
570
        $this->assertEquals($someid, $data->id);
571
 
572
        // Validate attributes array.
573
        // The following should not be included: id, class, name, disabled.
574
        $this->assertFalse(in_array(['name' => 'id', 'value' => $someid], $data->attributes));
575
        $this->assertFalse(in_array(['name' => 'class', 'value' => $fakeclass], $data->attributes));
576
        $this->assertFalse(in_array(['name' => 'name', 'value' => $fakeclass], $data->attributes));
577
        $this->assertFalse(in_array(['name' => 'disabled', 'value' => $fakedisabled], $data->attributes));
578
        // The rest should be fine.
579
        $this->assertTrue(in_array(['name' => 'data-action', 'value' => $dataaction], $data->attributes));
580
        $this->assertTrue(in_array(['name' => 'data-other', 'value' => $dataother], $data->attributes));
581
 
582
        // Validate label attributes.
583
        // The for attribute should not be included.
584
        $this->assertFalse(in_array(['name' => 'for', 'value' => $someid], $data->labelattributes));
585
        // The rest should be fine.
586
        $this->assertTrue(in_array(['name' => 'class', 'value' => $labelclass], $data->labelattributes));
587
        $this->assertTrue(in_array(['name' => 'style', 'value' => $labelstyle], $data->labelattributes));
588
    }
589
    /**
590
     * Test for checking the template context data for the single_select element.
591
     * @covers \single_button
592
     */
593
    public function test_single_button() {
594
        global $PAGE;
595
        $url = new \moodle_url('/');
596
        $realname = 'realname';
597
        $attributes = [
598
            'data-dummy' => 'dummy',
599
        ];
600
        $singlebutton = new single_button($url, $realname, 'post', single_button::BUTTON_SECONDARY, $attributes);
601
        $renderer = $PAGE->get_renderer('core');
602
        $data = $singlebutton->export_for_template($renderer);
603
 
604
        $this->assertEquals($realname, $data->label);
605
        $this->assertEquals('post', $data->method);
606
        $this->assertEquals('singlebutton', $data->classes);
607
        $this->assertEquals('secondary', $data->type);
608
        $this->assertEquals($attributes['data-dummy'], $data->attributes[0]['value']);
609
 
610
        $singlebutton = new single_button($url, $realname, 'post', single_button::BUTTON_PRIMARY, $attributes);
611
        $renderer = $PAGE->get_renderer('core');
612
        $data = $singlebutton->export_for_template($renderer);
613
 
614
        $this->assertEquals($realname, $data->label);
615
        $this->assertEquals('post', $data->method);
616
        $this->assertEquals('singlebutton', $data->classes);
617
        $this->assertEquals('primary', $data->type);
618
        $this->assertEquals($attributes['data-dummy'], $data->attributes[0]['value']);
619
    }
620
 
621
    /**
622
     * Test for checking the template context data for the single_select element legacy API.
623
     * @covers \single_button
624
     */
625
    public function test_single_button_deprecated() {
626
        global $PAGE;
627
        $url = new \moodle_url('/');
628
        $realname = 'realname';
629
        $attributes = [
630
            'data-dummy' => 'dummy',
631
        ];
632
 
633
        // Test that when we use a true boolean value for the 4th parameter this is set as primary type.
634
        $singlebutton = new single_button($url, $realname, 'post', single_button::BUTTON_PRIMARY, $attributes);
635
        $renderer = $PAGE->get_renderer('core');
636
        $data = $singlebutton->export_for_template($renderer);
637
        $this->assertEquals($realname, $data->label);
638
        $this->assertEquals('post', $data->method);
639
        $this->assertEquals('singlebutton', $data->classes);
640
        $this->assertEquals('primary', $data->type);
641
        $this->assertEquals($attributes['data-dummy'], $data->attributes[0]['value']);
642
 
643
        // Test that when we use a false boolean value for the 4th parameter this is set as secondary type.
644
        $singlebutton = new single_button($url, $realname, 'post', false, $attributes);
645
        $this->assertDebuggingCalled();
646
        $renderer = $PAGE->get_renderer('core');
647
        $data = $singlebutton->export_for_template($renderer);
648
        $this->assertEquals($realname, $data->label);
649
        $this->assertEquals('post', $data->method);
650
        $this->assertEquals('singlebutton', $data->classes);
651
        $this->assertEquals('secondary', $data->type);
652
        $this->assertEquals($attributes['data-dummy'], $data->attributes[0]['value']);
653
 
654
        // Test that when we set the primary value, then this is reflected in the type.
655
        $singlebutton->primary = false;
656
        $this->assertDebuggingCalled();
657
        $this->assertEquals(single_button::BUTTON_SECONDARY, $singlebutton->type);
658
        $singlebutton->primary = true;
659
        $this->assertDebuggingCalled();
660
        $this->assertEquals(single_button::BUTTON_PRIMARY, $singlebutton->type);
661
        // Then set the type directly.
662
 
663
        $singlebutton->type = single_button::BUTTON_DANGER;
664
        $data = $singlebutton->export_for_template($renderer);
665
        $this->assertEquals('danger', $data->type);
666
 
667
    }
668
 
669
    /**
670
     * Test for checking the template context data for the url_select element.
671
     */
672
    public function test_url_select() {
673
        global $PAGE;
674
 
675
        $fakename = 'fakename';
676
        $fakeclass = 'fakeclass';
677
        $faketitle = 'faketitle';
678
        $fakedisabled = true;
679
        $fakefor = 'fakefor';
680
 
681
        $someid = 'someid';
682
        $realclass = 'realclass';
683
        $realtitle = 'realtitle';
684
        $realdisabled = false;
685
        $reallabel = 'Some cool label';
686
        $labelclass = 'somelabelclass';
687
        $labelstyle = 'font-weight: bold';
688
 
689
        $dataaction = 'actiondata';
690
        $dataother = 'otherdata';
691
 
692
        $attributes = [
693
            'id' => $someid,
694
            'class' => $fakeclass,
695
            'title' => $faketitle,
696
            'disabled' => $fakedisabled,
697
            'name' => $fakename,
698
            'data-action' => $dataaction,
699
            'data-other' => $dataother,
700
        ];
701
        $labelattributes = [
702
            'for' => $fakefor,
703
            'class' => $labelclass,
704
            'style' => $labelstyle
705
        ];
706
 
707
        $url1 = new \moodle_url("/#a");
708
        $url2 = new \moodle_url("/#b");
709
        $url3 = new \moodle_url("/#c");
710
 
711
        $urls = [
712
            $url1->out() => 'A',
713
            $url2->out() => 'B',
714
            $url3->out() => 'C',
715
        ];
716
        $nothing = ['' => 'choosedots'];
717
 
718
        $urlselect = new url_select($urls, null, $nothing, 'someformid');
719
        $urlselect->class = $realclass;
720
        $urlselect->tooltip = $realtitle;
721
        $urlselect->disabled = $realdisabled;
722
        $urlselect->attributes = $attributes;
723
        $urlselect->label = $reallabel;
724
        $urlselect->labelattributes = $labelattributes;
725
 
726
        $renderer = $PAGE->get_renderer('core');
727
        $data = $urlselect->export_for_template($renderer);
728
 
729
        $this->assertEquals($realtitle, $data->title);
730
        $this->assertEquals($urlselect->class, $data->classes);
731
        $this->assertEquals($reallabel, $data->label);
732
        $this->assertEquals($realdisabled, $data->disabled);
733
        $this->assertEquals($someid, $data->id);
734
 
735
        // Validate attributes array.
736
        // The following should not be included: id, class, name, disabled.
737
        $this->assertFalse(in_array(['name' => 'id', 'value' => $someid], $data->attributes));
738
        $this->assertFalse(in_array(['name' => 'class', 'value' => $fakeclass], $data->attributes));
739
        $this->assertFalse(in_array(['name' => 'name', 'value' => $fakeclass], $data->attributes));
740
        $this->assertFalse(in_array(['name' => 'disabled', 'value' => $fakedisabled], $data->attributes));
741
        // The rest should be fine.
742
        $this->assertTrue(in_array(['name' => 'data-action', 'value' => $dataaction], $data->attributes));
743
        $this->assertTrue(in_array(['name' => 'data-other', 'value' => $dataother], $data->attributes));
744
 
745
        // Validate label attributes.
746
        // The for attribute should not be included.
747
        $this->assertFalse(in_array(['name' => 'for', 'value' => $someid], $data->labelattributes));
748
        // The rest should be fine.
749
        $this->assertTrue(in_array(['name' => 'class', 'value' => $labelclass], $data->labelattributes));
750
        $this->assertTrue(in_array(['name' => 'style', 'value' => $labelstyle], $data->labelattributes));
751
    }
752
 
753
    /**
754
     * Data provider for test_block_contents_is_fake().
755
     *
756
     * @return array
757
     */
758
    public function block_contents_is_fake_provider() {
759
        return [
760
            'Null' => [null, false],
761
            'Not set' => [false, false],
762
            'Fake' => ['_fake', true],
763
            'Real block' => ['activity_modules', false],
764
        ];
765
    }
766
 
767
    /**
768
     * Test block_contents is_fake() method.
769
     *
770
     * @dataProvider block_contents_is_fake_provider
771
     * @param mixed $value Value for the data-block attribute
772
     * @param boolean $expected The expected result
773
     */
774
    public function test_block_contents_is_fake($value, $expected) {
775
        $bc = new block_contents(array());
776
        if ($value !== false) {
777
            $bc->attributes['data-block'] = $value;
778
        }
779
        $this->assertEquals($expected, $bc->is_fake());
780
    }
781
}