### Question:
IdentityGroup extends IdentityPrincipal<IdentityGroup> { ListenableFuture<Boolean> removeMember(EntityKey memberKey, IdentityService identityService) throws IOException { Membership existing = members.get(memberKey); if (existing == null) { return Futures.immediateFuture(true); } String groupId = groupResourceName.get(); String memberId = existing.getName(); ListenableFuture<Operation> created = identityService.deleteMembership(memberId); return Futures.transform( created, new Function<Operation, Boolean>() { @Override @Nullable public Boolean apply(@Nullable Operation input) { try { validateOperation(input); removeMember(memberKey); return true; } catch (IOException e) { logger.log( Level.WARNING, String.format("Failed to delete membership %s under group %s", existing, groupId), e); return false; } } }, getExecutor()); } IdentityGroup(Builder buider); ImmutableSet<Membership> getMembers(); EntityKey getGroupKey(); @Override Kind getKind(); @Override ListenableFuture<Boolean> unmap(IdentityService service); @Override ListenableFuture<IdentityGroup> sync(
      IdentityGroup previouslySynced, IdentityService service); @Override int hashCode(); @Override boolean equals(Object obj); static final ImmutableMap<String, String> GROUP_LABELS; }### Answer:
@Test public void testRemoveMember() throws IOException, InterruptedException, ExecutionException { Membership member = new Membership() .setName("groups/id1/memberships/existing") .setPreferredMemberKey(new EntityKey().setId("existing@domain.com")); EntityKey memberKeyToRemove = new EntityKey().setId("removed@domain.com"); Membership removed = new Membership() .setName("groups/id1/memberships/removed") .setPreferredMemberKey(memberKeyToRemove); IdentityGroup identityGroup = new IdentityGroup.Builder() .setGroupIdentity("domain\\group1") .setGroupKey(GROUP_KEY) .setGroupResourceName("groups/id1") .setMembers(ImmutableSet.of(member, removed)) .build(); IdentityGroup expected = new IdentityGroup.Builder() .setGroupIdentity("domain\\group1") .setGroupKey(GROUP_KEY) .setGroupResourceName("groups/id1") .setMembers(ImmutableSet.of(member)) .build(); when(mockIdentityService.deleteMembership("groups/id1/memberships/removed")) .thenReturn(Futures.immediateFuture(new Operation().setDone(true))); ListenableFuture<Boolean> removeMember = identityGroup.removeMember( memberKeyToRemove, mockIdentityService); assertTrue(removeMember.get()); assertEquals(expected, identityGroup); }
@Test public void testRemoveNonExistingMember() throws IOException, InterruptedException, ExecutionException { Membership member = new Membership() .setName("groups/id1/memberships/existing") .setPreferredMemberKey(new EntityKey().setId("existing@domain.com")); IdentityGroup identityGroup = new IdentityGroup.Builder() .setGroupIdentity("domain\\group1") .setGroupKey(GROUP_KEY) .setGroupResourceName("groups/id1") .setMembers(ImmutableSet.of(member)) .build(); EntityKey removed = new EntityKey().setId("nonexisting@domain.com"); IdentityGroup expected = new IdentityGroup.Builder() .setGroupIdentity("domain\\group1") .setGroupKey(GROUP_KEY) .setGroupResourceName("groups/id1") .setMembers(ImmutableSet.of(member)) .build(); ListenableFuture<Boolean> removeMember = identityGroup.removeMember(removed, mockIdentityService); assertTrue(removeMember.get()); assertEquals(expected, identityGroup); verifyZeroInteractions(mockIdentityService); }