@SuppressWarnings("unchecked")
  @Test
  public void testExplicitAuth() throws Exception {

    FilterTestEnv env = new FilterTestEnv("GET", "/auth", null);
    env.filter.setFilterProcessesUrl(env.req.getRequestURI());
    env.filter.setPostLoginUrl("/success");

    ConnectionFactory<Object> factory = mock(MockConnectionFactory.class);
    when(factory.getProviderId()).thenReturn("mock");
    env.req.setRequestURI(env.req.getRequestURI() + "/" + factory.getProviderId());

    SocialAuthenticationService<Object> authService = mock(SocialAuthenticationService.class);
    when(authService.getConnectionCardinality()).thenReturn(ConnectionCardinality.ONE_TO_ONE);
    when(authService.getConnectionFactory()).thenReturn(factory);
    when(authService.getAuthToken(env.req, env.res)).thenReturn(env.auth);
    env.addAuthService(authService);

    when(env.authManager.authenticate(env.auth)).thenReturn(env.authSuccess);

    assertNull(SecurityContextHolder.getContext().getAuthentication());

    env.doFilter();

    assertNotNull(SecurityContextHolder.getContext().getAuthentication());

    assertEquals("/success", env.res.getRedirectedUrl());
  }
  @SuppressWarnings("unchecked")
  private void testFailedAuth(FilterTestEnv env) throws Exception {
    env.filter.setFilterProcessesUrl(env.req.getRequestURI());
    env.filter.setPostLoginUrl("/success");

    ConnectionFactory<Object> factory = mock(MockConnectionFactory.class);
    when(factory.getProviderId()).thenReturn("mock");
    env.req.setRequestURI(env.req.getRequestURI() + "/" + factory.getProviderId());

    SocialAuthenticationService<Object> authService = mock(SocialAuthenticationService.class);
    when(authService.getConnectionCardinality()).thenReturn(ConnectionCardinality.ONE_TO_ONE);
    when(authService.getConnectionFactory()).thenReturn(factory);
    when(authService.getAuthToken(env.req, env.res)).thenReturn(env.auth);
    env.addAuthService(authService);

    when(env.authManager.authenticate(env.auth)).thenThrow(new BadCredentialsException("Failed"));

    assertNull(SecurityContextHolder.getContext().getAuthentication());

    env.doFilter();

    assertNull(SecurityContextHolder.getContext().getAuthentication());

    assertEquals("http://localhost/register", env.res.getRedirectedUrl());
  }
  @SuppressWarnings("unchecked")
  @Test
  public void addConnection_authenticated() throws Exception {

    FilterTestEnv env = new FilterTestEnv("GET", "/auth", null);
    env.filter.setFilterProcessesUrl(env.req.getRequestURI());
    env.filter.setPostLoginUrl("/success");
    env.filter.setConnectionAddedRedirectUrl("/added");
    env.filter.setConnectionAddingFailureRedirectUrl("/add-failed");

    Connection<?> connection = env.auth.getConnection();
    ConnectionData data = connection.createData();
    String userId = "joe";

    ConnectionFactory<Object> factory = mock(MockConnectionFactory.class);
    when(factory.getProviderId()).thenReturn("mock");
    when(factory.createConnection(data)).thenReturn((Connection<Object>) connection);
    env.req.setRequestURI(env.req.getRequestURI() + "/" + factory.getProviderId());

    SocialAuthenticationService<Object> authService = mock(SocialAuthenticationService.class);
    when(authService.getConnectionCardinality()).thenReturn(ConnectionCardinality.ONE_TO_ONE);
    when(authService.getConnectionFactory()).thenReturn(factory);
    when(authService.getAuthToken(env.req, env.res)).thenReturn(env.auth);
    env.addAuthService(authService);

    when(env.userIdSource.getUserId()).thenReturn(userId);

    when(env.usersConnectionRepository.findUserIdsConnectedTo(
            data.getProviderId(), set(data.getProviderUserId())))
        .thenReturn(empty(String.class));

    // fallback to default /added
    when(authService.getConnectionAddedRedirectUrl(env.req, connection)).thenReturn(null);

    // already authenticated
    SecurityContextHolder.getContext().setAuthentication(env.authSuccess);

    env.doFilter();

    // still authenticated
    assertSame(env.authSuccess, SecurityContextHolder.getContext().getAuthentication());

    assertEquals("/added", env.res.getRedirectedUrl());

    verify(env.connectionRepository).addConnection(env.auth.getConnection());
  }