diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 8217a1c..3afe4da 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -58,7 +58,7 @@ public static function get_metadata(collection $collection): collection { 'id' => 'privacy:metadata:block_quickmail_log:id', 'courseid' => 'privacy:metadata:block_quickmail_log:courseid', 'userid' => 'privacy:metadata:block_quickmail_log:userid', - 'alterateid' => 'privacy:metadata:block_quickmail_log:alterateid', + 'alternateid' => 'privacy:metadata:block_quickmail_log:alternateid', 'mailto' => 'privacy:metadata:block_quickmail_log:mailto', 'subject' => 'privacy:metadata:block_quickmail_log:subject', 'message' => 'privacy:metadata:block_quickmail_log:message', @@ -71,18 +71,6 @@ public static function get_metadata(collection $collection): collection { 'privacy:metadata:block_quickmail_log', ); - $collection->add_database_table( - 'block_quickmail_signatures', - [ - 'id' => 'privacy:metadata:block_quickmail_signatures:id', - 'userid' => 'privacy:metadata:block_quickmail_signatures:userid', - 'title' => 'privacy:metadata:block_quickmail_signatures:title', - 'signature' => 'privacy:metadata:block_quickmail_signatures:signature', - 'default_flag' => 'privacy:metadata:block_quickmail_signatures:default_flag', - ], - 'privacy:metadata:block_quickmail_signatures', - ); - $collection->add_database_table( 'block_quickmail_drafts', [ @@ -101,6 +89,18 @@ public static function get_metadata(collection $collection): collection { 'privacy:metadata:block_quickmail_drafts' ); + $collection->add_database_table( + 'block_quickmail_signatures', + [ + 'id' => 'privacy:metadata:block_quickmail_signatures:id', + 'userid' => 'privacy:metadata:block_quickmail_signatures:userid', + 'title' => 'privacy:metadata:block_quickmail_signatures:title', + 'signature' => 'privacy:metadata:block_quickmail_signatures:signature', + 'default_flag' => 'privacy:metadata:block_quickmail_signatures:default_flag', + ], + 'privacy:metadata:block_quickmail_signatures', + ); + return $collection; } @@ -292,14 +292,12 @@ public static function get_users_in_context(userlist $userlist): void { * @throws dml_exception */ public static function delete_data_for_users(approved_userlist $userlist): void { - $users = $userlist->get_users(); - foreach ($users as $user) { - $contextlist = new approved_contextlist( - $user, - 'block_quickmail', - [context_user::instance($user->id)->id] - ); - self::delete_data_for_user($contextlist); + global $DB; + $context = $userlist->get_context(); + if ($context instanceof context_user && in_array($context->instanceid, $userlist->get_userids())) { + $DB->delete_records('block_quickmail_log', ['userid' => $context->instanceid]); + $DB->delete_records('block_quickmail_drafts', ['userid' => $context->instanceid]); + $DB->delete_records('block_quickmail_signatures', ['userid' => $context->instanceid]); } } } diff --git a/lang/en/block_quickmail.php b/lang/en/block_quickmail.php index 6ad2d2b..f157b7a 100644 --- a/lang/en/block_quickmail.php +++ b/lang/en/block_quickmail.php @@ -149,7 +149,7 @@ $string['privacy:metadata:block_quickmail_drafts:userid'] = 'The ID of the user who created this draft.'; $string['privacy:metadata:block_quickmail_log'] = 'Stores sent quickmail messages.'; $string['privacy:metadata:block_quickmail_log:additional_emails'] = 'Emails of additional recipients.'; -$string['privacy:metadata:block_quickmail_log:alterateid'] = 'The ID of the alternate email for this message.'; +$string['privacy:metadata:block_quickmail_log:alternateid'] = 'The ID of the alternate email for this message.'; $string['privacy:metadata:block_quickmail_log:attachment'] = 'The names of files attached to this message.'; $string['privacy:metadata:block_quickmail_log:courseid'] = 'The ID of the course this message belongs to.'; $string['privacy:metadata:block_quickmail_log:failuserids'] = 'A list of user IDs for the failed recipients.'; diff --git a/lang/en_us/block_quickmail.php b/lang/en_us/block_quickmail.php index bab3a03..8d59df6 100644 --- a/lang/en_us/block_quickmail.php +++ b/lang/en_us/block_quickmail.php @@ -148,7 +148,7 @@ $string['privacy:metadata:block_quickmail_drafts:userid'] = 'The ID of the user who created this draft.'; $string['privacy:metadata:block_quickmail_log'] = 'Stores sent quickmail messages.'; $string['privacy:metadata:block_quickmail_log:additional_emails'] = 'Emails of additional recipients.'; -$string['privacy:metadata:block_quickmail_log:alterateid'] = 'The ID of the alternate email for this message.'; +$string['privacy:metadata:block_quickmail_log:alternateid'] = 'The ID of the alternate email for this message.'; $string['privacy:metadata:block_quickmail_log:attachment'] = 'The names of files attached to this message.'; $string['privacy:metadata:block_quickmail_log:courseid'] = 'The ID of the course this message belongs to.'; $string['privacy:metadata:block_quickmail_log:failuserids'] = 'A list of user IDs for the failed recipients.'; diff --git a/tests/generator/lib.php b/tests/generator/lib.php new file mode 100644 index 0000000..d9bef04 --- /dev/null +++ b/tests/generator/lib.php @@ -0,0 +1,183 @@ +. + +/** + * Data generator for block_quickmail. + * + * @package block_quickmail + * @copyright The Regents of the University of California + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +/** + * Quickmail block data generator class. + * + * @package block_quickmail + * @copyright The Regents of the University of California + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class block_quickmail_generator extends testing_block_generator { + + /** + * Creates and returns a quickmail log (aka "sent message") record with the given data points. + * + * @param stdClass $user The message sender. + * @param stdClass $course The course that this message was sent in. + * @param array $recipients A list of user records that are recipients of this message. + * @param stdClass|null $alternateemail An alternate email to be used as sender. + * @param string|null $subject The message subject. + * @param string|null $message The message contents. + * @param string|null $attachment A comma-separated list of attachment names. + * @param int|null $format The message format. + * @param int|null $timesent The timestamp of when the message was sent. + * @param string|null $faileduserids A comma-separated list of user IDs where message delivery failed. + * @param string|null $additionalemails A comma-separated list of emails that this message was sent to. + * @return stdClass The log record. + * @throws dml_exception + */ + public function create_quickmail_log( + stdClass $user, + stdClass $course, + array $recipients = [], + ?stdClass $alternateemail = null, + ?string $subject = null, + ?string $message = null, + ?string $attachment = null, + ?int $format = null, + ?int $timesent = null, + ?string $faileduserids = null, + ?string $additionalemails = null, + ): stdClass { + global $DB; + + $record = []; + $record['courseid'] = $course->id; + $record['userid'] = $user->id; + $record['alternateid'] = $alternateemail?->id; + $recipientids = []; + foreach ($recipients as $recipient) { + $recipientids[] = $recipient->id; + } + $record['mailto'] = implode(',', $recipientids); + $record['subject'] = $subject ?? 'test subject'; + $record['message'] = $message ?? 'test message'; + $record['attachment'] = $attachment ?? ''; + $record['format'] = $format ?? 0; + $record['time'] = $timesent ?? time(); + $record['failuserids'] = $faileduserids ?? ''; + $record['additional_emails'] = $additionalemails ?? ''; + + $id = $DB->insert_record('block_quickmail_log', $record); + return $DB->get_record('block_quickmail_log', ['id' => $id]); + } + + /** + * Creates a quickmail draft (aka "message draft") record with the given data points. + * + * @param stdClass $user The message sender. + * @param stdClass $course The course that this message will be sent in. + * @param array $recipients A list of user records that will be recipients of this message. + * @param stdClass|null $alternateemail An alternate email to be used as sender. + * @param string|null $subject The message subject. + * @param string|null $message The message contents. + * @param string|null $attachment A comma-separated list of attachment names. + * @param int|null $format The message format. + * @param int|null $timecreated The timestamp of when the draft was created. + * @param string|null $additionalemails A comma-separated list of emails that this message will be sent to. + * @return stdClass The message draft record. + * @throws dml_exception + */ + public function create_quickmail_draft( + stdClass $user, + stdClass $course, + array $recipients = [], + ?stdClass $alternateemail = null, + ?string $subject = null, + ?string $message = null, + ?string $attachment = null, + ?int $format = null, + ?int $timecreated = null, + ?string $additionalemails = null, + ): stdClass { + global $DB; + + $record = []; + $record['courseid'] = $course->id; + $record['userid'] = $user->id; + $record['alternateid'] = $alternateemail?->id; + $recipientids = []; + foreach ($recipients as $recipient) { + $recipientids[] = $recipient->id; + } + $record['mailto'] = implode(',', $recipientids); + $record['subject'] = $subject ?? 'test subject'; + $record['message'] = $message ?? 'test message'; + $record['attachment'] = $attachment ?? ''; + $record['format'] = $format ?? 0; + $record['time'] = $timecreated ?? time(); + $record['additional_emails'] = $additionalemails ?? ''; + + $id = $DB->insert_record('block_quickmail_drafts', $record); + return $DB->get_record('block_quickmail_drafts', ['id' => $id]); + + } + + /** + * Creates a quickmail email signature record with the given data points. + * @param stdClass $user The signature owner. + * @param string|null $title The title of this signature. + * @param string|null $signature The email signature. + * @param int|null $isdefault Set to 1 to indicate that this is the user's default signature, 0 otherwise. + * @return stdClass The signature record. + * @throws dml_exception + */ + public function create_quickmail_signature( + stdClass $user, + ?string $title = null, + ?string $signature = null, + ?int $isdefault = null + ): stdClass { + global $DB; + + $record = []; + $record['userid'] = $user->id; + $record['title'] = $title ?? "email signature for user $user->id"; + $record['signature'] = $signature ?? "$user->id signature"; + $record['default_flag'] = $isdefault ?? 0; + $id = $DB->insert_record('block_quickmail_signatures', $record); + return $DB->get_record('block_quickmail_signatures', ['id' => $id]); + } + + /** + * Creates a quickmail alternate email sender record for the given course. + * + * @param stdClass $course The course. + * @param ?string $email The alternate email address. + * @param ?int $valid Set to 1 to indicate a valid record, 0 for invalid. + * @return stdClass The alternate email record. + * @throws dml_exception + */ + public function create_quickmail_alternate(stdClass $course, ?string $email = null, ?int $valid = null): stdClass { + global $DB; + + $record = []; + $record['courseid'] = $course->id; + $record['address'] = $email ?? "course$course->id@example.edu"; + $record['valid'] = $valid ?? 1; + $id = $DB->insert_record('block_quickmail_alternate', $record); + return $DB->get_record('block_quickmail_alternate', ['id' => $id]); + } +} diff --git a/tests/generator_test.php b/tests/generator_test.php new file mode 100644 index 0000000..835a716 --- /dev/null +++ b/tests/generator_test.php @@ -0,0 +1,238 @@ +. + +/** + * Test coverage for Quickmail block data generator. + * + * @package block_quickmail + * @copyright The Regents of the University of California + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace block_quickmail; + +use advanced_testcase; + +/** + * Quickmail block data generator testcase. + * + * @package block_quickmail + * @copyright The Regents of the University of California + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \block_quickmail_generator + */ +final class generator_test extends advanced_testcase { + /** + * Tests quickmail log record generator. + */ + public function test_create_quickmail_log(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $generator->get_plugin_generator('block_quickmail'); + + $this->assertEquals(0, $DB->count_records('block_quickmail_log')); + + $user = $generator->create_user(); + $user2 = $generator->create_user(); + $user3 = $generator->create_user(); + $course = $generator->create_course(); + + // Create quickmail log record with required properties only. + $log = $plugingenerator->create_quickmail_log($user, $course, []); + + // Confirm that record count in the DB ticked up. + $this->assertEquals(1, $DB->count_records('block_quickmail_log')); + + // Check log record props. + $this->assertEquals($course->id, $log->courseid); + $this->assertEquals($user->id, $log->userid); + $this->assertNull($log->alternateid); + $this->assertEquals('', $log->mailto); + $this->assertEquals('test subject', $log->subject); + $this->assertEquals('test message', $log->message); + $this->assertEquals('', $log->attachment); + $this->assertEquals(0, $log->format); + $this->assertLessThanOrEqual(time(), $log->time); + $this->assertGreaterThan(0, $log->time); + $this->assertEquals('', $log->failuserids); + $this->assertEquals('', $log->additional_emails); + + // Create another log record with overridden defaults. + $alternate = $plugingenerator->create_quickmail_alternate($course); + $timesent = time() + 10000; + + $log = $plugingenerator->create_quickmail_log( + $user, + $course, + [$user2, $user3], + $alternate, + 'lorem', + 'ipsum', + 'test.png', + 2, + $timesent, + '1,2,3', + 'foo@bar.com', + ); + $this->assertEquals(2, $DB->count_records('block_quickmail_log')); + + $this->assertEquals($course->id, $log->courseid); + $this->assertEquals($user->id, $log->userid); + $this->assertEquals($alternate->id, $log->alternateid); + $this->assertEquals("$user2->id,$user3->id", $log->mailto); + $this->assertEquals('lorem', $log->subject); + $this->assertEquals('ipsum', $log->message); + $this->assertEquals('test.png', $log->attachment); + $this->assertEquals(2, $log->format); + $this->assertEquals($timesent, $log->time); + $this->assertEquals('1,2,3', $log->failuserids); + $this->assertEquals('foo@bar.com', $log->additional_emails); + } + + /** + * Tests quickmail draft record generator. + */ + public function test_create_quickmail_draft(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $generator->get_plugin_generator('block_quickmail'); + + $this->assertEquals(0, $DB->count_records('block_quickmail_drafts')); + + $user = $generator->create_user(); + $user2 = $generator->create_user(); + $user3 = $generator->create_user(); + $course = $generator->create_course(); + + // Create quickmail draft record with required properties only. + $draft = $plugingenerator->create_quickmail_draft($user, $course, []); + + // Confirm that record count in the DB ticked up. + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts')); + + // Check draft record props. + $this->assertEquals($course->id, $draft->courseid); + $this->assertEquals($user->id, $draft->userid); + $this->assertNull($draft->alternateid); + $this->assertEquals('', $draft->mailto); + $this->assertEquals('test subject', $draft->subject); + $this->assertEquals('test message', $draft->message); + $this->assertEquals('', $draft->attachment); + $this->assertEquals(0, $draft->format); + $this->assertLessThanOrEqual(time(), $draft->time); + $this->assertGreaterThan(0, $draft->time); + $this->assertEquals('', $draft->additional_emails); + + // Create another draft record with overridden defaults. + $alternate = $plugingenerator->create_quickmail_alternate($course); + $timecreated = time() + 10000; + + $draft = $plugingenerator->create_quickmail_draft( + $user, + $course, + [$user2, $user3], + $alternate, + 'lorem', + 'ipsum', + 'test.png', + 2, + $timecreated, + 'foo@bar.com', + ); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts')); + + $this->assertEquals($course->id, $draft->courseid); + $this->assertEquals($user->id, $draft->userid); + $this->assertEquals($alternate->id, $draft->alternateid); + $this->assertEquals("$user2->id,$user3->id", $draft->mailto); + $this->assertEquals('lorem', $draft->subject); + $this->assertEquals('ipsum', $draft->message); + $this->assertEquals('test.png', $draft->attachment); + $this->assertEquals(2, $draft->format); + $this->assertEquals($timecreated, $draft->time); + $this->assertEquals('foo@bar.com', $draft->additional_emails); + } + + /** + * Tests quickmail alternate email record record generator. + */ + public function test_create_quickmail_alternate(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $generator->get_plugin_generator('block_quickmail'); + + $this->assertEquals(0, $DB->count_records('block_quickmail_alternate')); + + $course = $generator->create_course(); + + // Create quickmail alternate email record with required properties only. + $alternate = $plugingenerator->create_quickmail_alternate($course); + + // Confirm that record count in the DB ticked up. + $this->assertEquals(1, $DB->count_records('block_quickmail_alternate')); + + // Check log record props. + $this->assertEquals($course->id, $alternate->courseid); + $this->assertEquals("course$course->id@example.edu", $alternate->address); + $this->assertEquals(1, $alternate->valid); + + // Create another alt email record with overridden defaults. + $alternate = $plugingenerator->create_quickmail_alternate($course, 'someemail@example.edu', 0); + $this->assertEquals($course->id, $alternate->courseid); + $this->assertEquals("someemail@example.edu", $alternate->address); + $this->assertEquals(0, $alternate->valid); + } + + /** + * Tests quickmail email signature record generator. + */ + public function test_create_quickmail_signature(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $generator->get_plugin_generator('block_quickmail'); + + $this->assertEquals(0, $DB->count_records('block_quickmail_signatures')); + + $user = $generator->create_user(); + + // Create quickmail email signature with required properties only. + $signature = $plugingenerator->create_quickmail_signature($user); + + // Confirm that record count in the DB ticked up. + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures')); + + // Check signature record props. + $this->assertEquals($user->id, $signature->userid); + $this->assertEquals("email signature for user $user->id", $signature->title); + $this->assertEquals("$user->id signature", $signature->signature); + $this->assertEquals(0, $signature->default_flag); + + // Create another signature record with overridden defaults. + $signature = $plugingenerator->create_quickmail_signature($user, 'foo', 'bar', 1); + $this->assertEquals($user->id, $signature->userid); + $this->assertEquals('foo', $signature->title); + $this->assertEquals('bar', $signature->signature); + $this->assertEquals(1, $signature->default_flag); + } +} diff --git a/tests/privacy/provider_test.php b/tests/privacy/provider_test.php new file mode 100644 index 0000000..1f4ff82 --- /dev/null +++ b/tests/privacy/provider_test.php @@ -0,0 +1,461 @@ +. + +/** + * Privacy provider tests for block_quickmail. + * + * @package block_quickmail + * @copyright The Regents of the University of California + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace block_quickmail\privacy; + +use context_system; +use context_user; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\approved_contextlist; +use core_privacy\local\request\approved_userlist; +use core_privacy\local\request\userlist; +use core_privacy\local\request\writer; +use core_privacy\tests\provider_testcase; +use dml_exception; + +/** + * Privacy provider test case. + * + * @package block_quickmail + * @copyright The Regents of the University of California + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \block_quickmail\privacy\provider + */ +final class provider_test extends provider_testcase { + /** + * @var string This component's name. + */ + public const COMPONENT_NAME = 'block_quickmail'; + + /** + * Test getting the context for the user ID related to this plugin. + * @throws dml_exception + */ + public function test_get_contexts_for_userid(): void { + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $this->getDataGenerator()->get_plugin_generator(self::COMPONENT_NAME); + + // Create four users and a course. + $user1 = $generator->create_user(); + $usercontext1 = context_user::instance($user1->id); + $user2 = $generator->create_user(); + $usercontext2 = context_user::instance($user2->id); + $user3 = $generator->create_user(); + $usercontext3 = context_user::instance($user3->id); + $user4 = $generator->create_user(); + $course = $generator->create_course(); + + // No contexts returned before user-specific block configurations are applied. + $contextlist1 = provider::get_contexts_for_userid($user1->id); + $this->assertCount(0, $contextlist1); + $contextlist2 = provider::get_contexts_for_userid($user2->id); + $this->assertCount(0, $contextlist2); + + // Create some quickmail data points for all users but user4. + $plugingenerator->create_quickmail_log($user1, $course, [$user2]); + $plugingenerator->create_quickmail_log($user2, $course, [$user3]); + $plugingenerator->create_quickmail_draft($user1, $course, [$user2]); + $plugingenerator->create_quickmail_draft($user3, $course, [$user4]); + $plugingenerator->create_quickmail_signature($user1); + + // Ensure provider only fetches the user's own context. + $contextlist1 = provider::get_contexts_for_userid($user1->id); + $this->assertCount(1, $contextlist1); + $this->assertEquals($usercontext1, $contextlist1->current()); + $contextlist2 = provider::get_contexts_for_userid($user2->id); + $this->assertCount(1, $contextlist2); + $this->assertEquals($usercontext2, $contextlist2->current()); + $contextlist3 = provider::get_contexts_for_userid($user3->id); + $this->assertCount(1, $contextlist3); + $this->assertEquals($usercontext3, $contextlist3->current()); + $contextlist4 = provider::get_contexts_for_userid($user4->id); + $this->assertCount(0, $contextlist4); + } + + /** + * Test getting users in the context ID related to this plugin. + */ + public function test_get_users_in_context(): void { + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $this->getDataGenerator()->get_plugin_generator(self::COMPONENT_NAME); + + // Create four users and a course. + $user1 = $generator->create_user(); + $usercontext1 = context_user::instance($user1->id); + $user2 = $generator->create_user(); + $usercontext2 = context_user::instance($user2->id); + $user3 = $generator->create_user(); + $usercontext3 = context_user::instance($user3->id); + $user4 = $generator->create_user(); + $usercontext4 = context_user::instance($user4->id); + $course = $generator->create_course(); + + // No users in given user-contexts before user-related data has been added. + $userlist1 = new userlist($usercontext1, self::COMPONENT_NAME); + provider::get_users_in_context($userlist1); + $this->assertCount(0, $userlist1); + $userlist2 = new userlist($usercontext2, self::COMPONENT_NAME); + provider::get_users_in_context($userlist2); + $this->assertCount(0, $userlist2); + $userlist3 = new userlist($usercontext3, self::COMPONENT_NAME); + provider::get_users_in_context($userlist3); + $this->assertCount(0, $userlist3); + $userlist4 = new userlist($usercontext4, self::COMPONENT_NAME); + provider::get_users_in_context($userlist4); + $this->assertCount(0, $userlist4); + + // Create some quickmail data points for all users but user4. + $plugingenerator->create_quickmail_log($user1, $course, [$user2]); + $plugingenerator->create_quickmail_log($user2, $course, [$user3]); + $plugingenerator->create_quickmail_draft($user1, $course, [$user2]); + $plugingenerator->create_quickmail_draft($user3, $course, [$user4]); + $plugingenerator->create_quickmail_signature($user1); + + // Ensure provider only fetches the user whose user context is checked. + $userlist1 = new userlist($usercontext1, self::COMPONENT_NAME); + provider::get_users_in_context($userlist1); + $this->assertCount(1, $userlist1); + $this->assertEquals($user1, $userlist1->current()); + + $userlist2 = new userlist($usercontext2, self::COMPONENT_NAME); + provider::get_users_in_context($userlist2); + $this->assertCount(1, $userlist2); + $this->assertEquals($user2, $userlist2->current()); + + $userlist3 = new userlist($usercontext3, self::COMPONENT_NAME); + provider::get_users_in_context($userlist3); + $this->assertCount(1, $userlist3); + $this->assertEquals($user3, $userlist3->current()); + + // User4 has no quickmail data associated with it, so the users list will come back empty. + $userlist4 = new userlist($usercontext4, self::COMPONENT_NAME); + provider::get_users_in_context($userlist4); + $this->assertCount(0, $userlist4); + } + + /** + * Test fetching information about user data stored. + */ + public function test_get_metadata(): void { + $collection = new collection(self::COMPONENT_NAME); + $newcollection = provider::get_metadata($collection); + $itemcollection = $newcollection->get_collection(); + $this->assertCount(3, $itemcollection); + + $table = reset($itemcollection); + $this->assertEquals('block_quickmail_log', $table->get_name()); + $privacyfields = $table->get_privacy_fields(); + $this->assertCount(12, $privacyfields); + $this->assertArrayHasKey('id', $privacyfields); + $this->assertArrayHasKey('courseid', $privacyfields); + $this->assertArrayHasKey('userid', $privacyfields); + $this->assertArrayHasKey('alternateid', $privacyfields); + $this->assertArrayHasKey('mailto', $privacyfields); + $this->assertArrayHasKey('subject', $privacyfields); + $this->assertArrayHasKey('message', $privacyfields); + $this->assertArrayHasKey('attachment', $privacyfields); + $this->assertArrayHasKey('format', $privacyfields); + $this->assertArrayHasKey('time', $privacyfields); + $this->assertArrayHasKey('failuserids', $privacyfields); + $this->assertArrayHasKey('additional_emails', $privacyfields); + $this->assertEquals('privacy:metadata:block_quickmail_log', $table->get_summary()); + + $table = next($itemcollection); + $this->assertEquals('block_quickmail_drafts', $table->get_name()); + $privacyfields = $table->get_privacy_fields(); + $this->assertCount(11, $privacyfields); + $this->assertArrayHasKey('id', $privacyfields); + $this->assertArrayHasKey('courseid', $privacyfields); + $this->assertArrayHasKey('userid', $privacyfields); + $this->assertArrayHasKey('alternateid', $privacyfields); + $this->assertArrayHasKey('mailto', $privacyfields); + $this->assertArrayHasKey('subject', $privacyfields); + $this->assertArrayHasKey('message', $privacyfields); + $this->assertArrayHasKey('attachment', $privacyfields); + $this->assertArrayHasKey('format', $privacyfields); + $this->assertArrayHasKey('time', $privacyfields); + $this->assertArrayHasKey('additional_emails', $privacyfields); + $this->assertEquals('privacy:metadata:block_quickmail_drafts', $table->get_summary()); + + $table = next($itemcollection); + $this->assertEquals('block_quickmail_signatures', $table->get_name()); + $privacyfields = $table->get_privacy_fields(); + $this->assertCount(5, $privacyfields); + $this->assertArrayHasKey('id', $privacyfields); + $this->assertArrayHasKey('userid', $privacyfields); + $this->assertArrayHasKey('title', $privacyfields); + $this->assertArrayHasKey('signature', $privacyfields); + $this->assertArrayHasKey('default_flag', $privacyfields); + $this->assertEquals('privacy:metadata:block_quickmail_signatures', $table->get_summary()); + } + + /** + * Test exporting data for an approved contextlist. + */ + public function test_export_user_data(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $this->getDataGenerator()->get_plugin_generator(self::COMPONENT_NAME); + + $user = $generator->create_user(); + $usercontext = context_user::instance($user->id); + $course = $generator->create_user(); + + // Create data for user. + $plugingenerator->create_quickmail_log($user, $course); + $plugingenerator->create_quickmail_log($user, $course); + $plugingenerator->create_quickmail_draft($user, $course); + $plugingenerator->create_quickmail_draft($user, $course); + $plugingenerator->create_quickmail_signature($user); + $plugingenerator->create_quickmail_signature($user); + + // Confirm data is present. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', ['userid' => $user->id, 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', ['userid' => $user->id, 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures', ['userid' => $user->id])); + + // Export data for user. + $approvedlist = new approved_contextlist($user, self::COMPONENT_NAME, [$usercontext->id]); + provider::export_user_data($approvedlist); + + // Confirm user's data is exported. + $subcontext = get_string('pluginname', self::COMPONENT_NAME); + $writer = writer::with_context($usercontext); + $this->assertTrue($writer->has_any_data([$subcontext])); + $data = (array) $writer->get_data([$subcontext]); + $this->assertCount(2, $data['signatures']); + foreach (array_values($data['signatures']) as $signature) { + $this->assertEquals($user->id, $signature->userid); + } + $this->assertCount(2, $data['log']); + foreach (array_values($data['log']) as $log) { + $this->assertEquals($user->id, $log->userid); + $this->assertEquals($course->id, $log->courseid); + } + $this->assertCount(2, $data['drafts']); + foreach (array_values($data['drafts']) as $draft) { + $this->assertEquals($user->id, $draft->userid); + $this->assertEquals($course->id, $draft->courseid); + } + } + + /** + * Test deleting data for all users within an approved contextlist. + */ + public function test_delete_data_for_all_users_in_context(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $this->getDataGenerator()->get_plugin_generator(self::COMPONENT_NAME); + + // Create two users and a course. + $user1 = $generator->create_user(); + $usercontext1 = context_user::instance($user1->id); + $user2 = $generator->create_user(); + $usercontext2 = context_user::instance($user2->id); + $course = $generator->create_course(); + + // Add some data for both users. + $plugingenerator->create_quickmail_log($user1, $course); + $plugingenerator->create_quickmail_log($user2, $course); + $plugingenerator->create_quickmail_draft($user1, $course); + $plugingenerator->create_quickmail_draft($user2, $course); + $plugingenerator->create_quickmail_signature($user1); + $plugingenerator->create_quickmail_signature($user2); + + // Check that the DB got populated correctly. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user2->id ])); + + // Attempt system context deletion (should have no effect). + $systemcontext = context_system::instance(); + provider::delete_data_for_all_users_in_context($systemcontext); + + // Confirm that user data is still there. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + + // Delete all data in user1 user context. + provider::delete_data_for_all_users_in_context($usercontext1); + + // Confirm that only user1's block data got deleted. + $this->assertEquals(0, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(0, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(0, $DB->count_records('block_quickmail_signatures', ['userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user2->id ])); + } + + /** + * Test deleting data within an approved contextlist for a user. + */ + public function test_delete_data_for_user(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $this->getDataGenerator()->get_plugin_generator(self::COMPONENT_NAME); + + // Create two users and a course. + $user1 = $generator->create_user(); + $usercontext1 = context_user::instance($user1->id); + $user2 = $generator->create_user(); + $usercontext2 = context_user::instance($user2->id); + $course = $generator->create_course(); + + // Add some data for both users. + $plugingenerator->create_quickmail_log($user1, $course); + $plugingenerator->create_quickmail_log($user2, $course); + $plugingenerator->create_quickmail_draft($user1, $course); + $plugingenerator->create_quickmail_draft($user2, $course); + $plugingenerator->create_quickmail_signature($user1); + $plugingenerator->create_quickmail_signature($user2); + + // Check that the DB got populated correctly. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user2->id ])); + + // Attempt system context deletion (should have no effect). + $systemcontext = context_system::instance(); + $approvedlist = new approved_contextlist($user1, self::COMPONENT_NAME, [$systemcontext->id]); + provider::delete_data_for_user($approvedlist); + + // Confirm that user data is still there. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + + // Attempt to delete user1 data in user2 user context (should have no effect). + $approvedlist = new approved_contextlist($user2, self::COMPONENT_NAME, [$usercontext1->id]); + provider::delete_data_for_user($approvedlist); + + // Confirm that user data is still there. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + + // Delete all data in user1 user context. + $approvedlist = new approved_contextlist($user1, self::COMPONENT_NAME, [$usercontext1->id]); + provider::delete_data_for_user($approvedlist); + + // Confirm that only user1's block data got deleted. + $this->assertEquals(0, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(0, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(0, $DB->count_records('block_quickmail_signatures', ['userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user2->id ])); + } + + /** + * Test deleting data within a context for an approved userlist. + */ + public function test_delete_data_for_users(): void { + global $DB; + + $this->resetAfterTest(); + $generator = $this->getDataGenerator(); + $plugingenerator = $this->getDataGenerator()->get_plugin_generator(self::COMPONENT_NAME); + + // Create two users and a course. + $user1 = $generator->create_user(); + $usercontext1 = context_user::instance($user1->id); + $user2 = $generator->create_user(); + $course = $generator->create_course(); + + // Add some data for both users. + $plugingenerator->create_quickmail_log($user1, $course); + $plugingenerator->create_quickmail_log($user2, $course); + $plugingenerator->create_quickmail_draft($user1, $course); + $plugingenerator->create_quickmail_draft($user2, $course); + $plugingenerator->create_quickmail_signature($user1); + $plugingenerator->create_quickmail_signature($user2); + + // Check that the DB got populated correctly. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user2->id ])); + + // Attempt system context deletion (should have no effect). + $systemcontext = context_system::instance(); + $approvedlist = new approved_userlist($systemcontext, self::COMPONENT_NAME, [$user1->id, $user2->id]); + provider::delete_data_for_users($approvedlist); + + // Confirm that user data is still there. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + + // Attempt to delete data in another user's context (should have no effect). + $approvedlist = new approved_userlist($usercontext1, self::COMPONENT_NAME, [$user2->id]); + provider::delete_data_for_users($approvedlist); + + // Confirm that user data is still there. + $this->assertEquals(2, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(2, $DB->count_records('block_quickmail_signatures')); + + // Delete data for user1 and user2 in the user context for user1. + $approvedlist = new approved_userlist($usercontext1, self::COMPONENT_NAME, [$user1->id, $user2->id]); + provider::delete_data_for_users($approvedlist); + + // Confirm only user1's data is deleted. + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures')); + $this->assertEquals(0, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(0, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user1->id ])); + $this->assertEquals(0, $DB->count_records('block_quickmail_signatures', ['userid' => $user1->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_log', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_drafts', [ 'courseid' => $course->id, 'userid' => $user2->id ])); + $this->assertEquals(1, $DB->count_records('block_quickmail_signatures', ['userid' => $user2->id ])); + + } +}