From c1615cbd165fb06493e9a1ec22db5565e6b39502 Mon Sep 17 00:00:00 2001 From: Mark Nelson Date: Thu, 26 Nov 2020 19:54:58 +0800 Subject: [PATCH] Do not email out certificates with no elements (#276) --- classes/task/email_certificate_task.php | 12 +++ tests/email_certificate_task_test.php | 136 ++++++++++++++++++++++-- 2 files changed, 140 insertions(+), 8 deletions(-) diff --git a/classes/task/email_certificate_task.php b/classes/task/email_certificate_task.php index 846151f..fb27769 100644 --- a/classes/task/email_certificate_task.php +++ b/classes/task/email_certificate_task.php @@ -69,6 +69,18 @@ class email_certificate_task extends \core\task\scheduled_task { $htmlrenderer = $PAGE->get_renderer('mod_customcert', 'email', 'htmlemail'); $textrenderer = $PAGE->get_renderer('mod_customcert', 'email', 'textemail'); foreach ($customcerts as $customcert) { + // Do not process an empty certificate. + $sql = "SELECT ce.* + FROM {customcert_elements} ce + JOIN {customcert_pages} cp + ON cp.id = ce.pageid + JOIN {customcert_templates} ct + ON ct.id = cp.templateid + WHERE ct.contextid = :contextid"; + if (!$DB->record_exists_sql($sql, ['contextid' => $customcert->contextid])) { + continue; + } + // Get the context. $context = \context::instance_by_id($customcert->contextid); diff --git a/tests/email_certificate_task_test.php b/tests/email_certificate_task_test.php index 1fc6d52..285acd6 100644 --- a/tests/email_certificate_task_test.php +++ b/tests/email_certificate_task_test.php @@ -25,8 +25,6 @@ defined('MOODLE_INTERNAL') || die(); -global $CFG; - /** * Unit tests for the email certificate task. * @@ -44,6 +42,32 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc $this->resetAfterTest(); } + /** + * Tests the email certificate task when there are no elements. + */ + public function test_email_certificates_no_elements() { + // Create a course. + $course = $this->getDataGenerator()->create_course(); + + // Create a user. + $user1 = $this->getDataGenerator()->create_user(); + + // Create a custom certificate with no elements. + $this->getDataGenerator()->create_module('customcert', ['course' => $course->id, 'emailstudents' => 1]); + + // Enrol the user as a student + $this->getDataGenerator()->enrol_user($user1->id, $course->id); + + // Run the task. + $sink = $this->redirectEmails(); + $task = new \mod_customcert\task\email_certificate_task(); + $task->execute(); + $emails = $sink->get_messages(); + + // Confirm that we did not send any emails because the certificate has no elements. + $this->assertCount(0, $emails); + } + /** * Tests the email certificate task for users without a capability to receive a certificate. */ @@ -65,7 +89,23 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc unassign_capability('mod/customcert:receiveissue', $roleids['student']); // Create a custom certificate. - $this->getDataGenerator()->create_module('customcert', ['course' => $course->id, 'emailstudents' => 1]); + $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id, 'emailstudents' => 1]); + + // Create template object. + $template = new stdClass(); + $template->id = $customcert->templateid; + $template->name = 'A template'; + $template->contextid = context_course::instance($course->id)->id; + $template = new \mod_customcert\template($template); + + // Add a page to this template. + $pageid = $template->add_page(); + + // Add an element to the page. + $element = new stdClass(); + $element->pageid = $pageid; + $element->name = 'Image'; + $DB->insert_record('customcert_elements', $element); // Run the task. $sink = $this->redirectEmails(); @@ -103,6 +143,22 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, 'emailstudents' => 1)); + // Create template object. + $template = new stdClass(); + $template->id = $customcert->templateid; + $template->name = 'A template'; + $template->contextid = context_course::instance($course->id)->id; + $template = new \mod_customcert\template($template); + + // Add a page to this template. + $pageid = $template->add_page(); + + // Add an element to the page. + $element = new stdClass(); + $element->pageid = $pageid; + $element->name = 'Image'; + $DB->insert_record('customcert_elements', $element); + // Ok, now issue this to one user. \mod_customcert\certificate::issue_certificate($customcert->id, $user1->id); @@ -169,9 +225,25 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc $this->getDataGenerator()->enrol_user($user3->id, $course->id, $roleids['editingteacher']); // Create a custom certificate. - $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, + $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, 'emailteachers' => 1)); + // Create template object. + $template = new stdClass(); + $template->id = $customcert->templateid; + $template->name = 'A template'; + $template->contextid = context_course::instance($course->id)->id; + $template = new \mod_customcert\template($template); + + // Add a page to this template. + $pageid = $template->add_page(); + + // Add an element to the page. + $element = new stdClass(); + $element->pageid = $pageid; + $element->name = 'Image'; + $DB->insert_record('customcert_elements', $element); + // Run the task. $sink = $this->redirectEmails(); $task = new \mod_customcert\task\email_certificate_task(); @@ -192,7 +264,7 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc * Tests the email certificate task for others. */ public function test_email_certificates_others() { - global $CFG; + global $CFG, $DB; // Create a course. $course = $this->getDataGenerator()->create_course(); @@ -206,9 +278,25 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc $this->getDataGenerator()->enrol_user($user2->id, $course->id); // Create a custom certificate. - $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, + $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, 'emailothers' => 'testcustomcert@example.com, doo@dah')); + // Create template object. + $template = new stdClass(); + $template->id = $customcert->templateid; + $template->name = 'A template'; + $template->contextid = context_course::instance($course->id)->id; + $template = new \mod_customcert\template($template); + + // Add a page to this template. + $pageid = $template->add_page(); + + // Add an element to the page. + $element = new stdClass(); + $element->pageid = $pageid; + $element->name = 'Image'; + $DB->insert_record('customcert_elements', $element); + // Run the task. $sink = $this->redirectEmails(); $task = new \mod_customcert\task\email_certificate_task(); @@ -242,7 +330,23 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc $this->getDataGenerator()->enrol_user($user1->id, $course->id); // Create a custom certificate. - $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, 'emailstudents' => 1)); + $customcert = $this->getDataGenerator()->create_module('customcert', ['course' => $course->id, 'emailstudents' => 1]); + + // Create template object. + $template = new stdClass(); + $template->id = $customcert->templateid; + $template->name = 'A template'; + $template->contextid = context_course::instance($course->id)->id; + $template = new \mod_customcert\template($template); + + // Add a page to this template. + $pageid = $template->add_page(); + + // Add an element to the page. + $element = new stdClass(); + $element->pageid = $pageid; + $element->name = 'Image'; + $DB->insert_record('customcert_elements', $element); // Remove the permission for the user to view the certificate. assign_capability('mod/customcert:view', CAP_PROHIBIT, $roleids['student'], \context_course::instance($course->id)); @@ -280,9 +384,25 @@ class mod_customcert_task_email_certificate_task_testcase extends advanced_testc $this->getDataGenerator()->enrol_user($user1->id, $course->id); // Create a custom certificate. - $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, 'emailstudents' => 1, + $customcert = $this->getDataGenerator()->create_module('customcert', array('course' => $course->id, 'emailstudents' => 1, 'requiredtime' => '60')); + // Create template object. + $template = new stdClass(); + $template->id = $customcert->templateid; + $template->name = 'A template'; + $template->contextid = context_course::instance($course->id)->id; + $template = new \mod_customcert\template($template); + + // Add a page to this template. + $pageid = $template->add_page(); + + // Add an element to the page. + $element = new stdClass(); + $element->pageid = $pageid; + $element->name = 'Image'; + $DB->insert_record('customcert_elements', $element); + // Run the task. $sink = $this->redirectEmails(); $task = new \mod_customcert\task\email_certificate_task();