diff --git src/bp-groups/bp-groups-cache.php src/bp-groups/bp-groups-cache.php
index 10ba004..44aeaf6 100644
--- src/bp-groups/bp-groups-cache.php
+++ src/bp-groups/bp-groups-cache.php
@@ -202,6 +202,31 @@ function groups_clear_group_administrator_cache_on_member_save( BP_Groups_Member
 }
 add_action( 'groups_member_after_save', 'groups_clear_group_administrator_cache_on_member_save' );
 
+/**
+ * Clear caches on membership save.
+ *
+ * @since BuddyPress (2.3.0)
+ */
+function bp_groups_clear_user_group_cache_on_membership_save( BP_Groups_Member $member ) {
+	wp_cache_delete( $member->user_id, 'bp_groups_memberships_for_user' );
+	wp_cache_delete( $member->id, 'bp_groups_memberships' );
+}
+add_action( 'groups_member_before_save', 'bp_groups_clear_user_group_cache_on_membership_save' );
+add_action( 'groups_member_before_remove', 'bp_groups_clear_user_group_cache_on_membership_save' );
+
+/**
+ * Clear group memberships cache on miscellaneous actions not covered by the 'after_save' hook.
+ *
+ * @since BuddyPress (2.3.0)
+ */
+function bp_groups_clear_user_group_cache_on_other_events( $user_id, $group_id ) {
+	wp_cache_delete( $user_id, 'bp_groups_memberships_for_user' );
+
+	$membership = new BP_Groups_Member( $user_id, $group_id );
+	wp_cache_delete( $membership->id, 'bp_groups_memberships' );
+}
+add_action( 'bp_groups_member_before_delete', 'bp_groups_clear_user_group_cache_on_other_events', 10, 2 );
+
 /* List actions to clear super cached pages on, if super cache is installed */
 add_action( 'groups_join_group',                 'bp_core_clear_cache' );
 add_action( 'groups_leave_group',                'bp_core_clear_cache' );
diff --git src/bp-groups/bp-groups-functions.php src/bp-groups/bp-groups-functions.php
index 2aed47e..5a060fa 100644
--- src/bp-groups/bp-groups-functions.php
+++ src/bp-groups/bp-groups-functions.php
@@ -758,6 +758,116 @@ function groups_get_user_groups( $user_id = 0, $pag_num = 0, $pag_page = 0 ) {
 }
 
 /**
+ * Get a list of groups of which the specified user is a member.
+ *
+ * @since BuddyPress (2.3.0)
+ *
+ * @param int $user_id ID of the user.
+ * @param array $args {
+ *     Array of optional args.
+ *     @param bool|null   $is_confirmed Whether to return only confirmed memberships. Pass `null` to disable this
+ *                                      filter. Default: true.
+ *     @param bool|null   $is_banned    Whether to return only banned memberships. Pass `null` to disable this filter.
+ *                                      Default: false.
+ *     @param bool|null   $is_admin     Whether to return only admin memberships. Pass `null` to disable this filter.
+ *                                      Default: false.
+ *     @param bool|null   $is_mod       Whether to return only mod memberships. Pass `null` to disable this filter.
+ *                                      Default: false.
+ *     @param bool|null   $invite_sent  Whether to return only memberships with 'invite_sent'. Pass `null` to disable
+ *                                      this filter. Default: false.
+ *     @param string $orderby           Field to order by. Accepts 'id' (membership ID), 'group_id', 'date_modified'.
+ *                                      Default: 'group_id'.
+ *     @param string $order             Sort order. Accepts 'ASC' or 'DESC'. Default: 'ASC'.
+ * }
+ * @return array Array of matching group memberships, keyed by group ID.
+ */
+function bp_get_user_groups( $user_id, $args = array() ) {
+	$r = bp_parse_args( $args, array(
+		'is_confirmed' => true,
+		'is_banned'    => false,
+		'is_admin'     => false,
+		'is_mod'       => false,
+		'invite_sent'  => null,
+		'orderby'      => 'group_id',
+		'order'        => 'ASC',
+	), 'get_user_groups' );
+
+	$user_id = intval( $user_id );
+
+	$membership_ids = wp_cache_get( $user_id, 'bp_groups_memberships_for_user' );
+	if ( false === $membership_ids ) {
+		$membership_ids = BP_Groups_Member::get_membership_ids_for_user( $user_id );
+		wp_cache_set( $user_id, $membership_ids, 'bp_groups_memberships_for_user' );
+	}
+
+	// Prime the membership cache.
+	$uncached_membership_ids = bp_get_non_cached_ids( $membership_ids, 'bp_groups_memberships' );
+	if ( ! empty( $uncached_membership_ids ) ) {
+		$uncached_memberships = BP_Groups_Member::get_memberships_by_id( $uncached_membership_ids );
+
+		foreach ( $uncached_memberships as $uncached_membership ) {
+			wp_cache_set( $uncached_membership->id, $uncached_membership, 'bp_groups_memberships' );
+		}
+	}
+
+	// Populate group membership array from cache.
+	$groups = array();
+	foreach ( $membership_ids as $membership_id ) {
+		$membership = wp_cache_get( $membership_id, 'bp_groups_memberships' );
+
+		// Sanity check.
+		if ( ! isset( $membership->group_id ) ) {
+			continue;
+		}
+
+		$group_id = (int) $membership->group_id;
+
+		$groups[ $group_id ] = $membership;
+	}
+
+	// Normalize group data.
+	foreach ( $groups as &$group ) {
+		// Integer values.
+		$group_id = intval( $group->group_id );
+		foreach ( array( 'id', 'group_id', 'user_id', 'inviter_id' ) as $index ) {
+			$group->{$index} = intval( $group->{$index} );
+		}
+
+		// Boolean values.
+		foreach ( array( 'is_admin', 'is_mod', 'is_confirmed', 'is_banned', 'invite_sent' ) as $index ) {
+			$group->{$index} = (bool) $group->{$index};
+		}
+	}
+
+	// Assemble filter array for use in `wp_list_filter()`.
+	$filters = wp_array_slice_assoc( $r, array( 'is_confirmed', 'is_banned', 'is_admin', 'is_mod', 'invite_sent' ) );
+	foreach ( $filters as $filter_name => $filter_value ) {
+		if ( is_null( $filter_value ) ) {
+			unset( $filters[ $filter_name ] );
+		}
+	}
+
+	if ( ! empty( $filters ) ) {
+		$groups = wp_list_filter( $groups, $filters );
+	}
+
+	// By default, results are ordered by membership id.
+	if ( 'group_id' === $r['orderby'] ) {
+		ksort( $groups );
+	} elseif ( in_array( $r['orderby'], array( 'id', 'date_modified' ) ) ) {
+		$groups = bp_sort_by_key( $groups, $r['orderby'] );
+	}
+
+	// By default, results are ordered ASC.
+	if ( 'DESC' === strtoupper( $r['order'] ) ) {
+		// `true` to preserve keys.
+		$groups = array_reverse( $groups, true );
+	}
+
+	return $groups;
+}
+
+/**
  * Get the count of groups of which the specified user is a member.
  *
  * @param int $user_id Optional. Default: ID of the displayed user.
@@ -851,7 +961,17 @@ function groups_avatar_upload_dir( $group_id = 0 ) {
  * @param int|null ID of the membership if the user is an admin, otherwise null.
  */
 function groups_is_user_admin( $user_id, $group_id ) {
-	return BP_Groups_Member::check_is_admin( $user_id, $group_id );
+	$is_admin = false;
+
+	$user_groups = bp_get_user_groups( $user_id, array(
+		'is_admin' => true,
+	) );
+
+	if ( isset( $user_groups[ $group_id ] ) ) {
+		$is_admin = $user_groups[ $group_id ]->id;
+	}
+
+	return $is_admin;
 }
 
 /**
@@ -862,7 +982,17 @@ function groups_is_user_admin( $user_id, $group_id ) {
  * @param int|null ID of the membership if the user is a mod, otherwise null.
  */
 function groups_is_user_mod( $user_id, $group_id ) {
-	return BP_Groups_Member::check_is_mod( $user_id, $group_id );
+	$is_mod = false;
+
+	$user_groups = bp_get_user_groups( $user_id, array(
+		'is_mod' => true,
+	) );
+
+	if ( isset( $user_groups[ $group_id ] ) ) {
+		$is_mod = $user_groups[ $group_id ]->id;
+	}
+
+	return $is_mod;
 }
 
 /**
@@ -873,11 +1003,81 @@ function groups_is_user_mod( $user_id, $group_id ) {
  * @param int|null ID of the membership if the user is a member, otherwise null.
  */
 function groups_is_user_member( $user_id, $group_id ) {
-	return BP_Groups_Member::check_is_member( $user_id, $group_id );
+	$is_member = false;
+
+	$user_groups = bp_get_user_groups( $user_id, array(
+		'is_admin' => null,
+		'is_mod' => null,
+	) );
+
+	if ( isset( $user_groups[ $group_id ] ) ) {
+		$is_member = $user_groups[ $group_id ]->id;
+	}
+
+	return $is_member;
 }
 
 function groups_is_user_banned( $user_id, $group_id ) {
-	return BP_Groups_Member::check_is_banned( $user_id, $group_id );
+	$is_banned = false;
+
+	$user_groups = bp_get_user_groups( $user_id, array(
+		'is_confirmed' => null,
+		'is_banned' => true,
+	) );
+
+	if ( isset( $user_groups[ $group_id ] ) ) {
+		$is_banned = $user_groups[ $group_id ]->id;
+	}
+
+	return $is_banned;
+}
+
+/**
+ * Check whether a user has an outstanding invitation to a group.
+ *
+ * @since BuddyPress (2.3.0)
+ *
+ * @param int $user_id ID of the user.
+ * @param int $group_id ID of the group.
+ * @return int|null ID of the membership if found.
+ */
+function groups_is_user_invited( $user_id, $group_id ) {
+	$is_invited = false;
+
+	$user_groups = bp_get_user_groups( $user_id, array(
+		'invite_sent' => true,
+		'is_confirmed' => false,
+	) );
+
+	if ( isset( $user_groups[ $group_id ] ) ) {
+		$is_invited = $user_groups[ $group_id ]->id;
+	}
+
+	return $is_invited;
+}
+
+/**
+ * Check whether a user has a pending membership request for a group.
+ *
+ * @since BuddyPress (2.3.0)
+ *
+ * @param int $user_id ID of the user.
+ * @param int $group_id ID of the group.
+ * @return int|null ID of the membership if found.
+ */
+function groups_is_user_pending( $user_id, $group_id ) {
+	$is_pending = false;
+
+	$user_groups = bp_get_user_groups( $user_id, array(
+		'invite_sent' => false,
+		'is_confirmed' => false,
+	) );
+
+	if ( isset( $user_groups[ $group_id ] ) ) {
+		$is_pending = $user_groups[ $group_id ]->id;
+	}
+
+	return $is_pending;
 }
 
 /**
diff --git src/bp-groups/bp-groups-loader.php src/bp-groups/bp-groups-loader.php
index 14d43c6..b0ce70e 100644
--- src/bp-groups/bp-groups-loader.php
+++ src/bp-groups/bp-groups-loader.php
@@ -741,6 +741,8 @@ class BP_Groups_Component extends BP_Component {
 			'bp_groups',
 			'bp_group_admins',
 			'bp_group_invite_count',
+			'bp_groups_memberships',
+			'bp_groups_memberships_for_user',
 			'group_meta'
 		) );
 
diff --git src/bp-groups/classes/class-bp-groups-group.php src/bp-groups/classes/class-bp-groups-group.php
index 2ccb2a6..47b5f8a 100644
--- src/bp-groups/classes/class-bp-groups-group.php
+++ src/bp-groups/classes/class-bp-groups-group.php
@@ -1362,68 +1362,13 @@ class BP_Groups_Group {
 	 * @return array $paged_groups
 	 */
 	public static function get_group_extras( &$paged_groups, &$group_ids, $type = false ) {
-		global $wpdb;
-
-		if ( empty( $group_ids ) )
-			return $paged_groups;
-
-		$bp = buddypress();
-
-		// Sanitize group IDs
-		$group_ids = implode( ',', wp_parse_id_list( $group_ids ) );
-
-		// Fetch the logged-in user's status within each group
-		if ( is_user_logged_in() ) {
-			$user_status_results = $wpdb->get_results( $wpdb->prepare( "SELECT group_id, is_confirmed, invite_sent FROM {$bp->groups->table_name_members} WHERE user_id = %d AND group_id IN ( {$group_ids} ) AND is_banned = 0", bp_loggedin_user_id() ) );
-		} else {
-			$user_status_results = array();
-		}
-
-		// Reindex
-		$user_status = array();
-		foreach ( $user_status_results as $user_status_result ) {
-			$user_status[ $user_status_result->group_id ] = $user_status_result;
-		}
-
-		for ( $i = 0, $count = count( $paged_groups ); $i < $count; ++$i ) {
-			$is_member = $is_invited = $is_pending = '0';
-			$gid = $paged_groups[ $i ]->id;
-
-			if ( isset( $user_status[ $gid ] ) ) {
-
-				// is_confirmed means the user is a member
-				if ( $user_status[ $gid ]->is_confirmed ) {
-					$is_member = '1';
+		$user_id = bp_loggedin_user_id();
 
-				// invite_sent means the user has been invited
-				} elseif ( $user_status[ $gid ]->invite_sent ) {
-					$is_invited = '1';
-
-				// User has sent request, but has not been confirmed
-				} else {
-					$is_pending = '1';
-				}
-			}
-
-			$paged_groups[ $i ]->is_member = $is_member;
-			$paged_groups[ $i ]->is_invited = $is_invited;
-			$paged_groups[ $i ]->is_pending = $is_pending;
-		}
-
-		if ( is_user_logged_in() ) {
-			$user_banned = $wpdb->get_col( $wpdb->prepare( "SELECT group_id FROM {$bp->groups->table_name_members} WHERE is_banned = 1 AND user_id = %d AND group_id IN ( {$group_ids} )", bp_loggedin_user_id() ) );
-		} else {
-			$user_banned = array();
-		}
-
-		for ( $i = 0, $count = count( $paged_groups ); $i < $count; ++$i ) {
-			$paged_groups[$i]->is_banned = false;
-
-			foreach ( (array) $user_banned as $group_id ) {
-				if ( $group_id == $paged_groups[$i]->id ) {
-					$paged_groups[$i]->is_banned = true;
-				}
-			}
+		foreach ( $paged_groups as &$group ) {
+			$group->is_member  = groups_is_user_member( $user_id, $group->id ) ? '1' : '0';
+			$group->is_invited = groups_is_user_invited( $user_id, $group->id ) ? '1' : '0';
+			$group->is_pending = groups_is_user_pending( $user_id, $group->id ) ? '1' : '0';
+			$group->is_banned  = (bool) groups_is_user_banned( $user_id, $group->id );
 		}
 
 		return $paged_groups;
diff --git src/bp-groups/classes/class-bp-groups-member.php src/bp-groups/classes/class-bp-groups-member.php
index 06a0705..e3a9aef 100644
--- src/bp-groups/classes/class-bp-groups-member.php
+++ src/bp-groups/classes/class-bp-groups-member.php
@@ -939,6 +939,23 @@ class BP_Groups_Member {
 	}
 
 	/**
+	 * Get group membership objects by ID (or an array of IDs).
+	 *
+	 * @since BuddyPress (2.3.0)
+	 *
+	 * @param int|string|array $membership_ids Single membership ID or comma-separated/array list of membership IDs.
+	 * @return array
+	 */
+	public static function get_memberships_by_id( $membership_ids ) {
+		global $wpdb;
+
+		$bp = buddypress();
+
+		$membership_ids = implode( ',', wp_parse_id_list( $membership_ids ) );
+		return $wpdb->get_results( "SELECT * FROM {$bp->groups->table_name_members} WHERE id IN ({$membership_ids})" );
+	}
+
+	/**
 	 * Get the IDs users with outstanding membership requests to the group.
 	 *
 	 * @param int $group_id ID of the group.
@@ -1037,6 +1054,24 @@ class BP_Groups_Member {
 	}
 
 	/**
+	 * Get all membership IDs for a user.
+	 *
+	 * @since BuddyPress (2.3.0)
+	 *
+	 * @param int $user_id ID of the user.
+	 * @return array
+	 */
+	public static function get_membership_ids_for_user( $user_id ) {
+		global $wpdb;
+
+		$bp = buddypress();
+
+		$group_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->groups->table_name_members} WHERE user_id = %d ORDER BY id ASC", $user_id ) );
+
+		return $group_ids;
+	}
+
+	/**
 	 * Delete all memberships for a given group.
 	 *
 	 * @param int $group_id ID of the group.
diff --git tests/phpunit/testcases/groups/class-bp-groups-member.php tests/phpunit/testcases/groups/class-bp-groups-member.php
index 7289c59..6e65525 100644
--- tests/phpunit/testcases/groups/class-bp-groups-member.php
+++ tests/phpunit/testcases/groups/class-bp-groups-member.php
@@ -215,5 +215,37 @@ class BP_Tests_BP_Groups_Member_TestCases extends BP_UnitTestCase {
 
 		$this->set_current_user( $old_current_user );
 	}
+
+	/**
+	 * @group get_memberships_by_id
+	 */
+	public function test_get_memberships_by_id_with_single_id() {
+		$users = $this->factory->user->create_many( 2 );
+		$groups = $this->factory->group->create_many( 2 );
+
+		$m0 = $this->add_user_to_group( $users[0], $groups[0] );
+		$m1 = $this->add_user_to_group( $users[1], $groups[1] );
+
+		$found = BP_Groups_Member::get_memberships_by_id( $m0 );
+
+		$this->assertSame( 1, count( $found ) );
+		$this->assertEquals( $m0, $found[0]->id );
+	}
+
+	/**
+	 * @group get_memberships_by_id
+	 */
+	public function test_get_memberships_by_id_with_multiple_ids() {
+		$users = $this->factory->user->create_many( 2 );
+		$groups = $this->factory->group->create_many( 2 );
+
+		$m0 = $this->add_user_to_group( $users[0], $groups[0] );
+		$m1 = $this->add_user_to_group( $users[1], $groups[1] );
+
+		$found = BP_Groups_Member::get_memberships_by_id( array( $m0, $m1 ) );
+
+		$this->assertSame( 2, count( $found ) );
+		$this->assertEqualSets( array( $m0, $m1 ), wp_list_pluck( $found, 'id' ) );
+	}
 }
 
diff --git tests/phpunit/testcases/groups/functions/bpGetUserGroups.php tests/phpunit/testcases/groups/functions/bpGetUserGroups.php
new file mode 100644
index 0000000..12197a3
--- /dev/null
+++ tests/phpunit/testcases/groups/functions/bpGetUserGroups.php
@@ -0,0 +1,565 @@
+<?php
+
+/**
+ * @group groups
+ */
+class BP_Tests_Groups_Functions_BpGetUserGroups extends BP_UnitTestCase {
+	static $user;
+	static $admin_user;
+	static $groups;
+
+	public function setUp() {
+		parent::setUp();
+		groups_remove_member( self::$user, self::$groups[2] );
+	}
+
+	public static function setUpBeforeClass() {
+		$f = new BP_UnitTest_Factory();
+
+		self::$user = $f->user->create( array(
+			'user_login' => 'bp_get_user_groups_user',
+			'user_email' => 'bp_get_user_groups_user@example.com',
+		) );
+		self::$admin_user = $f->user->create( array(
+			'user_login' => 'bp_get_user_groups_admin_user',
+			'user_email' => 'bp_get_user_groups_admin_user@example.com',
+		) );
+		self::$groups = $f->group->create_many( 4, array(
+			'creator_id' => self::$admin_user,
+		) );
+
+		$now = time();
+		self::add_user_to_group( self::$user, self::$groups[1], array(
+			'date_modified' => date( 'Y-m-d H:i:s', $now - 10 ),
+		) );
+		self::add_user_to_group( self::$user, self::$groups[0], array(
+			'date_modified' => date( 'Y-m-d H:i:s', $now ),
+		) );
+
+		self::commit_transaction();
+	}
+
+	public static function tearDownAfterClass() {
+		foreach ( self::$groups as $group ) {
+			groups_delete_group( $group );
+		}
+
+		if ( is_multisite() ) {
+			wpmu_delete_user( self::$user );
+			wpmu_delete_user( self::$admin_user );
+		} else {
+			wp_delete_user( self::$user );
+			wp_delete_user( self::$admin_user );
+		}
+
+		self::commit_transaction();
+	}
+
+	public function test_default_params() {
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( array( self::$groups[0], self::$groups[1] ), wp_list_pluck( $found, 'group_id' ) );
+
+		foreach ( $found as $index => $f ) {
+			$this->assertInternalType( 'int', $index );
+			$this->assertInternalType( 'object', $f );
+			$this->assertInternalType( 'int', $f->group_id );
+			$this->assertSame( $index, $f->group_id );
+		}
+	}
+
+	public function test_is_confirmed_true() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_confirmed' => false,
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => true,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_confirmed_false() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_confirmed' => false,
+		) );
+
+		$expected = array( self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => false,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_confirmed_null() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_confirmed' => false,
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_banned_true() {
+		$this->add_user_to_group( self::$user, self::$groups[2] );
+		$member = new BP_Groups_Member( self::$user, self::$groups[2] );
+		$member->ban();
+
+		$expected = array( self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_banned' => true,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_banned_false() {
+		$this->add_user_to_group( self::$user, self::$groups[2] );
+		$member = new BP_Groups_Member( self::$user, self::$groups[2] );
+		$member->ban();
+
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_banned' => false,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_banned_null() {
+		$this->add_user_to_group( self::$user, self::$groups[2] );
+		$member = new BP_Groups_Member( self::$user, self::$groups[2] );
+		$member->ban();
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_banned' => null,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_admin_true() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_admin' => true,
+		) );
+
+		$expected = array( self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_admin' => true,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_admin_false() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_admin' => true,
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_admin' => false,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_admin_null() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_admin' => false,
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_admin' => null,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_mod_true() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_mod' => true,
+		) );
+
+		$expected = array( self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_mod' => true,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_mod_false() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_mod' => true,
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_mod' => false,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_is_mod_null() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'is_mod' => false,
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_mod' => null,
+		) );
+
+		$this->assertEqualSets( $expected, wp_list_pluck( $found, 'group_id' ) );
+	}
+
+	public function test_orderby_should_default_to_group_id() {
+		$expected = bp_get_user_groups( self::$user );
+		$found = bp_get_user_groups( self::$user, array(
+			'orderby' => 'group_id',
+		) );
+
+		$this->assertEquals( $expected, $found );
+	}
+
+	public function test_orderby_group_id() {
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user, array(
+			'orderby' => 'group_id',
+		) );
+
+		$this->assertSame( $expected, array_keys( $found ) );
+	}
+
+	public function test_orderby_id() {
+		$expected = array( self::$groups[1], self::$groups[0] );
+		$found = bp_get_user_groups( self::$user, array(
+			'orderby' => 'id',
+		) );
+
+		$this->assertSame( $expected, array_values( wp_list_pluck( $found, 'group_id' ) ) );
+	}
+
+	public function test_orderby_date_modified() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'date_modified' => '2015-03-14 09:26:53',
+		) );
+
+		$expected = array( self::$groups[2], self::$groups[1], self::$groups[0] );
+		$found = bp_get_user_groups( self::$user, array(
+			'orderby' => 'date_modified',
+		) );
+
+		$this->assertSame( $expected, array_values( wp_list_pluck( $found, 'group_id' ) ) );
+	}
+
+	public function test_orderby_group_id_with_order_desc() {
+		$expected = array( self::$groups[1], self::$groups[0] );
+		$found = bp_get_user_groups( self::$user, array(
+			'orderby' => 'group_id',
+			'order' => 'DESC',
+		) );
+
+		$this->assertSame( $expected, array_keys( $found ) );
+	}
+
+	public function test_orderby_date_modified_with_order_desc() {
+		$this->add_user_to_group( self::$user, self::$groups[2], array(
+			'date_modified' => '2015-03-14 09:26:53',
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'orderby' => 'date_modified',
+			'order' => 'DESC',
+		) );
+
+		$this->assertSame( $expected, array_values( wp_list_pluck( $found, 'group_id' ) ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_results_should_be_cached() {
+		global $wpdb;
+
+		$g1 = bp_get_user_groups( self::$user );
+
+		$num_queries = $wpdb->num_queries;
+		$g2 = bp_get_user_groups( self::$user );
+
+		$this->assertSame( $num_queries, $wpdb->num_queries );
+		$this->assertEquals( $g1, $g2 );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_join() {
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user );
+
+		groups_join_group( self::$groups[2], self::$user );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_leave() {
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user );
+
+		groups_leave_group( self::$groups[1], self::$user );
+
+		$expected = array( self::$groups[0] );
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_remove() {
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user );
+
+		$m = new BP_Groups_Member( self::$user, self::$groups[1] );
+		$m->remove();
+
+		$expected = array( self::$groups[0] );
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_ban() {
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user );
+
+		$m = new BP_Groups_Member( self::$user, self::$groups[1] );
+		$m->ban();
+
+		$expected = array( self::$groups[0] );
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_unban() {
+		$m1 = new BP_Groups_Member( self::$user, self::$groups[1] );
+		$m1->ban();
+
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user );
+
+		$m2 = new BP_Groups_Member( self::$user, self::$groups[1] );
+		$m2->unban();
+
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_invite() {
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		groups_invite_user( array(
+			'user_id' => self::$user,
+			'group_id' => self::$groups[2],
+			'inviter_id' => self::$admin_user,
+		) );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_uninvite() {
+		groups_invite_user( array(
+			'user_id' => self::$user,
+			'group_id' => self::$groups[2],
+			'inviter_id' => self::$admin_user,
+		) );
+
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		groups_uninvite_user( self::$user, self::$groups[2] );
+
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_invite_acceptance() {
+		groups_invite_user( array(
+			'user_id' => self::$user,
+			'group_id' => self::$groups[2],
+			'inviter_id' => self::$admin_user,
+		) );
+
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user );
+
+		groups_accept_invite( self::$user, self::$groups[2] );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_invite_reject() {
+		groups_invite_user( array(
+			'user_id' => self::$user,
+			'group_id' => self::$groups[2],
+			'inviter_id' => self::$admin_user,
+		) );
+
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		groups_reject_invite( self::$user, self::$groups[2] );
+
+		$expected = array( self::$groups[0], self::$groups[1] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_invite_delete() {
+		groups_invite_user( array(
+			'user_id' => self::$user,
+			'group_id' => self::$groups[2],
+			'inviter_id' => self::$admin_user,
+		) );
+
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		groups_delete_invite( self::$user, self::$groups[2] );
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_request() {
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		// For `wp_mail()`.
+		$server_name = isset( $_SERVER['SERVER_NAME'] ) ? $_SERVER['SERVER_NAME'] : null;
+		$_SERVER['SERVER_NAME'] = '';
+
+		groups_send_membership_request( self::$user, self::$groups[2] );
+
+		// For `wp_mail()`.
+		if ( is_null( $server_name ) ) {
+			unset( $_SERVER['SERVER_NAME'] );
+		} else {
+			$_SERVER['SERVER_NAME'] = $server_name;
+		}
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user, array(
+			'is_confirmed' => null,
+		) );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+
+	/**
+	 * @group cache
+	 */
+	public function test_cache_should_be_invalidated_on_group_request_acceptance() {
+		// For `wp_mail()`.
+		$server_name = isset( $_SERVER['SERVER_NAME'] ) ? $_SERVER['SERVER_NAME'] : null;
+		$_SERVER['SERVER_NAME'] = '';
+
+		groups_send_membership_request( self::$user, self::$groups[2] );
+
+		// Populate cache.
+		$g1 = bp_get_user_groups( self::$user );
+
+		$m = new BP_Groups_Member( self::$user, self::$groups[2] );
+
+		groups_accept_membership_request( $m->id, self::$user, self::$groups[2] );
+
+		// For `wp_mail()`.
+		if ( is_null( $server_name ) ) {
+			unset( $_SERVER['SERVER_NAME'] );
+		} else {
+			$_SERVER['SERVER_NAME'] = $server_name;
+		}
+
+		$expected = array( self::$groups[0], self::$groups[1], self::$groups[2] );
+		$found = bp_get_user_groups( self::$user );
+
+		$this->assertEqualSets( $expected, array_keys( $found ) );
+	}
+}
diff --git tests/phpunit/testcases/groups/functions/groupsIsUser.php tests/phpunit/testcases/groups/functions/groupsIsUser.php
index 5a2abc3..b40df66 100644
--- tests/phpunit/testcases/groups/functions/groupsIsUser.php
+++ tests/phpunit/testcases/groups/functions/groupsIsUser.php
@@ -54,7 +54,7 @@ class BP_Tests_Groups_Functions_GroupsIsUser extends BP_UnitTestCase {
 			'is_admin' => true,
 		) );
 
-		$this->assertEquals( true, groups_is_user_admin( self::$user, self::$groups[1] ) );
+		$this->assertNotEmpty( groups_is_user_admin( self::$user, self::$groups[1] ) );
 	}
 
 	public function test_groups_is_user_admin_expected_false() {
@@ -76,7 +76,7 @@ class BP_Tests_Groups_Functions_GroupsIsUser extends BP_UnitTestCase {
 			'is_mod' => true,
 		) );
 
-		$this->assertEquals( true, groups_is_user_mod( self::$user, self::$groups[1] ) );
+		$this->assertNotEmpty( groups_is_user_mod( self::$user, self::$groups[1] ) );
 	}
 
 	public function test_groups_is_user_mod_expected_false() {
@@ -107,7 +107,23 @@ class BP_Tests_Groups_Functions_GroupsIsUser extends BP_UnitTestCase {
 	public function test_groups_is_user_member_expected_true() {
 		$this->add_user_to_group( self::$user, self::$groups[1] );
 
-		$this->assertEquals( true, groups_is_user_member( self::$user, self::$groups[1] ) );
+		$this->assertNotEmpty( groups_is_user_member( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_member_should_return_true_for_admin() {
+		$this->add_user_to_group( self::$user, self::$groups[1], array(
+			'is_admin' => true,
+		) );
+
+		$this->assertNotEmpty( groups_is_user_member( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_member_should_return_true_for_mod() {
+		$this->add_user_to_group( self::$user, self::$groups[1], array(
+			'is_mod' => true,
+		) );
+
+		$this->assertNotEmpty( groups_is_user_member( self::$user, self::$groups[1] ) );
 	}
 
 	public function test_groups_is_user_member_expected_false() {
@@ -143,6 +159,65 @@ class BP_Tests_Groups_Functions_GroupsIsUser extends BP_UnitTestCase {
 		$m = new BP_Groups_Member( self::$user, self::$groups[1] );
 		$m->ban();
 
-		$this->assertEquals( true, groups_is_user_banned( self::$user, self::$groups[1] ) );
+		$this->assertNotEmpty( groups_is_user_banned( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_invited_should_return_false_for_confirmed_member() {
+		$this->add_user_to_group( self::$user, self::$groups[1] );
+		$this->assertEquals( false, groups_is_user_invited( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_invited_should_return_false_for_uninvited_member() {
+		$this->assertEquals( false, groups_is_user_invited( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_invited_should_return_true_for_invited_member() {
+		$i = groups_invite_user( array(
+			'user_id' => self::$user,
+			'group_id' => self::$groups[1],
+			'inviter_id' => 123,
+		) );
+
+		// Send invite.
+		$m = new BP_Groups_Member( self::$user, self::$groups[1] );
+		$m->invite_sent = 1;
+		$m->save();
+
+		$this->assertNotEmpty( groups_is_user_invited( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_pending_should_return_false_for_pending_member() {
+		groups_invite_user( array(
+			'user_id' => self::$user,
+			'group_id' => self::$groups[1],
+			'inviter_id' => 123,
+		) );
+
+		// Send invite.
+		$m = new BP_Groups_Member( self::$user, self::$groups[1] );
+		$m->invite_sent = 1;
+		$m->save();
+
+		$this->assertEquals( false, groups_is_user_pending( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_pending_should_return_false_for_member_with_no_request() {
+		$this->assertEquals( false, groups_is_user_pending( self::$user, self::$groups[1] ) );
+	}
+
+	public function test_groups_is_user_pending_should_return_true_for_pending_member() {
+
+		$m                = new BP_Groups_Member;
+		$m->group_id      = self::$groups[1];
+		$m->user_id       = self::$user;
+		$m->inviter_id    = 0;
+		$m->is_admin      = 0;
+		$m->user_title    = '';
+		$m->date_modified = bp_core_current_time();
+		$m->is_confirmed  = 0;
+		$m->comments      = 'request';
+		$m->save();
+
+		$this->assertNotEmpty( groups_is_user_pending( self::$user, self::$groups[1] ) );
 	}
 }
