Search moodle.org's
Developer Documentation

Long Term Support Release

  • Bug fixes for general core bugs in 3.5.x ended May 2019 (12 months).
  • Bug fixes for security issues in 3.5.x will end 10 May 2021 (36 months) - Support has ended.
  • minimum PHP 7.0.0 Note: minimum PHP version has increased since Moodle 3.3. PHP 7.1.x and 7.2.x are supported too. PHP 7.x could have some engine limitations.
  • Differences Between: [Versions 35 and 310] [Versions 35 and 311] [Versions 35 and 36] [Versions 35 and 37] [Versions 35 and 38] [Versions 35 and 39]

       1  <?php
       2  // This file is part of Moodle - http://moodle.org/
       3  //
       4  // Moodle is free software: you can redistribute it and/or modify
       5  // it under the terms of the GNU General Public License as published by
       6  // the Free Software Foundation, either version 3 of the License, or
       7  // (at your option) any later version.
       8  //
       9  // Moodle is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  //
      14  // You should have received a copy of the GNU General Public License
      15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
      16  
      17  /**
      18   * Data provider tests.
      19   *
      20   * @package    core_badges
      21   * @category   test
      22   * @copyright  2018 Frédéric Massart
      23   * @author     Frédéric Massart <fred@branchup.tech>
      24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      25   */
      26  
      27  defined('MOODLE_INTERNAL') || die();
      28  global $CFG;
      29  
      30  use core_privacy\tests\provider_testcase;
      31  use core_privacy\local\request\approved_contextlist;
      32  use core_privacy\local\request\transform;
      33  use core_privacy\local\request\writer;
      34  use core_badges\privacy\provider;
      35  use core_privacy\local\request\approved_userlist;
      36  
      37  require_once($CFG->libdir . '/badgeslib.php');
      38  
      39  /**
      40   * Data provider testcase class.
      41   *
      42   * @package    core_badges
      43   * @category   test
      44   * @copyright  2018 Frédéric Massart
      45   * @author     Frédéric Massart <fred@branchup.tech>
      46   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      47   */
      48  class core_badges_privacy_testcase extends provider_testcase {
      49  
      50      public function setUp() {
      51          $this->resetAfterTest();
      52      }
      53  
      54      public function test_get_contexts_for_userid_for_badge_editing() {
      55          $dg = $this->getDataGenerator();
      56          $u1 = $dg->create_user();
      57          $u2 = $dg->create_user();
      58          $u3 = $dg->create_user();
      59          $u4 = $dg->create_user();
      60          $u5 = $dg->create_user();
      61          $c1 = $dg->create_course();
      62          $c2 = $dg->create_course();
      63          $sysctx = context_system::instance();
      64          $c1ctx = context_course::instance($c1->id);
      65          $c2ctx = context_course::instance($c2->id);
      66  
      67          // Assert that we find contexts where we created/modified a badge.
      68          $this->create_badge(['usercreated' => $u1->id, 'usermodified' => $u5->id]);
      69          $this->create_badge(['usercreated' => $u2->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
      70          $this->create_badge(['usermodified' => $u3->id]);
      71          $this->create_badge(['usermodified' => $u4->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $c2->id,
      72              'usercreated' => $u5->id]);
      73  
      74          $contexts = provider::get_contexts_for_userid($u1->id)->get_contextids();
      75          $this->assertCount(1, $contexts);
      76          $this->assertEquals($sysctx->id, $contexts[0]);
      77  
      78          $contexts = provider::get_contexts_for_userid($u2->id)->get_contextids();
      79          $this->assertCount(1, $contexts);
      80          $this->assertEquals($c1ctx->id, $contexts[0]);
      81  
      82          $contexts = provider::get_contexts_for_userid($u3->id)->get_contextids();
      83          $this->assertCount(1, $contexts);
      84          $this->assertEquals($sysctx->id, $contexts[0]);
      85  
      86          $contexts = provider::get_contexts_for_userid($u4->id)->get_contextids();
      87          $this->assertCount(1, $contexts);
      88          $this->assertEquals($c2ctx->id, $contexts[0]);
      89  
      90          $contexts = provider::get_contexts_for_userid($u5->id)->get_contextids();
      91          $this->assertCount(2, $contexts);
      92          $this->assertTrue(in_array($sysctx->id, $contexts));
      93          $this->assertTrue(in_array($c2ctx->id, $contexts));
      94      }
      95  
      96      public function test_get_contexts_for_userid_for_manual_award() {
      97          global $DB;
      98  
      99          $dg = $this->getDataGenerator();
     100          $u1 = $dg->create_user();
     101          $u2 = $dg->create_user();
     102          $u3 = $dg->create_user();
     103          $u4 = $dg->create_user();
     104          $c1 = $dg->create_course();
     105          $sysctx = context_system::instance();
     106          $c1ctx = context_course::instance($c1->id);
     107          $u1ctx = context_user::instance($u1->id);
     108          $u2ctx = context_user::instance($u2->id);
     109          $u3ctx = context_user::instance($u3->id);
     110          $u4ctx = context_user::instance($u4->id);
     111          $b1 = $this->create_badge();
     112          $b2 = $this->create_badge(['type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
     113  
     114          $this->create_manual_award(['recipientid' => $u4->id, 'issuerid' => $u1->id, 'badgeid' => $b1->id]);
     115          $this->create_manual_award(['recipientid' => $u3->id, 'issuerid' => $u2->id, 'badgeid' => $b1->id]);
     116          $this->create_manual_award(['recipientid' => $u3->id, 'issuerid' => $u2->id, 'badgeid' => $b2->id]);
     117  
     118          $contexts = provider::get_contexts_for_userid($u1->id)->get_contextids();
     119          $this->assertCount(1, $contexts);
     120          $this->assertEquals($u4ctx->id, $contexts[0]);
     121  
     122          $contexts = provider::get_contexts_for_userid($u2->id)->get_contextids();
     123          $this->assertCount(1, $contexts);
     124          $this->assertEquals($u3ctx->id, $contexts[0]);
     125      }
     126  
     127      public function test_get_contexts_for_userid_for_my_stuff() {
     128          global $DB;
     129  
     130          $dg = $this->getDataGenerator();
     131          $u1 = $dg->create_user();
     132          $u2 = $dg->create_user();
     133          $u3 = $dg->create_user();
     134          $u4 = $dg->create_user();
     135          $c1 = $dg->create_course();
     136          $sysctx = context_system::instance();
     137          $c1ctx = context_course::instance($c1->id);
     138          $u1ctx = context_user::instance($u1->id);
     139          $u2ctx = context_user::instance($u2->id);
     140          $u3ctx = context_user::instance($u3->id);
     141          $u4ctx = context_user::instance($u4->id);
     142          $b1 = $this->create_badge();
     143          $b2 = $this->create_badge(['type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
     144  
     145          $this->create_backpack(['userid' => $u1->id]);
     146          $this->create_manual_award(['recipientid' => $u2->id, 'badgeid' => $b1->id]);
     147          $this->create_issued(['badgeid' => $b2->id, 'userid' => $u3->id]);
     148  
     149          $crit = $this->create_criteria_manual($b1->id);
     150          $crit->mark_complete($u4->id);
     151  
     152          $contexts = provider::get_contexts_for_userid($u1->id)->get_contextids();
     153          $this->assertCount(1, $contexts);
     154          $this->assertEquals($u1ctx->id, $contexts[0]);
     155  
     156          $contexts = provider::get_contexts_for_userid($u2->id)->get_contextids();
     157          $this->assertCount(1, $contexts);
     158          $this->assertEquals($u2ctx->id, $contexts[0]);
     159  
     160          $contexts = provider::get_contexts_for_userid($u3->id)->get_contextids();
     161          $this->assertCount(1, $contexts);
     162          $this->assertEquals($u3ctx->id, $contexts[0]);
     163  
     164          $contexts = provider::get_contexts_for_userid($u4->id)->get_contextids();
     165          $this->assertCount(1, $contexts);
     166          $this->assertEquals($u4ctx->id, $contexts[0]);
     167      }
     168  
     169      public function test_delete_data_for_user() {
     170          global $DB;
     171  
     172          $dg = $this->getDataGenerator();
     173          $u1 = $dg->create_user();
     174          $u2 = $dg->create_user();
     175          $c1 = $dg->create_course();
     176          $sysctx = context_system::instance();
     177          $c1ctx = context_course::instance($c1->id);
     178          $u1ctx = context_user::instance($u1->id);
     179          $u2ctx = context_user::instance($u2->id);
     180  
     181          $b1 = $this->create_badge(['usercreated' => $u1->id, 'usermodified' => $u2->id]);
     182          $b2 = $this->create_badge(['usercreated' => $u2->id, 'usermodified' => $u1->id,
     183              'type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
     184  
     185          $this->create_backpack(['userid' => $u1->id]);
     186          $this->create_backpack(['userid' => $u2->id]);
     187          $this->create_manual_award(['recipientid' => $u1->id, 'badgeid' => $b1->id]);
     188          $this->create_manual_award(['recipientid' => $u2->id, 'badgeid' => $b1->id, 'issuerid' => $u1->id]);
     189          $this->create_issued(['badgeid' => $b2->id, 'userid' => $u1->id]);
     190          $this->create_issued(['badgeid' => $b2->id, 'userid' => $u2->id]);
     191  
     192          $crit = $this->create_criteria_manual($b1->id);
     193          $crit->mark_complete($u2->id);
     194          $crit = $this->create_criteria_manual($b2->id);
     195          $crit->mark_complete($u1->id);
     196  
     197          $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
     198          $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
     199          $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
     200          $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
     201          $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
     202          $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
     203          $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
     204          $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
     205          $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u1->id]));
     206          $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
     207          $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
     208          $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
     209  
     210          provider::delete_data_for_user(new approved_contextlist($u1, 'core_badges', [$sysctx->id, $c1ctx->id,
     211              $u1ctx->id, $u2ctx->id]));
     212  
     213          $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
     214          $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
     215          $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
     216          $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
     217          $this->assertFalse($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
     218          $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
     219          $this->assertFalse($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
     220          $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
     221          $this->assertFalse($DB->record_exists('badge_issued', ['userid' => $u1->id]));
     222          $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
     223          $this->assertFalse($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
     224          $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
     225      }
     226  
     227      public function test_delete_data_for_all_users_in_context() {
     228          global $DB;
     229  
     230          $dg = $this->getDataGenerator();
     231          $u1 = $dg->create_user();
     232          $u2 = $dg->create_user();
     233          $c1 = $dg->create_course();
     234          $sysctx = context_system::instance();
     235          $c1ctx = context_course::instance($c1->id);
     236          $u1ctx = context_user::instance($u1->id);
     237          $u2ctx = context_user::instance($u2->id);
     238  
     239          $b1 = $this->create_badge(['usercreated' => $u1->id, 'usermodified' => $u2->id]);
     240          $b2 = $this->create_badge(['usercreated' => $u2->id, 'usermodified' => $u1->id,
     241              'type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id]);
     242  
     243          $this->create_backpack(['userid' => $u1->id]);
     244          $this->create_backpack(['userid' => $u2->id]);
     245          $this->create_manual_award(['recipientid' => $u1->id, 'badgeid' => $b1->id]);
     246          $this->create_manual_award(['recipientid' => $u2->id, 'badgeid' => $b1->id, 'issuerid' => $u1->id]);
     247          $this->create_issued(['badgeid' => $b2->id, 'userid' => $u1->id]);
     248          $this->create_issued(['badgeid' => $b2->id, 'userid' => $u2->id]);
     249  
     250          $crit = $this->create_criteria_manual($b1->id);
     251          $crit->mark_complete($u2->id);
     252          $crit = $this->create_criteria_manual($b2->id);
     253          $crit->mark_complete($u1->id);
     254  
     255          $assertnochange = function() use ($DB, $u1, $u2) {
     256              $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
     257              $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
     258              $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
     259              $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
     260              $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
     261              $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
     262              $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
     263              $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
     264              $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u1->id]));
     265              $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
     266              $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
     267              $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
     268          };
     269          $assertnochange();
     270  
     271          provider::delete_data_for_all_users_in_context($sysctx);
     272          $assertnochange();
     273  
     274          provider::delete_data_for_all_users_in_context($c1ctx);
     275          $assertnochange();
     276  
     277          provider::delete_data_for_all_users_in_context($u1ctx);
     278          $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u1->id]));
     279          $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u1->id]));
     280          $this->assertTrue($DB->record_exists('badge', ['usercreated' => $u2->id]));
     281          $this->assertTrue($DB->record_exists('badge', ['usermodified' => $u2->id]));
     282          $this->assertFalse($DB->record_exists('badge_backpack', ['userid' => $u1->id]));
     283          $this->assertTrue($DB->record_exists('badge_backpack', ['userid' => $u2->id]));
     284          $this->assertFalse($DB->record_exists('badge_manual_award', ['recipientid' => $u1->id]));
     285          $this->assertTrue($DB->record_exists('badge_manual_award', ['recipientid' => $u2->id]));
     286          $this->assertFalse($DB->record_exists('badge_issued', ['userid' => $u1->id]));
     287          $this->assertTrue($DB->record_exists('badge_issued', ['userid' => $u2->id]));
     288          $this->assertFalse($DB->record_exists('badge_criteria_met', ['userid' => $u1->id]));
     289          $this->assertTrue($DB->record_exists('badge_criteria_met', ['userid' => $u2->id]));
     290      }
     291  
     292      public function test_export_data_for_user() {
     293          global $DB;
     294  
     295          $yes = transform::yesno(true);
     296          $no = transform::yesno(false);
     297  
     298          $dg = $this->getDataGenerator();
     299          $u1 = $dg->create_user();
     300          $u2 = $dg->create_user();
     301          $u3 = $dg->create_user();
     302          $c1 = $dg->create_course();
     303          $sysctx = context_system::instance();
     304          $c1ctx = context_course::instance($c1->id);
     305          $u1ctx = context_user::instance($u1->id);
     306          $u2ctx = context_user::instance($u2->id);
     307  
     308          $b1 = $this->create_badge(['usercreated' => $u3->id]);
     309          $b2 = $this->create_badge(['type' => BADGE_TYPE_COURSE, 'courseid' => $c1->id, 'usermodified' => $u3->id]);
     310          $b3 = $this->create_badge();
     311          $b3crit = $this->create_criteria_manual($b3->id);
     312          $b4 = $this->create_badge();
     313  
     314          // Create things for user 2, to check it's not exported it.
     315          $this->create_issued(['badgeid' => $b4->id, 'userid' => $u2->id]);
     316          $this->create_backpack(['userid' => $u2->id, 'email' => $u2->email]);
     317          $this->create_manual_award(['badgeid' => $b1->id, 'recipientid' => $u2->id, 'issuerid' => $u3->id]);
     318  
     319          // Create a set of stuff for u1.
     320          $this->create_issued(['badgeid' => $b1->id, 'userid' => $u1->id, 'uniquehash' => 'yoohoo']);
     321          $this->create_manual_award(['badgeid' => $b2->id, 'recipientid' => $u1->id, 'issuerid' => $u3->id]);
     322          $b3crit->mark_complete($u1->id);
     323          $this->create_backpack(['userid' => $u1->id, 'email' => $u1->email]);
     324  
     325          // Check u1.
     326          writer::reset();
     327          provider::export_user_data(new approved_contextlist($u1, 'core_badges', [$u1ctx->id, $u2ctx->id,
     328              $sysctx->id, $c1ctx->id]));
     329          $this->assertFalse(writer::with_context($u2ctx)->has_any_data());
     330          $this->assertFalse(writer::with_context($sysctx)->has_any_data());
     331          $this->assertFalse(writer::with_context($c1ctx)->has_any_data());
     332  
     333          $path = [get_string('badges', 'core_badges'), "{$b1->name} ({$b1->id})"];
     334          $data = writer::with_context($u1ctx)->get_data($path);
     335          $this->assertEquals($b1->name, $data->name);
     336          $this->assertNotEmpty($data->issued);
     337          $this->assertEmpty($data->manual_award);
     338          $this->assertEmpty($data->criteria_met);
     339          $this->assertFalse(isset($data->course));
     340          $this->assertEquals('yoohoo', $data->issued['unique_hash']);
     341          $this->assertNull($data->issued['expires_on']);
     342  
     343          $path = [get_string('badges', 'core_badges'), "{$b2->name} ({$b2->id})"];
     344          $data = writer::with_context($u1ctx)->get_data($path);
     345          $this->assertEquals($b2->name, $data->name);
     346          $this->assertEmpty($data->issued);
     347          $this->assertNotEmpty($data->manual_award);
     348          $this->assertEmpty($data->criteria_met);
     349          $this->assertEquals($c1->fullname, $data->course);
     350          $this->assertEquals($u3->id, $data->manual_award['issuer']);
     351  
     352          $path = [get_string('badges', 'core_badges'), "{$b3->name} ({$b3->id})"];
     353          $data = writer::with_context($u1ctx)->get_data($path);
     354          $this->assertEquals($b3->name, $data->name);
     355          $this->assertEmpty($data->issued);
     356          $this->assertEmpty($data->manual_award);
     357          $this->assertNotEmpty($data->criteria_met);
     358          $this->assertNotFalse(strpos($data->criteria_met[0], get_string('criteria_descr_2', 'core_badges', 'ALL')));
     359  
     360          $path = [get_string('badges', 'core_badges')];
     361          $data = writer::with_context($u1ctx)->get_related_data($path, 'backpacks');
     362          $this->assertCount(1, $data->backpacks);
     363          $this->assertEquals($u1->email, $data->backpacks[0]['email']);
     364  
     365          // Confirm we do not have u2.
     366          $path = [get_string('badges', 'core_badges'), "{$b4->name} ({$b4->id})"];
     367          $data = writer::with_context($u1ctx)->get_data($path);
     368          $this->assertEmpty($data);
     369          $data = writer::with_context($u2ctx)->get_data($path);
     370          $this->assertEmpty($data);
     371  
     372          // Export for u3.
     373          writer::reset();
     374          $path = [get_string('badges', 'core_badges')];
     375          provider::export_user_data(new approved_contextlist($u3, 'core_badges', [$u1ctx->id, $u2ctx->id,
     376              $sysctx->id, $c1ctx->id]));
     377  
     378          $data = writer::with_context($u2ctx)->get_related_data($path, 'manual_awards');
     379          $this->assertCount(1, $data->badges);
     380          $this->assertEquals($b1->name, $data->badges[0]['name']);
     381          $this->assertEquals($yes, $data->badges[0]['issued_by_you']);
     382          $this->assertEquals('Manager', $data->badges[0]['issuer_role']);
     383  
     384          $data = writer::with_context($sysctx)->get_data($path);
     385          $this->assertCount(1, $data->badges);
     386          $this->assertEquals($b1->name, $data->badges[0]['name']);
     387          $this->assertEquals($yes, $data->badges[0]['created_by_you']);
     388          $this->assertEquals($no, $data->badges[0]['modified_by_you']);
     389  
     390          $data = writer::with_context($c1ctx)->get_data($path);
     391          $this->assertCount(1, $data->badges);
     392          $this->assertEquals($b2->name, $data->badges[0]['name']);
     393          $this->assertEquals($no, $data->badges[0]['created_by_you']);
     394          $this->assertEquals($yes, $data->badges[0]['modified_by_you']);
     395  
     396          $data = writer::with_context($u1ctx)->get_related_data($path, 'manual_awards');
     397          $this->assertCount(1, $data->badges);
     398          $this->assertEquals($b3->name, $data->badges[0]['name']);
     399          $this->assertEquals($yes, $data->badges[0]['issued_by_you']);
     400          $this->assertEquals('Manager', $data->badges[0]['issuer_role']);
     401      }
     402  
     403      /**
     404       * Test that only users within a user, system and course context are fetched.
     405       */
     406      public function test_get_users_in_context() {
     407          $component = 'core_badges';
     408  
     409          // Create course1.
     410          $course1 = $this->getDataGenerator()->create_course();
     411          $coursecontext1 = context_course::instance($course1->id);
     412          // Create course2.
     413          $course2 = $this->getDataGenerator()->create_course();
     414          $coursecontext2 = context_course::instance($course2->id);
     415          // Create user1.
     416          $user1 = $this->getDataGenerator()->create_user();
     417          $usercontext1 = context_user::instance($user1->id);
     418          // Create user2.
     419          $user2 = $this->getDataGenerator()->create_user();
     420          $usercontext2 = context_user::instance($user2->id);
     421          // Create user3.
     422          $user3 = $this->getDataGenerator()->create_user();
     423          $usercontext3 = context_user::instance($user3->id);
     424  
     425          // The list of users in usercontext1 should not return anything yet (related data still haven't been created).
     426          $userlist1 = new \core_privacy\local\request\userlist($usercontext1, $component);
     427          provider::get_users_in_context($userlist1);
     428          $this->assertCount(0, $userlist1);
     429          // The list of users in coursecontext1 should not return anything yet (related data still haven't been created).
     430          $userlist2 = new \core_privacy\local\request\userlist($coursecontext1, $component);
     431          provider::get_users_in_context($userlist2);
     432          $this->assertCount(0, $userlist2);
     433          // The list of users in systemcontext should not return anything yet (related data still haven't been created).
     434          $systemcontext = context_system::instance();
     435          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
     436          provider::get_users_in_context($userlist3);
     437          $this->assertCount(0, $userlist3);
     438  
     439          // Assert that we find contexts where we created/modified a badge.
     440          $this->create_badge(['usercreated' => $user1->id, 'usermodified' => $user2->id]);
     441          $badge1 = $this->create_badge(['usercreated' => $user2->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $course1->id]);
     442          $badge2 = $this->create_badge(['usercreated' => $user3->id, 'usermodified' => $user1->id]);
     443  
     444          $this->create_manual_award(['recipientid' => $user2->id, 'issuerid' => $user1->id, 'badgeid' => $badge1->id]);
     445          $this->create_manual_award(['recipientid' => $user3->id, 'issuerid' => $user2->id, 'badgeid' => $badge1->id]);
     446          $this->create_manual_award(['recipientid' => $user1->id, 'issuerid' => $user2->id, 'badgeid' => $badge2->id]);
     447  
     448          $this->create_backpack(['userid' => $user2->id]);
     449          $this->create_issued(['badgeid' => $badge2->id, 'userid' => $user3->id]);
     450  
     451          $crit = $this->create_criteria_manual($badge1->id);
     452          $crit->mark_complete($user3->id);
     453  
     454          // The list of users for user context should return user1 and user2.
     455          provider::get_users_in_context($userlist1);
     456          $this->assertCount(2, $userlist1);
     457          $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
     458          $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
     459  
     460          // The list of users for course context should return user2.
     461          provider::get_users_in_context($userlist2);
     462          $this->assertCount(1, $userlist2);
     463          $this->assertTrue(in_array($user2->id, $userlist2->get_userids()));
     464  
     465          // The list of users for system context should return user1, user2 and user3.
     466          provider::get_users_in_context($userlist3);
     467          $this->assertCount(3, $userlist3);
     468          $this->assertTrue(in_array($user1->id, $userlist3->get_userids()));
     469          $this->assertTrue(in_array($user2->id, $userlist3->get_userids()));
     470          $this->assertTrue(in_array($user3->id, $userlist3->get_userids()));
     471      }
     472  
     473      /**
     474       * Test that data for users in approved userlist is deleted.
     475       */
     476      public function test_delete_data_for_users() {
     477          $component = 'core_badges';
     478  
     479          // Create course1.
     480          $course1 = $this->getDataGenerator()->create_course();
     481          $coursecontext1 = context_course::instance($course1->id);
     482          // Create course2.
     483          $course2 = $this->getDataGenerator()->create_course();
     484          $coursecontext2 = context_course::instance($course2->id);
     485          // Create user1.
     486          $user1 = $this->getDataGenerator()->create_user();
     487          $usercontext1 = context_user::instance($user1->id);
     488          // Create user2.
     489          $user2 = $this->getDataGenerator()->create_user();
     490          $usercontext2 = context_user::instance($user2->id);
     491          // Create user3.
     492          $user3 = $this->getDataGenerator()->create_user();
     493          $usercontext3 = context_user::instance($user3->id);
     494  
     495          $this->create_badge(['usercreated' => $user1->id, 'usermodified' => $user2->id]);
     496          $badge1 = $this->create_badge(['usercreated' => $user2->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $course1->id]);
     497          $badge2 = $this->create_badge(['usercreated' => $user3->id, 'type' => BADGE_TYPE_COURSE, 'courseid' => $course2->id,
     498              'usermodified' => $user1->id]);
     499  
     500          $this->create_manual_award(['recipientid' => $user2->id, 'issuerid' => $user1->id, 'badgeid' => $badge1->id]);
     501          $this->create_manual_award(['recipientid' => $user3->id, 'issuerid' => $user2->id, 'badgeid' => $badge1->id]);
     502          $this->create_manual_award(['recipientid' => $user1->id, 'issuerid' => $user2->id, 'badgeid' => $badge2->id]);
     503  
     504          $this->create_backpack(['userid' => $user2->id]);
     505          $this->create_issued(['badgeid' => $badge2->id, 'userid' => $user3->id]);
     506  
     507          $crit = $this->create_criteria_manual($badge1->id);
     508          $crit->mark_complete($user3->id);
     509  
     510          // The list of users for usercontext2 context should return users.
     511          $userlist1 = new \core_privacy\local\request\userlist($usercontext2, $component);
     512          provider::get_users_in_context($userlist1);
     513          $this->assertCount(2, $userlist1);
     514          $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
     515          $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
     516  
     517          // The list of users for coursecontext2 context should return users.
     518          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
     519          provider::get_users_in_context($userlist2);
     520          $this->assertCount(2, $userlist2);
     521          $this->assertTrue(in_array($user1->id, $userlist2->get_userids()));
     522          $this->assertTrue(in_array($user3->id, $userlist2->get_userids()));
     523  
     524          // The list of users for system context should return users.
     525          $systemcontext = context_system::instance();
     526          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
     527          provider::get_users_in_context($userlist3);
     528          $this->assertCount(2, $userlist3);
     529          $this->assertTrue(in_array($user1->id, $userlist3->get_userids()));
     530          $this->assertTrue(in_array($user2->id, $userlist3->get_userids()));
     531  
     532          // Delete the data for user1 in usercontext2.
     533          $approvedlist = new approved_userlist($usercontext2, $component, [$user1->id]);
     534          // Delete using delete_data_for_user. No data for users in usercontext2 should be removed.
     535          provider::delete_data_for_users($approvedlist);
     536          // The list of users for usercontext2 context should still return user1, user2.
     537          $userlist1 = new \core_privacy\local\request\userlist($usercontext2, $component);
     538          provider::get_users_in_context($userlist1);
     539          $this->assertCount(2, $userlist1);
     540          $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
     541          $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
     542  
     543          // Delete the data for user2 in usercontext2.
     544          $approvedlist = new approved_userlist($usercontext2, $component, [$user2->id]);
     545          // Delete using delete_data_for_user. The user data in usercontext2 should be removed.
     546          provider::delete_data_for_users($approvedlist);
     547          // The list of users for usercontext2 context should not return any users.
     548          $userlist1 = new \core_privacy\local\request\userlist($usercontext2, $component);
     549          provider::get_users_in_context($userlist1);
     550          $this->assertCount(0, $userlist1);
     551  
     552          // The list of users for coursecontext2 context should return the previous users.
     553          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
     554          provider::get_users_in_context($userlist2);
     555          $this->assertCount(2, $userlist2);
     556  
     557          // The list of users for system context should return the previous users.
     558          $systemcontext = context_system::instance();
     559          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
     560          provider::get_users_in_context($userlist3);
     561          $this->assertCount(2, $userlist3);
     562  
     563          // Make sure data is only deleted in the user context, nothing in course or system.
     564          // Convert $userlist2 into an approved_contextlist.
     565          $approvedlist = new approved_userlist($coursecontext2, $component, $userlist2->get_userids());
     566          provider::delete_data_for_users($approvedlist);
     567  
     568          // The list of users for coursecontext2 context should still return the user data.
     569          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
     570          provider::get_users_in_context($userlist2);
     571          $this->assertCount(2, $userlist2);
     572      }
     573  
     574      /**
     575       * Create a badge.
     576       *
     577       * @param array $params Parameters.
     578       * @return object
     579       */
     580      protected function create_badge(array $params = []) {
     581          global $DB, $USER;
     582          $record = (object) array_merge([
     583              'name' => "Test badge with 'apostrophe' and other friends (<>&@#)",
     584              'description' => "Testing badges",
     585              'timecreated' => time(),
     586              'timemodified' => time(),
     587              'usercreated' => $USER->id,
     588              'usermodified' => $USER->id,
     589              'issuername' => "Test issuer",
     590              'issuerurl' => "http://issuer-url.domain.co.nz",
     591              'issuercontact' => "issuer@example.com",
     592              'expiredate' => null,
     593              'expireperiod' => null,
     594              'type' => BADGE_TYPE_SITE,
     595              'courseid' => null,
     596              'messagesubject' => "Test message subject",
     597              'message' => "Test message body",
     598              'attachment' => 1,
     599              'notification' => 0,
     600              'status' => BADGE_STATUS_ACTIVE,
     601          ], $params);
     602          $record->id = $DB->insert_record('badge', $record);
     603  
     604          return $record;
     605      }
     606  
     607      /**
     608       * Create a backpack.
     609       *
     610       * @param array $params Parameters.
     611       * @return object
     612       */
     613      protected function create_backpack(array $params = []) {
     614          global $DB;
     615          $record = (object) array_merge([
     616              'userid' => null,
     617              'email' => 'test@example.com',
     618              'backpackurl' => "http://here.there.com",
     619              'backpackuid' => "12345",
     620              'autosync' => 0,
     621              'password' => '',
     622          ], $params);
     623          $record->id = $DB->insert_record('badge_backpack', $record);
     624          return $record;
     625      }
     626  
     627      /**
     628       * Create a criteria of type badge.
     629       *
     630       * @param int $badgeid The badge ID.
     631       * @param array $params Parameters.
     632       * @return object
     633       */
     634      protected function create_criteria_badge($badgeid, array $params = []) {
     635          $badge = new badge($badgeid);
     636          if (empty($badge->criteria)) {
     637              $overall = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id]);
     638              $overall->save(['agg' => BADGE_CRITERIA_AGGREGATION_ALL]);
     639          }
     640  
     641          $criteria = award_criteria::build([
     642              'badgeid' => $badge->id,
     643              'criteriatype' => BADGE_CRITERIA_TYPE_BADGE,
     644          ]);
     645  
     646          if (isset($params['badgeid'])) {
     647              $params['badge_' . $params['badgeid']] = $params['badgeid'];
     648              unset($params['badgeid']);
     649          }
     650  
     651          $criteria->save($params);
     652          $badge = new badge($badgeid);
     653          return $badge->criteria[BADGE_CRITERIA_TYPE_BADGE];
     654      }
     655  
     656      /**
     657       * Create a criteria of type manual.
     658       *
     659       * @param int $badgeid The badge ID.
     660       * @param array $params Parameters.
     661       * @return object
     662       */
     663      protected function create_criteria_manual($badgeid, array $params = []) {
     664          global $DB;
     665  
     666          $badge = new badge($badgeid);
     667          if (empty($badge->criteria)) {
     668              $overall = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id]);
     669              $overall->save(['agg' => BADGE_CRITERIA_AGGREGATION_ALL]);
     670          }
     671  
     672          $criteria = award_criteria::build([
     673              'badgeid' => $badge->id,
     674              'criteriatype' => BADGE_CRITERIA_TYPE_MANUAL,
     675          ]);
     676  
     677          $managerroleid = $DB->get_field_select('role', 'id', 'shortname = ?', ['manager'], IGNORE_MULTIPLE);
     678          if (empty($params)) {
     679              $params = [
     680                  'role_' . $managerroleid = $managerroleid
     681              ];
     682          }
     683  
     684          $criteria->save($params);
     685          $badge = new badge($badgeid);
     686          return $badge->criteria[BADGE_CRITERIA_TYPE_MANUAL];
     687      }
     688  
     689      /**
     690       * Create a badge issued.
     691       *
     692       * @param array $params Parameters.
     693       * @return object
     694       */
     695      protected function create_issued(array $params = []) {
     696          global $DB, $USER;
     697          $record = (object) array_merge([
     698              'badgeid' => null,
     699              'userid' => null,
     700              'uniquehash' => random_string(40),
     701              'dateissued' => time(),
     702              'dateexpire' => null,
     703              'visible' => 1,
     704              'issuernotified' => null,
     705          ], $params);
     706          $record->id = $DB->insert_record('badge_issued', $record);
     707          return $record;
     708      }
     709  
     710      /**
     711       * Create a manual award.
     712       *
     713       * @param array $params Parameters.
     714       * @return object
     715       */
     716      protected function create_manual_award(array $params = []) {
     717          global $DB, $USER;
     718          $record = (object) array_merge([
     719              'badgeid' => null,
     720              'recipientid' => null,
     721              'issuerid' => $USER->id,
     722              'issuerrole' => $DB->get_field_select('role', 'id', 'shortname = ?', ['manager'], IGNORE_MULTIPLE),
     723              'datemet' => time()
     724          ], $params);
     725          $record->id = $DB->insert_record('badge_manual_award', $record);
     726          return $record;
     727      }
     728  
     729  }