001    /**
002     * Copyright 2005-2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kim.test.service;
017    
018    import org.apache.ojb.broker.metadata.DescriptorRepository;
019    import org.apache.ojb.broker.metadata.MetadataManager;
020    import org.junit.Test;
021    import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
022    import org.kuali.rice.kim.api.identity.Person;
023    import org.kuali.rice.kim.api.identity.principal.Principal;
024    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
025    import org.kuali.rice.kim.impl.KIMPropertyConstants;
026    import org.kuali.rice.kim.impl.identity.PersonServiceImpl;
027    import org.kuali.rice.kim.impl.identity.external.EntityExternalIdentifierBo;
028    import org.kuali.rice.kim.test.KIMTestCase;
029    import org.kuali.rice.kim.test.bo.BOContainingPerson;
030    import org.kuali.rice.kns.lookup.Lookupable;
031    import org.kuali.rice.kns.service.KNSServiceLocator;
032    import org.kuali.rice.krad.bo.BusinessObject;
033    import org.kuali.rice.krad.service.BusinessObjectService;
034    import org.kuali.rice.krad.service.KRADServiceLocator;
035    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
036    import org.kuali.rice.krad.service.SequenceAccessorService;
037    import org.kuali.rice.test.BaselineTestCase;
038    import org.springframework.core.io.DefaultResourceLoader;
039    import org.springframework.util.AutoPopulatingList;
040    
041    import javax.xml.namespace.QName;
042    import java.io.InputStream;
043    import java.util.ArrayList;
044    import java.util.HashMap;
045    import java.util.List;
046    import java.util.Map;
047    
048    import static org.junit.Assert.*;
049    
050    /**
051     * This is a description of what this class does - kellerj don't forget to fill this in.
052     *
053     * @author Kuali Rice Team (rice.collab@kuali.org)
054     *
055     */
056    @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
057    public class PersonServiceImplTest extends KIMTestCase {
058    
059            private PersonServiceImpl personService;
060    
061            public void setUp() throws Exception {
062                    super.setUp();
063                    personService = (PersonServiceImpl) GlobalResourceLoader.getService(new QName("personService"));
064                    
065            }
066    
067            /**
068             * Test method for {@link org.kuali.rice.kim.impl.identity.PersonServiceImpl#getPersonByExternalIdentifier(java.lang.String, java.lang.String)}.
069             */
070            @Test
071            public void testGetPersonByExternalIdentifier() {
072                    //insert external identifier
073                    Principal principal = KimApiServiceLocator.getIdentityService().getPrincipal("p1");
074                    
075                    SequenceAccessorService sas = KRADServiceLocator.getSequenceAccessorService();
076                    Long externalIdentifierId = sas.getNextAvailableSequenceNumber("KRIM_ENTITY_EXT_ID_ID_S", EntityExternalIdentifierBo.class);
077                    EntityExternalIdentifierBo externalIdentifier = new EntityExternalIdentifierBo();
078                    externalIdentifier.setId("externalIdentifierId");
079                    externalIdentifier.setEntityId(principal.getEntityId());
080                    externalIdentifier.setExternalId("000-00-0000");
081                    externalIdentifier.setExternalIdentifierTypeCode("SSN");
082                    KRADServiceLocator.getBusinessObjectService().save(externalIdentifier);
083                    
084                    List<Person> people = personService.getPersonByExternalIdentifier( "SSN", "000-00-0000" );
085                    assertNotNull( "result object must not be null", people );
086                    assertEquals( "exactly one record should be returned", 1, people.size() );
087                    assertEquals( "the returned principal is not correct", "p1", people.get(0).getPrincipalId() );
088            }
089    
090    //      @Test
091    //      public void testHasRole_Inherited() {
092    //              Person p = personService.getPersonByPrincipalName( "wwren" );
093    //              assertNotNull( "person object must not be null", p );
094    //              assertTrue( "person must be a member of PA_MAINTENANCE_USERS", personService.hasRole( p, org.kuali.rice.kim.util.KimApiConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE, "PA_AP_MAINTENANCE_USERS" ) );
095    //              assertTrue( "person must be NOT a member of PA_MAINTENANCE_USERS", !personService.hasRole( p, org.kuali.rice.kim.util.KimApiConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE, "PA_MAINTENANCE_USERS" ) );
096    //      }
097    //
098    //      @Test
099    //      public void testGetPersonRoles() {
100    //              Person p = personService.getPerson( "KULUSER" );
101    //              assertNotNull( "person object must not be null", p );
102    //              List<KimRole> roles = personService.getPersonRoles( p, null );
103    //              assertNotNull( "role list must not be null", roles );
104    //              System.out.println( roles );
105    //              assertTrue( "role list must have non-zero length", roles.size() > 0 );
106    //              KimRole r = KimImplServiceLocator.getAuthorizationService().getRoleByNamespaceCodeAndName( org.kuali.rice.kim.util.KimApiConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE, "SY_FUNCTIONAL_SUPER_USERS" );
107    //              assertTrue( "one of the roles must be SY_FUNCTIONAL_SUPER_USERS", roles.contains( r ) );
108    //      }
109    //
110    //      @Test
111    //      public void testHasRole() {
112    //              Person p = personService.getPerson( "KULUSER" );
113    //              assertTrue( "person must have role SY_FUNCTIONAL_SUPER_USERS", personService.hasRole( p, org.kuali.rice.kim.util.KimApiConstants.KIM_GROUP_DEFAULT_NAMESPACE_CODE, "SY_FUNCTIONAL_SUPER_USERS" ) );
114    //      }
115    
116            @Test
117            public void testGetPerson() {
118                    Person p = personService.getPerson( "KULUSER" );
119                    assertNotNull( "person object must not be null", p );
120                    assertEquals( "class must match implementation class defined on service", personService.getPersonImplementationClass(), p.getClass() );
121                    assertEquals( "person name does not match", "KULUSER", p.getFirstNameUnmasked() );
122                    assertEquals( "principal name does not match", "kuluser", p.getPrincipalName() );
123                    assertEquals( "KULUSER should have no address record", "", p.getAddressLine1Unmasked() );
124                    assertEquals( "KULUSER should have no campus code", "", p.getCampusCode() );
125                    assertEquals( "KULUSER should have no email address", "", p.getEmailAddressUnmasked() );
126                    assertNotNull( "entity ID should be set", p.getEntityId() );
127                    assertNotNull( "principal ID should be set", p.getPrincipalId() );
128                    
129                    // check an employee id
130                    Person p1Person = personService.getPerson( "p1" );
131                    assertNotNull( "person object must not be null", p );
132                    assertEquals("employee ID does not match", "p1emplId", p1Person.getEmployeeId());
133            }
134    
135            @Test
136            public void testGetPersonInactive() {
137                    Person p = personService.getPerson( "inactiveuserid" );
138                    assertNotNull( "person object must not be null", p );
139            assertEquals("principal ID does not match", "inactiveusernm", p.getPrincipalName());
140    
141            }
142            
143            @Test
144            public void testGetPersonByPrincipalName() {
145                    Person p = personService.getPersonByPrincipalName( "kuluser" );
146                    assertNotNull( "person object must not be null", p );
147                    assertEquals( "person name does not match", "KULUSER", p.getFirstName() );
148                    assertEquals( "principal id does not match", "KULUSER", p.getPrincipalId() );
149            }
150            
151            @Test
152            public void testGetPersonByPrincipalNameInactive() {
153                    Person p = personService.getPersonByPrincipalName( "inactiveusernm" );
154            assertEquals("principal ID does not match", "inactiveuserid", p.getPrincipalId());
155        }
156            
157        @Test
158        public void testGetPersonByEmployeeIdNoInfo() {
159            Person p = personService.getPersonByEmployeeId( "" );
160            assertNull( "person object will be null", p );
161        }
162        
163        @Test
164        public void testGetPersonByEmployeeIdNotFound() {
165            Person p = personService.getPersonByEmployeeId( "NotFound" );
166            assertNull( "person object will be null", p );
167        }
168        
169        @Test
170        public void testGetPersonByEmployeeIdActive() {
171            Person p = personService.getPersonByEmployeeId( "0000001138" );
172            assertNotNull( "person object must not be null", p );
173            assertEquals( "person name does not match", "activeUserFirst", p.getFirstName() );
174            assertEquals( "principal id does not match", "activeuserid", p.getPrincipalId() );
175        }
176        
177        @Test
178        public void testGetPersonByEmployeeIdInactiveUser() {
179            Person p = personService.getPersonByEmployeeId( "0000001139" );
180            assertNotNull( "person object must not be null", p );
181            assertEquals( "person name does not match", "InactiveUserFirst", p.getFirstName() );
182            assertEquals( "principal id does not match", "inactiveuserid", p.getPrincipalId() );
183        }
184        
185        @Test
186        public void testGetPersonByEmployeeIdInactiveEmp() {
187            Person p = personService.getPersonByEmployeeId( "0000001140" );
188            assertNotNull( "person object must not be null", p );
189            assertEquals( "person name does not match", "InactiveEmplFirst", p.getFirstName() );
190            assertEquals( "principal id does not match", "inactiveempid", p.getPrincipalId() );
191        }
192        
193            @Test
194            public void testConvertPersonPropertiesToEntityProperties() {
195                    HashMap<String,String> criteria = new HashMap<String,String>();
196                    criteria.put( "firstName", "System User" );
197                    Map<String,String> entityCriteria = personService.convertPersonPropertiesToEntityProperties( criteria );
198                    assertEquals( "number of criteria is not correct", 5, entityCriteria.size() );
199                    assertNotNull( "criteria must filter for active entity types", entityCriteria.get( "entityTypeContactInfos.active" ) );
200                    assertNotNull( "criteria must filter on entity type code", entityCriteria.get( "entityTypeContactInfos.entityTypeCode" ) );
201                    assertNotNull( "criteria must filter for first name", entityCriteria.get( "names.firstName" ) );
202                    assertNotNull( "criteria must filter for active names", entityCriteria.get( "names.active" ) );
203                    assertNotNull( "criteria must filter for the default name", entityCriteria.get( "names.defaultValue" ) );
204            }
205    
206            /**
207             * Test method for {@link org.kuali.rice.kim.impl.identity.PersonServiceImpl#findPeople(Map)}.
208             */
209        @Test
210        public void testFindPeople() {
211            HashMap<String,String> criteria = new HashMap<String,String>();
212            criteria.put( "firstName", "KULUSER" );
213            List<Person> people = personService.findPeople( criteria );
214            assertNotNull( "result must not be null", people );
215            assertEquals( "wrong number of people returned", 1, people.size() );
216            Person p = people.get( 0 );
217            assertEquals( "name must match criteria", "KULUSER", p.getFirstName() );
218            assertEquals( "principal name must be kuluser", "kuluser", p.getPrincipalName() );
219        }
220            
221        @Test
222        public void testFindPeopleInactive() {
223            HashMap<String,String> criteria = new HashMap<String,String>();
224            criteria.put( "principals.active", "N" );
225            List<Person> people = personService.findPeople( criteria );
226            assertNotNull( "result must not be null", people );
227            assertEquals( "wrong number of people returned", 1, people.size() );
228        }
229    
230        @Test
231        public void testFindPeopleBothInactiveAndActive() {
232            HashMap<String,String> criteria = new HashMap<String,String>();
233            criteria.put( "firstName", "InactiveUserFirst" );
234            List<Person> people = personService.findPeople( criteria );
235            assertNotNull( "result must not be null", people );
236            assertEquals( "wrong number of people returned", 1, people.size() );
237        }    
238        
239        @Test
240        public void testFindPeopleByWildcard() {
241            HashMap<String,String> criteria = new HashMap<String,String>();
242            criteria.put( "principalName", "!quick*" );
243            List<Person> people = personService.findPeople( criteria );
244            assertNotNull( "result must not be null", people );
245            assertEquals( "wrong number of people returned", 53, people.size() );
246            for (Person p: people) {
247                if (p.getPrincipalName().startsWith("quick")) {
248                    fail("Invalid wildcard search results");
249                }
250            }
251        }
252    
253            @Test
254            public void testResolvePrincipalNamesToPrincipalIds() throws Exception {
255                    
256                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().addConfigFileLocation("KR-KIM", "classpath:org/kuali/rice/kim/bo/datadictionary/test/SampleBO.xml" );
257                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().parseDataDictionaryConfigurationFiles( false );
258    
259                    Map<String,String> criteria = new HashMap<String,String>();
260                    criteria.put( "anAttribute", "aValue" );
261                    criteria.put( "anotherAttribute", "anotherValue" );
262                    criteria.put( "personAttribute.principalName", "kuluser" );
263                    System.out.println( "Before: " + criteria );
264                    Map<String,String> newCritiera = personService.resolvePrincipalNamesToPrincipalIds( new SampleBO(), criteria );
265                    assertNotNull( "returned map must not be null", newCritiera );
266                    System.out.println( "After:  " + newCritiera );
267                    assertTrue( "new criteria must have a personPrincipalId entry", newCritiera.containsKey( "personPrincipalId" ) );
268                    assertEquals( "resulting principal ID is not that expected", "KULUSER", newCritiera.get( "personPrincipalId" ) );
269                    assertFalse( "new criteria must not contain the original PrincipalName entry", newCritiera.containsKey( "personAttribute.principalName" ) );
270    
271                    // check when already has value in result field
272                    criteria.put( "personPrincipalId", "NOT KULUSER" );
273                    System.out.println( "Before: " + criteria );
274                    newCritiera = personService.resolvePrincipalNamesToPrincipalIds( new SampleBO(), criteria );
275                    assertNotNull( "returned map must not be null", newCritiera );
276                    System.out.println( "After:  " + newCritiera );
277                    assertTrue( "new criteria must have a personPrincipalId entry", newCritiera.containsKey( "personPrincipalId" ) );
278                    assertEquals( "resulting principal ID should have been changed", "KULUSER", newCritiera.get( "personPrincipalId" ) );
279            }
280    
281            @Test
282            public void testResolvePrincipalNamesToPrincipalIds_Nested() throws Exception {
283    
284            KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().addConfigFileLocation("",  "classpath:org/kuali/rice/kim/bo/datadictionary/test/SampleBO.xml" );
285            KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().parseDataDictionaryConfigurationFiles( false );
286    
287                    Map<String,String> criteria = new HashMap<String,String>();
288                    criteria.put( "add.childBos.childsPersonAttribute.principalName", "kuluser" );
289                    System.out.println( "Before: " + criteria );
290                    Map<String,String> newCritiera = personService.resolvePrincipalNamesToPrincipalIds( new SampleBO(), criteria );
291                    assertNotNull( "returned map must not be null", newCritiera );
292                    System.out.println( "After:  " + newCritiera );
293                    // TODO: property is being appended in the wrong place - fix
294                    assertTrue( "new criteria must have a childsPersonPrincipalId entry", newCritiera.containsKey( "add.childBos.childsPersonPrincipalId" ) );
295                    assertFalse( "new criteria must not contain the original PrincipalName entry", newCritiera.containsKey( "add.childBos.childsPersonAttribute.principalName" ) );
296            }
297    
298            @Test
299            public void testUpdateWhenNecessary() {
300                    SampleBO bo = new SampleBO();
301                    bo.setPersonPrincipalId( "KULUSER" );
302                    Person p = bo.getPersonAttribute();
303                    assertNotNull( "person object must not be null", p );
304                    assertEquals( "principal IDs do not match", bo.getPersonPrincipalId(), p.getPrincipalId() );
305                    assertSame( "second retrieval must return same object since ID not changed", p, bo.getPersonAttribute() );
306            }
307    
308            @Test
309            public void testLookupWithPersonJoin() throws Exception {
310                    
311                    // merge the OJB file in containing the OJB metadata
312            InputStream is = new DefaultResourceLoader().getResource("classpath:org/kuali/rice/kim/test/OJB-repository-kimunittests.xml").getInputStream();
313            MetadataManager mm = MetadataManager.getInstance();
314            DescriptorRepository dr = mm.readDescriptorRepository(is);
315            mm.mergeDescriptorRepository(dr);
316                    
317                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().addConfigFileLocation("KR-KIM", "classpath:org/kuali/rice/kim/bo/datadictionary/test/BOContainingPerson.xml" );
318                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().parseDataDictionaryConfigurationFiles( false );
319                    BusinessObjectService bos = KRADServiceLocator.getBusinessObjectService();
320                    bos.delete( new ArrayList(bos.findAll( BOContainingPerson.class )) );
321                    BOContainingPerson bo = new BOContainingPerson();
322                    bo.setBoPrimaryKey( "ONE" );
323                    bo.setPrincipalId( "p1" );
324                    bos.save( bo );
325                    bo = new BOContainingPerson();
326                    bo.setBoPrimaryKey( "TWO" );
327                    bo.setPrincipalId( "p2" );
328                    bos.save( bo );
329    
330                    Lookupable l = KNSServiceLocator.getKualiLookupable();
331                    l.setBusinessObjectClass( BOContainingPerson.class );
332                    Map<String,String> criteria = new HashMap<String,String>();
333                    criteria.put( "person.principalName", "principal1" );
334                    List<BOContainingPerson> results = (List)l.getSearchResultsUnbounded( (Map)criteria );
335                    System.out.println( results );
336                    assertNotNull( "results may not be null", results );
337                    assertEquals( "number of results is incorrect", 1, results.size() );
338                    bo =  results.iterator().next();
339                    assertEquals( "principalId does not match", "p1", bo.getPrincipalId() );
340            }
341    
342    //      @Test
343    //      public void testConfirmOnlyPKUsed() {
344    //              HashMap<String,String> criteria = new HashMap<String,String>();
345    //              criteria.put( "lastName", "HUNTLEY" );
346    //              criteria.put( "firstName", "KEISHA" );
347    //              Collection<Person> people = (Collection<Person>)KRADServiceLocatorInternal.getLookupService().findCollectionBySearchUnbounded(Person.class, criteria);
348    //              personService.findPeople( criteria );
349    //              assertNotNull( "result must not be null", people );
350    //              assertEquals( "wrong number of people returned", 1, people.size() );
351    //              Person p = people.iterator().next();
352    //              assertEquals( "principal name does not match", "khuntley", p.getPrincipalName() );
353    //
354    //              criteria.put( "principalName", "kuluser" );
355    //              people = people = (Collection<Person>)KRADServiceLocatorInternal.getLookupService().findCollectionBySearchUnbounded(Person.class, criteria);
356    //              assertNotNull( "result must not be null", people );
357    //              assertEquals( "wrong number of people returned", 1, people.size() );
358    //              p = people.iterator().next();
359    //              assertEquals( "principal name must be kuluser", "kuluser", p.getPrincipalName() );
360    //      }
361    
362            public static class SampleBO implements BusinessObject {
363                    private String anAttribute;
364                    private String anotherAttribute;
365                    private String personPrincipalId;
366                    private Person personAttribute;
367                    private List<SampleChildBOWithPerson> childBos = new AutoPopulatingList(SampleChildBOWithPerson.class);
368                    public String getAnAttribute() {
369                            return this.anAttribute;
370                    }
371                    public void setAnAttribute(String anAttribute) {
372                            this.anAttribute = anAttribute;
373                    }
374                    public String getAnotherAttribute() {
375                            return this.anotherAttribute;
376                    }
377                    public void setAnotherAttribute(String anotherAttribute) {
378                            this.anotherAttribute = anotherAttribute;
379                    }
380                    public String getPersonPrincipalId() {
381                            return this.personPrincipalId;
382                    }
383                    public void setPersonPrincipalId(String personPrincipalId) {
384                            this.personPrincipalId = personPrincipalId;
385                    }
386                    public Person getPersonAttribute() {
387                            personAttribute = KimApiServiceLocator.getPersonService().updatePersonIfNecessary( personPrincipalId, personAttribute );
388                            return personAttribute;
389                    }
390                    public void setPersonAttribute(Person personAttribute) {
391                            this.personAttribute = personAttribute;
392                    }
393                    public void refresh() {}
394                    public List<SampleChildBOWithPerson> getChildBos() {
395                            return this.childBos;
396                    }
397                    public void setChildBos(List<SampleChildBOWithPerson> childBos) {
398                            this.childBos = childBos;
399                    }
400            }
401    
402            public static class SampleChildBOWithPerson implements BusinessObject {
403    
404                    private String childsAttribute;
405                    private String childsPersonPrincipalId;
406                    private Person childsPersonAttribute;
407    
408    
409    
410                    public String getChildsAttribute() {
411                            return this.childsAttribute;
412                    }
413                    public void setChildsAttribute(String childsAttribute) {
414                            this.childsAttribute = childsAttribute;
415                    }
416                    public String getChildsPersonPrincipalId() {
417                            return this.childsPersonPrincipalId;
418                    }
419                    public void setChildsPersonPrincipalId(String childsPersonPrincipalId) {
420                            this.childsPersonPrincipalId = childsPersonPrincipalId;
421                    }
422                    public Person getChildsPersonAttribute() {
423                            childsPersonAttribute = KimApiServiceLocator.getPersonService().updatePersonIfNecessary( childsPersonPrincipalId, childsPersonAttribute );
424                            return childsPersonAttribute;
425                    }
426                    public void setChildsPersonAttribute(Person childsPersonAttribute) {
427                            this.childsPersonAttribute = childsPersonAttribute;
428                    }
429                    public void refresh() {}
430            }
431    }