Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]
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 /** 18 * Persistent class tests. 19 * 20 * @package core 21 * @copyright 2015 Frédéric Massart - FMCorz.net 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 global $CFG; 27 28 /** 29 * Persistent testcase. 30 * 31 * @package core 32 * @copyright 2015 Frédéric Massart - FMCorz.net 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class core_persistent_testcase extends advanced_testcase { 36 37 public function setUp(): void { 38 $this->make_persistent_table(); 39 $this->make_second_persistent_table(); 40 $this->resetAfterTest(); 41 } 42 43 /** 44 * Make the table for the persistent. 45 */ 46 protected function make_persistent_table() { 47 global $DB; 48 $dbman = $DB->get_manager(); 49 50 $table = new xmldb_table(core_testable_persistent::TABLE); 51 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 52 $table->add_field('shortname', XMLDB_TYPE_CHAR, '100', null, null, null, null); 53 $table->add_field('idnumber', XMLDB_TYPE_CHAR, '100', null, null, null, null); 54 $table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null); 55 $table->add_field('descriptionformat', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, '0'); 56 $table->add_field('parentid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 57 $table->add_field('path', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null); 58 $table->add_field('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 59 $table->add_field('scaleid', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 60 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 61 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 62 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 63 64 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); 65 66 if ($dbman->table_exists($table)) { 67 $dbman->drop_table($table); 68 } 69 70 $dbman->create_table($table); 71 } 72 73 /** 74 * Make the second table for the persistent. 75 */ 76 protected function make_second_persistent_table() { 77 global $DB; 78 $dbman = $DB->get_manager(); 79 80 $table = new xmldb_table(core_testable_second_persistent::TABLE); 81 $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 82 $table->add_field('someint', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 83 $table->add_field('intnull', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 84 $table->add_field('somefloat', XMLDB_TYPE_FLOAT, '10,5', null, null, null, null); 85 $table->add_field('sometext', XMLDB_TYPE_TEXT, null, null, null, null, null); 86 $table->add_field('someraw', XMLDB_TYPE_CHAR, '100', null, null, null, null); 87 $table->add_field('booltrue', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0'); 88 $table->add_field('boolfalse', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0'); 89 $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 90 $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 91 $table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0'); 92 93 $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); 94 95 if ($dbman->table_exists($table)) { 96 $dbman->drop_table($table); 97 } 98 99 $dbman->create_table($table); 100 } 101 102 public function test_properties_definition() { 103 $expected = array( 104 'shortname' => array( 105 'type' => PARAM_TEXT, 106 'default' => '', 107 'null' => NULL_NOT_ALLOWED 108 ), 109 'idnumber' => array( 110 'type' => PARAM_TEXT, 111 'null' => NULL_NOT_ALLOWED 112 ), 113 'description' => array( 114 'type' => PARAM_TEXT, 115 'default' => '', 116 'null' => NULL_NOT_ALLOWED 117 ), 118 'descriptionformat' => array( 119 'choices' => array(FORMAT_HTML, FORMAT_MOODLE, FORMAT_PLAIN, FORMAT_MARKDOWN), 120 'type' => PARAM_INT, 121 'default' => FORMAT_HTML, 122 'null' => NULL_NOT_ALLOWED 123 ), 124 'parentid' => array( 125 'type' => PARAM_INT, 126 'default' => 0, 127 'null' => NULL_NOT_ALLOWED 128 ), 129 'path' => array( 130 'type' => PARAM_RAW, 131 'default' => '', 132 'null' => NULL_NOT_ALLOWED 133 ), 134 'sortorder' => array( 135 'type' => PARAM_INT, 136 'message' => new lang_string('invalidrequest', 'error'), 137 'null' => NULL_NOT_ALLOWED 138 ), 139 'scaleid' => array( 140 'default' => null, 141 'type' => PARAM_INT, 142 'null' => NULL_ALLOWED 143 ), 144 'id' => array( 145 'default' => 0, 146 'type' => PARAM_INT, 147 'null' => NULL_NOT_ALLOWED 148 ), 149 'timecreated' => array( 150 'default' => 0, 151 'type' => PARAM_INT, 152 'null' => NULL_NOT_ALLOWED 153 ), 154 'timemodified' => array( 155 'default' => 0, 156 'type' => PARAM_INT, 157 'null' => NULL_NOT_ALLOWED 158 ), 159 'usermodified' => array( 160 'default' => 0, 161 'type' => PARAM_INT, 162 'null' => NULL_NOT_ALLOWED 163 ), 164 ); 165 $this->assertEquals($expected, core_testable_persistent::properties_definition()); 166 } 167 168 public function test_to_record() { 169 $p = new core_testable_persistent(); 170 $expected = (object) array( 171 'shortname' => '', 172 'idnumber' => null, 173 'description' => '', 174 'descriptionformat' => FORMAT_HTML, 175 'parentid' => 0, 176 'path' => '', 177 'sortorder' => null, 178 'id' => 0, 179 'timecreated' => 0, 180 'timemodified' => 0, 181 'usermodified' => 0, 182 'scaleid' => null, 183 ); 184 $this->assertEquals($expected, $p->to_record()); 185 } 186 187 public function test_from_record() { 188 $p = new core_testable_persistent(); 189 $data = (object) array( 190 'shortname' => 'ddd', 191 'idnumber' => 'abc', 192 'description' => 'xyz', 193 'descriptionformat' => FORMAT_PLAIN, 194 'parentid' => 999, 195 'path' => '/a/b/c', 196 'sortorder' => 12, 197 'id' => 1, 198 'timecreated' => 2, 199 'timemodified' => 3, 200 'usermodified' => 4, 201 'scaleid' => null, 202 ); 203 $p->from_record($data); 204 $this->assertEquals($data, $p->to_record()); 205 } 206 207 public function test_from_record_invalid_param() { 208 $p = new core_testable_persistent(); 209 $data = (object) array( 210 'shortname' => 'ddd', 211 'idnumber' => 'abc', 212 'description' => 'xyz', 213 'descriptionformat' => FORMAT_PLAIN, 214 'parentid' => 999, 215 'path' => '/a/b/c', 216 'sortorder' => 12, 217 'id' => 1, 218 'timecreated' => 2, 219 'timemodified' => 3, 220 'usermodified' => 4, 221 'scaleid' => null, 222 'invalidparam' => 'abc' 223 ); 224 225 $p->from_record($data); 226 227 // Previous call should succeed, assert we get back all data except invalid param. 228 unset($data->invalidparam); 229 $this->assertEquals($data, $p->to_record()); 230 } 231 232 public function test_validate() { 233 $data = (object) array( 234 'idnumber' => 'abc', 235 'sortorder' => 0 236 ); 237 $p = new core_testable_persistent(0, $data); 238 $this->assertFalse(isset($p->beforevalidate)); 239 $this->assertTrue($p->validate()); 240 $this->assertTrue(isset($p->beforevalidate)); 241 $this->assertTrue($p->is_valid()); 242 $this->assertEquals(array(), $p->get_errors()); 243 $p->set('descriptionformat', -100); 244 245 $expected = array( 246 'descriptionformat' => new lang_string('invaliddata', 'error'), 247 ); 248 $this->assertEquals($expected, $p->validate()); 249 $this->assertFalse($p->is_valid()); 250 $this->assertEquals($expected, $p->get_errors()); 251 } 252 253 public function test_validation_required() { 254 $data = (object) array( 255 'idnumber' => 'abc' 256 ); 257 $p = new core_testable_persistent(0, $data); 258 $expected = array( 259 'sortorder' => new lang_string('requiredelement', 'form'), 260 ); 261 $this->assertFalse($p->is_valid()); 262 $this->assertEquals($expected, $p->get_errors()); 263 } 264 265 public function test_validation_custom() { 266 $data = (object) array( 267 'idnumber' => 'abc', 268 'sortorder' => 10, 269 ); 270 $p = new core_testable_persistent(0, $data); 271 $expected = array( 272 'sortorder' => new lang_string('invalidkey', 'error'), 273 ); 274 $this->assertFalse($p->is_valid()); 275 $this->assertEquals($expected, $p->get_errors()); 276 } 277 278 public function test_validation_custom_message() { 279 $data = (object) array( 280 'idnumber' => 'abc', 281 'sortorder' => 'abc', 282 ); 283 $p = new core_testable_persistent(0, $data); 284 $expected = array( 285 'sortorder' => new lang_string('invalidrequest', 'error'), 286 ); 287 $this->assertFalse($p->is_valid()); 288 $this->assertEquals($expected, $p->get_errors()); 289 } 290 291 public function test_validation_choices() { 292 $data = (object) array( 293 'idnumber' => 'abc', 294 'sortorder' => 0, 295 'descriptionformat' => -100 296 ); 297 $p = new core_testable_persistent(0, $data); 298 $expected = array( 299 'descriptionformat' => new lang_string('invaliddata', 'error'), 300 ); 301 $this->assertFalse($p->is_valid()); 302 $this->assertEquals($expected, $p->get_errors()); 303 } 304 305 public function test_validation_type() { 306 $data = (object) array( 307 'idnumber' => 'abc', 308 'sortorder' => 'NaN' 309 ); 310 $p = new core_testable_persistent(0, $data); 311 $this->assertFalse($p->is_valid()); 312 $this->assertArrayHasKey('sortorder', $p->get_errors()); 313 } 314 315 public function test_validation_null() { 316 $data = (object) array( 317 'idnumber' => null, 318 'sortorder' => 0, 319 'scaleid' => 'bad!' 320 ); 321 $p = new core_testable_persistent(0, $data); 322 $this->assertFalse($p->is_valid()); 323 $this->assertArrayHasKey('idnumber', $p->get_errors()); 324 $this->assertArrayHasKey('scaleid', $p->get_errors()); 325 $p->set('idnumber', 'abc'); 326 $this->assertFalse($p->is_valid()); 327 $this->assertArrayNotHasKey('idnumber', $p->get_errors()); 328 $this->assertArrayHasKey('scaleid', $p->get_errors()); 329 $p->set('scaleid', null); 330 $this->assertTrue($p->is_valid()); 331 $this->assertArrayNotHasKey('scaleid', $p->get_errors()); 332 } 333 334 public function test_create() { 335 global $DB; 336 $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); 337 $this->assertFalse(isset($p->beforecreate)); 338 $this->assertFalse(isset($p->aftercreate)); 339 $p->create(); 340 $record = $DB->get_record(core_testable_persistent::TABLE, array('id' => $p->get('id')), '*', MUST_EXIST); 341 $expected = $p->to_record(); 342 $this->assertTrue(isset($p->beforecreate)); 343 $this->assertTrue(isset($p->aftercreate)); 344 $this->assertEquals($expected->sortorder, $record->sortorder); 345 $this->assertEquals($expected->idnumber, $record->idnumber); 346 $this->assertEquals($expected->id, $record->id); 347 $this->assertTrue($p->is_valid()); // Should always be valid after a create. 348 } 349 350 public function test_update() { 351 global $DB; 352 $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); 353 $p->create(); 354 $id = $p->get('id'); 355 $p->set('sortorder', 456); 356 $p->from_record((object) array('idnumber' => 'def')); 357 $this->assertFalse(isset($p->beforeupdate)); 358 $this->assertFalse(isset($p->afterupdate)); 359 $p->update(); 360 361 $expected = $p->to_record(); 362 $record = $DB->get_record(core_testable_persistent::TABLE, array('id' => $p->get('id')), '*', MUST_EXIST); 363 $this->assertTrue(isset($p->beforeupdate)); 364 $this->assertTrue(isset($p->afterupdate)); 365 $this->assertEquals($id, $record->id); 366 $this->assertEquals(456, $record->sortorder); 367 $this->assertEquals('def', $record->idnumber); 368 $this->assertTrue($p->is_valid()); // Should always be valid after an update. 369 } 370 371 /** 372 * Test set_many prior to updating the persistent 373 */ 374 public function test_set_many_update(): void { 375 global $DB; 376 377 $persistent = (new core_testable_persistent(0, (object) [ 378 'idnumber' => 'test', 379 'sortorder' => 2 380 ]))->create(); 381 382 // Set multiple properties, and update. 383 $persistent->set_many([ 384 'idnumber' => 'test2', 385 'sortorder' => 1, 386 ])->update(); 387 388 // Confirm our persistent was updated. 389 $record = $DB->get_record(core_testable_persistent::TABLE, ['id' => $persistent->get('id')], '*', MUST_EXIST); 390 $this->assertEquals('test2', $record->idnumber); 391 $this->assertEquals(1, $record->sortorder); 392 } 393 394 public function test_save() { 395 global $DB; 396 $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); 397 $this->assertFalse(isset($p->beforecreate)); 398 $this->assertFalse(isset($p->aftercreate)); 399 $this->assertFalse(isset($p->beforeupdate)); 400 $this->assertFalse(isset($p->beforeupdate)); 401 $p->save(); 402 $record = $DB->get_record(core_testable_persistent::TABLE, array('id' => $p->get('id')), '*', MUST_EXIST); 403 $expected = $p->to_record(); 404 $this->assertTrue(isset($p->beforecreate)); 405 $this->assertTrue(isset($p->aftercreate)); 406 $this->assertFalse(isset($p->beforeupdate)); 407 $this->assertFalse(isset($p->beforeupdate)); 408 $this->assertEquals($expected->sortorder, $record->sortorder); 409 $this->assertEquals($expected->idnumber, $record->idnumber); 410 $this->assertEquals($expected->id, $record->id); 411 $this->assertTrue($p->is_valid()); // Should always be valid after a save/create. 412 413 $p->set('idnumber', 'abcd'); 414 $p->save(); 415 $record = $DB->get_record(core_testable_persistent::TABLE, array('id' => $p->get('id')), '*', MUST_EXIST); 416 $expected = $p->to_record(); 417 $this->assertTrue(isset($p->beforeupdate)); 418 $this->assertTrue(isset($p->beforeupdate)); 419 $this->assertEquals($expected->sortorder, $record->sortorder); 420 $this->assertEquals($expected->idnumber, $record->idnumber); 421 $this->assertEquals($expected->id, $record->id); 422 $this->assertTrue($p->is_valid()); // Should always be valid after a save/update. 423 } 424 425 /** 426 * Test set_many prior to saving the persistent 427 */ 428 public function test_set_many_save(): void { 429 global $DB; 430 431 $persistent = (new core_testable_persistent(0, (object) [ 432 'idnumber' => 'test', 433 'sortorder' => 2 434 ])); 435 436 // Set multiple properties, and save. 437 $persistent->set_many([ 438 'idnumber' => 'test2', 439 'sortorder' => 1, 440 ])->save(); 441 442 // Confirm our persistent was saved. 443 $record = $DB->get_record(core_testable_persistent::TABLE, ['id' => $persistent->get('id')], '*', MUST_EXIST); 444 $this->assertEquals('test2', $record->idnumber); 445 $this->assertEquals(1, $record->sortorder); 446 } 447 448 /** 449 * Test set_many with empty array should not modify the persistent 450 */ 451 public function test_set_many_empty(): void { 452 global $DB; 453 454 $persistent = (new core_testable_persistent(0, (object) [ 455 'idnumber' => 'test', 456 'sortorder' => 2 457 ]))->create(); 458 459 // Set empty properties, and update. 460 $persistent->set_many([])->update(); 461 462 // Confirm our persistent was not updated. 463 $record = $DB->get_record(core_testable_persistent::TABLE, ['id' => $persistent->get('id')], '*', MUST_EXIST); 464 $this->assertEquals('test', $record->idnumber); 465 $this->assertEquals(2, $record->sortorder); 466 } 467 468 /** 469 * Test set with invalid property 470 */ 471 public function test_set_invalid_property(): void { 472 $persistent = (new core_testable_persistent(0, (object) [ 473 'idnumber' => 'test', 474 'sortorder' => 2 475 ])); 476 477 $this->expectException(coding_exception::class); 478 $this->expectExceptionMessage('Unexpected property \'invalid\' requested'); 479 $persistent->set('invalid', 'stuff'); 480 } 481 482 /** 483 * Test set_many with invalid property 484 */ 485 public function test_set_many_invalid_property(): void { 486 $persistent = (new core_testable_persistent(0, (object) [ 487 'idnumber' => 'test', 488 'sortorder' => 2 489 ])); 490 491 $this->expectException(coding_exception::class); 492 $this->expectExceptionMessage('Unexpected property \'invalid\' requested'); 493 $persistent->set_many(['invalid' => 'stuff']); 494 } 495 496 public function test_read() { 497 $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); 498 $p->create(); 499 unset($p->beforevalidate); 500 unset($p->beforecreate); 501 unset($p->aftercreate); 502 503 $p2 = new core_testable_persistent($p->get('id')); 504 $this->assertEquals($p, $p2); 505 506 $p3 = new core_testable_persistent(); 507 $p3->set('id', $p->get('id')); 508 $p3->read(); 509 $this->assertEquals($p, $p3); 510 } 511 512 public function test_delete() { 513 global $DB; 514 515 $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); 516 $p->create(); 517 $this->assertNotEquals(0, $p->get('id')); 518 $this->assertTrue($DB->record_exists_select(core_testable_persistent::TABLE, 'id = ?', array($p->get('id')))); 519 $this->assertFalse(isset($p->beforedelete)); 520 $this->assertFalse(isset($p->afterdelete)); 521 522 $p->delete(); 523 $this->assertFalse($DB->record_exists_select(core_testable_persistent::TABLE, 'id = ?', array($p->get('id')))); 524 $this->assertEquals(0, $p->get('id')); 525 $this->assertEquals(true, $p->beforedelete); 526 $this->assertEquals(true, $p->afterdelete); 527 } 528 529 public function test_has_property() { 530 $this->assertFalse(core_testable_persistent::has_property('unknown')); 531 $this->assertTrue(core_testable_persistent::has_property('idnumber')); 532 } 533 534 public function test_custom_setter_getter() { 535 global $DB; 536 537 $path = array(1, 2, 3); 538 $json = json_encode($path); 539 540 $p = new core_testable_persistent(0, (object) array('sortorder' => 0, 'idnumber' => 'abc')); 541 $p->set('path', $path); 542 $this->assertEquals($path, $p->get('path')); 543 $this->assertEquals($json, $p->to_record()->path); 544 545 $p->create(); 546 $record = $DB->get_record(core_testable_persistent::TABLE, array('id' => $p->get('id')), 'id, path', MUST_EXIST); 547 $this->assertEquals($json, $record->path); 548 } 549 550 public function test_record_exists() { 551 global $DB; 552 $this->assertFalse($DB->record_exists(core_testable_persistent::TABLE, array('idnumber' => 'abc'))); 553 $p = new core_testable_persistent(0, (object) array('sortorder' => 123, 'idnumber' => 'abc')); 554 $p->create(); 555 $id = $p->get('id'); 556 $this->assertTrue(core_testable_persistent::record_exists($id)); 557 $this->assertTrue($DB->record_exists(core_testable_persistent::TABLE, array('idnumber' => 'abc'))); 558 $p->delete(); 559 $this->assertFalse(core_testable_persistent::record_exists($id)); 560 } 561 562 public function test_get_sql_fields() { 563 $expected = '' . 564 'c.id AS prefix_id, ' . 565 'c.shortname AS prefix_shortname, ' . 566 'c.idnumber AS prefix_idnumber, ' . 567 'c.description AS prefix_description, ' . 568 'c.descriptionformat AS prefix_descriptionformat, ' . 569 'c.parentid AS prefix_parentid, ' . 570 'c.path AS prefix_path, ' . 571 'c.sortorder AS prefix_sortorder, ' . 572 'c.scaleid AS prefix_scaleid, ' . 573 'c.timecreated AS prefix_timecreated, ' . 574 'c.timemodified AS prefix_timemodified, ' . 575 'c.usermodified AS prefix_usermodified'; 576 $this->assertEquals($expected, core_testable_persistent::get_sql_fields('c', 'prefix_')); 577 } 578 579 public function test_get_sql_fields_too_long() { 580 $this->expectException(coding_exception::class); 581 $this->expectExceptionMessageMatches('/The alias .+ exceeds 30 characters/'); 582 core_testable_persistent::get_sql_fields('c'); 583 } 584 585 public function test_get(): void { 586 $data = [ 587 'someint' => 123, 588 'intnull' => null, 589 'somefloat' => 33.44, 590 'sometext' => 'Hello', 591 'someraw' => '/dev/hello', 592 'booltrue' => true, 593 'boolfalse' => false, 594 ]; 595 $p = new core_testable_second_persistent(0, (object)$data); 596 $p->create(); 597 598 $this->assertSame($data['intnull'], $p->get('intnull')); 599 $this->assertSame($data['someint'], $p->get('someint')); 600 $this->assertIsFloat($p->get('somefloat')); // Avoid === comparisons on floats, verify type and value separated. 601 $this->assertEqualsWithDelta($data['somefloat'], $p->get('somefloat'), 0.00001); 602 $this->assertSame($data['sometext'], $p->get('sometext')); 603 $this->assertSame($data['someraw'], $p->get('someraw')); 604 $this->assertSame($data['booltrue'], $p->get('booltrue')); 605 $this->assertSame($data['boolfalse'], $p->get('boolfalse')); 606 607 // Ensure that types are correct after reloading data from database. 608 $p->read(); 609 610 $this->assertSame($data['someint'], $p->get('someint')); 611 $this->assertSame($data['intnull'], $p->get('intnull')); 612 $this->assertIsFloat($p->get('somefloat')); // Avoid === comparisons on floats, verify type and value separated. 613 $this->assertEqualsWithDelta($data['somefloat'], $p->get('somefloat'), 0.00001); 614 $this->assertSame($data['sometext'], $p->get('sometext')); 615 $this->assertSame($data['someraw'], $p->get('someraw')); 616 $this->assertSame($data['booltrue'], $p->get('booltrue')); 617 $this->assertSame($data['boolfalse'], $p->get('boolfalse')); 618 } 619 } 620 621 /** 622 * Example persistent class. 623 * 624 * @package core 625 * @copyright 2015 Frédéric Massart - FMCorz.net 626 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 627 */ 628 class core_testable_persistent extends \core\persistent { 629 630 const TABLE = 'phpunit_persistent'; 631 632 protected static function define_properties() { 633 return array( 634 'shortname' => array( 635 'type' => PARAM_TEXT, 636 'default' => '' 637 ), 638 'idnumber' => array( 639 'type' => PARAM_TEXT, 640 ), 641 'description' => array( 642 'type' => PARAM_TEXT, 643 'default' => '' 644 ), 645 'descriptionformat' => array( 646 'choices' => array(FORMAT_HTML, FORMAT_MOODLE, FORMAT_PLAIN, FORMAT_MARKDOWN), 647 'type' => PARAM_INT, 648 'default' => FORMAT_HTML 649 ), 650 'parentid' => array( 651 'type' => PARAM_INT, 652 'default' => 0 653 ), 654 'path' => array( 655 'type' => PARAM_RAW, 656 'default' => '' 657 ), 658 'sortorder' => array( 659 'type' => PARAM_INT, 660 'message' => new lang_string('invalidrequest', 'error') 661 ), 662 'scaleid' => array( 663 'type' => PARAM_INT, 664 'default' => null, 665 'null' => NULL_ALLOWED 666 ) 667 ); 668 } 669 670 protected function before_validate() { 671 $this->beforevalidate = true; 672 } 673 674 protected function before_create() { 675 $this->beforecreate = true; 676 } 677 678 protected function before_update() { 679 $this->beforeupdate = true; 680 } 681 682 protected function before_delete() { 683 $this->beforedelete = true; 684 } 685 686 protected function after_create() { 687 $this->aftercreate = true; 688 } 689 690 protected function after_update($result) { 691 $this->afterupdate = true; 692 } 693 694 protected function after_delete($result) { 695 $this->afterdelete = true; 696 } 697 698 protected function get_path() { 699 $value = $this->raw_get('path'); 700 if (!empty($value)) { 701 $value = json_decode($value); 702 } 703 return $value; 704 } 705 706 protected function set_path($value) { 707 if (!empty($value)) { 708 $value = json_encode($value); 709 } 710 $this->raw_set('path', $value); 711 } 712 713 protected function validate_sortorder($value) { 714 if ($value == 10) { 715 return new lang_string('invalidkey', 'error'); 716 } 717 return true; 718 } 719 720 } 721 722 /** 723 * Example persistent class to test types. 724 * 725 * @package core 726 * @copyright 2021 David Matamoros <davidmc@moodle.com> 727 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 728 */ 729 class core_testable_second_persistent extends \core\persistent { 730 731 /** Table name for the persistent. */ 732 const TABLE = 'phpunit_second_persistent'; 733 734 /** 735 * Return the list of properties. 736 * 737 * @return array 738 */ 739 protected static function define_properties(): array { 740 return [ 741 'someint' => [ 742 'type' => PARAM_INT, 743 ], 744 'intnull' => [ 745 'type' => PARAM_INT, 746 'null' => NULL_ALLOWED, 747 'default' => null, 748 ], 749 'somefloat' => [ 750 'type' => PARAM_FLOAT, 751 ], 752 'sometext' => [ 753 'type' => PARAM_TEXT, 754 'default' => '' 755 ], 756 'someraw' => [ 757 'type' => PARAM_RAW, 758 'default' => '' 759 ], 760 'booltrue' => [ 761 'type' => PARAM_BOOL, 762 ], 763 'boolfalse' => [ 764 'type' => PARAM_BOOL, 765 ] 766 ]; 767 } 768 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body