blob: 3c5879781d79cebdd14b212df2634cebdc33e43c [file] [log] [blame]
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.acceptance.testsuite.group;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.google.common.truth.Correspondence;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.truth.NullAwareCorrespondence;
import com.google.inject.Inject;
import java.time.Instant;
import java.util.Optional;
import org.junit.Test;
public class GroupOperationsImplTest extends AbstractDaemonTest {
@Inject private AccountOperations accountOperations;
@Inject private GroupOperationsImpl groupOperations;
private int uniqueGroupNameIndex;
@Test
public void groupCanBeCreatedWithoutSpecifyingAnyParameters() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.id).isEqualTo(groupUuid.get());
assertThat(foundGroup.name).isNotEmpty();
}
@Test
public void twoGroupsWithoutAnyParametersDoNotClash() throws Exception {
AccountGroup.UUID groupUuid1 = groupOperations.newGroup().create();
AccountGroup.UUID groupUuid2 = groupOperations.newGroup().create();
TestGroup group1 = groupOperations.group(groupUuid1).get();
TestGroup group2 = groupOperations.group(groupUuid2).get();
assertThat(group1.groupUuid()).isNotEqualTo(group2.groupUuid());
}
@Test
public void groupCreatedByTestApiCanBeRetrievedViaOfficialApi() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().name("unique group created via test API").create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.id).isEqualTo(groupUuid.get());
assertThat(foundGroup.name).isEqualTo("unique group created via test API");
}
@Test
public void specifiedNameIsRespectedForGroupCreation() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().name("XYZ-123-this-name-must-be-unique").create();
GroupInfo group = getGroupFromServer(groupUuid);
assertThat(group.name).isEqualTo("XYZ-123-this-name-must-be-unique");
}
@Test
public void specifiedDescriptionIsRespectedForGroupCreation() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().description("All authenticated users").create();
GroupInfo group = getGroupFromServer(groupUuid);
assertThat(group.description).isEqualTo("All authenticated users");
}
@Test
public void requestingNoDescriptionIsPossibleForGroupCreation() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearDescription().create();
GroupInfo group = getGroupFromServer(groupUuid);
assertThat(group.description).isNull();
}
@Test
public void specifiedOwnerIsRespectedForGroupCreation() throws Exception {
AccountGroup.UUID ownerGroupUuid = groupOperations.newGroup().create();
AccountGroup.UUID groupUuid =
groupOperations.newGroup().ownerGroupUuid(ownerGroupUuid).create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.ownerId).isEqualTo(ownerGroupUuid.get());
}
@Test
public void specifiedVisibilityIsRespectedForGroupCreation() throws Exception {
AccountGroup.UUID group1Uuid = groupOperations.newGroup().visibleToAll(true).create();
AccountGroup.UUID group2Uuid = groupOperations.newGroup().visibleToAll(false).create();
GroupInfo foundGroup1 = getGroupFromServer(group1Uuid);
GroupInfo foundGroup2 = getGroupFromServer(group2Uuid);
assertThat(foundGroup1.options.visibleToAll).isTrue();
// False == null
assertThat(foundGroup2.options.visibleToAll).isNull();
}
@Test
public void specifiedMembersAreRespectedForGroupCreation() throws Exception {
Account.Id account1Id = accountOperations.newAccount().create();
Account.Id account2Id = accountOperations.newAccount().create();
Account.Id account3Id = accountOperations.newAccount().create();
Account.Id account4Id = accountOperations.newAccount().create();
AccountGroup.UUID groupUuid =
groupOperations
.newGroup()
.members(account1Id, account2Id)
.addMember(account3Id)
.addMember(account4Id)
.create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.members)
.comparingElementsUsing(getAccountToIdCorrespondence())
.containsExactly(account1Id, account2Id, account3Id, account4Id);
}
@Test
public void directlyAddingMembersIsPossibleForGroupCreation() throws Exception {
Account.Id account1Id = accountOperations.newAccount().create();
Account.Id account2Id = accountOperations.newAccount().create();
AccountGroup.UUID groupUuid =
groupOperations.newGroup().addMember(account1Id).addMember(account2Id).create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.members)
.comparingElementsUsing(getAccountToIdCorrespondence())
.containsExactly(account1Id, account2Id);
}
@Test
public void requestingNoMembersIsPossibleForGroupCreation() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearMembers().create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.members).isEmpty();
}
@Test
public void specifiedSubgroupsAreRespectedForGroupCreation() throws Exception {
AccountGroup.UUID group1Uuid = groupOperations.newGroup().create();
AccountGroup.UUID group2Uuid = groupOperations.newGroup().create();
AccountGroup.UUID group3Uuid = groupOperations.newGroup().create();
AccountGroup.UUID group4Uuid = groupOperations.newGroup().create();
AccountGroup.UUID groupUuid =
groupOperations
.newGroup()
.subgroups(group1Uuid, group2Uuid)
.addSubgroup(group3Uuid)
.addSubgroup(group4Uuid)
.create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.includes)
.comparingElementsUsing(getGroupToUuidCorrespondence())
.containsExactly(group1Uuid, group2Uuid, group3Uuid, group4Uuid);
}
@Test
public void directlyAddingSubgroupsIsPossibleForGroupCreation() throws Exception {
AccountGroup.UUID group1Uuid = groupOperations.newGroup().create();
AccountGroup.UUID group2Uuid = groupOperations.newGroup().create();
AccountGroup.UUID groupUuid =
groupOperations.newGroup().addSubgroup(group1Uuid).addSubgroup(group2Uuid).create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.includes)
.comparingElementsUsing(getGroupToUuidCorrespondence())
.containsExactly(group1Uuid, group2Uuid);
}
@Test
public void requestingNoSubgroupsIsPossibleForGroupCreation() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearSubgroups().create();
GroupInfo foundGroup = getGroupFromServer(groupUuid);
assertThat(foundGroup.includes).isEmpty();
}
@Test
public void existingGroupCanBeCheckedForExistence() throws Exception {
AccountGroup.UUID groupUuid = createGroupInServer(createArbitraryGroupInput());
boolean exists = groupOperations.group(groupUuid).exists();
assertThat(exists).isTrue();
}
@Test
public void notExistingGroupCanBeCheckedForExistence() throws Exception {
AccountGroup.UUID notExistingGroupUuid = AccountGroup.uuid("not-existing-group");
boolean exists = groupOperations.group(notExistingGroupUuid).exists();
assertThat(exists).isFalse();
}
@Test
public void retrievingNotExistingGroupFails() throws Exception {
AccountGroup.UUID notExistingGroupUuid = AccountGroup.uuid("not-existing-group");
assertThrows(
IllegalStateException.class, () -> groupOperations.group(notExistingGroupUuid).get());
}
@Test
public void groupNotCreatedByTestApiCanBeRetrieved() throws Exception {
GroupInput input = createArbitraryGroupInput();
input.name = "unique group not created via test API";
AccountGroup.UUID groupUuid = createGroupInServer(input);
TestGroup foundGroup = groupOperations.group(groupUuid).get();
assertThat(foundGroup.groupUuid()).isEqualTo(groupUuid);
assertThat(foundGroup.name()).isEqualTo("unique group not created via test API");
}
@Test
public void uuidOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().create();
AccountGroup.UUID foundGroupUuid = groupOperations.group(groupUuid).get().groupUuid();
assertThat(foundGroupUuid).isEqualTo(groupUuid);
}
@Test
public void nameOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().name("ABC-789-this-name-must-be-unique").create();
String groupName = groupOperations.group(groupUuid).get().name();
assertThat(groupName).isEqualTo("ABC-789-this-name-must-be-unique");
}
@Test
public void nameKeyOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().name("ABC-789-this-name-must-be-unique").create();
AccountGroup.NameKey groupName = groupOperations.group(groupUuid).get().nameKey();
assertThat(groupName).isEqualTo(AccountGroup.nameKey("ABC-789-this-name-must-be-unique"));
}
@Test
public void descriptionOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations
.newGroup()
.description("This is a very detailed description of this group.")
.create();
Optional<String> description = groupOperations.group(groupUuid).get().description();
assertThat(description).hasValue("This is a very detailed description of this group.");
}
@Test
public void emptyDescriptionOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearDescription().create();
Optional<String> description = groupOperations.group(groupUuid).get().description();
assertThat(description).isEmpty();
}
@Test
public void ownerGroupUuidOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID originalOwnerGroupUuid = AccountGroup.uuid("owner group");
AccountGroup.UUID groupUuid =
groupOperations.newGroup().ownerGroupUuid(originalOwnerGroupUuid).create();
AccountGroup.UUID ownerGroupUuid = groupOperations.group(groupUuid).get().ownerGroupUuid();
assertThat(ownerGroupUuid).isEqualTo(originalOwnerGroupUuid);
}
@Test
public void visibilityOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID visibleGroupUuid = groupOperations.newGroup().visibleToAll(true).create();
AccountGroup.UUID invisibleGroupUuid = groupOperations.newGroup().visibleToAll(false).create();
TestGroup visibleGroup = groupOperations.group(visibleGroupUuid).get();
TestGroup invisibleGroup = groupOperations.group(invisibleGroupUuid).get();
assertWithMessage("visibility of visible group").that(visibleGroup.visibleToAll()).isTrue();
assertWithMessage("visibility of invisible group")
.that(invisibleGroup.visibleToAll())
.isFalse();
}
@Test
public void createdOnOfExistingGroupCanBeRetrieved() throws Exception {
GroupInfo group = gApi.groups().create(createArbitraryGroupInput()).detail();
AccountGroup.UUID groupUuid = AccountGroup.uuid(group.id);
Instant createdOn = groupOperations.group(groupUuid).get().createdOn();
assertThat(createdOn).isEqualTo(group.createdOn.toInstant());
}
@Test
public void membersOfExistingGroupCanBeRetrieved() throws Exception {
Account.Id memberId1 = Account.id(1000);
Account.Id memberId2 = Account.id(2000);
Account.Id memberId3 = Account.id(3000);
AccountGroup.UUID groupUuid =
groupOperations.newGroup().members(memberId1, memberId2, memberId3).create();
ImmutableSet<Account.Id> members = groupOperations.group(groupUuid).get().members();
assertThat(members).containsExactly(memberId1, memberId2, memberId3);
}
@Test
public void emptyMembersOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearMembers().create();
ImmutableSet<Account.Id> members = groupOperations.group(groupUuid).get().members();
assertThat(members).isEmpty();
}
@Test
public void subgroupsOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID subgroupUuid1 = AccountGroup.uuid("subgroup 1");
AccountGroup.UUID subgroupUuid2 = AccountGroup.uuid("subgroup 2");
AccountGroup.UUID subgroupUuid3 = AccountGroup.uuid("subgroup 3");
AccountGroup.UUID groupUuid =
groupOperations.newGroup().subgroups(subgroupUuid1, subgroupUuid2, subgroupUuid3).create();
ImmutableSet<AccountGroup.UUID> subgroups = groupOperations.group(groupUuid).get().subgroups();
assertThat(subgroups).containsExactly(subgroupUuid1, subgroupUuid2, subgroupUuid3);
}
@Test
public void emptySubgroupsOfExistingGroupCanBeRetrieved() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearSubgroups().create();
ImmutableSet<AccountGroup.UUID> subgroups = groupOperations.group(groupUuid).get().subgroups();
assertThat(subgroups).isEmpty();
}
@Test
public void updateWithoutAnyParametersIsANoop() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().create();
TestGroup originalGroup = groupOperations.group(groupUuid).get();
groupOperations.group(groupUuid).forUpdate().update();
TestGroup updatedGroup = groupOperations.group(groupUuid).get();
assertThat(updatedGroup).isEqualTo(originalGroup);
}
@Test
public void updateWritesToInternalGroupSystem() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().description("original description").create();
groupOperations.group(groupUuid).forUpdate().description("updated description").update();
String currentDescription = getGroupFromServer(groupUuid).description;
assertThat(currentDescription).isEqualTo("updated description");
}
@Test
public void nameCanBeUpdated() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().name("original name").create();
groupOperations.group(groupUuid).forUpdate().name("updated name").update();
String currentName = groupOperations.group(groupUuid).get().name();
assertThat(currentName).isEqualTo("updated name");
}
@Test
public void descriptionCanBeUpdated() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().description("original description").create();
groupOperations.group(groupUuid).forUpdate().description("updated description").update();
Optional<String> currentDescription = groupOperations.group(groupUuid).get().description();
assertThat(currentDescription).hasValue("updated description");
}
@Test
public void descriptionCanBeCleared() throws Exception {
AccountGroup.UUID groupUuid =
groupOperations.newGroup().description("original description").create();
groupOperations.group(groupUuid).forUpdate().clearDescription().update();
Optional<String> currentDescription = groupOperations.group(groupUuid).get().description();
assertThat(currentDescription).isEmpty();
}
@Test
public void ownerGroupUuidCanBeUpdated() throws Exception {
AccountGroup.UUID originalOwnerGroupUuid = AccountGroup.uuid("original owner");
AccountGroup.UUID groupUuid =
groupOperations.newGroup().ownerGroupUuid(originalOwnerGroupUuid).create();
AccountGroup.UUID updatedOwnerGroupUuid = AccountGroup.uuid("updated owner");
groupOperations.group(groupUuid).forUpdate().ownerGroupUuid(updatedOwnerGroupUuid).update();
AccountGroup.UUID currentOwnerGroupUuid =
groupOperations.group(groupUuid).get().ownerGroupUuid();
assertThat(currentOwnerGroupUuid).isEqualTo(updatedOwnerGroupUuid);
}
@Test
public void visibilityCanBeUpdated() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().visibleToAll(true).create();
groupOperations.group(groupUuid).forUpdate().visibleToAll(false).update();
boolean visibleToAll = groupOperations.group(groupUuid).get().visibleToAll();
assertThat(visibleToAll).isFalse();
}
@Test
public void membersCanBeAdded() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearMembers().create();
Account.Id memberId1 = Account.id(1000);
Account.Id memberId2 = Account.id(2000);
groupOperations.group(groupUuid).forUpdate().addMember(memberId1).addMember(memberId2).update();
ImmutableSet<Account.Id> members = groupOperations.group(groupUuid).get().members();
assertThat(members).containsExactly(memberId1, memberId2);
}
@Test
public void membersCanBeRemoved() throws Exception {
Account.Id memberId1 = Account.id(1000);
Account.Id memberId2 = Account.id(2000);
AccountGroup.UUID groupUuid = groupOperations.newGroup().members(memberId1, memberId2).create();
groupOperations.group(groupUuid).forUpdate().removeMember(memberId2).update();
ImmutableSet<Account.Id> members = groupOperations.group(groupUuid).get().members();
assertThat(members).containsExactly(memberId1);
}
@Test
public void memberAdditionAndRemovalCanBeMixed() throws Exception {
Account.Id memberId1 = Account.id(1000);
Account.Id memberId2 = Account.id(2000);
AccountGroup.UUID groupUuid = groupOperations.newGroup().members(memberId1, memberId2).create();
Account.Id memberId3 = Account.id(3000);
groupOperations
.group(groupUuid)
.forUpdate()
.removeMember(memberId1)
.addMember(memberId3)
.update();
ImmutableSet<Account.Id> members = groupOperations.group(groupUuid).get().members();
assertThat(members).containsExactly(memberId2, memberId3);
}
@Test
public void membersCanBeCleared() throws Exception {
Account.Id memberId1 = Account.id(1000);
Account.Id memberId2 = Account.id(2000);
AccountGroup.UUID groupUuid = groupOperations.newGroup().members(memberId1, memberId2).create();
groupOperations.group(groupUuid).forUpdate().clearMembers().update();
ImmutableSet<Account.Id> members = groupOperations.group(groupUuid).get().members();
assertThat(members).isEmpty();
}
@Test
public void furtherMembersCanBeAddedAfterClearingAll() throws Exception {
Account.Id memberId1 = Account.id(1000);
Account.Id memberId2 = Account.id(2000);
AccountGroup.UUID groupUuid = groupOperations.newGroup().members(memberId1, memberId2).create();
Account.Id memberId3 = Account.id(3000);
groupOperations.group(groupUuid).forUpdate().clearMembers().addMember(memberId3).update();
ImmutableSet<Account.Id> members = groupOperations.group(groupUuid).get().members();
assertThat(members).containsExactly(memberId3);
}
@Test
public void subgroupsCanBeAdded() throws Exception {
AccountGroup.UUID groupUuid = groupOperations.newGroup().clearSubgroups().create();
AccountGroup.UUID subgroupUuid1 = AccountGroup.uuid("subgroup 1");
AccountGroup.UUID subgroupUuid2 = AccountGroup.uuid("subgroup 2");
groupOperations
.group(groupUuid)
.forUpdate()
.addSubgroup(subgroupUuid1)
.addSubgroup(subgroupUuid2)
.update();
ImmutableSet<AccountGroup.UUID> subgroups = groupOperations.group(groupUuid).get().subgroups();
assertThat(subgroups).containsExactly(subgroupUuid1, subgroupUuid2);
}
@Test
public void subgroupsCanBeRemoved() throws Exception {
AccountGroup.UUID subgroupUuid1 = AccountGroup.uuid("subgroup 1");
AccountGroup.UUID subgroupUuid2 = AccountGroup.uuid("subgroup 2");
AccountGroup.UUID groupUuid =
groupOperations.newGroup().subgroups(subgroupUuid1, subgroupUuid2).create();
groupOperations.group(groupUuid).forUpdate().removeSubgroup(subgroupUuid2).update();
ImmutableSet<AccountGroup.UUID> subgroups = groupOperations.group(groupUuid).get().subgroups();
assertThat(subgroups).containsExactly(subgroupUuid1);
}
@Test
public void subgroupAdditionAndRemovalCanBeMixed() throws Exception {
AccountGroup.UUID subgroupUuid1 = AccountGroup.uuid("subgroup 1");
AccountGroup.UUID subgroupUuid2 = AccountGroup.uuid("subgroup 2");
AccountGroup.UUID groupUuid =
groupOperations.newGroup().subgroups(subgroupUuid1, subgroupUuid2).create();
AccountGroup.UUID subgroupUuid3 = AccountGroup.uuid("subgroup 3");
groupOperations
.group(groupUuid)
.forUpdate()
.removeSubgroup(subgroupUuid1)
.addSubgroup(subgroupUuid3)
.update();
ImmutableSet<AccountGroup.UUID> subgroups = groupOperations.group(groupUuid).get().subgroups();
assertThat(subgroups).containsExactly(subgroupUuid2, subgroupUuid3);
}
@Test
public void subgroupsCanBeCleared() throws Exception {
AccountGroup.UUID subgroupUuid1 = AccountGroup.uuid("subgroup 1");
AccountGroup.UUID subgroupUuid2 = AccountGroup.uuid("subgroup 2");
AccountGroup.UUID groupUuid =
groupOperations.newGroup().subgroups(subgroupUuid1, subgroupUuid2).create();
groupOperations.group(groupUuid).forUpdate().clearSubgroups().update();
ImmutableSet<AccountGroup.UUID> subgroups = groupOperations.group(groupUuid).get().subgroups();
assertThat(subgroups).isEmpty();
}
@Test
public void furtherSubgroupsCanBeAddedAfterClearingAll() throws Exception {
AccountGroup.UUID subgroupUuid1 = AccountGroup.uuid("subgroup 1");
AccountGroup.UUID subgroupUuid2 = AccountGroup.uuid("subgroup 2");
AccountGroup.UUID groupUuid =
groupOperations.newGroup().subgroups(subgroupUuid1, subgroupUuid2).create();
AccountGroup.UUID subgroupUuid3 = AccountGroup.uuid("subgroup 3");
groupOperations
.group(groupUuid)
.forUpdate()
.clearSubgroups()
.addSubgroup(subgroupUuid3)
.update();
ImmutableSet<AccountGroup.UUID> subgroups = groupOperations.group(groupUuid).get().subgroups();
assertThat(subgroups).containsExactly(subgroupUuid3);
}
private GroupInput createArbitraryGroupInput() {
GroupInput groupInput = new GroupInput();
groupInput.name = name("verifiers-" + uniqueGroupNameIndex++);
return groupInput;
}
private GroupInfo getGroupFromServer(AccountGroup.UUID groupUuid) throws RestApiException {
return gApi.groups().id(groupUuid.get()).detail();
}
private AccountGroup.UUID createGroupInServer(GroupInput input) throws RestApiException {
GroupInfo group = gApi.groups().create(input).detail();
return AccountGroup.uuid(group.id);
}
private static Correspondence<AccountInfo, Account.Id> getAccountToIdCorrespondence() {
return NullAwareCorrespondence.transforming(
account -> Account.id(account._accountId), "has ID");
}
private static Correspondence<GroupInfo, AccountGroup.UUID> getGroupToUuidCorrespondence() {
return NullAwareCorrespondence.transforming(group -> AccountGroup.uuid(group.id), "has UUID");
}
}