diff --git a/lang/en/reportbuilder.php b/lang/en/reportbuilder.php index 10652bfd4e0..fa095f57f78 100644 --- a/lang/en/reportbuilder.php +++ b/lang/en/reportbuilder.php @@ -43,11 +43,14 @@ $string['allusers'] = 'All users'; $string['apply'] = 'Apply'; $string['audience'] = 'Audience'; $string['audienceadded'] = 'Added audience \'{$a}\''; +$string['audiencecreated'] = 'Audience created'; $string['audiencedeleted'] = 'Deleted audience \'{$a}\''; +$string['audiencedeletedevent'] = 'Audience deleted'; $string['audiencelabel'] = '{$a->name}: {$a->description}'; $string['audiencemultiselectpostfix'] = '{$a->elements} plus {$a->morecount} more'; $string['audiencenotsaved'] = 'Audience not saved'; $string['audiencesaved'] = 'Audience saved'; +$string['audienceupdated'] = 'Audience updated'; $string['cardview'] = 'Card view'; $string['cardview_help'] = 'Card view allows you to define the layout of your report when viewed on narrow devices. Columns will collapse beyond the limit set here, with a toggle to expand the card to view all report data.'; $string['cardviewfirstcolumntitle'] = 'First column title'; @@ -197,6 +200,7 @@ $string['reportdeleted'] = 'Report deleted'; $string['reportsource'] = 'Report source'; $string['reportsource_help'] = 'The report source defines where the data for the report will come from.'; $string['reportupdated'] = 'Report updated'; +$string['reportviewed'] = 'Report viewed'; $string['resetall'] = 'Reset all'; $string['resetconditions'] = 'Reset conditions'; $string['resetconditionsconfirm'] = 'Are you sure you want to reset all conditions for this report?'; diff --git a/reportbuilder/classes/event/audience_created.php b/reportbuilder/classes/event/audience_created.php new file mode 100644 index 00000000000..230b92e516e --- /dev/null +++ b/reportbuilder/classes/event/audience_created.php @@ -0,0 +1,111 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\event; + +use coding_exception; +use core\event\base; +use core_reportbuilder\local\models\audience; +use moodle_url; + +/** + * Report builder custom report audience created event class. + * + * @package core_reportbuilder + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @property-read array $other { + * Extra information about the event. + * + * - int reportid: The id of the report + * } + */ +class audience_created extends base { + + /** + * Initialise the event data. + */ + protected function init() { + $this->data['objecttable'] = audience::TABLE; + $this->data['crud'] = 'c'; + $this->data['edulevel'] = self::LEVEL_OTHER; + } + + /** + * Creates an instance from a report audience object + * + * @param audience $audience + * @return self + */ + public static function create_from_object(audience $audience): self { + $eventparams = [ + 'context' => $audience->get_report()->get_context(), + 'objectid' => $audience->get('id'), + 'other' => [ + 'reportid' => $audience->get('reportid'), + ] + ]; + $event = self::create($eventparams); + $event->add_record_snapshot($event->objecttable, $audience->to_record()); + return $event; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('audiencecreated', 'core_reportbuilder'); + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + $reportid = $this->other['reportid']; + return "The user with id '$this->userid' created an audience in the custom report with id '$reportid'."; + } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['reportid'])) { + throw new coding_exception('The \'reportid\' must be set in other.'); + } + } + + /** + * Returns relevant URL. + * + * @return moodle_url + */ + public function get_url(): moodle_url { + return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'audience'); + } +} diff --git a/reportbuilder/classes/event/audience_deleted.php b/reportbuilder/classes/event/audience_deleted.php new file mode 100644 index 00000000000..5c474d3ba12 --- /dev/null +++ b/reportbuilder/classes/event/audience_deleted.php @@ -0,0 +1,112 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\event; + +use coding_exception; +use core\event\base; +use core_reportbuilder\local\models\audience; +use moodle_url; + +/** + * Report builder custom report audience deleted event class. + * + * @package core_reportbuilder + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @property-read array $other { + * Extra information about the event. + * + * - int reportid: The id of the report + * } + */ +class audience_deleted extends base { + + /** + * Initialise the event data. + */ + protected function init() { + $this->data['objecttable'] = audience::TABLE; + $this->data['crud'] = 'd'; + $this->data['edulevel'] = self::LEVEL_OTHER; + } + + /** + * Creates an instance from a report audience object + * + * @param audience $audience + * @return self + */ + public static function create_from_object(audience $audience): self { + $eventparams = [ + 'context' => $audience->get_report()->get_context(), + 'objectid' => $audience->get('id'), + 'other' => [ + 'reportid' => $audience->get('reportid'), + ] + ]; + $event = self::create($eventparams); + $event->add_record_snapshot($event->objecttable, $audience->to_record()); + return $event; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('audiencedeletedevent', 'core_reportbuilder'); + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + $reportid = $this->other['reportid']; + return "The user with id '$this->userid' deleted the audience with id '$this->objectid' in the custom report" . + " with id '$reportid'."; + } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['reportid'])) { + throw new coding_exception('The \'reportid\' must be set in other.'); + } + } + + /** + * Returns relevant URL. + * + * @return moodle_url + */ + public function get_url(): moodle_url { + return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'audience'); + } +} diff --git a/reportbuilder/classes/event/audience_updated.php b/reportbuilder/classes/event/audience_updated.php new file mode 100644 index 00000000000..2ccd25e9471 --- /dev/null +++ b/reportbuilder/classes/event/audience_updated.php @@ -0,0 +1,112 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\event; + +use coding_exception; +use core\event\base; +use core_reportbuilder\local\models\audience; +use moodle_url; + +/** + * Report builder custom report audience created event class. + * + * @package core_reportbuilder + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @property-read array $other { + * Extra information about the event. + * + * - int reportid: The id of the report + * } + */ +class audience_updated extends base { + + /** + * Initialise the event data. + */ + protected function init() { + $this->data['objecttable'] = audience::TABLE; + $this->data['crud'] = 'u'; + $this->data['edulevel'] = self::LEVEL_OTHER; + } + + /** + * Creates an instance from a report audience object + * + * @param audience $audience + * @return self + */ + public static function create_from_object(audience $audience): self { + $eventparams = [ + 'context' => $audience->get_report()->get_context(), + 'objectid' => $audience->get('id'), + 'other' => [ + 'reportid' => $audience->get('reportid'), + ] + ]; + $event = self::create($eventparams); + $event->add_record_snapshot($event->objecttable, $audience->to_record()); + return $event; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('audienceupdated', 'core_reportbuilder'); + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + $reportid = $this->other['reportid']; + return "The user with id '$this->userid' updated the audience with id '$this->objectid' in the custom report" . + " with id '$reportid'."; + } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['reportid'])) { + throw new coding_exception('The \'reportid\' must be set in other.'); + } + } + + /** + * Returns relevant URL. + * + * @return moodle_url + */ + public function get_url(): moodle_url { + return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'audience'); + } +} diff --git a/reportbuilder/classes/event/report_created.php b/reportbuilder/classes/event/report_created.php index 56920ac58bb..2744c37c7de 100644 --- a/reportbuilder/classes/event/report_created.php +++ b/reportbuilder/classes/event/report_created.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace core_reportbuilder\event; +use coding_exception; use core\event\base; use core_reportbuilder\local\models\report; use moodle_url; @@ -85,6 +86,18 @@ class report_created extends base { return "The user with id '$this->userid' created the custom report with id '$this->objectid'."; } + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + } + /** * Returns relevant URL. * diff --git a/reportbuilder/classes/event/report_deleted.php b/reportbuilder/classes/event/report_deleted.php index 785defcab79..bc116637e25 100644 --- a/reportbuilder/classes/event/report_deleted.php +++ b/reportbuilder/classes/event/report_deleted.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace core_reportbuilder\event; +use coding_exception; use core\event\base; use core_reportbuilder\local\models\report; @@ -83,4 +84,16 @@ class report_deleted extends base { public function get_description() { return "The user with id '$this->userid' deleted the custom report with id '$this->objectid'."; } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + } } diff --git a/reportbuilder/classes/event/report_updated.php b/reportbuilder/classes/event/report_updated.php index d99b3b8d9d3..2503f8f2d7b 100644 --- a/reportbuilder/classes/event/report_updated.php +++ b/reportbuilder/classes/event/report_updated.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace core_reportbuilder\event; +use coding_exception; use core\event\base; use core_reportbuilder\local\models\report; use moodle_url; @@ -85,6 +86,18 @@ class report_updated extends base { return "The user with id '$this->userid' updated the custom report with id '$this->objectid'."; } + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + } + /** * Returns relevant URL. * diff --git a/reportbuilder/classes/event/report_viewed.php b/reportbuilder/classes/event/report_viewed.php new file mode 100644 index 00000000000..1347b005243 --- /dev/null +++ b/reportbuilder/classes/event/report_viewed.php @@ -0,0 +1,109 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\event; + +use coding_exception; +use core\event\base; +use core_reportbuilder\local\models\report; +use moodle_url; + +/** + * Report builder custom report viewed event class. + * + * @package core_reportbuilder + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @property-read array $other { + * Extra information about the event. + * + * - string name: The name of the report + * - string source: The report source class + * } + */ +class report_viewed extends base { + + /** + * Initialise the event data. + */ + protected function init() { + $this->data['objecttable'] = report::TABLE; + $this->data['crud'] = 'r'; + $this->data['edulevel'] = self::LEVEL_OTHER; + } + + /** + * Creates an instance from a report object + * + * @param report $report + * @return self + */ + public static function create_from_object(report $report): self { + $eventparams = [ + 'context' => $report->get_context(), + 'objectid' => $report->get('id'), + 'other' => [ + 'name' => $report->get('name'), + 'source' => $report->get('source'), + ] + ]; + $event = self::create($eventparams); + $event->add_record_snapshot($event->objecttable, $report->to_record()); + return $event; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('reportviewed', 'core_reportbuilder'); + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + return "The user with id '$this->userid' viewed the custom report with id '$this->objectid'."; + } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + } + + /** + * Returns relevant URL. + * + * @return moodle_url + */ + public function get_url(): moodle_url { + return new moodle_url('/reportbuilder/view.php', ['id' => $this->objectid]); + } +} diff --git a/reportbuilder/classes/event/schedule_created.php b/reportbuilder/classes/event/schedule_created.php new file mode 100644 index 00000000000..fc00b4e1eb8 --- /dev/null +++ b/reportbuilder/classes/event/schedule_created.php @@ -0,0 +1,111 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\event; + +use coding_exception; +use core\event\base; +use core_reportbuilder\local\models\schedule; +use moodle_url; + +/** + * Report builder custom report schedule created event class. + * + * @package core_reportbuilder + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @property-read array $other { + * Extra information about the event. + * + * - int reportid: The id of the report + * } + */ +class schedule_created extends base { + + /** + * Initialise the event data. + */ + protected function init() { + $this->data['objecttable'] = schedule::TABLE; + $this->data['crud'] = 'c'; + $this->data['edulevel'] = self::LEVEL_OTHER; + } + + /** + * Creates an instance from a report schedule object + * + * @param schedule $schedule + * @return self + */ + public static function create_from_object(schedule $schedule): self { + $eventparams = [ + 'context' => $schedule->get_report()->get_context(), + 'objectid' => $schedule->get('id'), + 'other' => [ + 'reportid' => $schedule->get('reportid'), + ] + ]; + $event = self::create($eventparams); + $event->add_record_snapshot($event->objecttable, $schedule->to_record()); + return $event; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('schedulecreated', 'core_reportbuilder'); + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + $reportid = $this->other['reportid']; + return "The user with id '$this->userid' created a schedule in the custom report with id '$reportid'."; + } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['reportid'])) { + throw new coding_exception('The \'reportid\' must be set in other.'); + } + } + + /** + * Returns relevant URL. + * + * @return moodle_url + */ + public function get_url(): moodle_url { + return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'schedules'); + } +} diff --git a/reportbuilder/classes/event/schedule_deleted.php b/reportbuilder/classes/event/schedule_deleted.php new file mode 100644 index 00000000000..93cc166bbff --- /dev/null +++ b/reportbuilder/classes/event/schedule_deleted.php @@ -0,0 +1,112 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\event; + +use coding_exception; +use core\event\base; +use core_reportbuilder\local\models\schedule; +use moodle_url; + +/** + * Report builder custom report schedule created event class. + * + * @package core_reportbuilder + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @property-read array $other { + * Extra information about the event. + * + * - int reportid: The id of the report + * } + */ +class schedule_deleted extends base { + + /** + * Initialise the event data. + */ + protected function init() { + $this->data['objecttable'] = schedule::TABLE; + $this->data['crud'] = 'd'; + $this->data['edulevel'] = self::LEVEL_OTHER; + } + + /** + * Creates an instance from a report schedule object + * + * @param schedule $schedule + * @return self + */ + public static function create_from_object(schedule $schedule): self { + $eventparams = [ + 'context' => $schedule->get_report()->get_context(), + 'objectid' => $schedule->get('id'), + 'other' => [ + 'reportid' => $schedule->get('reportid'), + ] + ]; + $event = self::create($eventparams); + $event->add_record_snapshot($event->objecttable, $schedule->to_record()); + return $event; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('scheduledeleted', 'core_reportbuilder'); + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + $reportid = $this->other['reportid']; + return "The user with id '$this->userid' deleted the schedule with id '$this->objectid' in the custom report" . + " with id '$reportid'."; + } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['reportid'])) { + throw new coding_exception('The \'reportid\' must be set in other.'); + } + } + + /** + * Returns relevant URL. + * + * @return moodle_url + */ + public function get_url(): moodle_url { + return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'schedules'); + } +} diff --git a/reportbuilder/classes/event/schedule_updated.php b/reportbuilder/classes/event/schedule_updated.php new file mode 100644 index 00000000000..91a440ea1f9 --- /dev/null +++ b/reportbuilder/classes/event/schedule_updated.php @@ -0,0 +1,112 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\event; + +use coding_exception; +use core\event\base; +use core_reportbuilder\local\models\schedule; +use moodle_url; + +/** + * Report builder custom report schedule updated event class. + * + * @package core_reportbuilder + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * + * @property-read array $other { + * Extra information about the event. + * + * - int reportid: The id of the report + * } + */ +class schedule_updated extends base { + + /** + * Initialise the event data. + */ + protected function init() { + $this->data['objecttable'] = schedule::TABLE; + $this->data['crud'] = 'u'; + $this->data['edulevel'] = self::LEVEL_OTHER; + } + + /** + * Creates an instance from a report schedule object + * + * @param schedule $schedule + * @return self + */ + public static function create_from_object(schedule $schedule): self { + $eventparams = [ + 'context' => $schedule->get_report()->get_context(), + 'objectid' => $schedule->get('id'), + 'other' => [ + 'reportid' => $schedule->get('reportid'), + ] + ]; + $event = self::create($eventparams); + $event->add_record_snapshot($event->objecttable, $schedule->to_record()); + return $event; + } + + /** + * Returns localised general event name. + * + * @return string + */ + public static function get_name() { + return get_string('scheduleupdated', 'core_reportbuilder'); + } + + /** + * Returns non-localised description of what happened. + * + * @return string + */ + public function get_description() { + $reportid = $this->other['reportid']; + return "The user with id '$this->userid' updated the schedule with id '$this->objectid' in the custom report" . + " with id '$reportid'."; + } + + /** + * Custom validations. + * + * @throws coding_exception + */ + protected function validate_data(): void { + parent::validate_data(); + if (!isset($this->objectid)) { + throw new coding_exception('The \'objectid\' must be set.'); + } + if (!isset($this->other['reportid'])) { + throw new coding_exception('The \'reportid\' must be set in other.'); + } + } + + /** + * Returns relevant URL. + * + * @return moodle_url + */ + public function get_url(): moodle_url { + return new moodle_url('/reportbuilder/edit.php', ['id' => $this->other['reportid']], 'schedules'); + } +} diff --git a/reportbuilder/classes/local/models/audience.php b/reportbuilder/classes/local/models/audience.php index 05376935759..108bda04d64 100644 --- a/reportbuilder/classes/local/models/audience.php +++ b/reportbuilder/classes/local/models/audience.php @@ -19,6 +19,9 @@ declare(strict_types=1); namespace core_reportbuilder\local\models; use context; +use core_reportbuilder\event\audience_created; +use core_reportbuilder\event\audience_deleted; +use core_reportbuilder\event\audience_updated; use lang_string; use core\persistent; use core_reportbuilder\local\helpers\audience as helper; @@ -86,6 +89,7 @@ class audience extends persistent { * Hook to execute after creation */ protected function after_create(): void { + audience_created::create_from_object($this)->trigger(); helper::purge_caches(); } @@ -96,6 +100,7 @@ class audience extends persistent { */ protected function after_update($result): void { if ($result) { + audience_updated::create_from_object($this)->trigger(); helper::purge_caches(); } } @@ -107,6 +112,7 @@ class audience extends persistent { */ protected function after_delete($result): void { if ($result) { + audience_deleted::create_from_object($this)->trigger(); helper::purge_caches(); } } diff --git a/reportbuilder/classes/local/models/schedule.php b/reportbuilder/classes/local/models/schedule.php index 6cad49e5172..233d9af21c9 100644 --- a/reportbuilder/classes/local/models/schedule.php +++ b/reportbuilder/classes/local/models/schedule.php @@ -19,6 +19,9 @@ declare(strict_types=1); namespace core_reportbuilder\local\models; use context; +use core_reportbuilder\event\schedule_created; +use core_reportbuilder\event\schedule_deleted; +use core_reportbuilder\event\schedule_updated; use lang_string; use core\persistent; @@ -192,4 +195,33 @@ class schedule extends persistent { return format_string($this->raw_get('name'), true, ['context' => $context]); } + + /** + * Hook to execute after creation + */ + protected function after_create(): void { + schedule_created::create_from_object($this)->trigger(); + } + + /** + * Hook to execute after update + * + * @param bool $result + */ + protected function after_update($result): void { + if ($result) { + schedule_updated::create_from_object($this)->trigger(); + } + } + + /** + * Hook to execute after deletion + * + * @param bool $result + */ + protected function after_delete($result): void { + if ($result) { + schedule_deleted::create_from_object($this)->trigger(); + } + } } diff --git a/reportbuilder/tests/local/models/audience_test.php b/reportbuilder/tests/local/models/audience_test.php new file mode 100644 index 00000000000..257b0b17d5e --- /dev/null +++ b/reportbuilder/tests/local/models/audience_test.php @@ -0,0 +1,155 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\local\models; + +use advanced_testcase; +use core\persistent; +use core_reportbuilder\event\audience_created; +use core_reportbuilder\event\audience_deleted; +use core_reportbuilder\event\audience_updated; +use core_reportbuilder_generator; +use core_user\reportbuilder\datasource\users; + +/** + * Unit tests for the audience model + * + * @package core_reportbuilder + * @covers \core_reportbuilder\local\models\audience + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class audience_test extends advanced_testcase { + + /** + * Tests for audience_created event + * + * @return persistent[] + * + * @covers \core_reportbuilder\event\audience_created + */ + public function test_audience_created_event(): array { + $this->resetAfterTest(); + $this->setAdminUser(); + + /** @var core_reportbuilder_generator $generator */ + $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); + + $report = $generator->create_report([ + 'name' => 'My report', + 'source' => users::class, + 'default' => false, + ]); + + // Catch the events. + $sink = $this->redirectEvents(); + $audience = $generator->create_audience(['reportid' => $report->get('id'), 'configdata' => []]) + ->get_persistent(); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(audience_created::class, $event); + $this->assertEquals(audience::TABLE, $event->objecttable); + $this->assertEquals($audience->get('id'), $event->objectid); + $this->assertEquals($report->get('id'), $event->other['reportid']); + $this->assertEquals($report->get_context()->id, $event->contextid); + + return [$report, $audience]; + } + + /** + * Tests for audience_updated event + * + * @param persistent[] $persistents + * @return persistent[] + * + * @depends test_audience_created_event + * @covers \core_reportbuilder\event\audience_updated + */ + public function test_audience_updated_event(array $persistents): array { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + // Re-create the persistents. + [$report, $audience] = $persistents; + $report = new report($DB->insert_record(report::TABLE, $report->to_record())); + $audience = new audience($DB->insert_record(audience::TABLE, $audience->to_record())); + + // Catch the events. + $sink = $this->redirectEvents(); + $audience->set('heading', 'Hello')->update(); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(audience_updated::class, $event); + $this->assertEquals(audience::TABLE, $event->objecttable); + $this->assertEquals($audience->get('id'), $event->objectid); + $this->assertEquals($report->get('id'), $event->other['reportid']); + $this->assertEquals($report->get_context()->id, $event->contextid); + + return [$report, $audience]; + } + + /** + * Tests for audience_deleted event + * + * @param persistent[] $persistents + * + * @depends test_audience_updated_event + * @covers \core_reportbuilder\event\audience_deleted + */ + public function test_audience_deleted_event(array $persistents): void { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + // Re-create the persistents (remembering audience ID which is removed from persistent upon deletion). + [$report, $audience] = $persistents; + $report = new report($DB->insert_record(report::TABLE, $report->to_record())); + + $audienceid = $DB->insert_record(audience::TABLE, $audience->to_record()); + $audience = new audience($audienceid); + + // Catch the events. + $sink = $this->redirectEvents(); + $audience->delete(); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(audience_deleted::class, $event); + $this->assertEquals(audience::TABLE, $event->objecttable); + $this->assertEquals($audienceid, $event->objectid); + $this->assertEquals($report->get('id'), $event->other['reportid']); + $this->assertEquals($report->get_context()->id, $event->contextid); + } +} diff --git a/reportbuilder/tests/local/models/report_test.php b/reportbuilder/tests/local/models/report_test.php new file mode 100644 index 00000000000..688010d4d51 --- /dev/null +++ b/reportbuilder/tests/local/models/report_test.php @@ -0,0 +1,149 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\local\models; + +use advanced_testcase; +use core_reportbuilder\event\report_created; +use core_reportbuilder\event\report_deleted; +use core_reportbuilder\event\report_updated; +use core_reportbuilder_generator; +use core_user\reportbuilder\datasource\users; + +/** + * Unit tests for the report model + * + * @package core_reportbuilder + * @covers \core_reportbuilder\local\models\report + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class report_test extends advanced_testcase { + + /** + * Tests for report_created event + * + * @return report + * + * @covers \core_reportbuilder\event\report_created + */ + public function test_report_created_event(): report { + $this->resetAfterTest(); + $this->setAdminUser(); + + /** @var core_reportbuilder_generator $generator */ + $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); + + // Catch the events. + $sink = $this->redirectEvents(); + $report = $generator->create_report([ + 'name' => 'My report', + 'source' => users::class, + 'default' => false, + ]); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(report_created::class, $event); + $this->assertEquals(report::TABLE, $event->objecttable); + $this->assertEquals($report->get('id'), $event->objectid); + $this->assertEquals($report->get('name'), $event->other['name']); + $this->assertEquals($report->get('source'), $event->other['source']); + $this->assertEquals($report->get_context()->id, $event->contextid); + + return $report; + } + + /** + * Tests for report_updated event + * + * @param report $report + * @return report + * + * @depends test_report_created_event + * @covers \core_reportbuilder\event\report_updated + */ + public function test_report_updated_event(report $report): report { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + // Re-create the persistent. + $report = new report($DB->insert_record(report::TABLE, $report->to_record())); + + // Catch the events. + $sink = $this->redirectEvents(); + $report->set('name', 'New report name')->update(); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(report_updated::class, $event); + $this->assertEquals(report::TABLE, $event->objecttable); + $this->assertEquals($report->get('id'), $event->objectid); + $this->assertEquals('New report name', $event->other['name']); + $this->assertEquals($report->get('source'), $event->other['source']); + $this->assertEquals($report->get_context()->id, $event->contextid); + + return $report; + } + + /** + * Tests for report_deleted event + * + * @param report $report + * + * @depends test_report_updated_event + * @covers \core_reportbuilder\event\report_deleted + */ + public function test_report_deleted_event(report $report): void { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + // Re-create the persistent (remembering report ID which is removed from persistent upon deletion). + $reportid = $DB->insert_record(report::TABLE, $report->to_record()); + $report = new report($reportid); + + // Catch the events. + $sink = $this->redirectEvents(); + $report->delete(); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(report_deleted::class, $event); + $this->assertEquals(report::TABLE, $event->objecttable); + $this->assertEquals($reportid, $event->objectid); + $this->assertEquals($report->get('name'), $event->other['name']); + $this->assertEquals($report->get('source'), $event->other['source']); + $this->assertEquals($report->get_context()->id, $event->contextid); + } +} diff --git a/reportbuilder/tests/local/models/schedule_test.php b/reportbuilder/tests/local/models/schedule_test.php new file mode 100644 index 00000000000..25e50e2c97f --- /dev/null +++ b/reportbuilder/tests/local/models/schedule_test.php @@ -0,0 +1,154 @@ +. + +declare(strict_types=1); + +namespace core_reportbuilder\local\models; + +use advanced_testcase; +use core\persistent; +use core_reportbuilder\event\schedule_created; +use core_reportbuilder\event\schedule_deleted; +use core_reportbuilder\event\schedule_updated; +use core_reportbuilder_generator; +use core_user\reportbuilder\datasource\users; + +/** + * Unit tests for the schedule model + * + * @package core_reportbuilder + * @covers \core_reportbuilder\local\models\schedule + * @copyright 2021 David Matamoros + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class schedule_test extends advanced_testcase { + + /** + * Tests for schedule_created event + * + * @return persistent[] + * + * @covers \core_reportbuilder\event\schedule_created + */ + public function test_schedule_created_event(): array { + $this->resetAfterTest(); + $this->setAdminUser(); + + /** @var core_reportbuilder_generator $generator */ + $generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder'); + + $report = $generator->create_report([ + 'name' => 'My report', + 'source' => users::class, + 'default' => false, + ]); + + // Catch the events. + $sink = $this->redirectEvents(); + $schedule = $generator->create_schedule(['reportid' => $report->get('id'), 'name' => 'My schedule']); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(schedule_created::class, $event); + $this->assertEquals(schedule::TABLE, $event->objecttable); + $this->assertEquals($schedule->get('id'), $event->objectid); + $this->assertEquals($report->get('id'), $event->other['reportid']); + $this->assertEquals($report->get_context()->id, $event->contextid); + + return [$report, $schedule]; + } + + /** + * Tests for schedule_updated event + * + * @param persistent[] $persistents + * @return persistent[] + * + * @depends test_schedule_created_event + * @covers \core_reportbuilder\event\schedule_updated + */ + public function test_schedule_updated_event(array $persistents): array { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + // Re-create the persistents. + [$report, $schedule] = $persistents; + $report = new report($DB->insert_record(report::TABLE, $report->to_record())); + $schedule = new schedule($DB->insert_record(schedule::TABLE, $schedule->to_record())); + + // Catch the events. + $sink = $this->redirectEvents(); + $schedule->set('name', 'My new schedule')->update(); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(schedule_updated::class, $event); + $this->assertEquals(schedule::TABLE, $event->objecttable); + $this->assertEquals($schedule->get('id'), $event->objectid); + $this->assertEquals($report->get('id'), $event->other['reportid']); + $this->assertEquals($report->get_context()->id, $event->contextid); + + return [$report, $schedule]; + } + + /** + * Tests for schedule_deleted event + * + * @param persistent[] $persistents + * + * @depends test_schedule_updated_event + * @covers \core_reportbuilder\event\schedule_deleted + */ + public function test_schedule_deleted_event(array $persistents): void { + global $DB; + + $this->resetAfterTest(); + $this->setAdminUser(); + + // Re-create the persistents (remembering schedule ID which is removed from persistent upon deletion). + [$report, $schedule] = $persistents; + $report = new report($DB->insert_record(report::TABLE, $report->to_record())); + + $scheduleid = $DB->insert_record(schedule::TABLE, $schedule->to_record()); + $schedule = new schedule($scheduleid); + + // Catch the events. + $sink = $this->redirectEvents(); + $schedule->delete(); + $events = $sink->get_events(); + $sink->close(); + + // Validate the event. + $this->assertCount(1, $events); + + $event = reset($events); + $this->assertInstanceOf(schedule_deleted::class, $event); + $this->assertEquals(schedule::TABLE, $event->objecttable); + $this->assertEquals($scheduleid, $event->objectid); + $this->assertEquals($report->get('id'), $event->other['reportid']); + $this->assertEquals($report->get_context()->id, $event->contextid); + } +} diff --git a/reportbuilder/view.php b/reportbuilder/view.php index add687916cc..9aab7a3990c 100644 --- a/reportbuilder/view.php +++ b/reportbuilder/view.php @@ -24,6 +24,7 @@ declare(strict_types=1); +use core_reportbuilder\event\report_viewed; use core_reportbuilder\manager; use core_reportbuilder\output\custom_report; use core_reportbuilder\permission; @@ -55,3 +56,6 @@ $export = (new custom_report($report->get_report_persistent(), false))->export_f echo $renderer->render_from_template('core_reportbuilder/report', $export); echo $OUTPUT->footer(); + +// Trigger report viewed event. +report_viewed::create_from_object($report->get_report_persistent())->trigger();