@Test
  public void shouldCopyPackagesFromOldRepositoryToTheUpdatedRepository() throws Exception {
    PackageDefinition nodePackage = new PackageDefinition("foo", "bar", new Configuration());
    oldPackageRepo.setPackages(new Packages(nodePackage));
    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);

    assertThat(cruiseConfig.getPackageRepositories().find(repoId), is(oldPackageRepo));
    assertThat(cruiseConfig.getPackageRepositories().find(repoId).getPackages().size(), is(1));
    assertThat(newPackageRepo.getPackages().size(), is(0));

    command.update(cruiseConfig);
    HttpLocalizedOperationResult expectedResult = new HttpLocalizedOperationResult();
    assertThat(result, is(expectedResult));
    assertThat(cruiseConfig.getPackageRepositories().find(repoId), is(newPackageRepo));
    assertThat(cruiseConfig.getPackageRepositories().find(repoId).getPackages().size(), is(1));
    assertThat(
        cruiseConfig.getPackageRepositories().find(repoId).getPackages().first(), is(nodePackage));
  }
 @Test
 public void shouldNotUpdatePackageRepositoryIfTheSpecifiedPluginTypeIsInvalid() throws Exception {
   when(packageRepositoryService.validatePluginId(newPackageRepo)).thenReturn(false);
   when(packageRepositoryService.validateRepositoryConfiguration(newPackageRepo)).thenReturn(true);
   UpdatePackageRepositoryCommand command =
       new UpdatePackageRepositoryCommand(
           goConfigService,
           packageRepositoryService,
           newPackageRepo,
           currentUser,
           "md5",
           entityHashingService,
           result,
           repoId);
   command.update(cruiseConfig);
   assertFalse(command.isValid(cruiseConfig));
 }
  @Test
  public void shouldContinueWithConfigSaveIfUserIsGroupAdmin() {
    when(goConfigService.isUserAdmin(currentUser)).thenReturn(false);
    when(goConfigService.isGroupAdministrator(currentUser.getUsername())).thenReturn(true);
    when(entityHashingService.md5ForEntity(any(PackageRepository.class))).thenReturn("md5");

    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);

    assertThat(command.canContinue(cruiseConfig), is(true));
  }
  @Test
  public void shouldNotUpdatePackageRepositoryWhenRepositoryHasInvalidName() throws Exception {
    newPackageRepo.setName("~!@#$%^&*(");
    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);
    command.update(cruiseConfig);

    assertFalse(command.isValid(cruiseConfig));
    assertThat(
        newPackageRepo.errors().firstError(),
        is(
            "Invalid PackageRepository name '~!@#$%^&*('. This must be alphanumeric and can contain underscores and periods (however, it cannot start with a period). The maximum allowed length is 255 characters."));
  }
  @Test
  public void shouldNotUpdatePackageRepositoryWhenRepositoryWithSpecifiedNameAlreadyExists()
      throws Exception {
    cruiseConfig.getPackageRepositories().add(newPackageRepo);
    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);

    assertFalse(command.isValid(cruiseConfig));
    assertThat(
        newPackageRepo.errors().firstError(),
        is(
            "You have defined multiple repositories called 'npmOrg'. Repository names are case-insensitive and must be unique."));
  }
  @Test
  public void shouldUpdatePackageRepository() throws Exception {
    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);

    assertThat(cruiseConfig.getPackageRepositories().size(), is(1));
    assertThat(cruiseConfig.getPackageRepositories().find(repoId), is(oldPackageRepo));

    command.update(cruiseConfig);
    HttpLocalizedOperationResult expectedResult = new HttpLocalizedOperationResult();
    assertThat(result, is(expectedResult));
    assertThat(cruiseConfig.getPackageRepositories().size(), is(1));
    assertThat(cruiseConfig.getPackageRepositories().find(repoId), is(newPackageRepo));
  }
  @Test
  public void shouldNotContinueIfTheUserDontHavePermissionsToOperateOnPackageRepositories()
      throws Exception {
    when(goConfigService.isUserAdmin(currentUser)).thenReturn(false);
    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);

    HttpLocalizedOperationResult expectedResult = new HttpLocalizedOperationResult();
    expectedResult.unauthorized(
        LocalizedMessage.string("UNAUTHORIZED_TO_EDIT"), HealthStateType.unauthorised());

    assertThat(command.canContinue(cruiseConfig), is(false));
    assertThat(result, is(expectedResult));
  }
  @Test
  public void shouldNotContinueIfRepoIdIsChanged() {
    when(goConfigService.isUserAdmin(currentUser)).thenReturn(true);
    when(goConfigService.getPackageRepository(repoId)).thenReturn(oldPackageRepo);
    when(entityHashingService.md5ForEntity(oldPackageRepo)).thenReturn("md5");
    HttpLocalizedOperationResult expectResult = new HttpLocalizedOperationResult();
    expectResult.unprocessableEntity(
        LocalizedMessage.string("PACKAGE_REPOSITORY_ID_CHANGED", "repository"));

    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            "old-repo-id");

    assertThat(command.canContinue(cruiseConfig), is(false));
    assertThat(result, is(expectResult));
  }
  @Test
  public void shouldNotContinueIfTheUserSubmittedStaleEtag() throws Exception {
    when(goConfigService.isUserAdmin(currentUser)).thenReturn(true);
    when(goConfigService.getPackageRepository(repoId)).thenReturn(oldPackageRepo);
    when(entityHashingService.md5ForEntity(oldPackageRepo)).thenReturn("foobar");
    HttpLocalizedOperationResult expectResult = new HttpLocalizedOperationResult();
    expectResult.stale(
        LocalizedMessage.string("STALE_RESOURCE_CONFIG", "Package Repository", repoId));

    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);

    assertThat(command.canContinue(cruiseConfig), is(false));
    assertThat(result, is(expectResult));
  }
  @Test
  public void shouldNotUpdatePackageRepositoryWhenRepositoryHasDuplicateConfigurationProperties()
      throws Exception {
    ConfigurationProperty property =
        new ConfigurationProperty(new ConfigurationKey("foo"), new ConfigurationValue("bar"));
    Configuration configuration = new Configuration(property, property);
    newPackageRepo.setConfiguration(configuration);

    UpdatePackageRepositoryCommand command =
        new UpdatePackageRepositoryCommand(
            goConfigService,
            packageRepositoryService,
            newPackageRepo,
            currentUser,
            "md5",
            entityHashingService,
            result,
            repoId);
    command.update(cruiseConfig);

    assertFalse(command.isValid(cruiseConfig));
    assertThat(
        property.errors().firstError(), is("Duplicate key 'foo' found for Repository 'npmOrg'"));
  }