| // Copyright (C) 2017 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.server.group.db; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| import static com.google.gerrit.server.group.testing.InternalGroupSubject.internalGroups; |
| import static com.google.gerrit.testing.GerritJUnit.assertThrows; |
| import static com.google.gerrit.truth.OptionalSubject.assertThat; |
| |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Sets; |
| import com.google.gerrit.common.Nullable; |
| import com.google.gerrit.entities.Account; |
| import com.google.gerrit.entities.AccountGroup; |
| import com.google.gerrit.entities.GroupDescription; |
| import com.google.gerrit.entities.InternalGroup; |
| import com.google.gerrit.entities.Project; |
| import com.google.gerrit.entities.RefNames; |
| import com.google.gerrit.server.extensions.events.GitReferenceUpdated; |
| import com.google.gerrit.server.git.meta.MetaDataUpdate; |
| import com.google.gerrit.server.group.testing.InternalGroupSubject; |
| import com.google.gerrit.server.util.time.TimeUtil; |
| import com.google.gerrit.truth.OptionalSubject; |
| import java.io.IOException; |
| import java.time.Instant; |
| import java.time.LocalDate; |
| import java.time.LocalDateTime; |
| import java.time.Month; |
| import java.time.ZoneId; |
| import java.util.Optional; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; |
| import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; |
| import org.eclipse.jgit.junit.TestRepository; |
| import org.eclipse.jgit.lib.PersonIdent; |
| import org.eclipse.jgit.lib.Ref; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.revwalk.RevCommit; |
| import org.eclipse.jgit.revwalk.RevWalk; |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| public class GroupConfigTest { |
| private Project.NameKey projectName; |
| private Repository repository; |
| private TestRepository<?> testRepository; |
| private final AccountGroup.UUID groupUuid = AccountGroup.uuid("users-XYZ"); |
| private final AccountGroup.NameKey groupName = AccountGroup.nameKey("users"); |
| private final AccountGroup.Id groupId = AccountGroup.id(123); |
| private final AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(ImmutableSet.of(), ImmutableSet.of(), "server-id"); |
| private final ZoneId zoneId = ZoneId.of("America/Los_Angeles"); |
| |
| @Before |
| public void setUp() throws Exception { |
| projectName = Project.nameKey("Test Repository"); |
| repository = new InMemoryRepository(new DfsRepositoryDescription("Test Repository")); |
| testRepository = new TestRepository<>(repository); |
| } |
| |
| @Test |
| public void specifiedGroupUuidIsRespectedForNewGroup() throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).build(); |
| createGroup(groupCreation); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().groupUuid().isEqualTo(groupUuid); |
| } |
| |
| @Test |
| public void specifiedNameIsRespectedForNewGroup() throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setNameKey(groupName).build(); |
| createGroup(groupCreation); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().nameKey().isEqualTo(groupName); |
| } |
| |
| @Test |
| public void nameOfGroupUpdateOverridesGroupCreation() throws Exception { |
| AccountGroup.NameKey anotherName = AccountGroup.nameKey("Another name"); |
| |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setNameKey(groupName).build(); |
| GroupDelta groupDelta = GroupDelta.builder().setName(anotherName).build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().nameKey().isEqualTo(anotherName); |
| } |
| |
| @Test |
| public void nameOfNewGroupMustNotBeEmpty() throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setNameKey(AccountGroup.nameKey("")).build(); |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| IOException thrown = |
| assertThrows(IOException.class, () -> groupConfig.commit(metaDataUpdate)); |
| assertThat(thrown.getCause()).isInstanceOf(ConfigInvalidException.class); |
| assertThat(thrown).hasMessageThat().contains("Name of the group " + groupUuid); |
| } |
| } |
| |
| @Test |
| public void specifiedIdIsRespectedForNewGroup() throws Exception { |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().setId(groupId).build(); |
| createGroup(groupCreation); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().id().isEqualTo(groupId); |
| } |
| |
| @Test |
| public void idOfNewGroupMustNotBeNegative() throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setId(AccountGroup.id(-2)).build(); |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| IOException thrown = |
| assertThrows(IOException.class, () -> groupConfig.commit(metaDataUpdate)); |
| assertThat(thrown.getCause()).isInstanceOf(ConfigInvalidException.class); |
| assertThat(thrown).hasMessageThat().contains("ID of the group " + groupUuid); |
| } |
| } |
| |
| @Test |
| public void descriptionDefaultsToNull() throws Exception { |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| createGroup(groupCreation); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().description().isNull(); |
| } |
| |
| @Test |
| public void specifiedDescriptionIsRespectedForNewGroup() throws Exception { |
| String description = "This is a test group."; |
| |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = GroupDelta.builder().setDescription(description).build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().description().isEqualTo(description); |
| } |
| |
| @Test |
| public void emptyDescriptionForNewGroupIsIgnored() throws Exception { |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = GroupDelta.builder().setDescription("").build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().description().isNull(); |
| } |
| |
| @Test |
| public void ownerGroupUuidDefaultsToGroupItself() throws Exception { |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| createGroup(groupCreation); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().ownerGroupUuid().isEqualTo(groupUuid); |
| } |
| |
| @Test |
| public void specifiedOwnerGroupUuidIsRespectedForNewGroup() throws Exception { |
| AccountGroup.UUID ownerGroupUuid = AccountGroup.uuid("anotherOwnerUuid"); |
| |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = GroupDelta.builder().setOwnerGroupUUID(ownerGroupUuid).build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().ownerGroupUuid().isEqualTo(ownerGroupUuid); |
| } |
| |
| @Test |
| public void ownerGroupUuidOfNewGroupMustNotBeEmpty() throws Exception { |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = GroupDelta.builder().setOwnerGroupUUID(AccountGroup.uuid("")).build(); |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| IOException thrown = |
| assertThrows(IOException.class, () -> groupConfig.commit(metaDataUpdate)); |
| assertThat(thrown.getCause()).isInstanceOf(ConfigInvalidException.class); |
| assertThat(thrown).hasMessageThat().contains("Owner UUID of the group " + groupUuid); |
| } |
| } |
| |
| @Test |
| public void visibleToAllDefaultsToFalse() throws Exception { |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| createGroup(groupCreation); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().visibleToAll().isFalse(); |
| } |
| |
| @Test |
| public void specifiedVisibleToAllIsRespectedForNewGroup() throws Exception { |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = GroupDelta.builder().setVisibleToAll(true).build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().visibleToAll().isTrue(); |
| } |
| |
| @Test |
| public void createdOnDefaultsToNow() throws Exception { |
| // Git timestamps are only precise to the second. |
| Instant testStart = TimeUtil.truncateToSecond(TimeUtil.now()); |
| |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| createGroup(groupCreation); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().createdOn().isAtLeast(testStart); |
| } |
| |
| @Test |
| public void specifiedCreatedOnIsRespectedForNewGroup() throws Exception { |
| Instant createdOn = toInstant(LocalDate.of(2017, Month.DECEMBER, 11).atTime(13, 44, 10)); |
| |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = GroupDelta.builder().setUpdatedOn(createdOn).build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().createdOn().isEqualTo(createdOn); |
| } |
| |
| @Test |
| public void specifiedMembersAreRespectedForNewGroup() throws Exception { |
| Account.Id member1 = Account.id(1); |
| Account.Id member2 = Account.id(2); |
| |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setMemberModification(members -> ImmutableSet.of(member1, member2)) |
| .build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().members().containsExactly(member1, member2); |
| } |
| |
| @Test |
| public void specifiedSubgroupsAreRespectedForNewGroup() throws Exception { |
| AccountGroup.UUID subgroup1 = AccountGroup.uuid("subgroup1"); |
| AccountGroup.UUID subgroup2 = AccountGroup.uuid("subgroup2"); |
| |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setSubgroupModification(subgroups -> ImmutableSet.of(subgroup1, subgroup2)) |
| .build(); |
| createGroup(groupCreation, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupCreation.getGroupUUID()); |
| assertThatGroup(group).value().subgroups().containsExactly(subgroup1, subgroup2); |
| } |
| |
| @Test |
| public void nameInConfigMayBeUndefined() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tid = 42\n\townerGroupUuid = owners\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().name().isEmpty(); |
| } |
| |
| @Test |
| public void nameInConfigMayBeEmpty() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=\n\tid = 42\n\townerGroupUuid = owners\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().name().isEmpty(); |
| } |
| |
| @Test |
| public void idInConfigMustBeDefined() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname = users\n\townerGroupUuid = owners\n"); |
| |
| ConfigInvalidException thrown = |
| assertThrows( |
| ConfigInvalidException.class, |
| () -> GroupConfig.loadForGroup(projectName, repository, groupUuid)); |
| assertThat(thrown).hasMessageThat().contains("ID of the group " + groupUuid); |
| } |
| |
| @Test |
| public void idInConfigMustNotBeNegative() throws Exception { |
| populateGroupConfig( |
| groupUuid, "[group]\n\tname = users\n\tid = -5\n\townerGroupUuid = owners\n"); |
| |
| ConfigInvalidException thrown = |
| assertThrows( |
| ConfigInvalidException.class, |
| () -> GroupConfig.loadForGroup(projectName, repository, groupUuid)); |
| assertThat(thrown).hasMessageThat().contains("ID of the group " + groupUuid); |
| } |
| |
| @Test |
| public void descriptionInConfigMayBeUndefined() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tid = 42\n\townerGroupUuid = owners\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().description().isNull(); |
| } |
| |
| @Test |
| public void descriptionInConfigMayBeEmpty() throws Exception { |
| populateGroupConfig( |
| groupUuid, "[group]\n\tdescription=\n\tid = 42\n\townerGroupUuid = owners\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().description().isNull(); |
| } |
| |
| @Test |
| public void ownerGroupUuidInConfigMustBeDefined() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname = users\n\tid = 42\n"); |
| |
| ConfigInvalidException thrown = |
| assertThrows( |
| ConfigInvalidException.class, |
| () -> GroupConfig.loadForGroup(projectName, repository, groupUuid)); |
| assertThat(thrown).hasMessageThat().contains("Owner UUID of the group " + groupUuid); |
| } |
| |
| @Test |
| public void membersFileNeedNotExist() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().members().isEmpty(); |
| } |
| |
| @Test |
| public void membersFileMayBeEmpty() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateSubgroupsFile(groupUuid, ""); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().members().isEmpty(); |
| } |
| |
| @Test |
| public void membersFileMayContainOnlyWhitespace() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateMembersFile(groupUuid, "\n\t\n\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().members().isEmpty(); |
| } |
| |
| @Test |
| public void membersFileMayUseAnyLineBreakCharacters() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateMembersFile(groupUuid, "1\n2\n3\r4\r\n5\u20296"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group) |
| .value() |
| .members() |
| .containsExactly( |
| Account.id(1), |
| Account.id(2), |
| Account.id(3), |
| Account.id(4), |
| Account.id(5), |
| Account.id(6)); |
| } |
| |
| @Test |
| public void membersFileMustContainIntegers() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateMembersFile(groupUuid, "One"); |
| |
| ConfigInvalidException thrown = |
| assertThrows(ConfigInvalidException.class, () -> loadGroup(groupUuid)); |
| assertThat(thrown).hasMessageThat().contains("Invalid file members"); |
| } |
| |
| @Test |
| public void membersFileUsesLineBreaksToSeparateMembers() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateMembersFile(groupUuid, "1\t2"); |
| |
| ConfigInvalidException thrown = |
| assertThrows(ConfigInvalidException.class, () -> loadGroup(groupUuid)); |
| assertThat(thrown).hasMessageThat().contains("Invalid file members"); |
| } |
| |
| @Test |
| public void subgroupsFileNeedNotExist() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().subgroups().isEmpty(); |
| } |
| |
| @Test |
| public void subgroupsFileMayBeEmpty() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateMembersFile(groupUuid, ""); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().subgroups().isEmpty(); |
| } |
| |
| @Test |
| public void subgroupsFileMayContainOnlyWhitespace() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateSubgroupsFile(groupUuid, "\n\t\n\n"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().subgroups().isEmpty(); |
| } |
| |
| @Test |
| public void subgroupsFileMayUseAnyLineBreakCharacters() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateSubgroupsFile(groupUuid, "1\n2\n3\r4\r\n5\u20296"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group) |
| .value() |
| .subgroups() |
| .containsExactly( |
| AccountGroup.uuid("1"), |
| AccountGroup.uuid("2"), |
| AccountGroup.uuid("3"), |
| AccountGroup.uuid("4"), |
| AccountGroup.uuid("5"), |
| AccountGroup.uuid("6")); |
| } |
| |
| @Test |
| public void subgroupsFileMayContainSubgroupsWithWhitespaceInUuid() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateSubgroupsFile(groupUuid, "1\t2 3"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().subgroups().containsExactly(AccountGroup.uuid("1\t2 3")); |
| } |
| |
| @Test |
| public void subgroupsFileUsesLineBreaksToSeparateSubgroups() throws Exception { |
| populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n"); |
| populateSubgroupsFile(groupUuid, "1\t2\n3"); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group) |
| .value() |
| .subgroups() |
| .containsExactly(AccountGroup.uuid("1\t2"), AccountGroup.uuid("3")); |
| } |
| |
| @Test |
| public void nameCanBeUpdated() throws Exception { |
| createArbitraryGroup(groupUuid); |
| AccountGroup.NameKey newName = AccountGroup.nameKey("New name"); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setName(newName).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().nameKey().isEqualTo(newName); |
| } |
| |
| @Test |
| public void nameCannotBeUpdatedToEmptyString() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid); |
| GroupDelta groupDelta = GroupDelta.builder().setName(AccountGroup.nameKey("")).build(); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| IOException thrown = |
| assertThrows(IOException.class, () -> groupConfig.commit(metaDataUpdate)); |
| assertThat(thrown.getCause()).isInstanceOf(ConfigInvalidException.class); |
| assertThat(thrown).hasMessageThat().contains("Name of the group " + groupUuid); |
| } |
| } |
| |
| @Test |
| public void nameCanBeUpdatedToEmptyStringIfExplicitlySpecified() throws Exception { |
| createArbitraryGroup(groupUuid); |
| AccountGroup.NameKey emptyName = AccountGroup.nameKey(""); |
| |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid); |
| groupConfig.setAllowSaveEmptyName(); |
| GroupDelta groupDelta = GroupDelta.builder().setName(emptyName).build(); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| commit(groupConfig); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().nameKey().isEqualTo(emptyName); |
| } |
| |
| @Test |
| public void descriptionCanBeUpdated() throws Exception { |
| createArbitraryGroup(groupUuid); |
| String newDescription = "New description"; |
| |
| GroupDelta groupDelta = GroupDelta.builder().setDescription(newDescription).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().description().isEqualTo(newDescription); |
| } |
| |
| @Test |
| public void descriptionCanBeRemoved() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setDescription("").build(); |
| Optional<InternalGroup> group = updateGroup(groupUuid, groupDelta); |
| |
| assertThatGroup(group).value().description().isNull(); |
| } |
| |
| @Test |
| public void ownerGroupUuidCanBeUpdated() throws Exception { |
| createArbitraryGroup(groupUuid); |
| AccountGroup.UUID newOwnerGroupUuid = AccountGroup.uuid("New owner"); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setOwnerGroupUUID(newOwnerGroupUuid).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().ownerGroupUuid().isEqualTo(newOwnerGroupUuid); |
| } |
| |
| @Test |
| public void ownerGroupUuidCannotBeUpdatedToEmptyString() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid); |
| GroupDelta groupDelta = GroupDelta.builder().setOwnerGroupUUID(AccountGroup.uuid("")).build(); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| IOException thrown = |
| assertThrows(IOException.class, () -> groupConfig.commit(metaDataUpdate)); |
| assertThat(thrown.getCause()).isInstanceOf(ConfigInvalidException.class); |
| assertThat(thrown).hasMessageThat().contains("Owner UUID of the group " + groupUuid); |
| } |
| } |
| |
| @Test |
| public void visibleToAllCanBeUpdated() throws Exception { |
| createArbitraryGroup(groupUuid); |
| boolean oldVisibleAll = loadGroup(groupUuid).map(InternalGroup::isVisibleToAll).orElse(false); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setVisibleToAll(!oldVisibleAll).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().visibleToAll().isEqualTo(!oldVisibleAll); |
| } |
| |
| @Test |
| public void createdOnIsNotAffectedByFurtherUpdates() throws Exception { |
| Instant createdOn = toInstant(LocalDate.of(2017, Month.MAY, 11).atTime(13, 44, 10)); |
| Instant updatedOn = toInstant(LocalDate.of(2017, Month.DECEMBER, 12).atTime(10, 21, 49)); |
| |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta initialGroupDelta = GroupDelta.builder().setUpdatedOn(createdOn).build(); |
| createGroup(groupCreation, initialGroupDelta); |
| |
| GroupDelta laterGroupDelta = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(updatedOn) |
| .build(); |
| Optional<InternalGroup> group = updateGroup(groupCreation.getGroupUUID(), laterGroupDelta); |
| |
| assertThatGroup(group).value().createdOn().isEqualTo(createdOn); |
| Optional<InternalGroup> reloadedGroup = loadGroup(groupUuid); |
| assertThatGroup(reloadedGroup).value().createdOn().isEqualTo(createdOn); |
| } |
| |
| @Test |
| public void membersCanBeAdded() throws Exception { |
| createArbitraryGroup(groupUuid); |
| Account.Id member1 = Account.id(1); |
| Account.Id member2 = Account.id(2); |
| |
| GroupDelta groupDelta1 = |
| GroupDelta.builder().setMemberModification(members -> ImmutableSet.of(member1)).build(); |
| updateGroup(groupUuid, groupDelta1); |
| |
| GroupDelta groupDelta2 = |
| GroupDelta.builder() |
| .setMemberModification(members -> Sets.union(members, ImmutableSet.of(member2))) |
| .build(); |
| updateGroup(groupUuid, groupDelta2); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().members().containsExactly(member1, member2); |
| } |
| |
| @Test |
| public void membersCanBeDeleted() throws Exception { |
| createArbitraryGroup(groupUuid); |
| Account.Id member1 = Account.id(1); |
| Account.Id member2 = Account.id(2); |
| |
| GroupDelta groupDelta1 = |
| GroupDelta.builder() |
| .setMemberModification(members -> ImmutableSet.of(member1, member2)) |
| .build(); |
| updateGroup(groupUuid, groupDelta1); |
| |
| GroupDelta groupDelta2 = |
| GroupDelta.builder() |
| .setMemberModification(members -> Sets.difference(members, ImmutableSet.of(member1))) |
| .build(); |
| updateGroup(groupUuid, groupDelta2); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().members().containsExactly(member2); |
| } |
| |
| @Test |
| public void subgroupsCanBeAdded() throws Exception { |
| createArbitraryGroup(groupUuid); |
| AccountGroup.UUID subgroup1 = AccountGroup.uuid("subgroups1"); |
| AccountGroup.UUID subgroup2 = AccountGroup.uuid("subgroups2"); |
| |
| GroupDelta groupDelta1 = |
| GroupDelta.builder() |
| .setSubgroupModification(subgroups -> ImmutableSet.of(subgroup1)) |
| .build(); |
| updateGroup(groupUuid, groupDelta1); |
| |
| GroupDelta groupDelta2 = |
| GroupDelta.builder() |
| .setSubgroupModification(subgroups -> Sets.union(subgroups, ImmutableSet.of(subgroup2))) |
| .build(); |
| updateGroup(groupUuid, groupDelta2); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().subgroups().containsExactly(subgroup1, subgroup2); |
| } |
| |
| @Test |
| public void subgroupsCanBeDeleted() throws Exception { |
| createArbitraryGroup(groupUuid); |
| AccountGroup.UUID subgroup1 = AccountGroup.uuid("subgroups1"); |
| AccountGroup.UUID subgroup2 = AccountGroup.uuid("subgroups2"); |
| |
| GroupDelta groupDelta1 = |
| GroupDelta.builder() |
| .setSubgroupModification(members -> ImmutableSet.of(subgroup1, subgroup2)) |
| .build(); |
| updateGroup(groupUuid, groupDelta1); |
| |
| GroupDelta groupDelta2 = |
| GroupDelta.builder() |
| .setSubgroupModification( |
| members -> Sets.difference(members, ImmutableSet.of(subgroup1))) |
| .build(); |
| updateGroup(groupUuid, groupDelta2); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().subgroups().containsExactly(subgroup2); |
| } |
| |
| @Test |
| public void createdGroupIsLoadedAutomatically() throws Exception { |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| Optional<InternalGroup> group = createGroup(groupCreation); |
| |
| assertThat(group).isPresent(); |
| } |
| |
| @Test |
| public void loadedNewGroupWithMandatoryPropertiesDoesNotChangeOnReload() throws Exception { |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| |
| Optional<InternalGroup> createdGroup = createGroup(groupCreation); |
| Optional<InternalGroup> reloadedGroup = loadGroup(groupCreation.getGroupUUID()); |
| |
| assertThat(createdGroup).isEqualTo(reloadedGroup); |
| } |
| |
| @Test |
| public void loadedNewGroupWithAllPropertiesDoesNotChangeOnReload() throws Exception { |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setDescription("A test group") |
| .setOwnerGroupUUID(AccountGroup.uuid("another owner")) |
| .setVisibleToAll(true) |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(Instant.ofEpochMilli(92900892)) |
| .setMemberModification(members -> ImmutableSet.of(Account.id(1), Account.id(2))) |
| .setSubgroupModification(subgroups -> ImmutableSet.of(AccountGroup.uuid("subgroup"))) |
| .build(); |
| |
| Optional<InternalGroup> createdGroup = createGroup(groupCreation, groupDelta); |
| Optional<InternalGroup> reloadedGroup = loadGroup(groupCreation.getGroupUUID()); |
| |
| assertThat(createdGroup).isEqualTo(reloadedGroup); |
| } |
| |
| @Test |
| public void loadedGroupAfterUpdatesForAllPropertiesDoesNotChangeOnReload() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setDescription("A test group") |
| .setOwnerGroupUUID(AccountGroup.uuid("another owner")) |
| .setVisibleToAll(true) |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(Instant.ofEpochMilli(92900892)) |
| .setMemberModification(members -> ImmutableSet.of(Account.id(1), Account.id(2))) |
| .setSubgroupModification(subgroups -> ImmutableSet.of(AccountGroup.uuid("subgroup"))) |
| .build(); |
| |
| Optional<InternalGroup> updatedGroup = updateGroup(groupUuid, groupDelta); |
| Optional<InternalGroup> reloadedGroup = loadGroup(groupUuid); |
| |
| assertThat(updatedGroup).isEqualTo(reloadedGroup); |
| } |
| |
| @Test |
| public void loadedGroupWithAllPropertiesAndUpdateOfSinglePropertyDoesNotChangeOnReload() |
| throws Exception { |
| // Create a group with all properties set. |
| InternalGroupCreation groupCreation = getPrefilledGroupCreationBuilder().build(); |
| GroupDelta initialGroupDelta = |
| GroupDelta.builder() |
| .setDescription("A test group") |
| .setOwnerGroupUUID(AccountGroup.uuid("another owner")) |
| .setVisibleToAll(true) |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(Instant.ofEpochMilli(92900892)) |
| .setMemberModification(members -> ImmutableSet.of(Account.id(1), Account.id(2))) |
| .setSubgroupModification(subgroups -> ImmutableSet.of(AccountGroup.uuid("subgroup"))) |
| .build(); |
| createGroup(groupCreation, initialGroupDelta); |
| |
| // Only update one of the properties. |
| GroupDelta groupDelta = |
| GroupDelta.builder().setName(AccountGroup.nameKey("Another name")).build(); |
| |
| Optional<InternalGroup> updatedGroup = updateGroup(groupCreation.getGroupUUID(), groupDelta); |
| Optional<InternalGroup> reloadedGroup = loadGroup(groupCreation.getGroupUUID()); |
| |
| assertThat(updatedGroup).isEqualTo(reloadedGroup); |
| } |
| |
| @Test |
| public void groupConfigMayBeReusedForFurtherUpdates() throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).setId(groupId).build(); |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| commit(groupConfig); |
| |
| AccountGroup.NameKey name = AccountGroup.nameKey("Robots"); |
| GroupDelta groupDelta1 = GroupDelta.builder().setName(name).build(); |
| groupConfig.setGroupDelta(groupDelta1, auditLogFormatter); |
| commit(groupConfig); |
| |
| String description = "Test group for robots"; |
| GroupDelta groupDelta2 = GroupDelta.builder().setDescription(description).build(); |
| groupConfig.setGroupDelta(groupDelta2, auditLogFormatter); |
| commit(groupConfig); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| assertThatGroup(group).value().id().isEqualTo(groupId); |
| assertThatGroup(group).value().nameKey().isEqualTo(name); |
| assertThatGroup(group).value().description().isEqualTo(description); |
| } |
| |
| @Test |
| public void newGroupIsRepresentedByARefPointingToARootCommit() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| Ref ref = repository.exactRef(RefNames.refsGroups(groupUuid)); |
| assertThat(ref.getObjectId()).isNotNull(); |
| |
| try (RevWalk revWalk = new RevWalk(repository)) { |
| RevCommit revCommit = revWalk.parseCommit(ref.getObjectId()); |
| assertThat(revCommit.getParentCount()).isEqualTo(0); |
| } |
| } |
| |
| @Test |
| public void updatedGroupIsRepresentedByARefPointingToACommitSequence() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| RevCommit commitAfterCreation = getLatestCommitForGroup(groupUuid); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder().setName(AccountGroup.nameKey("Another name")).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| assertThat(commitAfterUpdate).isNotEqualTo(commitAfterCreation); |
| assertThat(commitAfterUpdate.getParents()).asList().containsExactly(commitAfterCreation); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForEmptyUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = GroupDelta.builder().build(); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForPureUpdatedOnUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| Instant updatedOn = toInstant(LocalDate.of(3017, Month.DECEMBER, 12).atTime(10, 21, 49)); |
| GroupDelta groupDelta = GroupDelta.builder().setUpdatedOn(updatedOn).build(); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForRedundantNameUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setName(groupName).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForRedundantDescriptionUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setDescription("A test group").build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForRedundantVisibleToAllUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setVisibleToAll(true).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForRedundantOwnerGroupUuidUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder().setOwnerGroupUUID(AccountGroup.uuid("Another owner")).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForRedundantMemberUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setMemberModification(members -> Sets.union(members, ImmutableSet.of(Account.id(10)))) |
| .build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedForRedundantSubgroupsUpdate() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setSubgroupModification( |
| subgroups -> Sets.union(subgroups, ImmutableSet.of(AccountGroup.uuid("subgroup")))) |
| .build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit commitBeforeUpdate = getLatestCommitForGroup(groupUuid); |
| updateGroup(groupUuid, groupDelta); |
| RevCommit commitAfterUpdate = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterUpdate).isEqualTo(commitBeforeUpdate); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedWhenCommittingGroupCreationTwice() throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).build(); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder().setName(AccountGroup.nameKey("Another name")).build(); |
| |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| commit(groupConfig); |
| |
| RevCommit commitBeforeSecondCommit = getLatestCommitForGroup(groupUuid); |
| commit(groupConfig); |
| RevCommit commitAfterSecondCommit = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterSecondCommit).isEqualTo(commitBeforeSecondCommit); |
| } |
| |
| @Test |
| public void newCommitIsNotCreatedWhenCommittingGroupUpdateTwice() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta = GroupDelta.builder().setDescription("A test group").build(); |
| |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| commit(groupConfig); |
| |
| RevCommit commitBeforeSecondCommit = getLatestCommitForGroup(groupUuid); |
| commit(groupConfig); |
| RevCommit commitAfterSecondCommit = getLatestCommitForGroup(groupUuid); |
| |
| assertThat(commitAfterSecondCommit).isEqualTo(commitBeforeSecondCommit); |
| } |
| |
| @Test |
| public void commitTimeMatchesDefaultCreatedOnOfNewGroup() throws Exception { |
| // Git timestamps are only precise to the second. |
| long testStartAsSecondsSinceEpoch = TimeUtil.now().getEpochSecond(); |
| |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| createGroup(groupCreation); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getCommitTime()).isAtLeast((int) testStartAsSecondsSinceEpoch); |
| } |
| |
| @Test |
| public void commitTimeMatchesSpecifiedCreatedOnOfNewGroup() throws Exception { |
| // Git timestamps are only precise to the second. |
| long createdOnAsSecondsSinceEpoch = 9082093; |
| |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setUpdatedOn(Instant.ofEpochSecond(createdOnAsSecondsSinceEpoch)) |
| .build(); |
| createGroup(groupCreation, groupDelta); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getCommitTime()).isEqualTo(createdOnAsSecondsSinceEpoch); |
| } |
| |
| @Test |
| public void timestampOfCommitterMatchesSpecifiedCreatedOnOfNewGroup() throws Exception { |
| Instant committerTimestamp = |
| toInstant(LocalDate.of(2017, Month.DECEMBER, 13).atTime(15, 5, 27)); |
| Instant createdOn = toInstant(LocalDate.of(2016, Month.MARCH, 11).atTime(23, 49, 11)); |
| |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(createdOn) |
| .build(); |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| |
| PersonIdent committerIdent = |
| new PersonIdent("Jane", "Jane@gerritcodereview.com", committerTimestamp, zoneId); |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| metaDataUpdate.getCommitBuilder().setCommitter(committerIdent); |
| groupConfig.commit(metaDataUpdate); |
| } |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getCommitterIdent().getWhenAsInstant()).isEqualTo(createdOn); |
| assertThat(revCommit.getCommitterIdent().getZoneId().getRules().getOffset(createdOn)) |
| .isEqualTo(zoneId.getRules().getOffset(createdOn)); |
| } |
| |
| @Test |
| public void timestampOfAuthorMatchesSpecifiedCreatedOnOfNewGroup() throws Exception { |
| Instant authorTimestamp = toInstant(LocalDate.of(2017, Month.DECEMBER, 13).atTime(15, 5, 27)); |
| Instant createdOn = toInstant(LocalDate.of(2016, Month.MARCH, 11).atTime(23, 49, 11)); |
| |
| InternalGroupCreation groupCreation = |
| InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId) |
| .build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(createdOn) |
| .build(); |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| |
| PersonIdent authorIdent = |
| new PersonIdent("Jane", "Jane@gerritcodereview.com", authorTimestamp, zoneId); |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| metaDataUpdate.getCommitBuilder().setAuthor(authorIdent); |
| groupConfig.commit(metaDataUpdate); |
| } |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getAuthorIdent().getWhenAsInstant()).isEqualTo(createdOn); |
| assertThat(revCommit.getAuthorIdent().getZoneId().getRules().getOffset(createdOn)) |
| .isEqualTo(zoneId.getRules().getOffset(createdOn)); |
| } |
| |
| @Test |
| public void commitTimeMatchesDefaultUpdatedOnOfUpdatedGroup() throws Exception { |
| // Git timestamps are only precise to the second. |
| long testStartAsSecondsSinceEpoch = TimeUtil.now().getEpochSecond(); |
| |
| createArbitraryGroup(groupUuid); |
| GroupDelta groupDelta = |
| GroupDelta.builder().setName(AccountGroup.nameKey("Another name")).build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getCommitTime()).isAtLeast((int) testStartAsSecondsSinceEpoch); |
| } |
| |
| @Test |
| public void commitTimeMatchesSpecifiedUpdatedOnOfUpdatedGroup() throws Exception { |
| // Git timestamps are only precise to the second. |
| long updatedOnAsSecondsSinceEpoch = 9082093; |
| |
| createArbitraryGroup(groupUuid); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(Instant.ofEpochSecond(updatedOnAsSecondsSinceEpoch)) |
| .build(); |
| updateGroup(groupUuid, groupDelta); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getCommitTime()).isEqualTo(updatedOnAsSecondsSinceEpoch); |
| } |
| |
| @Test |
| public void timestampOfCommitterMatchesSpecifiedUpdatedOnOfUpdatedGroup() throws Exception { |
| Instant committerTimestamp = |
| toInstant(LocalDate.of(2017, Month.DECEMBER, 13).atTime(15, 5, 27)); |
| Instant updatedOn = toInstant(LocalDate.of(2016, Month.MARCH, 11).atTime(23, 49, 11)); |
| |
| createArbitraryGroup(groupUuid); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(updatedOn) |
| .build(); |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| |
| PersonIdent committerIdent = |
| new PersonIdent("Jane", "Jane@gerritcodereview.com", committerTimestamp, zoneId); |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| metaDataUpdate.getCommitBuilder().setCommitter(committerIdent); |
| groupConfig.commit(metaDataUpdate); |
| } |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getCommitterIdent().getWhenAsInstant()).isEqualTo(updatedOn); |
| assertThat(revCommit.getCommitterIdent().getZoneId().getRules().getOffset(updatedOn)) |
| .isEqualTo(zoneId.getRules().getOffset(updatedOn)); |
| } |
| |
| @Test |
| public void timestampOfAuthorMatchesSpecifiedUpdatedOnOfUpdatedGroup() throws Exception { |
| Instant authorTimestamp = toInstant(LocalDate.of(2017, Month.DECEMBER, 13).atTime(15, 5, 27)); |
| Instant updatedOn = toInstant(LocalDate.of(2016, Month.MARCH, 11).atTime(23, 49, 11)); |
| |
| createArbitraryGroup(groupUuid); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("Another name")) |
| .setUpdatedOn(updatedOn) |
| .build(); |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, groupUuid); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| |
| PersonIdent authorIdent = |
| new PersonIdent("Jane", "Jane@gerritcodereview.com", authorTimestamp, zoneId); |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| metaDataUpdate.getCommitBuilder().setAuthor(authorIdent); |
| groupConfig.commit(metaDataUpdate); |
| } |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getAuthorIdent().getWhenAsInstant()).isEqualTo(updatedOn); |
| assertThat(revCommit.getAuthorIdent().getZoneId().getRules().getOffset(updatedOn)) |
| .isEqualTo(zoneId.getRules().getOffset(updatedOn)); |
| } |
| |
| @Test |
| public void refStateOfLoadedGroupIsPopulatedWithCommitSha1() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| Optional<InternalGroup> group = loadGroup(groupUuid); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThatGroup(group).value().refState().isEqualTo(revCommit.copy()); |
| } |
| |
| @Test |
| public void groupCanBeLoadedAtASpecificRevision() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| AccountGroup.NameKey firstName = AccountGroup.nameKey("Bots"); |
| GroupDelta groupDelta1 = GroupDelta.builder().setName(firstName).build(); |
| updateGroup(groupUuid, groupDelta1); |
| |
| RevCommit commitAfterUpdate1 = getLatestCommitForGroup(groupUuid); |
| |
| GroupDelta groupDelta2 = GroupDelta.builder().setName(AccountGroup.nameKey("Robots")).build(); |
| updateGroup(groupUuid, groupDelta2); |
| |
| GroupConfig groupConfig = |
| GroupConfig.loadForGroupSnapshot( |
| projectName, repository, groupUuid, commitAfterUpdate1.copy()); |
| Optional<InternalGroup> group = groupConfig.getLoadedGroup(); |
| assertThatGroup(group).value().nameKey().isEqualTo(firstName); |
| assertThatGroup(group).value().refState().isEqualTo(commitAfterUpdate1.copy()); |
| } |
| |
| @Test |
| public void commitMessageOfNewGroupWithoutMembersOrSubgroupsContainsNoFooters() throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).build(); |
| createGroup(groupCreation); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()).isEqualTo("Create group"); |
| } |
| |
| @Test |
| public void commitMessageOfNewGroupWithAdditionalNameSpecificationContainsNoFooters() |
| throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder().setName(AccountGroup.nameKey("Another name")).build(); |
| createGroup(groupCreation, groupDelta); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()).isEqualTo("Create group"); |
| } |
| |
| @Test |
| public void commitMessageOfNewGroupWithMembersContainsFooters() throws Exception { |
| Account account13 = createAccount(Account.id(13), "John"); |
| Account account7 = createAccount(Account.id(7), "Jane"); |
| ImmutableSet<Account> accounts = ImmutableSet.of(account13, account7); |
| |
| AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(accounts, ImmutableSet.of(), "server-id"); |
| |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setMemberModification(members -> ImmutableSet.of(account13.id(), account7.id())) |
| .build(); |
| |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| commit(groupConfig); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()) |
| .isEqualTo("Create group\n\nAdd: Jane <7@server-id>\nAdd: John <13@server-id>"); |
| } |
| |
| @Test |
| public void commitMessageOfNewGroupWithSubgroupsContainsFooters() throws Exception { |
| GroupDescription.Basic group1 = createGroup(AccountGroup.uuid("129403"), "Bots"); |
| GroupDescription.Basic group2 = createGroup(AccountGroup.uuid("8903493"), "Verifiers"); |
| ImmutableSet<GroupDescription.Basic> groups = ImmutableSet.of(group1, group2); |
| |
| AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(ImmutableSet.of(), groups, "serverId"); |
| |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(groupUuid).build(); |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setSubgroupModification( |
| subgroups -> ImmutableSet.of(group1.getGroupUUID(), group2.getGroupUUID())) |
| .build(); |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| commit(groupConfig); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()) |
| .isEqualTo("Create group\n\nAdd-group: Bots <129403>\nAdd-group: Verifiers <8903493>"); |
| } |
| |
| @Test |
| public void commitMessageOfMemberAdditionContainsFooters() throws Exception { |
| Account account13 = createAccount(Account.id(13), "John"); |
| Account account7 = createAccount(Account.id(7), "Jane"); |
| ImmutableSet<Account> accounts = ImmutableSet.of(account13, account7); |
| |
| createArbitraryGroup(groupUuid); |
| |
| AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(accounts, ImmutableSet.of(), "GerritServer1"); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setMemberModification(members -> ImmutableSet.of(account13.id(), account7.id())) |
| .build(); |
| updateGroup(groupUuid, groupDelta, auditLogFormatter); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()) |
| .isEqualTo("Update group\n\nAdd: Jane <7@GerritServer1>\nAdd: John <13@GerritServer1>"); |
| } |
| |
| @Test |
| public void commitMessageOfMemberRemovalContainsFooters() throws Exception { |
| Account account13 = createAccount(Account.id(13), "John"); |
| Account account7 = createAccount(Account.id(7), "Jane"); |
| ImmutableSet<Account> accounts = ImmutableSet.of(account13, account7); |
| |
| createArbitraryGroup(groupUuid); |
| |
| AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(accounts, ImmutableSet.of(), "server-id"); |
| |
| GroupDelta groupDelta1 = |
| GroupDelta.builder() |
| .setMemberModification(members -> ImmutableSet.of(account13.id(), account7.id())) |
| .build(); |
| updateGroup(groupUuid, groupDelta1, auditLogFormatter); |
| |
| GroupDelta groupDelta2 = |
| GroupDelta.builder() |
| .setMemberModification(members -> ImmutableSet.of(account7.id())) |
| .build(); |
| updateGroup(groupUuid, groupDelta2, auditLogFormatter); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()).isEqualTo("Update group\n\nRemove: John <13@server-id>"); |
| } |
| |
| @Test |
| public void commitMessageOfSubgroupAdditionContainsFooters() throws Exception { |
| GroupDescription.Basic group1 = createGroup(AccountGroup.uuid("129403"), "Bots"); |
| GroupDescription.Basic group2 = createGroup(AccountGroup.uuid("8903493"), "Verifiers"); |
| ImmutableSet<GroupDescription.Basic> groups = ImmutableSet.of(group1, group2); |
| |
| createArbitraryGroup(groupUuid); |
| |
| AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(ImmutableSet.of(), groups, "serverId"); |
| |
| GroupDelta groupDelta = |
| GroupDelta.builder() |
| .setSubgroupModification( |
| subgroups -> ImmutableSet.of(group1.getGroupUUID(), group2.getGroupUUID())) |
| .build(); |
| updateGroup(groupUuid, groupDelta, auditLogFormatter); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()) |
| .isEqualTo("Update group\n\nAdd-group: Bots <129403>\nAdd-group: Verifiers <8903493>"); |
| } |
| |
| @Test |
| public void commitMessageOfSubgroupRemovalContainsFooters() throws Exception { |
| GroupDescription.Basic group1 = createGroup(AccountGroup.uuid("129403"), "Bots"); |
| GroupDescription.Basic group2 = createGroup(AccountGroup.uuid("8903493"), "Verifiers"); |
| ImmutableSet<GroupDescription.Basic> groups = ImmutableSet.of(group1, group2); |
| |
| createArbitraryGroup(groupUuid); |
| |
| AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(ImmutableSet.of(), groups, "serverId"); |
| |
| GroupDelta groupDelta1 = |
| GroupDelta.builder() |
| .setSubgroupModification( |
| subgroups -> ImmutableSet.of(group1.getGroupUUID(), group2.getGroupUUID())) |
| .build(); |
| updateGroup(groupUuid, groupDelta1, auditLogFormatter); |
| |
| GroupDelta groupDelta2 = |
| GroupDelta.builder() |
| .setSubgroupModification(subgroups -> ImmutableSet.of(group1.getGroupUUID())) |
| .build(); |
| updateGroup(groupUuid, groupDelta2, auditLogFormatter); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()) |
| .isEqualTo("Update group\n\nRemove-group: Verifiers <8903493>"); |
| } |
| |
| @Test |
| public void commitMessageOfGroupRenameContainsFooters() throws Exception { |
| createArbitraryGroup(groupUuid); |
| |
| GroupDelta groupDelta1 = GroupDelta.builder().setName(AccountGroup.nameKey("Old name")).build(); |
| updateGroup(groupUuid, groupDelta1); |
| |
| GroupDelta groupDelta2 = GroupDelta.builder().setName(AccountGroup.nameKey("New name")).build(); |
| updateGroup(groupUuid, groupDelta2); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()) |
| .isEqualTo("Update group\n\nRename from Old name to New name"); |
| } |
| |
| @Test |
| public void commitMessageFootersCanBeMixed() throws Exception { |
| Account account13 = createAccount(Account.id(13), "John"); |
| Account account7 = createAccount(Account.id(7), "Jane"); |
| ImmutableSet<Account> accounts = ImmutableSet.of(account13, account7); |
| GroupDescription.Basic group1 = createGroup(AccountGroup.uuid("129403"), "Bots"); |
| GroupDescription.Basic group2 = createGroup(AccountGroup.uuid("8903493"), "Verifiers"); |
| ImmutableSet<GroupDescription.Basic> groups = ImmutableSet.of(group1, group2); |
| |
| createArbitraryGroup(groupUuid); |
| |
| AuditLogFormatter auditLogFormatter = |
| AuditLogFormatter.createBackedBy(accounts, groups, "serverId"); |
| |
| GroupDelta groupDelta1 = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("Old name")) |
| .setMemberModification(members -> ImmutableSet.of(account7.id())) |
| .setSubgroupModification(subgroups -> ImmutableSet.of(group2.getGroupUUID())) |
| .build(); |
| updateGroup(groupUuid, groupDelta1, auditLogFormatter); |
| |
| GroupDelta groupDelta2 = |
| GroupDelta.builder() |
| .setName(AccountGroup.nameKey("New name")) |
| .setMemberModification(members -> ImmutableSet.of(account13.id())) |
| .setSubgroupModification(subgroups -> ImmutableSet.of(group1.getGroupUUID())) |
| .build(); |
| updateGroup(groupUuid, groupDelta2, auditLogFormatter); |
| |
| RevCommit revCommit = getLatestCommitForGroup(groupUuid); |
| assertThat(revCommit.getFullMessage()) |
| .isEqualTo( |
| "Update group\n" |
| + "\n" |
| + "Add-group: Bots <129403>\n" |
| + "Add: John <13@serverId>\n" |
| + "Remove-group: Verifiers <8903493>\n" |
| + "Remove: Jane <7@serverId>\n" |
| + "Rename from Old name to New name"); |
| } |
| |
| private static Instant toInstant(LocalDateTime localDateTime) { |
| return localDateTime.atZone(ZoneId.systemDefault()).toInstant(); |
| } |
| |
| private void populateGroupConfig(AccountGroup.UUID uuid, String fileContent) throws Exception { |
| testRepository |
| .branch(RefNames.refsGroups(uuid)) |
| .commit() |
| .message("Prepopulate group.config") |
| .add(GroupConfig.GROUP_CONFIG_FILE, fileContent) |
| .create(); |
| } |
| |
| private void populateMembersFile(AccountGroup.UUID uuid, String fileContent) throws Exception { |
| testRepository |
| .branch(RefNames.refsGroups(uuid)) |
| .commit() |
| .message("Prepopulate members") |
| .add(GroupConfig.MEMBERS_FILE, fileContent) |
| .create(); |
| } |
| |
| private void populateSubgroupsFile(AccountGroup.UUID uuid, String fileContent) throws Exception { |
| testRepository |
| .branch(RefNames.refsGroups(uuid)) |
| .commit() |
| .message("Prepopulate subgroups") |
| .add(GroupConfig.SUBGROUPS_FILE, fileContent) |
| .create(); |
| } |
| |
| private void createArbitraryGroup(AccountGroup.UUID uuid) throws Exception { |
| InternalGroupCreation groupCreation = |
| getPrefilledGroupCreationBuilder().setGroupUUID(uuid).build(); |
| createGroup(groupCreation); |
| } |
| |
| private InternalGroupCreation.Builder getPrefilledGroupCreationBuilder() { |
| return InternalGroupCreation.builder() |
| .setGroupUUID(groupUuid) |
| .setNameKey(groupName) |
| .setId(groupId); |
| } |
| |
| private Optional<InternalGroup> createGroup(InternalGroupCreation groupCreation) |
| throws Exception { |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| commit(groupConfig); |
| return groupConfig.getLoadedGroup(); |
| } |
| |
| private Optional<InternalGroup> createGroup( |
| InternalGroupCreation groupCreation, GroupDelta groupDelta) throws Exception { |
| GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| commit(groupConfig); |
| return groupConfig.getLoadedGroup(); |
| } |
| |
| private Optional<InternalGroup> updateGroup(AccountGroup.UUID uuid, GroupDelta groupDelta) |
| throws Exception { |
| return updateGroup(uuid, groupDelta, auditLogFormatter); |
| } |
| |
| private Optional<InternalGroup> updateGroup( |
| AccountGroup.UUID uuid, GroupDelta groupDelta, AuditLogFormatter auditLogFormatter) |
| throws Exception { |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, uuid); |
| groupConfig.setGroupDelta(groupDelta, auditLogFormatter); |
| commit(groupConfig); |
| return groupConfig.getLoadedGroup(); |
| } |
| |
| private Optional<InternalGroup> loadGroup(AccountGroup.UUID uuid) throws Exception { |
| GroupConfig groupConfig = GroupConfig.loadForGroup(projectName, repository, uuid); |
| return groupConfig.getLoadedGroup(); |
| } |
| |
| private void commit(GroupConfig groupConfig) throws IOException { |
| try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) { |
| groupConfig.commit(metaDataUpdate); |
| } |
| } |
| |
| private MetaDataUpdate createMetaDataUpdate() { |
| PersonIdent serverIdent = |
| new PersonIdent("Gerrit Server", "noreply@gerritcodereview.com", TimeUtil.now(), zoneId); |
| |
| MetaDataUpdate metaDataUpdate = |
| new MetaDataUpdate( |
| GitReferenceUpdated.DISABLED, Project.nameKey("Test Repository"), repository); |
| metaDataUpdate.getCommitBuilder().setCommitter(serverIdent); |
| metaDataUpdate.getCommitBuilder().setAuthor(serverIdent); |
| return metaDataUpdate; |
| } |
| |
| private RevCommit getLatestCommitForGroup(AccountGroup.UUID uuid) throws IOException { |
| Ref ref = repository.exactRef(RefNames.refsGroups(uuid)); |
| assertWithMessage("Precondition: Assumed that ref for group " + uuid + " exists.") |
| .that(ref.getObjectId()) |
| .isNotNull(); |
| |
| try (RevWalk revWalk = new RevWalk(repository)) { |
| return revWalk.parseCommit(ref.getObjectId()); |
| } |
| } |
| |
| private static Account createAccount(Account.Id id, String name) { |
| Account.Builder account = Account.builder(id, TimeUtil.now()); |
| account.setFullName(name); |
| return account.build(); |
| } |
| |
| private static GroupDescription.Basic createGroup(AccountGroup.UUID uuid, String name) { |
| return new GroupDescription.Basic() { |
| @Override |
| public AccountGroup.UUID getGroupUUID() { |
| return uuid; |
| } |
| |
| @Override |
| public String getName() { |
| return name; |
| } |
| |
| @Nullable |
| @Override |
| public String getEmailAddress() { |
| return null; |
| } |
| |
| @Nullable |
| @Override |
| public String getUrl() { |
| return null; |
| } |
| }; |
| } |
| |
| private static OptionalSubject<InternalGroupSubject, InternalGroup> assertThatGroup( |
| Optional<InternalGroup> loadedGroup) { |
| return assertThat(loadedGroup, internalGroups()); |
| } |
| } |