@Test
  public void testCheckHeaders() throws IOException {
    @SuppressWarnings("unchecked")
    Map<String, String> originalHeaders =
        JsonUtils.readObjectFromJsonString(
            IOUtils.toString(getClass().getResource("shibboleth_headers_original.json")),
            Map.class);
    Map<String, String> currentHeaders = new HashMap<>(originalHeaders);

    // When all headers are the same
    HeaderCheckResult result =
        institutionalSignInManager.checkHeaders(originalHeaders, currentHeaders);
    assertTrue(result.isSuccess());
    assertEquals(0, result.getMismatches().size());

    // When eppn is different
    currentHeaders.put("eppn", "*****@*****.**");
    result = institutionalSignInManager.checkHeaders(originalHeaders, currentHeaders);
    assertFalse(result.isSuccess());
    assertEquals(1, result.getMismatches().size());
    HeaderMismatch mismatch = result.getMismatches().get(0);
    assertEquals("eppn", mismatch.getHeaderName());
    assertEquals("*****@*****.**", mismatch.getOriginalValue());
    assertEquals("*****@*****.**", mismatch.getCurrentValue());

    // When eppn was originally there, but is not now
    currentHeaders.remove("eppn");
    result = institutionalSignInManager.checkHeaders(originalHeaders, currentHeaders);
    assertTrue(result.isSuccess());
    assertEquals(0, result.getMismatches().size());
  }
  @Test
  public void testDontPersistAndDontNotify() throws UnsupportedEncodingException {
    List<OrcidOauth2TokenDetail> existingTokens = new ArrayList<OrcidOauth2TokenDetail>();
    OrcidOauth2TokenDetail token1 = new OrcidOauth2TokenDetail();
    Date expirationDate = new Date(System.currentTimeMillis() + 5000);
    token1.setTokenExpiration(expirationDate);
    existingTokens.add(token1);
    when(mock_userConnectionDao.findByProviderIdAndProviderUserIdAndIdType(
            Matchers.anyString(), Matchers.anyString(), Matchers.anyString()))
        .thenReturn(new UserconnectionEntity());
    when(mock_clientDetailsEntityCacheManager.retrieveByIdP(Matchers.anyString()))
        .thenThrow(new IllegalArgumentException());
    when(mock_orcidOauth2TokenDetailDao.findByClientIdAndUserName(
            Matchers.anyString(), Matchers.anyString()))
        .thenReturn(existingTokens);

    institutionalSignInManager.createUserConnectionAndNotify(
        "idType",
        "remoteUserId",
        "displayName",
        "providerId",
        userOrcid,
        Collections.<String, String>emptyMap());

    verify(mock_userConnectionDao, never()).persist(Matchers.any());
    verify(mock_notificationManager, never()).sendAcknowledgeMessage(userOrcid, clientId);
  }
  @Test
  public void testDontSendNotificationIfAtLeastOneTokenIsNotExpired()
      throws UnsupportedEncodingException {
    ClientDetailsEntity testClient = new ClientDetailsEntity(clientId);
    List<OrcidOauth2TokenDetail> existingTokens = new ArrayList<OrcidOauth2TokenDetail>();

    // Expired 1
    OrcidOauth2TokenDetail token1 = new OrcidOauth2TokenDetail();
    token1.setTokenExpiration(new Date(System.currentTimeMillis() - 1000));

    // Expired 2
    OrcidOauth2TokenDetail token2 = new OrcidOauth2TokenDetail();
    token1.setTokenExpiration(new Date(System.currentTimeMillis() - 2000));

    // Expired 3
    OrcidOauth2TokenDetail token3 = new OrcidOauth2TokenDetail();
    token1.setTokenExpiration(new Date(System.currentTimeMillis() - 2000));

    // Live 1
    OrcidOauth2TokenDetail token4 = new OrcidOauth2TokenDetail();
    token1.setTokenExpiration(new Date(System.currentTimeMillis() + 5000));

    existingTokens.add(token1);
    existingTokens.add(token2);
    existingTokens.add(token3);
    existingTokens.add(token4);

    when(mock_userConnectionDao.findByProviderIdAndProviderUserIdAndIdType(
            Matchers.anyString(), Matchers.anyString(), Matchers.anyString()))
        .thenReturn(null);
    when(mock_clientDetailsEntityCacheManager.retrieveByIdP(Matchers.anyString()))
        .thenReturn(testClient);
    when(mock_orcidOauth2TokenDetailDao.findByClientIdAndUserName(
            Matchers.anyString(), Matchers.anyString()))
        .thenReturn(existingTokens);

    institutionalSignInManager.createUserConnectionAndNotify(
        "idType",
        "remoteUserId",
        "displayName",
        "providerId",
        userOrcid,
        Collections.<String, String>emptyMap());

    verify(mock_userConnectionDao, times(1)).persist(Matchers.any());
    verify(mock_notificationManager, never()).sendAcknowledgeMessage(userOrcid, clientId);
  }
  @Test
  public void testDontSendNotificationIfIdPNotLinkedToClient() throws UnsupportedEncodingException {
    when(mock_userConnectionDao.findByProviderIdAndProviderUserIdAndIdType(
            Matchers.anyString(), Matchers.anyString(), Matchers.anyString()))
        .thenReturn(null);
    when(mock_clientDetailsEntityCacheManager.retrieveByIdP(Matchers.anyString()))
        .thenThrow(new IllegalArgumentException());
    when(mock_orcidOauth2TokenDetailDao.findByClientIdAndUserName(
            Matchers.anyString(), Matchers.anyString()))
        .thenReturn(null);

    institutionalSignInManager.createUserConnectionAndNotify(
        "idType",
        "remoteUserId",
        "displayName",
        "providerId",
        userOrcid,
        Collections.<String, String>emptyMap());

    verify(mock_userConnectionDao, times(1)).persist(Matchers.any());
    verify(mock_notificationManager, never()).sendAcknowledgeMessage(userOrcid, clientId);
  }