diff --git a/src/Entity/Controller/GroupController.php b/src/Entity/Controller/GroupController.php index 31ae758c7a0f357680cbba2f9f6b59d66216d3c3..f25765696e413e547e367f1f75d74467afd76708 100644 --- a/src/Entity/Controller/GroupController.php +++ b/src/Entity/Controller/GroupController.php @@ -120,6 +120,7 @@ class GroupController extends ControllerBase { $values = [ 'type' => $relationship_type_storage->getRelationshipTypeId($group_type->id(), 'group_membership'), 'entity_id' => $this->currentUser()->id(), + 'group_roles' => $group_type->getCreatorRoleIds(), ]; $entity = $this->entityTypeManager()->getStorage('group_relationship')->create($values); } diff --git a/src/Entity/Group.php b/src/Entity/Group.php index 2ca7419f9046bdb9e928a60b9c890f2835200b4d..05afaa6a0abfed19bec813e1c9e611f247f8ed73 100644 --- a/src/Entity/Group.php +++ b/src/Entity/Group.php @@ -353,12 +353,13 @@ class Group extends EditorialContentEntityBase implements GroupInterface { parent::postSave($storage, $update); // If a new group is created and the group type is configured to grant group - // creators a membership by default, add the creator as a member. + // creators a membership by default, add the creator as a member unless it + // is being created using the wizard. // @todo Deprecate in 8.x-2.x in favor of a form-only approach. API-created // groups should not get this functionality because it may create // incomplete group memberships. $group_type = $this->getGroupType(); - if ($update === FALSE && $group_type->creatorGetsMembership()) { + if ($update === FALSE && $group_type->creatorGetsMembership() && !$group_type->creatorMustCompleteMembership()) { $values = ['group_roles' => $group_type->getCreatorRoleIds()]; $this->addMember($this->getOwner(), $values); } diff --git a/tests/src/Functional/GroupBrowserTestBase.php b/tests/src/Functional/GroupBrowserTestBase.php index d2b4b74415184c83b36d5bf8d22a8451ee5ddc9b..7ee8e7bb9ff2d6eeb8bf37b30cad3654b3e2f9bc 100644 --- a/tests/src/Functional/GroupBrowserTestBase.php +++ b/tests/src/Functional/GroupBrowserTestBase.php @@ -99,6 +99,7 @@ abstract class GroupBrowserTestBase extends BrowserTestBase { $group_type = $storage->create($values + [ 'id' => $this->randomMachineName(), 'label' => $this->randomString(), + 'creator_wizard' => FALSE, ]); $storage->save($group_type); return $group_type; diff --git a/tests/src/Functional/GroupCreatorWizardTest.php b/tests/src/Functional/GroupCreatorWizardTest.php index 29b0672a600621d525cf51491961fe66966b4d4e..78b0d1f4838488a3b8d8e04e719501a9eb02945e 100644 --- a/tests/src/Functional/GroupCreatorWizardTest.php +++ b/tests/src/Functional/GroupCreatorWizardTest.php @@ -2,6 +2,10 @@ namespace Drupal\Tests\group\Functional; +use Drupal\Core\Session\AccountInterface; +use Drupal\group\Entity\GroupInterface; +use Drupal\group\PermissionScopeInterface; + /** * Tests the group creator wizard. * @@ -21,16 +25,18 @@ class GroupCreatorWizardTest extends GroupBrowserTestBase { * Tests that a group creator gets a membership using the wizard. */ public function testCreatorMembershipWizard() { - $group_type = $this->createGroupType(); - $group_type_id = $group_type->id(); + $group_type = $this->createGroupTypeAndRole(TRUE, TRUE); - $role = $this->drupalCreateRole(["create $group_type_id group"]); - $this->groupCreator->addRole($role); - $this->groupCreator->save(); - - $this->drupalGet("/group/add/$group_type_id"); + $this->drupalGet("/group/add/{$group_type->id()}"); $this->assertSession()->statusCodeEquals(200); + $group_role = $this->createGroupRole([ + 'group_type' => $group_type->id(), + 'scope' => PermissionScopeInterface::INDIVIDUAL_ID, + ]); + $group_type->set('creator_roles', [$group_role->id()]); + $group_type->save(); + $submit_button = 'Create ' . $group_type->label() . ' and complete your membership'; $this->assertSession()->buttonExists($submit_button); $this->assertSession()->buttonExists('Cancel'); @@ -41,45 +47,135 @@ class GroupCreatorWizardTest extends GroupBrowserTestBase { $submit_button = 'Save group and membership'; $this->assertSession()->buttonExists($submit_button); $this->assertSession()->buttonExists('Back'); + + $this->submitForm([], $submit_button); + $this->assertSession()->statusCodeEquals(200); + + // Get the group. + $all_groups = $this->entityTypeManager->getStorage('group')->loadMultiple(); + $this->assertCount(1, $all_groups); + $group = reset($all_groups); + + // Check there is just one membership. + $membership_ids = $this->loadGroupMembershipIds($group, $this->groupCreator); + $this->assertCount(1, $membership_ids, 'Wizard set just one membership.'); + + // Check that the roles assigned to the created member are the same as what + // we configured in the group defaults. + $ids = []; + foreach ($group->getMember($this->groupCreator)->getGroupRelationship()->group_roles as $group_role_ref) { + $ids[] = $group_role_ref->target_id; + } + $this->assertEquals($group_type->getCreatorRoleIds(), $ids, 'Wizard set the correct creator roles.'); } /** * Tests that a group creator gets a membership without using the wizard. */ public function testCreatorMembershipNoWizard() { - $group_type = $this->createGroupType(['creator_wizard' => FALSE]); - $group_type_id = $group_type->id(); + $group_type = $this->createGroupTypeAndRole(TRUE, FALSE); - $role = $this->drupalCreateRole(["create $group_type_id group"]); - $this->groupCreator->addRole($role); - $this->groupCreator->save(); - - $this->drupalGet("/group/add/$group_type_id"); + $this->drupalGet("/group/add/{$group_type->id()}"); $this->assertSession()->statusCodeEquals(200); $submit_button = 'Create ' . $group_type->label() . ' and become a member'; $this->assertSession()->buttonExists($submit_button); $this->assertSession()->buttonNotExists('Cancel'); + + $edit = ['Title' => $this->randomString()]; + $this->submitForm($edit, $submit_button); + + // Get the group. + $all_groups = $this->entityTypeManager->getStorage('group')->loadMultiple(); + $this->assertCount(1, $all_groups); + $group = reset($all_groups); + + // @todo We do not want this behavior in Group 4.0.0, we only want the + // wizard to create a membership and assign roles. + // Check there is just one membership. + $membership_ids = $this->loadGroupMembershipIds($group, $this->groupCreator); + $this->assertCount(1, $membership_ids, 'Wizard set just one membership.'); + + // Check that the roles assigned to the created member are the same as what + // we configured in the group defaults. + $ids = []; + foreach ($group->getMember($this->groupCreator)->getGroupRelationship()->group_roles as $group_role_ref) { + $ids[] = $group_role_ref->target_id; + } + $this->assertEquals($group_type->getCreatorRoleIds(), $ids, 'Group::postCreate() correctly set the creator roles.'); } /** * Tests that a group form is not turned into a wizard. */ public function testNoWizard() { + $group_type = $this->createGroupTypeAndRole(FALSE, FALSE); + + $this->drupalGet("/group/add/{$group_type->id()}"); + $this->assertSession()->statusCodeEquals(200); + + $submit_button = 'Create ' . $group_type->label(); + $this->assertSession()->buttonExists($submit_button); + $this->assertSession()->buttonNotExists('Cancel'); + + $edit = ['Title' => $this->randomString()]; + $this->submitForm($edit, $submit_button); + + // Get the group. + $all_groups = $this->entityTypeManager->getStorage('group')->loadMultiple(); + $this->assertCount(1, $all_groups); + $group = reset($all_groups); + + // Check there is no membership. + $membership_ids = $this->loadGroupMembershipIds($group, $this->groupCreator); + $this->assertCount(0, $membership_ids, 'Group creation did not result in a membership.'); + $this->assertFalse($group->getMember($this->groupCreator), 'No membership found for group creator.'); + } + + /** + * Creates group type and role with creation rights. + * + * @param bool $creator_membership + * The group creator automatically receives a membership. + * @param bool $creator_wizard + * The group creator must immediately complete their membership. + * + * @return \Drupal\group\Entity\GroupType + * Group type. + */ + protected function createGroupTypeAndRole($creator_membership, $creator_wizard) { $group_type = $this->createGroupType([ - 'creator_membership' => FALSE, - 'creator_wizard' => FALSE, + 'creator_membership' => $creator_membership, + 'creator_wizard' => $creator_wizard, ]); - $group_type_id = $group_type->id(); - $role = $this->drupalCreateRole(["create $group_type_id group"]); + $role = $this->drupalCreateRole(["create {$group_type->id()} group"]); $this->groupCreator->addRole($role); $this->groupCreator->save(); - $this->drupalGet("/group/add/$group_type_id"); - $this->assertSession()->statusCodeEquals(200); - $this->assertSession()->buttonExists('Create ' . $group_type->label()); - $this->assertSession()->buttonNotExists('Cancel'); + return $group_type; + } + + /** + * Loads all membership IDs for a user in a group. + * + * @param GroupInterface $group + * The group used to get the membership IDs. + * @param AccountInterface $account + * The user account used to get the membership IDs. + * + * @return int[] + * The memberships IDs. + */ + protected function loadGroupMembershipIds(GroupInterface $group, AccountInterface $account) { + $storage = $this->entityTypeManager->getStorage('group_relationship'); + + return $storage->getQuery() + ->accessCheck(FALSE) + ->condition('gid', $group->id()) + ->condition('entity_id', $account->id()) + ->condition('plugin_id', 'group_membership') + ->execute(); } } diff --git a/tests/src/Functional/GroupTypeFormTest.php b/tests/src/Functional/GroupTypeFormTest.php index 425dbf83cfdfde6848511732f2aa0bc557c24794..d8f034e0170b5003fd9c85d5e158f75f10c58407 100644 --- a/tests/src/Functional/GroupTypeFormTest.php +++ b/tests/src/Functional/GroupTypeFormTest.php @@ -101,7 +101,10 @@ class GroupTypeFormTest extends GroupBrowserTestBase { * Tests granting the group creator a membership. */ public function testCreatorMembership() { - $edit = ['The group creator automatically becomes a member' => 1] + $this->commonValues; + $edit = [ + 'The group creator automatically becomes a member' => 1, + 'Group creator must complete their membership' => 0, + ] + $this->commonValues; $this->submitForm($edit, $this->setUpAddFormAndGetSubmitButton()); $group = $this->createGroup(['type' => $this->groupTypeId]); @@ -166,6 +169,7 @@ class GroupTypeFormTest extends GroupBrowserTestBase { public function testNoAssignAdminRole() { $edit = [ 'The group creator automatically becomes a member' => 1, + 'Group creator must complete their membership' => 0, 'Automatically configure an administrative role' => 1, 'Automatically assign this administrative role to group creators' => 0, ] + $this->commonValues; @@ -189,6 +193,7 @@ class GroupTypeFormTest extends GroupBrowserTestBase { public function testAssignAdminRole() { $edit = [ 'The group creator automatically becomes a member' => 1, + 'Group creator must complete their membership' => 0, 'Automatically configure an administrative role' => 1, 'Automatically assign this administrative role to group creators' => 1, ] + $this->commonValues; diff --git a/tests/src/Kernel/GroupKernelTestBase.php b/tests/src/Kernel/GroupKernelTestBase.php index 225c1e37bd7c11290a7abf2431b0f3fa9fb2acc2..bf38c158afef2ce77781c3d352f61e99b352a549 100644 --- a/tests/src/Kernel/GroupKernelTestBase.php +++ b/tests/src/Kernel/GroupKernelTestBase.php @@ -83,6 +83,7 @@ abstract class GroupKernelTestBase extends EntityKernelTestBase { $group_type = $storage->create($values + [ 'id' => $this->randomMachineName(), 'label' => $this->randomString(), + 'creator_wizard' => FALSE, ]); $storage->save($group_type); return $group_type; diff --git a/tests/src/Kernel/Views/GroupViewsKernelTestBase.php b/tests/src/Kernel/Views/GroupViewsKernelTestBase.php index 141da01a9530dc6b0e05e5343b239707644d810c..dca1e1d9b818c6c967324ec7fcad0e7b0b17b617 100644 --- a/tests/src/Kernel/Views/GroupViewsKernelTestBase.php +++ b/tests/src/Kernel/Views/GroupViewsKernelTestBase.php @@ -125,6 +125,7 @@ abstract class GroupViewsKernelTestBase extends ViewsKernelTestBase { $group_type = $storage->create($values + [ 'id' => $this->randomMachineName(), 'label' => $this->randomString(), + 'creator_wizard' => FALSE, ]); $storage->save($group_type); return $group_type;