package org.apereo.cas.authentication.principal;

import org.apereo.cas.adaptors.ldap.AbstractLdapTests;
import org.apereo.cas.authentication.CoreAuthenticationTestUtils;
import org.apereo.cas.authentication.UsernamePasswordCredential;
import org.apereo.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler;
import org.apereo.cas.authentication.principal.resolvers.ChainingPrincipalResolver;
import org.apereo.cas.authentication.principal.resolvers.EchoingPrincipalResolver;
import org.apereo.cas.authentication.principal.resolvers.PersonDirectoryPrincipalResolver;
import org.apereo.cas.config.CasPersonDirectoryConfiguration;
import org.apereo.services.persondir.IPersonAttributeDao;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.*;

/**
 * This is {@link PersonDirectoryPrincipalResolverLdaptiveTests}.
 *
 * @author Misagh Moayyed
 * @since 5.0.0
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {CasPersonDirectoryConfiguration.class, RefreshAutoConfiguration.class})
@TestPropertySource(locations = {"classpath:/ldap.properties"})
@DirtiesContext
public class PersonDirectoryPrincipalResolverLdaptiveTests extends AbstractLdapTests {
    private static final Logger LOGGER = LoggerFactory.getLogger(PersonDirectoryPrincipalResolverLdaptiveTests.class);

    private static final String ATTR_NAME_PASSWORD = "userPassword";

    @Autowired
    @Qualifier("attributeRepository")
    private IPersonAttributeDao attributeRepository;

    @BeforeClass
    public static void bootstrap() throws Exception {
        LOGGER.debug("Running [{}]", PersonDirectoryPrincipalResolverLdaptiveTests.class.getSimpleName());
        initDirectoryServer();
    }

    @Test
    public void verifyResolver() {
        getEntries().forEach(entry -> {
            final String username = entry.getAttribute("sAMAccountName").getStringValue();
            final String psw = entry.getAttribute(ATTR_NAME_PASSWORD).getStringValue();
            final PersonDirectoryPrincipalResolver resolver = new PersonDirectoryPrincipalResolver(this.attributeRepository);
            final Principal p = resolver.resolve(new UsernamePasswordCredential(username, psw),
                    CoreAuthenticationTestUtils.getPrincipal(),
                    new SimpleTestUsernamePasswordAuthenticationHandler());
            assertNotNull(p);
            assertTrue(p.getAttributes().containsKey("displayName"));
        });
    }

    @Test
    public void verifyChainedResolver() {
        getEntries().forEach(entry -> {
            final String username = entry.getAttribute("sAMAccountName").getStringValue();
            final String psw = entry.getAttribute(ATTR_NAME_PASSWORD).getStringValue();
            final PersonDirectoryPrincipalResolver resolver = new PersonDirectoryPrincipalResolver(this.attributeRepository);
            final ChainingPrincipalResolver chain = new ChainingPrincipalResolver();
            chain.setChain(Arrays.asList(resolver, new EchoingPrincipalResolver()));
            final Map<String, Object> attributes = new HashMap<>(2);
            attributes.put("a1", "v1");
            attributes.put("a2", "v2");
            final Principal p = chain.resolve(new UsernamePasswordCredential(username, psw),
                    CoreAuthenticationTestUtils.getPrincipal(username, attributes),
                    new SimpleTestUsernamePasswordAuthenticationHandler());
            assertNotNull(p);
            assertTrue(p.getAttributes().containsKey("displayName"));
            assertTrue(p.getAttributes().containsKey("a1"));
            assertTrue(p.getAttributes().containsKey("a2"));
        });
    }
}

@@ -2366,32 +2366,72 @@
 ifyResolver() %7B%0A
+        if (getEntries() != null) %7B%0A    
         getEntri
@@ -2446,32 +2446,36 @@
 Each(entry -%3E %7B%0A
+    
             fina
@@ -2553,32 +2553,36 @@
 ();%0A            
+    
 final String psw
@@ -2645,32 +2645,36 @@
 ();%0A            
+  
+  
 final PersonDire
@@ -2775,32 +2775,36 @@
 y);%0A            
+    
 final Principal 
@@ -2883,32 +2883,36 @@
                 
+ 
+   
 CoreAuthenticati
@@ -2951,32 +2951,36 @@
                 
+   
+ 
 new SimpleTestUs
@@ -3023,32 +3023,36 @@
 ));%0A            
+    
 assertNotNull(p)
@@ -3057,32 +3057,36 @@
 p);%0A            
+ 
+   
 assertTrue(p.get
@@ -3131,28 +3131,42 @@
 ));%0A        
+   
+ 
 %7D);%0A
+        %7D%0A
     %7D%0A%0A    @
@@ -3204,32 +3204,72 @@
 nedResolver() %7B%0A
+        if (getEntries() != null) %7B%0A    
         getEntri
@@ -3284,32 +3284,36 @@
 Each(entry -%3E %7B%0A
+    
             fina
@@ -3391,32 +3391,36 @@
 ();%0A            
+  
+  
 final String psw
@@ -3471,32 +3471,36 @@
 tStringValue();%0A
+    
             fina
@@ -3617,24 +3617,28 @@
             
+    
 final Chaini
@@ -3694,24 +3694,28 @@
 Resolver();%0A
+    
             
@@ -3783,24 +3783,28 @@
 solver()));%0A
+    
             
@@ -3864,32 +3864,36 @@
 2);%0A            
+    
 attributes.put(%22
@@ -3900,24 +3900,28 @@
 a1%22, %22v1%22);%0A
+    
             
@@ -3944,24 +3944,28 @@
 a2%22, %22v2%22);%0A
+    
             
@@ -4057,32 +4057,36 @@
                 
+ 
+   
 CoreAuthenticati
@@ -4145,32 +4145,36 @@
                 
+   
+ 
 new SimpleTestUs
@@ -4217,32 +4217,36 @@
 ));%0A            
+    
 assertNotNull(p)
@@ -4251,32 +4251,36 @@
 p);%0A            
+ 
+   
 assertTrue(p.get
@@ -4313,32 +4313,36 @@
 displayName%22));%0A
+    
             asse
@@ -4390,32 +4390,36 @@
 ));%0A            
+    
 assertTrue(p.get
@@ -4455,24 +4455,38 @@
 ));%0A        
+  
+  
 %7D);%0A
+        %7D%0A
     %7D%0A%7D%0A

add safety check for tests