### Question:
IdentityGroup extends IdentityPrincipal<IdentityGroup> { ListenableFuture<Membership> addMember(Membership m, IdentityService identityService) throws IOException { Membership existing = members.get(m.getPreferredMemberKey()); if (existing != null) { return Futures.immediateFuture(existing); } String groupId = groupResourceName.get(); ListenableFuture<Operation> created = identityService.createMembership(groupId, m); return Futures.transformAsync( created, new AsyncFunction<Operation, Membership>() { @Override @Nullable public ListenableFuture<Membership> apply(@Nullable Operation input) { try { Membership memberCreated = m.setName(extractResourceName(input)); addMember(memberCreated); logger.log(Level.FINE, "Successfully created membership {0}", memberCreated); return Futures.immediateFuture(memberCreated); } catch (IOException e) { logger.log( Level.WARNING, String.format("Failed to create membership %s under group %s", m, groupId), e); return Futures.immediateFailedFuture(e); } } }, 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 testAddMember() 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(); Membership added = new Membership().setPreferredMemberKey(new EntityKey().setId("user@domain.com")); Membership memberToReturn = new Membership() .setPreferredMemberKey(new EntityKey().setId("user@domain.com")) .setName("groups/id1/memberships/added"); IdentityGroup expected = new IdentityGroup.Builder() .setGroupIdentity("domain\\group1") .setGroupKey(GROUP_KEY) .setGroupResourceName("groups/id1") .setMembers(ImmutableSet.of(member, memberToReturn)) .build(); when(mockIdentityService.createMembership("groups/id1", added)) .thenReturn( Futures.immediateFuture(new Operation().setDone(true).setResponse(memberToReturn))); ListenableFuture<Membership> addMember = identityGroup.addMember(added, mockIdentityService); assertEquals(memberToReturn, addMember.get()); assertEquals(expected, identityGroup); }
@Test public void testAddExistingMember() 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(); Membership added = new Membership().setPreferredMemberKey(new EntityKey().setId("existing@domain.com")); IdentityGroup expected = new IdentityGroup.Builder() .setGroupIdentity("domain\\group1") .setGroupKey(GROUP_KEY) .setGroupResourceName("groups/id1") .setMembers(ImmutableSet.of(member)) .build(); ListenableFuture<Membership> addMember = identityGroup.addMember(added, mockIdentityService); assertEquals(member, addMember.get()); assertEquals(expected, identityGroup); verifyZeroInteractions(mockIdentityService); }