@Test
  public void grantAccessTokenUserNotFound() throws Exception {
    oauth.clientId("resource-owner");

    OAuthClient.AccessTokenResponse response =
        oauth.doGrantAccessTokenRequest("secret", "invalid", "invalid");

    assertEquals(401, response.getStatusCode());

    assertEquals("invalid_grant", response.getError());

    events
        .expectLogin()
        .client("resource-owner")
        .user((String) null)
        .session((String) null)
        .detail(Details.AUTH_METHOD, "oauth_credentials")
        .detail(Details.RESPONSE_TYPE, "token")
        .detail(Details.USERNAME, "invalid")
        .removeDetail(Details.CODE_ID)
        .removeDetail(Details.REDIRECT_URI)
        .removeDetail(Details.CONSENT)
        .error(Errors.INVALID_USER_CREDENTIALS)
        .assertEvent();
  }
  @Test
  public void grantAccessTokenLogout() throws Exception {
    oauth.clientId("resource-owner");

    OAuthClient.AccessTokenResponse response =
        oauth.doGrantAccessTokenRequest("secret", "test-user@localhost", "password");

    assertEquals(200, response.getStatusCode());

    AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
    RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken());

    events
        .expectLogin()
        .client("resource-owner")
        .session(accessToken.getSessionState())
        .detail(Details.AUTH_METHOD, "oauth_credentials")
        .detail(Details.RESPONSE_TYPE, "token")
        .detail(Details.TOKEN_ID, accessToken.getId())
        .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
        .removeDetail(Details.CODE_ID)
        .removeDetail(Details.REDIRECT_URI)
        .removeDetail(Details.CONSENT)
        .assertEvent();

    HttpResponse logoutResponse = oauth.doLogout(response.getRefreshToken(), "secret");
    assertEquals(204, logoutResponse.getStatusLine().getStatusCode());
    events
        .expectLogout(accessToken.getSessionState())
        .client("resource-owner")
        .removeDetail(Details.REDIRECT_URI)
        .assertEvent();

    response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret");
    assertEquals(400, response.getStatusCode());
    assertEquals("invalid_grant", response.getError());

    events
        .expectRefresh(refreshToken.getId(), refreshToken.getSessionState())
        .client("resource-owner")
        .removeDetail(Details.TOKEN_ID)
        .removeDetail(Details.UPDATED_REFRESH_TOKEN_ID)
        .error(Errors.INVALID_TOKEN)
        .assertEvent();
  }
  private void grantAccessToken(String login) throws Exception {
    oauth.clientId("resource-owner");

    OAuthClient.AccessTokenResponse response =
        oauth.doGrantAccessTokenRequest("secret", login, "password");

    assertEquals(200, response.getStatusCode());

    AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
    RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken());

    events
        .expectLogin()
        .client("resource-owner")
        .user(userId)
        .session(accessToken.getSessionState())
        .detail(Details.AUTH_METHOD, "oauth_credentials")
        .detail(Details.RESPONSE_TYPE, "token")
        .detail(Details.TOKEN_ID, accessToken.getId())
        .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
        .detail(Details.USERNAME, login)
        .removeDetail(Details.CODE_ID)
        .removeDetail(Details.REDIRECT_URI)
        .removeDetail(Details.CONSENT)
        .assertEvent();

    assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());

    OAuthClient.AccessTokenResponse refreshedResponse =
        oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret");

    AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken());
    RefreshToken refreshedRefreshToken =
        oauth.verifyRefreshToken(refreshedResponse.getRefreshToken());

    assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState());
    assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState());

    events
        .expectRefresh(refreshToken.getId(), refreshToken.getSessionState())
        .user(userId)
        .client("resource-owner")
        .assertEvent();
  }
  @Test
  public void grantAccessTokenInvalidClientCredentials() throws Exception {
    oauth.clientId("resource-owner");

    OAuthClient.AccessTokenResponse response =
        oauth.doGrantAccessTokenRequest("invalid", "test-user@localhost", "password");

    assertEquals(400, response.getStatusCode());

    assertEquals("unauthorized_client", response.getError());

    events
        .expectLogin()
        .client("resource-owner")
        .session((String) null)
        .clearDetails()
        .error(Errors.INVALID_CLIENT_CREDENTIALS)
        .user((String) null)
        .assertEvent();
  }
  @Test
  public void getApplicationSessions() throws Exception {
    OAuthClient.AccessTokenResponse response =
        oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
    assertEquals(200, response.getStatusCode());

    OAuthClient.AuthorizationCodeResponse codeResponse =
        oauth.doLogin("test-user@localhost", "password");

    OAuthClient.AccessTokenResponse response2 =
        oauth.doAccessTokenRequest(codeResponse.getCode(), "password");
    assertEquals(200, response2.getStatusCode());

    ApplicationResource app = keycloak.realm("test").applications().get("test-app");

    assertEquals(2, (long) app.getApplicationSessionCount().get("count"));

    List<UserSessionRepresentation> userSessions = app.getUserSessions(0, 100);
    assertEquals(2, userSessions.size());
    assertEquals(1, userSessions.get(0).getApplications().size());
  }