Merge branch '4.10' into 4.11

This commit is contained in:
Guy Sartorelli 2022-05-27 12:55:35 +12:00
commit 972a77f4d3
3 changed files with 77 additions and 37 deletions

View File

@ -488,16 +488,7 @@ class Group extends DataObject
*/ */
public function setCode($val) public function setCode($val)
{ {
$currentGroups = Group::get() $this->setField('Code', Convert::raw2url($val));
->map('Code', 'Title')
->toArray();
$code = Convert::raw2url($val);
$count = 2;
while (isset($currentGroups[$code])) {
$code = Convert::raw2url($val . '-' . $count);
$count++;
}
$this->setField("Code", $code);
} }
public function validate() public function validate()
@ -528,17 +519,7 @@ class Group extends DataObject
->map('Code', 'Title') ->map('Code', 'Title')
->toArray(); ->toArray();
if (isset($currentGroups[$this->Code])) { if (in_array($this->Title, $currentGroups)) {
$result->addError(
_t(
'SilverStripe\\Security\\Group.ValidationIdentifierAlreadyExists',
'A Group ({group}) already exists with the same {identifier}',
['group' => $this->Code, 'identifier' => 'Code']
)
);
}
if (in_array($this->Title, $currentGroups ?? [])) {
$result->addError( $result->addError(
_t( _t(
'SilverStripe\\Security\\Group.ValidationIdentifierAlreadyExists', 'SilverStripe\\Security\\Group.ValidationIdentifierAlreadyExists',
@ -572,6 +553,9 @@ class Group extends DataObject
if (!$this->Code && $this->Title != _t(__CLASS__ . '.NEWGROUP', "New Group")) { if (!$this->Code && $this->Title != _t(__CLASS__ . '.NEWGROUP', "New Group")) {
$this->setCode($this->Title); $this->setCode($this->Title);
} }
// Make sure the code for this group is unique.
$this->dedupeCode();
} }
public function onBeforeDelete() public function onBeforeDelete()
@ -732,4 +716,25 @@ class Group extends DataObject
// Members are populated through Member->requireDefaultRecords() // Members are populated through Member->requireDefaultRecords()
} }
/**
* Code needs to be unique as it is used to identify a specific group. Ensure no duplicate
* codes are created.
*
* @deprecated 5.0 Remove deduping in favour of throwing a validation error for duplicates.
*/
private function dedupeCode(): void
{
$currentGroups = Group::get()
->exclude('ID', $this->ID)
->map('Code', 'Title')
->toArray();
$code = $this->Code;
$count = 2;
while (isset($currentGroups[$code])) {
$code = $this->Code . '-' . $count;
$count++;
}
$this->setField('Code', $code);
}
} }

View File

@ -24,6 +24,7 @@ class GroupCsvBulkLoaderTest extends SapphireTest
public function testOverwriteExistingImport() public function testOverwriteExistingImport()
{ {
// This group will be overwritten.
$existinggroup = new Group(); $existinggroup = new Group();
$existinggroup->Title = 'Old Group Title'; $existinggroup->Title = 'Old Group Title';
$existinggroup->Code = 'newgroup1'; $existinggroup->Code = 'newgroup1';
@ -33,13 +34,15 @@ class GroupCsvBulkLoaderTest extends SapphireTest
$results = $loader->load(__DIR__ . '/GroupCsvBulkLoaderTest/GroupCsvBulkLoaderTest.csv'); $results = $loader->load(__DIR__ . '/GroupCsvBulkLoaderTest/GroupCsvBulkLoaderTest.csv');
$created = $results->Created()->toArray(); $created = $results->Created()->toArray();
$this->assertEquals(count($created ?? []), 1); $this->assertEquals(1, count($created));
$this->assertEquals($created[0]->Code, 'newchildgroup1'); $this->assertEquals('newchildgroup1', $created[0]->Code);
$this->assertEquals('New Child Group 1', $created[0]->Title);
// This overrides the group because the code matches, which takes precedence over the ID.
$updated = $results->Updated()->toArray(); $updated = $results->Updated()->toArray();
$this->assertEquals(count($updated ?? []), 1); $this->assertEquals(1, count($updated));
$this->assertEquals($updated[0]->Code, 'newgroup1-2'); $this->assertEquals('newgroup1', $updated[0]->Code);
$this->assertEquals($updated[0]->Title, 'New Group 1'); $this->assertEquals('New Group 1', $updated[0]->Title);
} }
public function testImportPermissions() public function testImportPermissions()
@ -48,17 +51,17 @@ class GroupCsvBulkLoaderTest extends SapphireTest
$results = $loader->load(__DIR__ . '/GroupCsvBulkLoaderTest/GroupCsvBulkLoaderTest_withExisting.csv'); $results = $loader->load(__DIR__ . '/GroupCsvBulkLoaderTest/GroupCsvBulkLoaderTest_withExisting.csv');
$created = $results->Created()->toArray(); $created = $results->Created()->toArray();
$this->assertEquals(count($created ?? []), 1); $this->assertEquals(1, count($created));
$this->assertEquals($created[0]->Code, 'newgroup1'); $this->assertEquals('newgroup1', $created[0]->Code);
$this->assertEquals($created[0]->Permissions()->column('Code'), ['CODE1']); $this->assertEquals(['CODE1'], $created[0]->Permissions()->column('Code'));
$updated = $results->Updated()->toArray(); $updated = $results->Updated()->toArray();
$this->assertEquals(count($updated ?? []), 1); $this->assertEquals(1, count($updated));
$this->assertEquals($updated[0]->Code, 'existinggroup'); $this->assertEquals('existinggroup', $updated[0]->Code);
$array1=$updated[0]->Permissions()->column('Code'); $actual = $updated[0]->Permissions()->column('Code');
$array2=['CODE1', 'CODE2']; $expected = ['CODE1', 'CODE2'];
sort($array1); sort($actual);
sort($array2); sort($expected);
$this->assertEquals($array1, $array2); $this->assertEquals($expected, $actual);
} }
} }

View File

@ -334,8 +334,40 @@ class GroupTest extends FunctionalTest
$this->assertEquals('duplicate-2', $group->Code); $this->assertEquals('duplicate-2', $group->Code);
$group = new Group(); $group = new Group();
$group->Title = 'Duplicate'; $group->Title = 'Any Title';
$group->Code = 'duplicate';
$group->write(); $group->write();
$this->assertEquals('duplicate-3', $group->Code); $this->assertEquals('duplicate-3', $group->Code);
$group1 = new Group();
$group1->Title = 'Any Title1';
$group1->Code = 'some-code';
$group2 = new Group();
$group2->Title = 'Any Title2';
$group2->Code = 'some-code';
$group1->write();
$group2->write();
$this->assertEquals('some-code', $group1->Code);
$this->assertEquals('some-code-2', $group2->Code);
}
public function testSettingCodeRepeatedly()
{
// Setting the code to the code it already was doesn't modify it
$group = $this->objFromFixture(Group::class, 'group1');
$previousCode = $group->Code;
$group->Code = $previousCode;
$group->write();
$this->assertEquals($previousCode, $group->Code);
// Setting the code to a new code does modify it
$group->Code = 'new-code';
$group->write();
$this->assertEquals('new-code', $group->Code);
// The old code can be reused
$group->Code = $previousCode;
$group->write();
$this->assertEquals($previousCode, $group->Code);
} }
} }