@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());
  }
  @SuppressWarnings("unchecked")
  @Test
  public void addConnection() {
    UsersConnectionRepository usersConnectionRepository = mock(UsersConnectionRepository.class);
    SocialAuthenticationFilter filter =
        new SocialAuthenticationFilter(null, null, usersConnectionRepository, null);

    SocialAuthenticationService<Object> authService = mock(SocialAuthenticationService.class);
    ConnectionRepository connectionRepository = mock(ConnectionRepository.class);
    ConnectionFactory<Object> connectionFactory = mock(MockConnectionFactory.class);

    MockHttpServletRequest request = new MockHttpServletRequest();
    ConnectionData data =
        new ConnectionData("dummyprovider", "1234", null, null, null, null, null, null, null);
    String userId = "joe";

    DummyConnection<Object> connection = DummyConnection.dummy(data.getProviderId(), userId);

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

    when(authService.getConnectionCardinality()).thenReturn(ConnectionCardinality.ONE_TO_ONE);
    when(authService.getConnectionFactory()).thenReturn(connectionFactory);
    when(authService.getConnectionAddedRedirectUrl(request, connection)).thenReturn("/redirect");

    when(connectionFactory.createConnection(data)).thenReturn(connection);

    Connection<?> addedConnection = filter.addConnection(authService, userId, data);
    assertNotNull(addedConnection);
    assertSame(connection, addedConnection);

    verify(connectionRepository).addConnection(connection);
  }