@Test
  public void test_create_new_application() throws IOException {
    SubjectCredentials subjectCredentials =
        SubjectCredentials.Builder.create()
            .authenticationType(SubjectCredentials.AuthenticationType.CERTIFICATE)
            .name("app1")
            .certificate(getCertificate())
            .enabled(true)
            .build();
    subjectCredentialsService.save(subjectCredentials);

    List<SubjectCredentials> list =
        newArrayList(
            subjectCredentialsService.getSubjectCredentials(
                SubjectCredentials.AuthenticationType.CERTIFICATE));
    assertThat(list).hasSize(1);
    assertSubjectEquals(subjectCredentials, list.get(0));

    SubjectCredentials found =
        subjectCredentialsService.getSubjectCredentials(subjectCredentials.getName());
    assertSubjectEquals(subjectCredentials, found);

    OpalKeyStore keyStore = credentialsKeyStoreService.getKeyStore();
    assertThat(keyStore.aliasExists(subjectCredentials.getCertificateAlias())).isTrue();
    assertThat(keyStore.getKeyType(subjectCredentials.getCertificateAlias()))
        .isEqualTo(OpalKeyStore.KeyType.CERTIFICATE);
  }
  @Test
  public void test_remove_groups_from_user() {
    SubjectCredentials subjectCredentials =
        SubjectCredentials.Builder.create()
            .authenticationType(SubjectCredentials.AuthenticationType.PASSWORD)
            .name("user1")
            .password("password")
            .groups(Sets.newHashSet("group1", "group2"))
            .build();
    subjectCredentialsService.save(subjectCredentials);

    subjectCredentials.removeGroup("group1");
    subjectCredentialsService.save(subjectCredentials);

    SubjectCredentials found =
        subjectCredentialsService.getSubjectCredentials(subjectCredentials.getName());
    assertSubjectEquals(subjectCredentials, found);

    assertThat(subjectCredentialsService.getGroups()).hasSize(2);

    Group group1 = subjectCredentialsService.getGroup("group1");
    assertThat(group1).isNotNull();
    assertThat(group1.getSubjectCredentials()).isEmpty();

    Group group2 = subjectCredentialsService.getGroup("group2");
    assertThat(group2).isNotNull();
    assertThat(group2.getSubjectCredentials()).hasSize(1);
    assertThat(group2.getSubjectCredentials()).contains(subjectCredentials.getName());
  }
  @Test
  public void test_update_user() {
    SubjectCredentials subjectCredentials =
        SubjectCredentials.Builder.create()
            .authenticationType(SubjectCredentials.AuthenticationType.PASSWORD)
            .name("user1")
            .password("password")
            .enabled(true)
            .build();
    subjectCredentialsService.save(subjectCredentials);

    subjectCredentials.setPassword("new password");
    subjectCredentialsService.save(subjectCredentials);

    List<SubjectCredentials> list =
        newArrayList(
            subjectCredentialsService.getSubjectCredentials(
                SubjectCredentials.AuthenticationType.PASSWORD));
    assertThat(list).hasSize(1);
    assertSubjectEquals(subjectCredentials, list.get(0));

    SubjectCredentials found =
        subjectCredentialsService.getSubjectCredentials(subjectCredentials.getName());
    assertSubjectEquals(subjectCredentials, found);
    Asserts.assertUpdatedTimestamps(subjectCredentials, found);
  }
  private void assertSubjectEquals(SubjectCredentials expected, SubjectCredentials found) {
    assertThat(found).isNotNull();
    assertThat(found).isEqualTo(expected);
    assertThat(found.getName()).isEqualTo(expected.getName());
    assertThat(found.getAuthenticationType()).isEqualTo(expected.getAuthenticationType());
    assertThat(found.getPassword()).isEqualTo(expected.getPassword());
    assertThat(found.isEnabled()).isEqualTo(expected.isEnabled());

    assertThat(expected.getGroups()).isEqualTo(found.getGroups());
    Asserts.assertCreatedTimestamps(expected, found);
  }
  @Test
  public void test_change_password_with_password_changed() {
    SubjectCredentials subjectCredentials =
        SubjectCredentials.Builder.create()
            .authenticationType(SubjectCredentials.AuthenticationType.PASSWORD)
            .name("user1")
            .password(subjectCredentialsService.hashPassword("password"))
            .build();

    subjectCredentialsService.save(subjectCredentials);
    subjectCredentialsService.changePassword("user1", "password", "password1");
    SubjectCredentials subjectCredentials1 =
        subjectCredentialsService.getSubjectCredentials("user1");
    assertThat(
            subjectCredentials1
                .getPassword()
                .equals(subjectCredentialsService.hashPassword("password1")))
        .isTrue();
  }
  @Test
  public void test_delete_application() throws IOException {
    SubjectCredentials subjectCredentials =
        SubjectCredentials.Builder.create()
            .authenticationType(SubjectCredentials.AuthenticationType.CERTIFICATE)
            .name("app1")
            .certificate(getCertificate())
            .enabled(true)
            .build();
    subjectCredentialsService.save(subjectCredentials);

    subjectCredentialsService.delete(subjectCredentials);
    assertThat(
            subjectCredentialsService.getSubjectCredentials(
                SubjectCredentials.AuthenticationType.CERTIFICATE))
        .isEmpty();

    OpalKeyStore keyStore = credentialsKeyStoreService.getKeyStore();
    assertThat(keyStore.aliasExists(subjectCredentials.getName())).isFalse();
  }