| Línea 18... |
Línea 18... |
| 18 |
|
18 |
|
| Línea 19... |
Línea 19... |
| 19 |
namespace core_reportbuilder\local\helpers;
|
19 |
namespace core_reportbuilder\local\helpers;
|
| 20 |
|
20 |
|
| - |
|
21 |
use advanced_testcase;
|
| 21 |
use advanced_testcase;
|
22 |
use invalid_parameter_exception;
|
| 22 |
use invalid_parameter_exception;
|
23 |
use core\clock;
|
| 23 |
use core_cohort\reportbuilder\audience\cohortmember;
|
24 |
use core_cohort\reportbuilder\audience\cohortmember;
|
| 24 |
use core_reportbuilder_generator;
|
25 |
use core_reportbuilder_generator;
|
| 25 |
use core_reportbuilder\local\models\schedule as model;
|
26 |
use core_reportbuilder\local\models\schedule as model;
|
| Línea 32... |
Línea 33... |
| 32 |
* @package core_reportbuilder
|
33 |
* @package core_reportbuilder
|
| 33 |
* @covers \core_reportbuilder\local\helpers\schedule
|
34 |
* @covers \core_reportbuilder\local\helpers\schedule
|
| 34 |
* @copyright 2021 Paul Holden <paulh@moodle.com>
|
35 |
* @copyright 2021 Paul Holden <paulh@moodle.com>
|
| 35 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
36 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
| 36 |
*/
|
37 |
*/
|
| 37 |
class schedule_test extends advanced_testcase {
|
38 |
final class schedule_test extends advanced_testcase {
|
| - |
|
39 |
|
| - |
|
40 |
/** @var clock $clock */
|
| - |
|
41 |
private readonly clock $clock;
|
| - |
|
42 |
|
| - |
|
43 |
/**
|
| - |
|
44 |
* Mock the clock
|
| - |
|
45 |
*/
|
| - |
|
46 |
protected function setUp(): void {
|
| - |
|
47 |
parent::setUp();
|
| - |
|
48 |
$this->clock = $this->mock_clock_with_frozen(1622847600);
|
| - |
|
49 |
}
|
| Línea 38... |
Línea 50... |
| 38 |
|
50 |
|
| 39 |
/**
|
51 |
/**
|
| 40 |
* Test create schedule
|
52 |
* Test create schedule
|
| 41 |
*/
|
53 |
*/
|
| Línea 45... |
Línea 57... |
| 45 |
|
57 |
|
| 46 |
/** @var core_reportbuilder_generator $generator */
|
58 |
/** @var core_reportbuilder_generator $generator */
|
| 47 |
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
59 |
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
| Línea -... |
Línea 60... |
| - |
|
60 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
| 48 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
61 |
|
| 49 |
|
62 |
// Create schedule for tomorrow.
|
| 50 |
$timescheduled = time() + DAYSECS;
|
63 |
$timescheduled = $this->clock->time() + DAYSECS;
|
| 51 |
$schedule = schedule::create_schedule((object) [
|
64 |
$schedule = schedule::create_schedule((object) [
|
| 52 |
'name' => 'My schedule',
|
65 |
'name' => 'My schedule',
|
| 53 |
'reportid' => $report->get('id'),
|
66 |
'reportid' => $report->get('id'),
|
| Línea 79... |
Línea 92... |
| 79 |
$schedule = $generator->create_schedule(['reportid' => $report->get('id'), 'name' => 'My schedule']);
|
92 |
$schedule = $generator->create_schedule(['reportid' => $report->get('id'), 'name' => 'My schedule']);
|
| Línea 80... |
Línea 93... |
| 80 |
|
93 |
|
| 81 |
// Update some record properties.
|
94 |
// Update some record properties.
|
| 82 |
$record = $schedule->to_record();
|
95 |
$record = $schedule->to_record();
|
| 83 |
$record->name = 'My updated schedule';
|
96 |
$record->name = 'My updated schedule';
|
| Línea 84... |
Línea 97... |
| 84 |
$record->timescheduled = 1861340400; // 25/12/2028 07:00 UTC.
|
97 |
$record->timescheduled += (12 * HOURSECS);
|
| 85 |
|
98 |
|
| 86 |
$schedule = schedule::update_schedule($record);
|
99 |
$schedule = schedule::update_schedule($record);
|
| - |
|
100 |
$this->assertEquals($record->name, $schedule->get('name'));
|
| 87 |
$this->assertEquals($record->name, $schedule->get('name'));
|
101 |
$this->assertEquals($record->timescheduled, $schedule->get('timescheduled'));
|
| Línea 88... |
Línea 102... |
| 88 |
$this->assertEquals($record->timescheduled, $schedule->get('timescheduled'));
|
102 |
$this->assertEquals($record->timescheduled, $schedule->get('timenextsend'));
|
| 89 |
}
|
103 |
}
|
| 90 |
|
104 |
|
| Línea 247... |
Línea 261... |
| 247 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
261 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
| 248 |
$schedule = $generator->create_schedule(['reportid' => $report->get('id'), 'name' => 'My schedule']);
|
262 |
$schedule = $generator->create_schedule(['reportid' => $report->get('id'), 'name' => 'My schedule']);
|
| Línea 249... |
Línea 263... |
| 249 |
|
263 |
|
| 250 |
// There is only one row in the report (the only user on the site).
|
264 |
// There is only one row in the report (the only user on the site).
|
| - |
|
265 |
$count = schedule::get_schedule_report_count($schedule);
|
| 251 |
$count = schedule::get_schedule_report_count($schedule);
|
266 |
$this->assertDebuggingCalled();
|
| 252 |
$this->assertEquals(1, $count);
|
267 |
$this->assertEquals(1, $count);
|
| Línea 253... |
Línea 268... |
| 253 |
}
|
268 |
}
|
| 254 |
|
269 |
|
| 255 |
/**
|
270 |
/**
|
| 256 |
* Data provider for {@see test_get_schedule_report_file}
|
271 |
* Data provider for {@see test_get_schedule_report_file}
|
| 257 |
*
|
272 |
*
|
| 258 |
* @return string[]
|
273 |
* @return string[]
|
| 259 |
*/
|
274 |
*/
|
| 260 |
public function get_schedule_report_file_format(): array {
|
275 |
public static function get_schedule_report_file_format(): array {
|
| 261 |
return [
|
276 |
return [
|
| 262 |
['csv'],
|
277 |
['csv'],
|
| 263 |
['excel'],
|
278 |
['excel'],
|
| Línea 292... |
Línea 307... |
| 292 |
/**
|
307 |
/**
|
| 293 |
* Data provider for {@see test_should_send_schedule}
|
308 |
* Data provider for {@see test_should_send_schedule}
|
| 294 |
*
|
309 |
*
|
| 295 |
* @return array[]
|
310 |
* @return array[]
|
| 296 |
*/
|
311 |
*/
|
| 297 |
public function should_send_schedule_provider(): array {
|
312 |
public static function should_send_schedule_provider(): array {
|
| 298 |
$time = time();
|
- |
|
| 299 |
|
- |
|
| 300 |
// We just need large offsets for dates in the past/future.
|
- |
|
| 301 |
$yesterday = $time - DAYSECS;
|
- |
|
| 302 |
$tomorrow = $time + DAYSECS;
|
- |
|
| 303 |
|
- |
|
| 304 |
return [
|
313 |
return [
|
| 305 |
'Disabled' => [[
|
- |
|
| 306 |
'enabled' => false,
|
- |
|
| 307 |
], false],
|
- |
|
| 308 |
'Time scheduled in the past' => [[
|
314 |
'Time scheduled in the past' => [
|
| 309 |
'recurrence' => model::RECURRENCE_NONE,
|
315 |
model::RECURRENCE_NONE, '-1 hour', null, null, true,
|
| 310 |
'timescheduled' => $yesterday,
|
- |
|
| 311 |
], true],
|
316 |
],
|
| 312 |
'Time scheduled in the past, already sent prior to schedule' => [[
|
317 |
'Time scheduled in the past, already sent prior to schedule' => [
|
| 313 |
'recurrence' => model::RECURRENCE_NONE,
|
318 |
model::RECURRENCE_NONE, '-1 hour', '-2 hour', null, true,
|
| 314 |
'timescheduled' => $yesterday,
|
- |
|
| 315 |
'timelastsent' => $yesterday - HOURSECS,
|
- |
|
| 316 |
], true],
|
319 |
],
|
| 317 |
'Time scheduled in the past, already sent on schedule' => [[
|
320 |
'Time scheduled in the past, already sent on schedule' => [
|
| 318 |
'recurrence' => model::RECURRENCE_NONE,
|
321 |
model::RECURRENCE_NONE, '-1 hour', '-1 hour', null, false,
|
| 319 |
'timescheduled' => $yesterday,
|
- |
|
| 320 |
'timelastsent' => $yesterday,
|
- |
|
| 321 |
], false],
|
322 |
],
|
| 322 |
'Time scheduled in the future' => [[
|
323 |
'Time scheduled in the future' => [
|
| 323 |
'recurrence' => model::RECURRENCE_NONE,
|
324 |
model::RECURRENCE_NONE, '+1 hour', null, null, false,
|
| 324 |
'timescheduled' => $tomorrow,
|
- |
|
| 325 |
], false],
|
325 |
],
|
| 326 |
'Time scheduled in the future, already sent prior to schedule' => [[
|
326 |
'Time scheduled in the future, already sent prior to schedule' => [
|
| 327 |
'recurrence' => model::RECURRENCE_NONE,
|
327 |
model::RECURRENCE_NONE, '+1 hour', '-1 hour', null, false,
|
| 328 |
'timelastsent' => $yesterday,
|
- |
|
| 329 |
'timescheduled' => $tomorrow,
|
- |
|
| 330 |
], false],
|
328 |
],
|
| 331 |
'Next send in the past' => [[
|
329 |
'Next send in the past' => [
|
| 332 |
'recurrence' => model::RECURRENCE_DAILY,
|
330 |
model::RECURRENCE_DAILY, '-1 hour', null, '-1 hour', true,
|
| 333 |
'timescheduled' => $yesterday,
|
- |
|
| 334 |
'timenextsend' => $yesterday,
|
- |
|
| 335 |
], true],
|
331 |
],
|
| 336 |
'Next send in the future' => [[
|
332 |
'Next send in the future' => [
|
| 337 |
'recurrence' => model::RECURRENCE_DAILY,
|
333 |
model::RECURRENCE_DAILY, '-1 hour', null, '+1 hour', false,
|
| 338 |
'timescheduled' => $yesterday,
|
- |
|
| 339 |
'timenextsend' => $tomorrow,
|
- |
|
| 340 |
], false],
|
334 |
],
|
| 341 |
];
|
335 |
];
|
| 342 |
}
|
336 |
}
|
| Línea 343... |
Línea 337... |
| 343 |
|
337 |
|
| 344 |
/**
|
338 |
/**
|
| 345 |
* Test for whether a schedule should be sent
|
339 |
* Test for whether a schedule should be sent
|
| 346 |
*
|
340 |
*
|
| - |
|
341 |
* @param int $recurrence
|
| - |
|
342 |
* @param string $timescheduled Relative time suitable for passing to {@see strtotime}
|
| - |
|
343 |
* @param string|null $timelastsent Relative time suitable for passing to {@see strtotime}, or null to ignore
|
| 347 |
* @param array $properties
|
344 |
* @param string|null $timenextsend Relative time suitable for passing to {@see strtotime}, or null to ignore
|
| 348 |
* @param bool $expected
|
345 |
* @param bool $expected
|
| 349 |
*
|
346 |
*
|
| 350 |
* @dataProvider should_send_schedule_provider
|
347 |
* @dataProvider should_send_schedule_provider
|
| 351 |
*/
|
348 |
*/
|
| - |
|
349 |
public function test_should_send_schedule(
|
| - |
|
350 |
int $recurrence,
|
| - |
|
351 |
string $timescheduled,
|
| - |
|
352 |
?string $timelastsent,
|
| - |
|
353 |
?string $timenextsend,
|
| - |
|
354 |
bool $expected,
|
| 352 |
public function test_should_send_schedule(array $properties, bool $expected): void {
|
355 |
): void {
|
| Línea 353... |
Línea 356... |
| 353 |
$this->resetAfterTest();
|
356 |
$this->resetAfterTest();
|
| 354 |
|
357 |
|
| 355 |
/** @var core_reportbuilder_generator $generator */
|
358 |
/** @var core_reportbuilder_generator $generator */
|
| Línea -... |
Línea 359... |
| - |
|
359 |
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
| - |
|
360 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
| - |
|
361 |
|
| - |
|
362 |
// Use relative time period if present, otherwise default to zero (never sent).
|
| - |
|
363 |
$scheduletimelastsent = 0;
|
| - |
|
364 |
if ($timelastsent !== null) {
|
| - |
|
365 |
$scheduletimelastsent = strtotime($timelastsent, $this->clock->time());
|
| - |
|
366 |
}
|
| - |
|
367 |
|
| - |
|
368 |
$schedule = $generator->create_schedule([
|
| 356 |
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
369 |
'reportid' => $report->get('id'),
|
| - |
|
370 |
'name' => 'My schedule',
|
| - |
|
371 |
'recurrence' => $recurrence,
|
| Línea 357... |
Línea 372... |
| 357 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
372 |
'timescheduled' => strtotime($timescheduled, $this->clock->time()),
|
| 358 |
|
373 |
'timelastsent' => $scheduletimelastsent,
|
| 359 |
$schedule = $generator->create_schedule(['reportid' => $report->get('id'), 'name' => 'My schedule'] + $properties);
|
374 |
]);
|
| 360 |
|
375 |
|
| Línea 361... |
Línea 376... |
| 361 |
// If "Time next send" is specified, then override calculated value.
|
376 |
// If "Time next send" is specified, then override calculated value.
|
| 362 |
if (array_key_exists('timenextsend', $properties)) {
|
377 |
if ($timenextsend !== null) {
|
| Línea 363... |
Línea 378... |
| 363 |
$schedule->set('timenextsend', $properties['timenextsend']);
|
378 |
$schedule->set('timenextsend', strtotime($timenextsend, $this->clock->time()));
|
| - |
|
379 |
}
|
| - |
|
380 |
|
| - |
|
381 |
$this->assertEquals($expected, schedule::should_send_schedule($schedule));
|
| - |
|
382 |
}
|
| - |
|
383 |
|
| - |
|
384 |
/**
|
| - |
|
385 |
* Test for whether a schedule should be sent that has been disabled
|
| - |
|
386 |
*/
|
| - |
|
387 |
public function test_should_send_schedule_disabled(): void {
|
| - |
|
388 |
$this->resetAfterTest();
|
| - |
|
389 |
|
| - |
|
390 |
/** @var core_reportbuilder_generator $generator */
|
| - |
|
391 |
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
| - |
|
392 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
| - |
|
393 |
$schedule = $generator->create_schedule([
|
| - |
|
394 |
'reportid' => $report->get('id'),
|
| - |
|
395 |
'name' => 'My schedule',
|
| - |
|
396 |
'enabled' => 0,
|
| 364 |
}
|
397 |
]);
|
| 365 |
|
398 |
|
| 366 |
$this->assertEquals($expected, schedule::should_send_schedule($schedule));
|
399 |
$this->assertFalse(schedule::should_send_schedule($schedule));
|
| 367 |
}
|
400 |
}
|
| 368 |
|
401 |
|
| 369 |
/**
|
402 |
/**
|
| 370 |
* Data provider for {@see test_calculate_next_send_time}
|
- |
|
| 371 |
*
|
- |
|
| 372 |
* @return array[]
|
403 |
* Data provider for {@see test_calculate_next_send_time}
|
| - |
|
404 |
*
|
| 373 |
*/
|
405 |
* @return array[]
|
| - |
|
406 |
*/
|
| 374 |
public function calculate_next_send_time_provider(): array {
|
407 |
public static function calculate_next_send_time_provider(): array {
|
| - |
|
408 |
// Times are based on the current clock time (Fri Jun 04 2021 23:00:00 UTC).
|
| - |
|
409 |
return [
|
| 375 |
$timescheduled = 1635865200; // Tue Nov 02 2021 15:00:00 GMT+0000.
|
410 |
'No recurrence' => [
|
| 376 |
$timenow = 1639846800; // Sat Dec 18 2021 17:00:00 GMT+0000.
|
411 |
model::RECURRENCE_NONE, '2021-06-03 12:00', '2021-06-03 12:00',
|
| - |
|
412 |
],
|
| 377 |
|
413 |
'Recurrence, time scheduled in future' => [
|
| 378 |
return [
|
414 |
model::RECURRENCE_DAILY, '2021-06-05 12:00', '2021-06-05 12:00',
|
| - |
|
415 |
],
|
| 379 |
'No recurrence' => [model::RECURRENCE_NONE, $timescheduled, $timenow, $timescheduled],
|
416 |
'Daily recurrence' => [
|
| 380 |
'Recurrence, time scheduled in future' => [model::RECURRENCE_DAILY, $timenow + DAYSECS, $timenow, $timenow + DAYSECS],
|
417 |
model::RECURRENCE_DAILY, '2021-06-02 12:00', '2021-06-05 12:00',
|
| - |
|
418 |
],
|
| 381 |
// Sun Dec 19 2021 15:00:00 GMT+0000.
|
419 |
'Weekday recurrence' => [
|
| 382 |
'Daily recurrence' => [model::RECURRENCE_DAILY, $timescheduled, $timenow, 1639926000],
|
420 |
model::RECURRENCE_WEEKDAYS, '2021-06-02 12:00', '2021-06-07 12:00',
|
| - |
|
421 |
],
|
| 383 |
// Mon Dec 20 2021 15:00:00 GMT+0000.
|
422 |
'Weekly recurrence' => [
|
| 384 |
'Weekday recurrence' => [model::RECURRENCE_WEEKDAYS, $timescheduled, $timenow, 1640012400],
|
423 |
model::RECURRENCE_WEEKLY, '2021-05-18 12:00', '2021-06-08 12:00',
|
| - |
|
424 |
],
|
| 385 |
// Tue Dec 21 2021 15:00:00 GMT+0000.
|
425 |
'Monthy recurrence' => [
|
| 386 |
'Weekly recurrence' => [model::RECURRENCE_WEEKLY, $timescheduled, $timenow, 1640098800],
|
426 |
model::RECURRENCE_MONTHLY, '2021-03-19 12:00', '2021-06-19 12:00',
|
| Línea 387... |
Línea 427... |
| 387 |
// Sun Jan 02 2022 15:00:00 GMT+0000.
|
427 |
],
|
| 388 |
'Monthy recurrence' => [model::RECURRENCE_MONTHLY, $timescheduled, $timenow, 1641135600],
|
428 |
'Annual recurrence' => [
|
| 389 |
// Wed Nov 02 2022 15:00:00 GMT+0000.
|
429 |
model::RECURRENCE_ANNUALLY, '2019-05-01 12:00', '2022-05-01 12:00',
|
| 390 |
'Annual recurrence' => [model::RECURRENCE_ANNUALLY, $timescheduled, $timenow, 1667401200],
|
430 |
],
|
| 391 |
];
|
431 |
];
|
| 392 |
}
|
- |
|
| 393 |
|
432 |
}
|
| 394 |
/**
|
433 |
|
| 395 |
* Test for calculating next schedule send time
|
434 |
/**
|
| 396 |
*
|
435 |
* Test for calculating next schedule send time
|
| 397 |
* @param int $recurrence
|
436 |
*
|
| 398 |
* @param int $timescheduled
|
437 |
* @param int $recurrence
|
| Línea 399... |
Línea 438... |
| 399 |
* @param int $timenow
|
438 |
* @param string $timescheduled Absolute time suitable for passing to {@see strtotime}
|
| 400 |
* @param int $expected
|
439 |
* @param string $expected Absolute time suitable for passing to {@see strtotime}
|
| 401 |
*
|
440 |
*
|
| Línea -... |
Línea 441... |
| - |
|
441 |
* @dataProvider calculate_next_send_time_provider
|
| 402 |
* @dataProvider calculate_next_send_time_provider
|
442 |
*/
|
| 403 |
*/
|
443 |
public function test_calculate_next_send_time(int $recurrence, string $timescheduled, string $expected): void {
|
| 404 |
public function test_calculate_next_send_time(int $recurrence, int $timescheduled, int $timenow, int $expected): void {
|
444 |
$this->resetAfterTest();
|
| 405 |
$this->resetAfterTest();
|
445 |
|
| 406 |
|
446 |
/** @var core_reportbuilder_generator $generator */
|
| 407 |
/** @var core_reportbuilder_generator $generator */
|
- |
|
| 408 |
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
447 |
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
| Línea -... |
Línea 448... |
| - |
|
448 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
| 409 |
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
449 |
|
| 410 |
|
450 |
// Create model manually, as the generator automatically calculates next send itself.
|
| 411 |
$schedule = $generator->create_schedule([
|
451 |
$schedule = new model(0, (object) [
|