package org.apereo.cas.web.flow.action;

import org.apereo.cas.authentication.Authentication;
import org.apereo.cas.authentication.AuthenticationResultBuilder;
import org.apereo.cas.authentication.CoreAuthenticationTestUtils;
import org.apereo.cas.authentication.SurrogateUsernamePasswordCredential;
import org.apereo.cas.authentication.surrogate.SurrogateAuthenticationService;
import org.apereo.cas.web.flow.CasWebflowConstants;
import org.apereo.cas.web.flow.SurrogateWebflowConfigurer;
import org.apereo.cas.web.support.WebUtils;

import lombok.val;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.webflow.context.servlet.ServletExternalContext;
import org.springframework.webflow.execution.Action;
import org.springframework.webflow.test.MockRequestContext;

import java.util.LinkedHashMap;
import java.util.Optional;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

/**
 * This is {@link LoadSurrogatesListActionTests}.
 *
 * @author Misagh Moayyed
 * @since 5.3.0
 */
public class LoadSurrogatesListActionTests extends BaseSurrogateInitialAuthenticationActionTests {

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Autowired
    @Qualifier("loadSurrogatesListAction")
    private Action loadSurrogatesListAction;

    @Test
    public void verifyGetListView() {
        try {
            val context = new MockRequestContext();
            val request = new MockHttpServletRequest();
            context.setExternalContext(new ServletExternalContext(new MockServletContext(), request, new MockHttpServletResponse()));

            WebUtils.putRequestSurrogateAuthentication(context, true);
            WebUtils.putCredential(context, CoreAuthenticationTestUtils.getCredentialsWithSameUsernameAndPassword("casuser"));

            assertEquals(SurrogateWebflowConfigurer.TRANSITION_ID_SURROGATE_VIEW, loadSurrogatesListAction.execute(context).getId());
            assertNotNull(WebUtils.getSurrogateAuthenticationAccounts(context));
        } catch (final Exception e) {
            throw new AssertionError(e);
        }
    }

    @Test
    public void verifyAuthenticate() throws Exception {
        val context = new MockRequestContext();
        WebUtils.putService(context, CoreAuthenticationTestUtils.getWebApplicationService());

        val attributes = new LinkedHashMap<String, Object>();
        attributes.put(SurrogateAuthenticationService.AUTHENTICATION_ATTR_SURROGATE_ENABLED, true);
        attributes.putAll(CoreAuthenticationTestUtils.getAttributeRepository().getBackingMap());

        val p = CoreAuthenticationTestUtils.getPrincipal("casuser", attributes);
        WebUtils.putAuthentication(CoreAuthenticationTestUtils.getAuthentication(p), context);

        val request = new MockHttpServletRequest();
        context.setExternalContext(new ServletExternalContext(new MockServletContext(), request, new MockHttpServletResponse()));

        val creds = new SurrogateUsernamePasswordCredential();
        creds.setPassword("Mellon");
        creds.setUsername("casuser");
        creds.setSurrogateUsername("cassurrogate");
        WebUtils.putCredential(context, creds);

        val builder = mock(AuthenticationResultBuilder.class);
        when(builder.getInitialAuthentication()).thenReturn(Optional.of(CoreAuthenticationTestUtils.getAuthentication()));
        when(builder.collect(any(Authentication.class))).thenReturn(builder);

        WebUtils.putAuthenticationResultBuilder(builder, context);
        assertEquals(CasWebflowConstants.TRANSITION_ID_SUCCESS, loadSurrogatesListAction.execute(context).getId());
    }
}

@@ -3977,11 +3977,1623 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void verifySkipAuthenticate() throws Exception %7B%0A        val context = new MockRequestContext();%0A        WebUtils.putService(context, CoreAuthenticationTestUtils.getWebApplicationService());%0A        WebUtils.putRequestSurrogateAuthentication(context, Boolean.TRUE);%0A%0A        val attributes = new LinkedHashMap%3CString, Object%3E();%0A        attributes.put(SurrogateAuthenticationService.AUTHENTICATION_ATTR_SURROGATE_ENABLED, true);%0A        attributes.putAll(CoreAuthenticationTestUtils.getAttributeRepository().getBackingMap());%0A%0A        val p = CoreAuthenticationTestUtils.getPrincipal(%22someuser%22, attributes);%0A        WebUtils.putAuthentication(CoreAuthenticationTestUtils.getAuthentication(p), context);%0A%0A        val request = new MockHttpServletRequest();%0A        context.setExternalContext(new ServletExternalContext(new MockServletContext(), request, new MockHttpServletResponse()));%0A%0A        val creds = new SurrogateUsernamePasswordCredential();%0A        creds.setPassword(%22Mellon%22);%0A        creds.setUsername(%22someuser%22);%0A        creds.setSurrogateUsername(%22others%22);%0A        WebUtils.putCredential(context, creds);%0A%0A        val builder = mock(AuthenticationResultBuilder.class);%0A        when(builder.getInitialAuthentication()).thenReturn(Optional.of(CoreAuthenticationTestUtils.getAuthentication()));%0A        when(builder.collect(any(Authentication.class))).thenReturn(builder);%0A%0A        WebUtils.putAuthenticationResultBuilder(builder, context);%0A        assertEquals(SurrogateWebflowConfigurer.TRANSITION_ID_SKIP_SURROGATE, loadSurrogatesListAction.execute(context).getId());%0A    %7D
 %0A%7D%0A

add tests for surrogate skip events in swf