diff --git a/src/Og.php b/src/Og.php index e31da01ab..5a4f18da4 100644 --- a/src/Og.php +++ b/src/Og.php @@ -7,7 +7,6 @@ namespace Drupal\og; -use Drupal\Component\Render\FormattableMarkup; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\Display\EntityFormDisplayInterface; use Drupal\Core\Entity\EntityInterface; @@ -119,9 +118,9 @@ public static function createField($plugin_id, $entity_type, $bundle, array $set * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity to get groups for. - * @param $states + * @param array $states * (optional) Array with the state to return. Defaults to active. - * @param $field_name + * @param string $field_name * (optional) The field name associated with the group. * * @return array @@ -395,10 +394,10 @@ public static function permissionHandler() { * @param $group_ids * Array with group IDs that their cache should be invalidated. */ - public static function invalidateCache($group_ids = array()) { + public static function invalidateCache($group_ids = []) { // @todo We should not be using drupal_static() review and remove. // Reset static cache. - $caches = array( + $caches = [ 'og_user_access', 'og_user_access_alter', 'og_role_permissions', @@ -408,7 +407,7 @@ public static function invalidateCache($group_ids = array()) { 'og_get_membership', 'og_get_field_og_membership_properties', 'og_get_user_roles', - ); + ]; foreach ($caches as $cache) { drupal_static_reset($cache); diff --git a/tests/og.test b/tests/og.test index 6400788a3..6dbcd694f 100644 --- a/tests/og.test +++ b/tests/og.test @@ -1022,175 +1022,6 @@ class OgMigrate7000TestCase extends UpgradePathTestCase { } } - -/** - * Test the complex widget. - */ -class OgComplexWidgetTestCase extends DrupalWebTestCase { - - public static function getInfo() { - return array( - 'name' => 'OG reference widget', - 'description' => 'Test the OG reference widget behavior.', - 'group' => 'Organic groups', - ); - } - - function setUp() { - parent::setUp('og'); - - // Add OG group field to a the node's "group" bundle. - $this->drupalCreateContentType(array('type' => 'group')); - og_create_field(OG_GROUP_FIELD, 'node', 'group'); - - // Add OG audience field to the node's "post" bundle. - $this->drupalCreateContentType(array('type' => 'post')); - $og_field = og_fields_info(OgGroupAudienceHelper::DEFAULT_FIELD); - $og_field['instance']['required'] = TRUE; - og_create_field(OgGroupAudienceHelper::DEFAULT_FIELD, 'node', 'post', $og_field); - } - - /** - * Test "field modes" of the OG reference widget. - */ - function testFieldModes() { - $user1 = $this->drupalCreateUser(array('administer group', 'access content', 'create post content')); - $user2 = $this->drupalCreateUser(array('access content', 'create post content')); - - // Create group nodes. - $settings = array( - 'type' => 'group', - OG_GROUP_FIELD . '[und][0][value]' => 1, - ); - $settings['uid'] = $user1->uid; - $group1 = $this->drupalCreateNode($settings); - - $settings['uid'] = $user2->uid; - $group2 = $this->drupalCreateNode($settings); - - $settings = array( - 'type' => 'post', - ); - $settings['uid'] = $user1->uid; - $post1 = $this->drupalCreateNode($settings); - og_group('node', $group1->nid, array('entity_type' => 'node', 'entity' => $post1)); - - $settings['uid'] = $user2->uid; - $post2 = $this->drupalCreateNode($settings); - og_group('node', $group2->nid, array('entity_type' => 'node', 'entity' => $post2)); - - $this->drupalLogin($user1); - $this->drupalGet("node/$post1->nid/edit"); - - $fields = $this->xpath('//*[@id="edit-og-group-ref-und-0-default"]'); - $this->assertEqual($fields[0]->option['value'], '_none', '"Default" field mode is not required for administrator.'); - - $fields = $this->xpath('//*[@id="edit-og-group-ref-und-0-admin-0-target-id"]'); - $this->assertTrue(strpos($fields[0]->attributes()->class[0], 'form-autocomplete'), '"Administrator field more is an autocomplete widget type."'); - - $this->drupalLogin($user2); - $this->drupalGet("node/$post2->nid/edit"); - - $fields = $this->xpath('//*[@id="edit-og-group-ref-und-0-default"]'); - $this->assertEqual($fields[0]->option['value'], $group2->nid, '"Default" field mode is required.'); - } - - /** - * Test non-accessible group IDs are saved, upon form submit. - */ - function testHiddenGroupIds() { - $user1 = $this->drupalCreateUser(array('administer group', 'access content', 'create post content')); - $user2 = $this->drupalCreateUser(array('access content', 'create post content')); - - // Create group nodes. - $settings = array( - 'type' => 'group', - OG_GROUP_FIELD . '[und][0][value]' => 1, - ); - $settings['uid'] = $user1->uid; - $group1 = $this->drupalCreateNode($settings); - - $settings['uid'] = $user2->uid; - $group2 = $this->drupalCreateNode($settings); - - $settings = array( - 'type' => 'post', - ); - $settings['uid'] = $user1->uid; - $post1 = $this->drupalCreateNode($settings); - og_group('node', $group1->nid, array('entity_type' => 'node', 'entity' => $post1)); - og_group('node', $group2->nid, array('entity_type' => 'node', 'entity' => $post1)); - - $this->drupalLogin($user2); - $this->drupalPost("node/$post1->nid/edit", array(), 'Save'); - - // Assert post still belongs to both groups, although user was able - // to select only one. - $gids = og_get_entity_groups('node', $post1); - $this->assertEqual(count($gids['node']), 2, 'Hidden groups remained.'); - } - - /** - * Test a non "administer group" user with pending membership, re-saving - * user edit. - */ - function testUserEdit() { - $user1 = $this->drupalCreateUser(); - $user2 = $this->drupalCreateUser(); - - $settings = array( - 'type' => 'group', - OG_GROUP_FIELD . '[und][0][value]' => 1, - ); - $settings['uid'] = $user1->uid; - $group1 = $this->drupalCreateNode($settings); - - og_group('node', $group1->nid, array('entity' => $user2, 'state' => OG_STATE_PENDING)); - - $this->drupalLogin($user2); - $this->drupalPost("user/$user2->uid/edit", array(), 'Save'); - - $this->assertTrue(og_get_entity_groups('user', $user2, array(OG_STATE_PENDING)), 'User membership was retained after user save.'); - } - - /** - * Test multiple group-audience fields. - */ - function testMultipleFields() { - // Add another group-audience field. - $og_field = og_fields_info(OgGroupAudienceHelper::DEFAULT_FIELD); - og_create_field('another_field', 'node', 'post', $og_field); - - $user1 = $this->drupalCreateUser(); - - // Create a group. - $settings = array( - 'type' => 'group', - OG_GROUP_FIELD . '[und][0][value]' => 1, - 'uid' => $user1->uid, - ); - $group1 = $this->drupalCreateNode($settings); - $group2 = $this->drupalCreateNode($settings); - - // Create group content. - $settings = array( - 'type' => 'post', - 'uid' => $user1->uid, - ); - $post1 = $this->drupalCreateNode($settings); - - og_group('node', $group1->nid, array('entity_type' => 'node', 'entity' => $post1, 'field_name' => OgGroupAudienceHelper::DEFAULT_FIELD)); - og_group('node', $group2->nid, array('entity_type' => 'node', 'entity' => $post1, 'field_name' => 'another_field')); - - $this->drupalLogin($user1); - $this->drupalGet("node/$post1->nid/edit"); - - // Assert correct selection in both fields. - $this->assertOptionSelected('edit-og-group-ref-und-0-default', $group1->nid); - $this->assertOptionSelected('edit-another-field-und-0-default', $group2->nid); - } -} - /** * Test the revocation of group roles. */ diff --git a/tests/src/Functional/OgComplexWidgetTest.php b/tests/src/Functional/OgComplexWidgetTest.php index 51daa99ae..00a4b4cc5 100644 --- a/tests/src/Functional/OgComplexWidgetTest.php +++ b/tests/src/Functional/OgComplexWidgetTest.php @@ -7,12 +7,17 @@ namespace Drupal\Tests\og\Functional; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\Query\QueryInterface; +use Drupal\KernelTests\AssertLegacyTrait; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; +use Drupal\og\Entity\OgMembership; use Drupal\og\Og; use Drupal\og\OgGroupAudienceHelper; +use Drupal\og\OgMembershipInterface; use Drupal\og\Plugin\Field\FieldType\OgMembershipReferenceItemList; +use Drupal\simpletest\AssertContentTrait; use Drupal\simpletest\BrowserTestBase; use Drupal\simpletest\ContentTypeCreationTrait; use Drupal\simpletest\NodeCreationTrait; @@ -24,13 +29,17 @@ */ class OgComplexWidgetTest extends BrowserTestBase { + use AssertContentTrait; + // @todo Convert legacy asserts and remove legacy trait. + use AssertLegacyTrait; use ContentTypeCreationTrait; use NodeCreationTrait; /** * {@inheritdoc} + * @todo Remove field_ui */ - public static $modules = ['node', 'og']; + public static $modules = ['field_ui', 'node', 'og']; /** * {@inheritdoc} @@ -95,4 +104,196 @@ function testOtherGroups() { $this->assertEquals($group->id(), $reference_list->first()->getValue()['target_id'], 'The "Other Groups" field references the correct group.'); } + /** + * Tests "field modes" of the OG reference widget. + */ + function testFieldModes() { + $user1 = $this->drupalCreateUser(['administer group', 'access content', 'create post content']); + $user2 = $this->drupalCreateUser(['access content', 'create post content']); + + // Create two group nodes, one for each user. + $settings = [ + 'type' => 'group', + // @todo I think this is obsolete. + // OG_GROUP_FIELD . '[und][0][value]' => 1, + 'uid' => $user1->id(), + ]; + $group1 = $this->createNode($settings); + + $settings['uid'] = $user2->id(); + $group2 = $this->createNode($settings); + + // Create a post in each group. + $settings = [ + 'type' => 'post', + // @todo I think this is obsolete. + // OG_GROUP_FIELD . '[und][0][value]' => 1, + 'uid' => $user1->id(), + OgGroupAudienceHelper::DEFAULT_FIELD => [['target_id' => $group1->id()]], + ]; + $post1 = $this->createNode($settings); + + $settings['uid'] = $user2->id(); + $settings[OgGroupAudienceHelper::DEFAULT_FIELD] = [['target_id' => $group2->id()]]; + $post2 = $this->createNode($settings); + + $this->drupalLogin($user1); + $this->content = $this->drupalGet("node/{$post1->id()}/edit"); + + // @todo Not sure what this is supposed to be testing. What is "default + // field mode"? + $fields = $this->xpath('//*[@id="edit-og-group-ref-und-0-default"]'); + $this->assertEqual($fields[0]->option['value'], '_none', '"Default" field mode is not required for administrator.'); + + // @todo Update selector. + $fields = $this->xpath('//*[@id="edit-og-group-ref-und-0-admin-0-target-id"]'); + $this->assertTrue(strpos($fields[0]->attributes()->class[0], 'form-autocomplete'), '"Administrator field more is an autocomplete widget type."'); + + $this->drupalLogin($user2); + // @todo: Seems to be a bug here, the page returns access denied. + $this->content = $this->drupalGet("node/{$post2->id()}/edit"); + + // @todo When this page is visible, figure out what default field mode is. + $fields = $this->xpath('//*[@id="edit-og-group-ref-und-0-default"]'); + $this->assertEqual($fields[0]->option['value'], $group2->id(), '"Default" field mode is required.'); + } + + /** + * Test non-accessible group IDs are saved, upon form submit. + */ + function testHiddenGroupIds() { + $user1 = $this->drupalCreateUser(['administer group', 'access content', 'create post content']); + $user2 = $this->drupalCreateUser(['access content', 'create post content']); + + // Create a group for each user. + $settings = [ + 'type' => 'group', + 'uid' => $user1->id(), + ]; + $group1 = $this->createNode($settings); + + $settings['uid'] = $user2->id(); + $group2 = $this->createNode($settings); + + // Create a post that references both groups. + $settings = [ + 'type' => 'post', + 'uid' => $user1->id(), + ]; + $post1 = $this->createNode($settings); + + $this->addContentToGroup($post1, $group1); + $this->addContentToGroup($post1, $group2); + + // Check that both groups are referenced. + $gids = Og::getEntityGroups($post1); + $this->assertEquals(2, count($gids['node']), 'Both groups are referenced initially.'); + + // Reset the entity query from Og::getEntityGroups(). + Og::invalidateCache($gids['node']); + + // Log in as user 2. This user doesn't have group administration rights, so + // only its own group is visible in the form. Resave the form. + $this->drupalLogin($user2); + $this->drupalGet("node/{$post1->id()}/edit"); + $this->submitForm([], 'Save'); + + // Assert post still belongs to both groups, although user was able + // to select only one. + // @todo This currently fails, indicating that this functionality has + // regressed. + $gids = Og::getEntityGroups($post1); + $this->assertEquals(2, count($gids['node']), 'Hidden groups remained.'); + } + + /** + * Test a non "administer group" user with pending membership, re-saving + * user edit. + */ + function testUserEdit() { + $user1 = $this->drupalCreateUser(); + $user2 = $this->drupalCreateUser(); + + $settings = [ + 'type' => 'group', + // @todo I think this is obsolete. + // OG_GROUP_FIELD . '[und][0][value]' => 1, + 'uid' => $user1->id(), + ]; + $group1 = $this->createNode($settings); + + og_group('node', $group1->id(), ['entity' => $user2, 'state' => OgMembershipInterface::STATE_PENDING]); + + $this->drupalLogin($user2); + $this->submitForm("user/{$user2->id()}/edit", [], 'Save'); + + $this->assertTrue(Og::getEntityGroups('user', $user2, [OgMembershipInterface::STATE_PENDING]), 'User membership was retained after user save.'); + } + + /** + * Test multiple group-audience fields. + */ + function testMultipleFields() { + // Add another group-audience field. + $og_field = og_fields_info(OG_AUDIENCE_FIELD); + og_create_field('another_field', 'node', 'post', $og_field); + + $user1 = $this->drupalCreateUser(); + + // Create a group. + $settings = [ + 'type' => 'group', + OG_GROUP_FIELD . '[und][0][value]' => 1, + 'uid' => $user1->id(), + ]; + $group1 = $this->createNode($settings); + $group2 = $this->createNode($settings); + + // Create group content. + $settings = [ + 'type' => 'post', + 'uid' => $user1->id(), + ]; + $post1 = $this->createNode($settings); + + og_group('node', $group1->id(), ['entity_type' => 'node', 'entity' => $post1, 'field_name' => OG_AUDIENCE_FIELD]); + og_group('node', $group2->id(), ['entity_type' => 'node', 'entity' => $post1, 'field_name' => 'another_field']); + + $this->drupalLogin($user1); + $this->drupalGet("node/{$post1->id()}/edit"); + + // Assert correct selection in both fields. + $this->assertOptionSelected('edit-og-group-ref-und-0-default', $group1->id()); + $this->assertOptionSelected('edit-another-field-und-0-default', $group2->id()); + } + + /** + * Makes the given group content entity a member of the given group. + * + * @param ContentEntityInterface $member_entity + * The content entity to make a member. + * @param ContentEntityInterface $group_entity + * The group entity that will host the content entity. + * @param int $state + * The activation state of the membership. Can be one of the following: + * - OgMembershipInterface::STATE_ACTIVE + * - OgMembershipInterface::STATE_BLOCKED + * - OgMembershipInterface::STATE_PENDING + * Defaults to OgMembershipInterface::STATE_ACTIVE. + */ + protected function addUserToGroup(ContentEntityInterface $member_entity, ContentEntityInterface $group_entity, $state = OgMembershipInterface::STATE_ACTIVE) { + // @todo repurpose this to add users as members to groups. + // @see https://github.com/amitaibu/og/issues/116 + /** @var OgMembership $membership */ + $membership = Og::membershipStorage()->create(Og::membershipDefault()); + $membership + ->setFieldName(OgGroupAudienceHelper::DEFAULT_FIELD) + ->setMemberEntityType($member_entity->getEntityTypeId()) + ->setMemberEntityId($member_entity->id()) + ->setGroupEntityType($group_entity->getEntityTypeId()) + ->setGroupEntityid($group_entity->id()) + ->setState($state) + ->save(); + } + } diff --git a/tests/src/Kernel/Entity/ReferenceStringIdTest.php b/tests/src/Kernel/Entity/ReferenceStringIdTest.php index 4d8fd5008..e08082394 100644 --- a/tests/src/Kernel/Entity/ReferenceStringIdTest.php +++ b/tests/src/Kernel/Entity/ReferenceStringIdTest.php @@ -13,6 +13,8 @@ /** * Checks that groups with string IDs can be referenced. + * + * @group og */ class ReferenceStringIdTest extends KernelTestBase {