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( "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( "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                    Map<String,String> criteria = new HashMap<String,String>();
284                    criteria.put( "add.childBos.childsPersonAttribute.principalName", "kuluser" );
285                    System.out.println( "Before: " + criteria );
286                    Map<String,String> newCritiera = personService.resolvePrincipalNamesToPrincipalIds( new SampleBO(), criteria );
287                    assertNotNull( "returned map must not be null", newCritiera );
288                    System.out.println( "After:  " + newCritiera );
289                    // TODO: property is being appended in the wrong place - fix
290                    assertTrue( "new criteria must have a childsPersonPrincipalId entry", newCritiera.containsKey( "add.childBos.childsPersonPrincipalId" ) );
291                    assertFalse( "new criteria must not contain the original PrincipalName entry", newCritiera.containsKey( "add.childBos.childsPersonAttribute.principalName" ) );
292            }
293    
294            @Test
295            public void testUpdateWhenNecessary() {
296                    SampleBO bo = new SampleBO();
297                    bo.setPersonPrincipalId( "KULUSER" );
298                    Person p = bo.getPersonAttribute();
299                    assertNotNull( "person object must not be null", p );
300                    assertEquals( "principal IDs do not match", bo.getPersonPrincipalId(), p.getPrincipalId() );
301                    assertSame( "second retrieval must return same object since ID not changed", p, bo.getPersonAttribute() );
302            }
303    
304            @Test
305            public void testLookupWithPersonJoin() throws Exception {
306                    
307                    // merge the OJB file in containing the OJB metadata
308            InputStream is = new DefaultResourceLoader().getResource("classpath:org/kuali/rice/kim/test/OJB-repository-kimunittests.xml").getInputStream();
309            MetadataManager mm = MetadataManager.getInstance();
310            DescriptorRepository dr = mm.readDescriptorRepository(is);
311            mm.mergeDescriptorRepository(dr);
312                    
313                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().addConfigFileLocation( "classpath:org/kuali/rice/kim/bo/datadictionary/test/BOContainingPerson.xml" );
314                    KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().parseDataDictionaryConfigurationFiles( false );
315                    BusinessObjectService bos = KRADServiceLocator.getBusinessObjectService();
316                    bos.delete( new ArrayList(bos.findAll( BOContainingPerson.class )) );
317                    BOContainingPerson bo = new BOContainingPerson();
318                    bo.setBoPrimaryKey( "ONE" );
319                    bo.setPrincipalId( "p1" );
320                    bos.save( bo );
321                    bo = new BOContainingPerson();
322                    bo.setBoPrimaryKey( "TWO" );
323                    bo.setPrincipalId( "p2" );
324                    bos.save( bo );
325    
326                    Lookupable l = KNSServiceLocator.getKualiLookupable();
327                    l.setBusinessObjectClass( BOContainingPerson.class );
328                    Map<String,String> criteria = new HashMap<String,String>();
329                    criteria.put( "person.principalName", "principal1" );
330                    List<BOContainingPerson> results = (List)l.getSearchResultsUnbounded( (Map)criteria );
331                    System.out.println( results );
332                    assertNotNull( "results may not be null", results );
333                    assertEquals( "number of results is incorrect", 1, results.size() );
334                    bo =  results.iterator().next();
335                    assertEquals( "principalId does not match", "p1", bo.getPrincipalId() );
336            }
337    
338    //      @Test
339    //      public void testConfirmOnlyPKUsed() {
340    //              HashMap<String,String> criteria = new HashMap<String,String>();
341    //              criteria.put( "lastName", "HUNTLEY" );
342    //              criteria.put( "firstName", "KEISHA" );
343    //              Collection<Person> people = (Collection<Person>)KRADServiceLocatorInternal.getLookupService().findCollectionBySearchUnbounded(Person.class, criteria);
344    //              personService.findPeople( criteria );
345    //              assertNotNull( "result must not be null", people );
346    //              assertEquals( "wrong number of people returned", 1, people.size() );
347    //              Person p = people.iterator().next();
348    //              assertEquals( "principal name does not match", "khuntley", p.getPrincipalName() );
349    //
350    //              criteria.put( "principalName", "kuluser" );
351    //              people = people = (Collection<Person>)KRADServiceLocatorInternal.getLookupService().findCollectionBySearchUnbounded(Person.class, criteria);
352    //              assertNotNull( "result must not be null", people );
353    //              assertEquals( "wrong number of people returned", 1, people.size() );
354    //              p = people.iterator().next();
355    //              assertEquals( "principal name must be kuluser", "kuluser", p.getPrincipalName() );
356    //      }
357    
358            public static class SampleBO implements BusinessObject {
359                    private String anAttribute;
360                    private String anotherAttribute;
361                    private String personPrincipalId;
362                    private Person personAttribute;
363                    private List<SampleChildBOWithPerson> childBos = new AutoPopulatingList(SampleChildBOWithPerson.class);
364                    public String getAnAttribute() {
365                            return this.anAttribute;
366                    }
367                    public void setAnAttribute(String anAttribute) {
368                            this.anAttribute = anAttribute;
369                    }
370                    public String getAnotherAttribute() {
371                            return this.anotherAttribute;
372                    }
373                    public void setAnotherAttribute(String anotherAttribute) {
374                            this.anotherAttribute = anotherAttribute;
375                    }
376                    public String getPersonPrincipalId() {
377                            return this.personPrincipalId;
378                    }
379                    public void setPersonPrincipalId(String personPrincipalId) {
380                            this.personPrincipalId = personPrincipalId;
381                    }
382                    public Person getPersonAttribute() {
383                            personAttribute = KimApiServiceLocator.getPersonService().updatePersonIfNecessary( personPrincipalId, personAttribute );
384                            return personAttribute;
385                    }
386                    public void setPersonAttribute(Person personAttribute) {
387                            this.personAttribute = personAttribute;
388                    }
389                    public void refresh() {}
390                    public List<SampleChildBOWithPerson> getChildBos() {
391                            return this.childBos;
392                    }
393                    public void setChildBos(List<SampleChildBOWithPerson> childBos) {
394                            this.childBos = childBos;
395                    }
396            }
397    
398            public static class SampleChildBOWithPerson implements BusinessObject {
399    
400                    private String childsAttribute;
401                    private String childsPersonPrincipalId;
402                    private Person childsPersonAttribute;
403    
404    
405    
406                    public String getChildsAttribute() {
407                            return this.childsAttribute;
408                    }
409                    public void setChildsAttribute(String childsAttribute) {
410                            this.childsAttribute = childsAttribute;
411                    }
412                    public String getChildsPersonPrincipalId() {
413                            return this.childsPersonPrincipalId;
414                    }
415                    public void setChildsPersonPrincipalId(String childsPersonPrincipalId) {
416                            this.childsPersonPrincipalId = childsPersonPrincipalId;
417                    }
418                    public Person getChildsPersonAttribute() {
419                            childsPersonAttribute = KimApiServiceLocator.getPersonService().updatePersonIfNecessary( childsPersonPrincipalId, childsPersonAttribute );
420                            return childsPersonAttribute;
421                    }
422                    public void setChildsPersonAttribute(Person childsPersonAttribute) {
423                            this.childsPersonAttribute = childsPersonAttribute;
424                    }
425                    public void refresh() {}
426            }
427    }