Skip to content

Commit

Permalink
MDL-67499 restore: add 100% cov. to restore_dbops::precheck_user()
Browse files Browse the repository at this point in the history
Supports multiple mails to be tested.

So we can perform changes to it and also some related stuff,
like delete_user() with confidence.
  • Loading branch information
stronk7 authored and paulholden committed Apr 6, 2020
1 parent 343380d commit 68ba708
Showing 1 changed file with 233 additions and 0 deletions.
233 changes: 233 additions & 0 deletions backup/util/dbops/tests/restore_dbops_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,237 @@ public function test_backup_ids_cached() {
$this->assertSame('Table "backup_ids_temp" does not exist', $e->getMessage());
}
}

/**
* Data provider for {@link test_precheck_user()}
*/
public function precheck_user_provider() {

$emailmultiplier = [
'shortmail' => '[email protected]',
//'longmail' => str_repeat('a', 100) // It's not validated, hence any string is ok.
];

$providercases = [];

foreach ($emailmultiplier as $emailk => $email) {
// Get the related cases.
$cases = $this->precheck_user_cases($email);
// Rename them (keys).
foreach ($cases as $key => $case) {
$providercases[$key . ' - ' . $emailk] = $case;
}
}

return $providercases;
}

/**
* Get all the cases implemented in {@link restore_dbops::precheck_users()}
*/
private function precheck_user_cases($email) {
global $CFG;

$baseuserarr = [
'username' => 'normalusername',
'email' => $email,
'mnethostid' => $CFG->mnet_localhost_id,
'firstaccess'=> 123456789,
'deleted' => 0,
'forceemailcleanup' => false, // Hack to force the DB record to have empty mail.
'forceduplicateadminallowed' => false]; // Hack to enable import_general_duplicate_admin_allowed.

return [
// Cases with samesite = true.
'samesite match existing (1A)' => [
'dbuser' => $baseuserarr,
'backupuser' => $baseuserarr,
'samesite' => true,
'outcome' => 'match'
],
'samesite match existing anon (1B)' => [
'dbuser' => array_merge($baseuserarr, [
'username' => 'anon01']),
'backupuser' => array_merge($baseuserarr, [
'id' => -1, 'username' => 'anon01', 'firstname' => 'anonfirstname01',
'lastname' => 'anonlastname01', 'email' => '[email protected]']),
'samesite' => true,
'outcome' => 'match'
],
'samesite match existing deleted in db, alive in backup, by db username (1C)' => [
'dbuser' => array_merge($baseuserarr, [
'deleted' => 1]),
'backupuser' => array_merge($baseuserarr, [
'username' => 'this_wont_match']),
'samesite' => true,
'outcome' => 'match'
],
'samesite match existing deleted in db, alive in backup, by db email (1C)' => [
'dbuser' => array_merge($baseuserarr, [
'deleted' => 1]),
'backupuser' => array_merge($baseuserarr, [
'email' => 'this_wont_match']),
'samesite' => true,
'outcome' => 'match'
],
'samesite match existing alive in db, deleted in backup (1D)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr, [
'deleted' => 1]),
'samesite' => true,
'outcome' => 'match'
],
'samesite conflict (1E)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr, ['id' => -1]),
'samesite' => true,
'outcome' => false
],
'samesite create user (1F)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr,[
'username' => 'newusername']),
'samesite' => false,
'outcome' => true
],

// Cases with samesite = false.
'no samesite match existing, by db email (2A1)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr,[
'firstaccess' => 0]),
'samesite' => false,
'outcome' => 'match'
],
'no samesite match existing, by db firstaccess (2A1)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr,[
'email' => '[email protected]']),
'samesite' => false,
'outcome' => 'match'
],
'no samesite match existing anon (2A1 too)' => [
'dbuser' => array_merge($baseuserarr, [
'username' => 'anon01']),
'backupuser' => array_merge($baseuserarr, [
'id' => -1, 'username' => 'anon01', 'firstname' => 'anonfirstname01',
'lastname' => 'anonlastname01', 'email' => '[email protected]']),
'samesite' => false,
'outcome' => 'match'
],
'no samesite match dupe admin (2A2)' => [
'dbuser' => array_merge($baseuserarr, [
'username' => 'admin_old_site_id',
'forceduplicateadminallowed' => true]),
'backupuser' => array_merge($baseuserarr, [
'username' => 'admin']),
'samesite' => false,
'outcome' => 'match'
],
'no samesite match existing deleted in db, alive in backup, by db username (2B1)' => [
'dbuser' => array_merge($baseuserarr, [
'deleted' => 1]),
'backupuser' => array_merge($baseuserarr, [
'firstaccess' => 0]),
'samesite' => false,
'outcome' => 'match'
],
'no samesite match existing deleted in db, alive in backup, by db firstaccess (2B1)' => [
'dbuser' => array_merge($baseuserarr, [
'deleted' => 1]),
'backupuser' => array_merge($baseuserarr, [
'mail' => 'this_wont_match']),
'samesite' => false,
'outcome' => 'match'
],
'no samesite match existing deleted in db, alive in backup (2B2)' => [
'dbuser' => array_merge($baseuserarr, [
'deleted' => 1,
'forceemailcleanup' => true]),
'backupuser' => $baseuserarr,
'samesite' => false,
'outcome' => 'match'
],
'no samesite match existing alive in db, deleted in backup (2C)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr, [
'deleted' => 1]),
'samesite' => false,
'outcome' => 'match'
],
'no samesite conflict (2D)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr,[
'email' => '[email protected]', 'firstaccess' => 0]),
'samesite' => false,
'outcome' => false
],
'no samesite create user (2E)' => [
'dbuser' => $baseuserarr,
'backupuser' => array_merge($baseuserarr,[
'username' => 'newusername']),
'samesite' => false,
'outcome' => true
],

];
}

/**
* @dataProvider precheck_user_provider
* @covers restore_dbops::precheck_user()
* */
public function test_precheck_user($dbuser, $backupuser, $samesite, $outcome) {
global $DB;

$this->resetAfterTest();

$dbuser = (object)$dbuser;
$backupuser = (object)$backupuser;

$siteid = null;

// If the backup user must be deleted, simulate it (by temp inserting to DB, deleting and fetching it back).
if ($backupuser->deleted) {
$backupuser->id = $DB->insert_record('user', array_merge((array)$backupuser, ['deleted' => 0]));
delete_user($backupuser);
$backupuser = $DB->get_record('user', ['id' => $backupuser->id]);
$DB->delete_records('user', ['id' => $backupuser->id]);
unset($backupuser->id);
}

// Create the db user, normally.
$dbuser->id = $DB->insert_record('user', array_merge((array)$dbuser, ['deleted' => 0]));
$backupuser->id = $backupuser->id ?? $dbuser->id;

// We may want to enable the import_general_duplicate_admin_allowed setting and look for old admin records.
if ($dbuser->forceduplicateadminallowed) {
set_config('import_general_duplicate_admin_allowed', true, 'backup');
$siteid = 'old_site_id';
}

// If the DB user must be deleted, do it and fetch it back.
if ($dbuser->deleted) {
delete_user($dbuser);
// We may want to clean the mail field (old behavior, not containing the current md5(username)
if ($dbuser->forceemailcleanup) {
$DB->set_field('user', 'email', '', ['id' => $dbuser->id]);
}
}

// Get the dbuser record, because we may have changed it above.
$dbuser = $DB->get_record('user', ['id' => $dbuser->id]);

$method = (new ReflectionClass('restore_dbops'))->getMethod('precheck_user');
$method->setAccessible(true);
$result = $method->invoke(null, $backupuser, $samesite, $siteid);

if (is_bool($result)) {
$this->assertSame($outcome, $result);
} else {
$outcome = $dbuser; // Outcome is not bool, matching found, so it must be the dbuser,
// Just check ids, it means the expected match has been found in database.
$this->assertSame($outcome->id, $result->id);
}
}
}

0 comments on commit 68ba708

Please sign in to comment.