/*
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.jasig.cas.support.pac4j.authentication.handler.support;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;

import java.security.GeneralSecurityException;

import org.jasig.cas.support.pac4j.test.MockOpenScienceFrameworkInstitutionHandler;
import org.jasig.cas.authentication.HandlerResult;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.support.pac4j.authentication.principal.ClientCredential;
import org.jasig.cas.support.pac4j.test.MockCasClient;
import org.jasig.cas.support.pac4j.test.MockOrcidClient;
import org.junit.Before;
import org.junit.Test;
import org.pac4j.cas.client.CasClient;
import org.pac4j.cas.credentials.CasCredentials;
import org.pac4j.cas.profile.CasProfile;
import org.pac4j.core.client.Clients;
import org.pac4j.core.credentials.Credentials;
import org.pac4j.oauth.credentials.OAuthCredentials;
import org.pac4j.oauth.profile.orcid.OrcidProfile;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.context.servlet.ServletExternalContext;

import javax.security.auth.login.FailedLoginException;


/**
 *This class tests the {@link ClientAuthenticationHandler} class.
 *
 * @author Longze Chen
 * @since 4.1
 */
public final class ClientAuthenticationHandlerTests {

    private static final String CALLBACK_URL = "http://localhost:8080/login";

    private static final String INSTITUTION_CAS_CLIENT = "CasClientInstitution";

    private static final String NON_INSTITUTION_CAS_CLIENT = "CasClientNonInstitution";

    private static final String PROFILE_ID = "0123456789";

    private ClientAuthenticationHandler clientAuthenticationHandler;

    private ClientCredential clientCredential;

    private MockCasClient mockInstitutionCasClient;

    private MockCasClient mockNonInstitutionCasClient;

    private MockOrcidClient mockOrcidClient;

    private CasProfile mockCasProfile;

    private OrcidProfile mockOrcidProfile;


    @Before
    public void setUp() {

        // mock institution handler
        final MockOpenScienceFrameworkInstitutionHandler institutionHandler = new MockOpenScienceFrameworkInstitutionHandler();

        // mock institution cas client
        mockInstitutionCasClient = new MockCasClient();
        mockInstitutionCasClient.setClientName(INSTITUTION_CAS_CLIENT);
        mockInstitutionCasClient.setCasProtocol(CasClient.CasProtocol.SAML);

        // mock non-institution cas client
        mockNonInstitutionCasClient = new MockCasClient();
        mockNonInstitutionCasClient.setClientName(NON_INSTITUTION_CAS_CLIENT);
        mockNonInstitutionCasClient.setCasProtocol(CasClient.CasProtocol.CAS20);

        // mock orcid client
        mockOrcidClient = new MockOrcidClient();

        // initialize client and authentication handler
        final Clients clients = new Clients(
                CALLBACK_URL,
                mockInstitutionCasClient,
                mockNonInstitutionCasClient,
                mockOrcidClient
        );
        clientAuthenticationHandler = new ClientAuthenticationHandler(institutionHandler, clients);

        // mock profile
        mockCasProfile = new CasProfile();
        mockCasProfile.setId(PROFILE_ID);
        mockInstitutionCasClient.setCasProfile(mockCasProfile);
        mockNonInstitutionCasClient.setCasProfile(mockCasProfile);
        mockOrcidProfile = new OrcidProfile();
        mockOrcidProfile.setId(PROFILE_ID);
        mockOrcidClient.setOrcidProfile(mockOrcidProfile);

        ExternalContextHolder.setExternalContext(mock(ServletExternalContext.class));
    }

    @Test
    public void verifyPrincipleIdForInstitutionCasClients() throws GeneralSecurityException, PreventedException {

        final Credentials credentials = new CasCredentials(null, mockInstitutionCasClient.getName());
        clientCredential = new ClientCredential(credentials);

        final HandlerResult result = clientAuthenticationHandler.createResult(clientCredential, mockCasProfile);
        final Principal principal = result.getPrincipal();
        final String expectedPrincipalId = INSTITUTION_CAS_CLIENT + '#' + mockCasProfile.getId();
        assertEquals(expectedPrincipalId, principal.getId());
    }

    @Test(expected = FailedLoginException.class)
    public void verifyPrincipleIdForNonInstitutionCasClients() throws GeneralSecurityException, PreventedException {

        final Credentials credentials = new CasCredentials(null, mockNonInstitutionCasClient.getName());
        clientCredential = new ClientCredential(credentials);
        final HandlerResult result = clientAuthenticationHandler.createResult(clientCredential, mockCasProfile);
    }

    @Test
    public void verifyPrincipleIdForNonCasClients() throws GeneralSecurityException, PreventedException {

        final Credentials credentials = new OAuthCredentials(null, mockOrcidClient.getName());
        final ClientCredential clientCredential = new ClientCredential(credentials);

        final HandlerResult result = this.clientAuthenticationHandler.createResult(clientCredential, mockOrcidProfile);
        final Principal principal = result.getPrincipal();
        final String expectedPrincipalId = OrcidProfile.class.getSimpleName() + "#" + mockCasProfile.getId();
        assertEquals(expectedPrincipalId, principal.getId());
    }
}

@@ -1946,64 +1946,8 @@
 t;%0A%0A
-import javax.security.auth.login.FailedLoginException;%0A%0A
 %0A/**
@@ -2171,22 +2171,17 @@
 p://
-localhost:8080
+casserver
 /log
@@ -2272,97 +2272,8 @@
 %22;%0A%0A
-    private static final String NON_INSTITUTION_CAS_CLIENT = %22CasClientNonInstitution%22;%0A%0A
     
@@ -2515,49 +2515,33 @@
 ate 
-MockCasClient mockNonInstitutionCasClient
+CasProfile mockCasProfile
 ;%0A%0A 
@@ -2589,48 +2589,8 @@
 t;%0A%0A
-    private CasProfile mockCasProfile;%0A%0A
     
@@ -3083,271 +3083,8 @@
 );%0A%0A
-        // mock non-institution cas client%0A        mockNonInstitutionCasClient = new MockCasClient();%0A        mockNonInstitutionCasClient.setClientName(NON_INSTITUTION_CAS_CLIENT);%0A        mockNonInstitutionCasClient.setCasProtocol(CasClient.CasProtocol.CAS20);%0A%0A
     
@@ -3335,53 +3335,8 @@
 nt,%0A
-                mockNonInstitutionCasClient,%0A
     
@@ -3652,75 +3652,8 @@
 e);%0A
-        mockNonInstitutionCasClient.setCasProfile(mockCasProfile);%0A
     
@@ -4118,33 +4118,32 @@
 Name());%0A       
- 
 clientCredential
@@ -4365,680 +4365,129 @@
     
-final String expectedPrincipalId = INSTITUTION_CAS_CLIENT + '#' + mockCasProfile.getId();%0A        assertEquals(expectedPrincipalId, principal.getId());%0A    %7D%0A%0A    @Test(expected = FailedLoginException.class)%0A    public void verifyPrincipleIdForNonInstitutionCasClients() throws GeneralSecurityException, PreventedException %7B%0A%0A        final Credentials credentials = new CasCredentials(null, mockNonInstitutionCasClient.getName());%0A        clientCredential = new ClientCredential(credentials);%0A        final HandlerResult result = clientAuthenticationHandler.createResult(clientCredential, mockCasProfile);%0A    %7D%0A%0A    @Test%0A    public void verifyPrincipleIdForNonCasClients
+assertEquals(INSTITUTION_CAS_CLIENT, principal.getId());%0A    %7D%0A%0A    @Test%0A    public void verifyPrincipleIdForOrcidClient
 () t
@@ -4647,31 +4647,8 @@
     
-final ClientCredential 
 clie
@@ -4889,43 +4889,21 @@
     
-final String expectedPrincipalId = 
+assertEquals(
 Orci
@@ -4941,27 +4941,29 @@
 + %22#%22 + mock
-Cas
+Orcid
 Profile.getI
@@ -4969,50 +4969,8 @@
 Id()
-;%0A        assertEquals(expectedPrincipalId
 , pr

Update tests.