/** Test CRUD on person credentials, with listing */
  @Test
  public void testPersonCredentialsCRUD() throws Exception {
    PagingResults<String> systems = null;
    PagingResults<? extends BaseCredentialsInfo> creds = null;

    // Run as a test user
    AuthenticationUtil.setFullyAuthenticatedUser(TEST_USER_ONE);

    // Initially both should be empty empty
    systems = REMOTE_CREDENTIALS_SERVICE.listPersonRemoteSystems(new PagingRequest(10));
    assertEquals(
        "No systems should be found, got " + systems.getPage(), 0, systems.getPage().size());
    systems = REMOTE_CREDENTIALS_SERVICE.listSharedRemoteSystems(new PagingRequest(10));
    assertEquals(
        "No systems should be found, got " + systems.getPage(), 0, systems.getPage().size());

    // Create for a person
    PasswordCredentialsInfoImpl pwCred = new PasswordCredentialsInfoImpl();
    pwCred.setRemoteUsername(TEST_REMOTE_USERNAME_ONE);
    BaseCredentialsInfo credentials =
        REMOTE_CREDENTIALS_SERVICE.createPersonCredentials(TEST_REMOTE_SYSTEM_ONE, pwCred);

    // Check the new object was populated properly
    assertNotNull(credentials);
    assertNotNull(credentials.getNodeRef());
    assertNotNull(credentials.getRemoteSystemContainerNodeRef());
    assertEquals(TEST_REMOTE_SYSTEM_ONE, credentials.getRemoteSystemName());
    assertEquals(TEST_REMOTE_USERNAME_ONE, credentials.getRemoteUsername());
    assertEquals(
        RemoteCredentialsModel.TYPE_PASSWORD_CREDENTIALS, credentials.getCredentialsType());

    // Fetch and re-check
    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertNotNull(credentials);
    assertNotNull(credentials.getNodeRef());
    assertNotNull(credentials.getRemoteSystemContainerNodeRef());
    assertEquals(TEST_REMOTE_SYSTEM_ONE, credentials.getRemoteSystemName());
    assertEquals(TEST_REMOTE_USERNAME_ONE, credentials.getRemoteUsername());
    assertEquals(
        RemoteCredentialsModel.TYPE_PASSWORD_CREDENTIALS, credentials.getCredentialsType());

    // Won't be there for non-existent systems
    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_TWO);
    assertEquals(null, credentials);
    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_THREE);
    assertEquals(null, credentials);

    // Update
    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertEquals(PasswordCredentialsInfoImpl.class, credentials.getClass());
    pwCred = (PasswordCredentialsInfoImpl) credentials;

    pwCred.setRemoteUsername(TEST_REMOTE_USERNAME_TWO);
    pwCred.setRemotePassword("testing");

    credentials = REMOTE_CREDENTIALS_SERVICE.updateCredentials(pwCred);
    assertNotNull(credentials);
    assertEquals(TEST_REMOTE_USERNAME_TWO, credentials.getRemoteUsername());

    // Fetch and re-check
    pwCred =
        (PasswordCredentialsInfoImpl)
            REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertNotNull(pwCred);
    assertEquals(TEST_REMOTE_USERNAME_TWO, pwCred.getRemoteUsername());
    assertEquals("testing", pwCred.getRemotePassword());

    // Update the auth worked flag
    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertEquals(true, credentials.getLastAuthenticationSucceeded());

    // To the same thing
    credentials =
        REMOTE_CREDENTIALS_SERVICE.updateCredentialsAuthenticationSucceeded(true, credentials);
    assertEquals(true, credentials.getLastAuthenticationSucceeded());

    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertEquals(true, credentials.getLastAuthenticationSucceeded());

    // To a different things
    credentials =
        REMOTE_CREDENTIALS_SERVICE.updateCredentialsAuthenticationSucceeded(false, credentials);
    assertEquals(false, credentials.getLastAuthenticationSucceeded());

    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertEquals(false, credentials.getLastAuthenticationSucceeded());

    // And back
    credentials =
        REMOTE_CREDENTIALS_SERVICE.updateCredentialsAuthenticationSucceeded(true, credentials);
    assertEquals(true, credentials.getLastAuthenticationSucceeded());

    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertEquals(true, credentials.getLastAuthenticationSucceeded());

    // List remote systems
    systems = REMOTE_CREDENTIALS_SERVICE.listPersonRemoteSystems(new PagingRequest(10));
    assertEquals(1, systems.getPage().size());

    systems = REMOTE_CREDENTIALS_SERVICE.listSharedRemoteSystems(new PagingRequest(10));
    assertEquals(0, systems.getPage().size());

    systems = REMOTE_CREDENTIALS_SERVICE.listAllRemoteSystems(new PagingRequest(10));
    assertEquals(1, systems.getPage().size());

    // List the credentials
    creds =
        REMOTE_CREDENTIALS_SERVICE.listPersonCredentials(
            TEST_REMOTE_SYSTEM_ONE, null, new PagingRequest(10));
    assertEquals(1, creds.getPage().size());
    assertEquals(TEST_REMOTE_USERNAME_TWO, creds.getPage().get(0).getRemoteUsername());

    creds =
        REMOTE_CREDENTIALS_SERVICE.listSharedCredentials(
            TEST_REMOTE_SYSTEM_ONE, null, new PagingRequest(10));
    assertEquals(0, creds.getPage().size());

    creds =
        REMOTE_CREDENTIALS_SERVICE.listAllCredentials(
            TEST_REMOTE_SYSTEM_ONE, null, new PagingRequest(10));
    assertEquals(1, creds.getPage().size());
    assertEquals(TEST_REMOTE_USERNAME_TWO, creds.getPage().get(0).getRemoteUsername());

    // Delete
    REMOTE_CREDENTIALS_SERVICE.deleteCredentials(credentials);

    credentials = REMOTE_CREDENTIALS_SERVICE.getPersonCredentials(TEST_REMOTE_SYSTEM_ONE);
    assertEquals(null, credentials);

    // List again - credentials should have gone, but system remains
    creds =
        REMOTE_CREDENTIALS_SERVICE.listPersonCredentials(
            TEST_REMOTE_SYSTEM_ONE, null, new PagingRequest(10));
    assertEquals(0, creds.getPage().size());
    creds =
        REMOTE_CREDENTIALS_SERVICE.listSharedCredentials(
            TEST_REMOTE_SYSTEM_ONE, null, new PagingRequest(10));
    assertEquals(0, creds.getPage().size());
    creds =
        REMOTE_CREDENTIALS_SERVICE.listAllCredentials(
            TEST_REMOTE_SYSTEM_ONE, null, new PagingRequest(10));
    assertEquals(0, creds.getPage().size());

    systems = REMOTE_CREDENTIALS_SERVICE.listPersonRemoteSystems(new PagingRequest(10));
    assertEquals(1, systems.getPage().size());
    systems = REMOTE_CREDENTIALS_SERVICE.listSharedRemoteSystems(new PagingRequest(10));
    assertEquals(0, systems.getPage().size());
    systems = REMOTE_CREDENTIALS_SERVICE.listAllRemoteSystems(new PagingRequest(10));
    assertEquals(1, systems.getPage().size());

    // Create credentials of Password, OAuth1 and OAuth2 types
    pwCred = new PasswordCredentialsInfoImpl();
    pwCred.setRemoteUsername(TEST_REMOTE_USERNAME_ONE);
    REMOTE_CREDENTIALS_SERVICE.createPersonCredentials(TEST_REMOTE_SYSTEM_TWO, pwCred);

    OAuth1CredentialsInfoImpl oa1Cred = new OAuth1CredentialsInfoImpl();
    oa1Cred.setRemoteUsername(TEST_REMOTE_USERNAME_TWO);
    oa1Cred.setOAuthToken("test");
    REMOTE_CREDENTIALS_SERVICE.createPersonCredentials(TEST_REMOTE_SYSTEM_TWO, oa1Cred);

    OAuth2CredentialsInfoImpl oa2Cred = new OAuth2CredentialsInfoImpl();
    oa2Cred.setRemoteUsername(TEST_REMOTE_USERNAME_THREE);
    oa2Cred.setOauthAccessToken("testA");
    oa2Cred.setOauthRefreshToken("testR");
    REMOTE_CREDENTIALS_SERVICE.createPersonCredentials(TEST_REMOTE_SYSTEM_TWO, oa2Cred);

    // List, should see all three sets of credentials
    creds =
        REMOTE_CREDENTIALS_SERVICE.listPersonCredentials(
            TEST_REMOTE_SYSTEM_TWO, null, new PagingRequest(10));
    assertEquals(3, creds.getPage().size());
    creds =
        REMOTE_CREDENTIALS_SERVICE.listSharedCredentials(
            TEST_REMOTE_SYSTEM_TWO, null, new PagingRequest(10));
    assertEquals(0, creds.getPage().size());
    creds =
        REMOTE_CREDENTIALS_SERVICE.listAllCredentials(
            TEST_REMOTE_SYSTEM_TWO, null, new PagingRequest(10));
    assertEquals(3, creds.getPage().size());

    // List the systems, still only system one and two
    systems = REMOTE_CREDENTIALS_SERVICE.listPersonRemoteSystems(new PagingRequest(10));
    assertEquals(2, systems.getPage().size());
    systems = REMOTE_CREDENTIALS_SERVICE.listSharedRemoteSystems(new PagingRequest(10));
    assertEquals(0, systems.getPage().size());
    systems = REMOTE_CREDENTIALS_SERVICE.listAllRemoteSystems(new PagingRequest(10));
    assertEquals(2, systems.getPage().size());

    // Check we can filter credentials by type
    creds =
        REMOTE_CREDENTIALS_SERVICE.listPersonCredentials(
            TEST_REMOTE_SYSTEM_TWO, null, new PagingRequest(10));
    assertEquals(3, creds.getPage().size());

    creds =
        REMOTE_CREDENTIALS_SERVICE.listPersonCredentials(
            TEST_REMOTE_SYSTEM_TWO,
            RemoteCredentialsModel.TYPE_PASSWORD_CREDENTIALS,
            new PagingRequest(10));
    assertEquals(1, creds.getPage().size());
    assertEquals(TEST_REMOTE_USERNAME_ONE, creds.getPage().get(0).getRemoteUsername());

    creds =
        REMOTE_CREDENTIALS_SERVICE.listPersonCredentials(
            TEST_REMOTE_SYSTEM_TWO,
            RemoteCredentialsModel.TYPE_OAUTH1_CREDENTIALS,
            new PagingRequest(10));
    assertEquals(1, creds.getPage().size());
    assertEquals(TEST_REMOTE_USERNAME_TWO, creds.getPage().get(0).getRemoteUsername());

    creds =
        REMOTE_CREDENTIALS_SERVICE.listPersonCredentials(
            TEST_REMOTE_SYSTEM_TWO,
            RemoteCredentialsModel.TYPE_OAUTH2_CREDENTIALS,
            new PagingRequest(10));
    assertEquals(1, creds.getPage().size());
    assertEquals(TEST_REMOTE_USERNAME_THREE, creds.getPage().get(0).getRemoteUsername());
  }