package com.github.ulisesbocchio.spring.boot.security.saml.configurer.builder;

import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderEndpoints;
import com.github.ulisesbocchio.spring.boot.security.saml.configurer.ServiceProviderBuilder;
import com.github.ulisesbocchio.spring.boot.security.saml.properties.SAMLSSOProperties;
import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.saml.SAMLDiscovery;
import org.springframework.security.saml.SAMLEntryPoint;
import org.springframework.security.saml.SAMLProcessingFilter;
import org.springframework.security.saml.SAMLWebSSOHoKProcessingFilter;
import org.springframework.security.saml.websso.WebSSOProfileOptions;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;

import java.util.Collections;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;

/**
 * @author Ulises Bocchio
 */
public class SSOConfigurerTest {

    private ServiceProviderBuilder builder;
    private ServiceProviderEndpoints serviceProviderEndpoints;
    private SAMLSSOProperties properties;
    private AuthenticationManager authenticationManager;

    @Before
    public void setup() {
        properties = spy(new SAMLSSOProperties());
        serviceProviderEndpoints = spy(new ServiceProviderEndpoints());
        authenticationManager = mock(AuthenticationManager.class);
        builder = mock(ServiceProviderBuilder.class);
        when(builder.getSharedObject(ServiceProviderEndpoints.class)).thenReturn(serviceProviderEndpoints);
        when(builder.getSharedObject(SAMLSSOProperties.class)).thenReturn(properties);
        when(builder.getSharedObject(AuthenticationManager.class)).thenReturn(authenticationManager);
    }

    @Test
    public void init() throws Exception {
        SSOConfigurer configurer = new SSOConfigurer();
        configurer.init(builder);
        verify(builder).getSharedObject(eq(ServiceProviderEndpoints.class));
        verify(builder).getSharedObject(eq(SAMLSSOProperties.class));
        verify(builder).getSharedObject(eq(AuthenticationManager.class));
    }

    @Test
    public void configure_defaults() throws Exception {
        SSOConfigurer configurer = spy(new SSOConfigurer());
        SAMLProcessingFilter ssoFilter = mock(SAMLProcessingFilter.class);
        when(configurer.createDefaultSamlProcessingFilter()).thenReturn(ssoFilter);
        SAMLWebSSOHoKProcessingFilter ssoHoKFilter = mock(SAMLWebSSOHoKProcessingFilter.class);
        when(configurer.createDefaultSamlHoKProcessingFilter()).thenReturn(ssoHoKFilter);
        SAMLDiscovery discoveryFilter = mock(SAMLDiscovery.class);
        when(configurer.createDefaultSamlDiscoveryFilter()).thenReturn(discoveryFilter);
        SAMLEntryPoint entryPoint = mock(SAMLEntryPoint.class);
        when(configurer.createDefaultSamlEntryPoint()).thenReturn(entryPoint);
        SavedRequestAwareAuthenticationSuccessHandler successHandler = mock(SavedRequestAwareAuthenticationSuccessHandler.class);
        when(configurer.createDefaultSuccessHandler()).thenReturn(successHandler);
        SimpleUrlAuthenticationFailureHandler failureHandler = mock(SimpleUrlAuthenticationFailureHandler.class);
        when(configurer.createDefaultFailureHandler()).thenReturn(failureHandler);
        configurer.init(builder);
        configurer.configure(builder);

        verify(properties).getDefaultFailureUrl();
        verify(properties).getDefaultSuccessUrl();
        verify(properties).getDiscoveryProcessingUrl();
        verify(properties).getIdpSelectionPageUrl();
        verify(properties).getSsoHokProcessingUrl();
        verify(properties).getSsoLoginUrl();
        verify(properties).getSsoProcessingUrl();
        verify(properties).getProfileOptions();

        verify(successHandler).setDefaultTargetUrl(eq(properties.getDefaultSuccessUrl()));
        verify(failureHandler).setDefaultFailureUrl(eq(properties.getDefaultFailureUrl()));

        verify(ssoFilter).setAuthenticationManager(eq(authenticationManager));
        verify(ssoFilter).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoFilter).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoFilter).setFilterProcessesUrl(eq(properties.getSsoProcessingUrl()));

        verify(ssoHoKFilter).setAuthenticationManager(eq(authenticationManager));
        verify(ssoHoKFilter).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoHoKFilter).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoHoKFilter).setFilterProcessesUrl(eq(properties.getSsoHokProcessingUrl()));

        verify(serviceProviderEndpoints).setSsoProcessingURL(properties.getSsoProcessingUrl());
        verify(serviceProviderEndpoints).setSsoHoKProcessingURL(properties.getSsoHokProcessingUrl());
        verify(serviceProviderEndpoints).setDefaultFailureURL(properties.getDefaultFailureUrl());
        verify(serviceProviderEndpoints).setDiscoveryProcessingURL(properties.getDiscoveryProcessingUrl());
        verify(serviceProviderEndpoints).setIdpSelectionPageURL(properties.getIdpSelectionPageUrl());
        verify(serviceProviderEndpoints).setSsoLoginURL(properties.getSsoLoginUrl());

        verify(discoveryFilter).setFilterProcessesUrl(eq(properties.getDiscoveryProcessingUrl()));
        verify(discoveryFilter).setIdpSelectionPath(eq(properties.getIdpSelectionPageUrl()));

        verify(entryPoint).setFilterProcessesUrl(eq(properties.getSsoLoginUrl()));
        ArgumentCaptor<WebSSOProfileOptions> optionsCaptor = ArgumentCaptor.forClass(WebSSOProfileOptions.class);
        verify(entryPoint).setDefaultProfileOptions(optionsCaptor.capture());
        WebSSOProfileOptions options = optionsCaptor.getValue();
        Assertions.assertThat(options.isAllowCreate()).isEqualTo(properties.getProfileOptions().getAllowCreate());
        Assertions.assertThat(options.getAllowedIDPs()).isEqualTo(properties.getProfileOptions().getAllowedIdps());
        Assertions.assertThat(options.getAssertionConsumerIndex()).isEqualTo(properties.getProfileOptions().getAssertionConsumerIndex());
        Assertions.assertThat(options.getAuthnContextComparison()).isEqualTo(properties.getProfileOptions().getAuthnContextComparison().getType());
        Assertions.assertThat(options.getAuthnContexts()).isEqualTo(properties.getProfileOptions().getAuthnContexts());
        Assertions.assertThat(options.getBinding()).isEqualTo(properties.getProfileOptions().getBinding());
        Assertions.assertThat(options.getForceAuthN()).isEqualTo(properties.getProfileOptions().getForceAuthn());
        Assertions.assertThat(options.isIncludeScoping()).isEqualTo(properties.getProfileOptions().getIncludeScoping());
        Assertions.assertThat(options.getNameID()).isEqualTo(properties.getProfileOptions().getNameId());
        Assertions.assertThat(options.getPassive()).isEqualTo(properties.getProfileOptions().getPassive());
        Assertions.assertThat(options.getProviderName()).isEqualTo(properties.getProfileOptions().getProviderName());
        Assertions.assertThat(options.getProxyCount()).isEqualTo(properties.getProfileOptions().getProxyCount());
        Assertions.assertThat(options.getRelayState()).isEqualTo(properties.getProfileOptions().getRelayState());

        verify(builder).setSharedObject(eq(SAMLProcessingFilter.class), eq(ssoFilter));
        verify(builder).setSharedObject(eq(SAMLWebSSOHoKProcessingFilter.class), eq(ssoHoKFilter));
        verify(builder).setSharedObject(eq(SAMLDiscovery.class), eq(discoveryFilter));
        verify(builder).setSharedObject(eq(SAMLEntryPoint.class), eq(entryPoint));

    }

    @Test
    public void configure_custom() throws Exception {
        SSOConfigurer configurer = spy(new SSOConfigurer());
        SAMLProcessingFilter ssoFilter = mock(SAMLProcessingFilter.class);
        when(configurer.createDefaultSamlProcessingFilter()).thenReturn(ssoFilter);
        SAMLWebSSOHoKProcessingFilter ssoHoKFilter = mock(SAMLWebSSOHoKProcessingFilter.class);
        when(configurer.createDefaultSamlHoKProcessingFilter()).thenReturn(ssoHoKFilter);
        SAMLDiscovery discoveryFilter = mock(SAMLDiscovery.class);
        when(configurer.createDefaultSamlDiscoveryFilter()).thenReturn(discoveryFilter);
        SAMLEntryPoint entryPoint = mock(SAMLEntryPoint.class);
        when(configurer.createDefaultSamlEntryPoint()).thenReturn(entryPoint);
        SavedRequestAwareAuthenticationSuccessHandler successHandler = mock(SavedRequestAwareAuthenticationSuccessHandler.class);
        SimpleUrlAuthenticationFailureHandler failureHandler = mock(SimpleUrlAuthenticationFailureHandler.class);
        SessionAuthenticationStrategy sessionAuthenticationStrategy = mock(SessionAuthenticationStrategy.class);
        WebSSOProfileOptions profileOptions = new WebSSOProfileOptions();
        profileOptions.setAllowCreate(true);
        profileOptions.setAllowedIDPs(Collections.singleton("allowedIdps"));
        profileOptions.setAssertionConsumerIndex(999);
        profileOptions.setAuthnContextComparison(AuthnContextComparisonTypeEnumeration.MINIMUM);
        profileOptions.setAuthnContexts(Collections.singleton("contexts"));
        profileOptions.setBinding("binding");
        profileOptions.setForceAuthN(true);
        profileOptions.setIncludeScoping(true);
        profileOptions.setNameID("nameId");
        profileOptions.setPassive(true);
        profileOptions.setProviderName("providerName");
        profileOptions.setProxyCount(null);
        profileOptions.setRelayState("relayState");

        configurer.init(builder);
        configurer
                .defaultSuccessURL("/success")
                .failureHandler(failureHandler)
                .successHandler(successHandler)
                .defaultFailureURL("/failure")
                .discoveryProcessingURL("/discovery")
                .enableSsoHoK(true)
                .idpSelectionPageURL("/idp")
                .profileOptions(profileOptions)
                .ssoHoKProcessingURL("/hok")
                .ssoLoginURL("/login")
                .ssoProcessingURL("/sso")
                .sessionAuthenticationStrategy(sessionAuthenticationStrategy);
        configurer.configure(builder);

        verify(properties, never()).getDefaultFailureUrl();
        verify(properties, never()).getDefaultSuccessUrl();
        verify(properties, never()).getDiscoveryProcessingUrl();
        verify(properties, never()).getIdpSelectionPageUrl();
        verify(properties, never()).getSsoHokProcessingUrl();
        verify(properties, never()).getSsoLoginUrl();
        verify(properties, never()).getSsoProcessingUrl();
        verify(properties, never()).getProfileOptions();

        verify(successHandler, never()).setDefaultTargetUrl(eq("/success"));
        verify(failureHandler, never()).setDefaultFailureUrl(eq("/failure"));

        verify(ssoFilter).setAuthenticationManager(eq(authenticationManager));
        verify(ssoFilter).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoFilter).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoFilter).setFilterProcessesUrl(eq("/sso"));
        verify(ssoFilter).setSessionAuthenticationStrategy(eq(sessionAuthenticationStrategy));

        verify(ssoHoKFilter).setAuthenticationManager(eq(authenticationManager));
        verify(ssoHoKFilter).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoHoKFilter).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoHoKFilter).setFilterProcessesUrl(eq("/hok"));
        verify(ssoHoKFilter).setSessionAuthenticationStrategy(eq(sessionAuthenticationStrategy));

        verify(serviceProviderEndpoints).setSsoProcessingURL("/sso");
        verify(serviceProviderEndpoints).setSsoHoKProcessingURL("/hok");
        verify(serviceProviderEndpoints).setDefaultFailureURL("/failure");
        verify(serviceProviderEndpoints).setDiscoveryProcessingURL("/discovery");
        verify(serviceProviderEndpoints).setIdpSelectionPageURL("/idp");
        verify(serviceProviderEndpoints).setSsoLoginURL("/login");

        verify(discoveryFilter).setFilterProcessesUrl(eq("/discovery"));
        verify(discoveryFilter).setIdpSelectionPath(eq("/idp"));

        verify(entryPoint).setFilterProcessesUrl(eq("/login"));
        ArgumentCaptor<WebSSOProfileOptions> optionsCaptor = ArgumentCaptor.forClass(WebSSOProfileOptions.class);
        verify(entryPoint).setDefaultProfileOptions(optionsCaptor.capture());
        WebSSOProfileOptions options = optionsCaptor.getValue();
        Assertions.assertThat(options.isAllowCreate()).isEqualTo(true);
        Assertions.assertThat(options.getAllowedIDPs()).containsExactly("allowedIdps");
        Assertions.assertThat(options.getAssertionConsumerIndex()).isEqualTo(999);
        Assertions.assertThat(options.getAuthnContextComparison()).isEqualTo(AuthnContextComparisonTypeEnumeration.MINIMUM);
        Assertions.assertThat(options.getAuthnContexts()).containsExactly("contexts");
        Assertions.assertThat(options.getBinding()).isEqualTo("binding");
        Assertions.assertThat(options.getForceAuthN()).isEqualTo(true);
        Assertions.assertThat(options.isIncludeScoping()).isEqualTo(true);
        Assertions.assertThat(options.getNameID()).isEqualTo("nameId");
        Assertions.assertThat(options.getPassive()).isEqualTo(true);
        Assertions.assertThat(options.getProviderName()).isEqualTo("providerName");
        Assertions.assertThat(options.getProxyCount()).isEqualTo(null);
        Assertions.assertThat(options.getRelayState()).isEqualTo("relayState");

        verify(builder).setSharedObject(eq(SAMLProcessingFilter.class), eq(ssoFilter));
        verify(builder).setSharedObject(eq(SAMLWebSSOHoKProcessingFilter.class), eq(ssoHoKFilter));
        verify(builder).setSharedObject(eq(SAMLDiscovery.class), eq(discoveryFilter));
        verify(builder).setSharedObject(eq(SAMLEntryPoint.class), eq(entryPoint));

    }

    @SuppressWarnings("unchecked")
    @Test
    public void configure_custom_entry_point() throws Exception {
        SSOConfigurer configurer = spy(new SSOConfigurer());
        SAMLProcessingFilter ssoFilter = mock(SAMLProcessingFilter.class);
        when(configurer.createDefaultSamlProcessingFilter()).thenReturn(ssoFilter);
        SAMLWebSSOHoKProcessingFilter ssoHoKFilter = mock(SAMLWebSSOHoKProcessingFilter.class);
        when(configurer.createDefaultSamlHoKProcessingFilter()).thenReturn(ssoHoKFilter);
        SAMLDiscovery discoveryFilter = mock(SAMLDiscovery.class);
        when(configurer.createDefaultSamlDiscoveryFilter()).thenReturn(discoveryFilter);
        when(configurer.createDefaultSamlEntryPoint()).thenThrow(IllegalStateException.class);
        SavedRequestAwareAuthenticationSuccessHandler successHandler = mock(SavedRequestAwareAuthenticationSuccessHandler.class);
        SimpleUrlAuthenticationFailureHandler failureHandler = mock(SimpleUrlAuthenticationFailureHandler.class);
        WebSSOProfileOptions profileOptions = new WebSSOProfileOptions();
        profileOptions.setAllowCreate(true);
        profileOptions.setAllowedIDPs(Collections.singleton("allowedIdps"));
        profileOptions.setAssertionConsumerIndex(999);
        profileOptions.setAuthnContextComparison(AuthnContextComparisonTypeEnumeration.MINIMUM);
        profileOptions.setAuthnContexts(Collections.singleton("contexts"));
        profileOptions.setBinding("binding");
        profileOptions.setForceAuthN(true);
        profileOptions.setIncludeScoping(true);
        profileOptions.setNameID("nameId");
        profileOptions.setPassive(true);
        profileOptions.setProviderName("providerName");
        profileOptions.setProxyCount(null);
        profileOptions.setRelayState("relayState");

        SAMLEntryPoint customEntryPoint = mock(SAMLEntryPoint.class);
        configurer.init(builder);
        configurer
                .defaultSuccessURL("/success")
                .failureHandler(failureHandler)
                .successHandler(successHandler)
                .defaultFailureURL("/failure")
                .discoveryProcessingURL("/discovery")
                .enableSsoHoK(true)
                .idpSelectionPageURL("/idp")
                .profileOptions(profileOptions)
                .ssoHoKProcessingURL("/hok")
                .ssoLoginURL("/login")
                .ssoProcessingURL("/sso")
                .samlEntryPoint(customEntryPoint);
        configurer.configure(builder);

        verify(properties, never()).getDefaultFailureUrl();
        verify(properties, never()).getDefaultSuccessUrl();
        verify(properties, never()).getDiscoveryProcessingUrl();
        verify(properties, never()).getIdpSelectionPageUrl();
        verify(properties, never()).getSsoHokProcessingUrl();
        verify(properties, never()).getSsoLoginUrl();
        verify(properties, never()).getSsoProcessingUrl();
        verify(properties, never()).getProfileOptions();

        verify(successHandler, never()).setDefaultTargetUrl(eq("/success"));
        verify(failureHandler, never()).setDefaultFailureUrl(eq("/failure"));

        verify(ssoFilter).setAuthenticationManager(eq(authenticationManager));
        verify(ssoFilter).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoFilter).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoFilter).setFilterProcessesUrl(eq("/sso"));

        verify(ssoHoKFilter).setAuthenticationManager(eq(authenticationManager));
        verify(ssoHoKFilter).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoHoKFilter).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoHoKFilter).setFilterProcessesUrl(eq("/hok"));

        verify(serviceProviderEndpoints).setSsoProcessingURL("/sso");
        verify(serviceProviderEndpoints).setSsoHoKProcessingURL("/hok");
        verify(serviceProviderEndpoints).setDefaultFailureURL("/failure");
        verify(serviceProviderEndpoints).setDiscoveryProcessingURL("/discovery");
        verify(serviceProviderEndpoints).setIdpSelectionPageURL("/idp");
        verify(serviceProviderEndpoints).setSsoLoginURL("/login");

        verify(discoveryFilter).setFilterProcessesUrl(eq("/discovery"));
        verify(discoveryFilter).setIdpSelectionPath(eq("/idp"));

        verify(customEntryPoint).setFilterProcessesUrl(eq("/login"));
        ArgumentCaptor<WebSSOProfileOptions> optionsCaptor = ArgumentCaptor.forClass(WebSSOProfileOptions.class);
        verify(customEntryPoint).setDefaultProfileOptions(optionsCaptor.capture());
        WebSSOProfileOptions options = optionsCaptor.getValue();
        Assertions.assertThat(options.isAllowCreate()).isEqualTo(true);
        Assertions.assertThat(options.getAllowedIDPs()).containsExactly("allowedIdps");
        Assertions.assertThat(options.getAssertionConsumerIndex()).isEqualTo(999);
        Assertions.assertThat(options.getAuthnContextComparison()).isEqualTo(AuthnContextComparisonTypeEnumeration.MINIMUM);
        Assertions.assertThat(options.getAuthnContexts()).containsExactly("contexts");
        Assertions.assertThat(options.getBinding()).isEqualTo("binding");
        Assertions.assertThat(options.getForceAuthN()).isEqualTo(true);
        Assertions.assertThat(options.isIncludeScoping()).isEqualTo(true);
        Assertions.assertThat(options.getNameID()).isEqualTo("nameId");
        Assertions.assertThat(options.getPassive()).isEqualTo(true);
        Assertions.assertThat(options.getProviderName()).isEqualTo("providerName");
        Assertions.assertThat(options.getProxyCount()).isEqualTo(null);
        Assertions.assertThat(options.getRelayState()).isEqualTo("relayState");

        verify(builder).setSharedObject(eq(SAMLProcessingFilter.class), eq(ssoFilter));
        verify(builder).setSharedObject(eq(SAMLWebSSOHoKProcessingFilter.class), eq(ssoHoKFilter));
        verify(builder).setSharedObject(eq(SAMLDiscovery.class), eq(discoveryFilter));
        verify(builder).setSharedObject(eq(SAMLEntryPoint.class), eq(customEntryPoint));

    }

    @Test
    public void configure_custom_noHoK() throws Exception {
        SSOConfigurer configurer = spy(new SSOConfigurer());
        SAMLProcessingFilter ssoFilter = mock(SAMLProcessingFilter.class);
        when(configurer.createDefaultSamlProcessingFilter()).thenReturn(ssoFilter);
        SAMLWebSSOHoKProcessingFilter ssoHoKFilter = mock(SAMLWebSSOHoKProcessingFilter.class);
        when(configurer.createDefaultSamlHoKProcessingFilter()).thenReturn(ssoHoKFilter);
        SAMLDiscovery discoveryFilter = mock(SAMLDiscovery.class);
        when(configurer.createDefaultSamlDiscoveryFilter()).thenReturn(discoveryFilter);
        SAMLEntryPoint entryPoint = mock(SAMLEntryPoint.class);
        when(configurer.createDefaultSamlEntryPoint()).thenReturn(entryPoint);
        SavedRequestAwareAuthenticationSuccessHandler successHandler = mock(SavedRequestAwareAuthenticationSuccessHandler.class);
        SimpleUrlAuthenticationFailureHandler failureHandler = mock(SimpleUrlAuthenticationFailureHandler.class);
        WebSSOProfileOptions profileOptions = mock(WebSSOProfileOptions.class);

        configurer.init(builder);
        configurer
                .defaultSuccessURL("/success")
                .failureHandler(failureHandler)
                .successHandler(successHandler)
                .defaultFailureURL("/failure")
                .discoveryProcessingURL("/discovery")
                .enableSsoHoK(false)
                .idpSelectionPageURL("/idp")
                .profileOptions(profileOptions)
                .ssoHoKProcessingURL("/hok")
                .ssoLoginURL("/login")
                .ssoProcessingURL("/sso");
        configurer.configure(builder);

        verify(properties, never()).getDefaultFailureUrl();
        verify(properties, never()).getDefaultSuccessUrl();
        verify(properties, never()).getDiscoveryProcessingUrl();
        verify(properties, never()).getIdpSelectionPageUrl();
        verify(properties, never()).getSsoHokProcessingUrl();
        verify(properties, never()).getSsoLoginUrl();
        verify(properties, never()).getSsoProcessingUrl();
        verify(properties, never()).getProfileOptions();

        verify(successHandler, never()).setDefaultTargetUrl(eq("/success"));
        verify(failureHandler, never()).setDefaultFailureUrl(eq("/failure"));

        verify(ssoFilter).setAuthenticationManager(eq(authenticationManager));
        verify(ssoFilter).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoFilter).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoFilter).setFilterProcessesUrl(eq("/sso"));

        verify(ssoHoKFilter, never()).setAuthenticationManager(eq(authenticationManager));
        verify(ssoHoKFilter, never()).setAuthenticationSuccessHandler(eq(successHandler));
        verify(ssoHoKFilter, never()).setAuthenticationFailureHandler(eq(failureHandler));
        verify(ssoHoKFilter, never()).setFilterProcessesUrl(eq("/hok"));

        verify(serviceProviderEndpoints).setSsoProcessingURL("/sso");
        verify(serviceProviderEndpoints, never()).setSsoHoKProcessingURL("/hok");
        verify(serviceProviderEndpoints).setDefaultFailureURL("/failure");
        verify(serviceProviderEndpoints).setDiscoveryProcessingURL("/discovery");
        verify(serviceProviderEndpoints).setIdpSelectionPageURL("/idp");
        verify(serviceProviderEndpoints).setSsoLoginURL("/login");

        verify(discoveryFilter).setFilterProcessesUrl(eq("/discovery"));
        verify(discoveryFilter).setIdpSelectionPath(eq("/idp"));

        verify(entryPoint).setFilterProcessesUrl(eq("/login"));
        verify(entryPoint).setDefaultProfileOptions(eq(profileOptions));

        verify(builder).setSharedObject(eq(SAMLProcessingFilter.class), eq(ssoFilter));
        verify(builder).setSharedObject(eq(SAMLWebSSOHoKProcessingFilter.class), eq(null));
        verify(builder).setSharedObject(eq(SAMLDiscovery.class), eq(discoveryFilter));
        verify(builder).setSharedObject(eq(SAMLEntryPoint.class), eq(entryPoint));

    }

}