View Javadoc
1   /*
2    * Copyright (C) 2003-2016 eXo Platform SAS.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU Affero General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU Affero General Public License for more details.
13   *
14   * You should have received a copy of the GNU Affero General Public License
15   * along with this program. If not, see <http://www.gnu.org/licenses/>.
16   */
17  
18  package org.exoplatform.social.core.jpa.storage;
19  
20  import org.exoplatform.services.organization.*;
21  import org.exoplatform.social.core.identity.SpaceMemberFilterListAccess.Type;
22  import org.exoplatform.social.core.identity.model.Identity;
23  import org.exoplatform.social.core.identity.model.Profile;
24  import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider;
25  import org.exoplatform.social.core.identity.provider.SpaceIdentityProvider;
26  import org.exoplatform.social.core.jpa.test.AbstractCoreTest;
27  import org.exoplatform.social.core.jpa.test.MaxQueryNumber;
28  import org.exoplatform.social.core.jpa.test.QueryNumberTest;
29  import org.exoplatform.social.core.model.AvatarAttachment;
30  import org.exoplatform.social.core.model.BannerAttachment;
31  import org.exoplatform.social.core.profile.ProfileFilter;
32  import org.exoplatform.social.core.service.LinkProvider;
33  import org.exoplatform.social.core.space.SpaceUtils;
34  import org.exoplatform.social.core.space.impl.DefaultSpaceApplicationHandler;
35  import org.exoplatform.social.core.space.model.Space;
36  import org.exoplatform.social.core.storage.api.IdentityStorage;
37  import org.exoplatform.social.core.storage.api.SpaceStorage;
38  
39  import java.io.InputStream;
40  import java.util.ArrayList;
41  import java.util.Collections;
42  import java.util.Iterator;
43  import java.util.List;
44  import java.util.stream.Collectors;
45  
46  /**
47   * Created by IntelliJ IDEA.
48   * User: zun
49   * Date: Jun 17, 2010
50   * Time: 9:34:56 AM
51   */
52  @QueryNumberTest
53  public class IdentityStorageTest extends AbstractCoreTest {
54    private IdentityStorage identityStorage;
55    private SpaceStorage spaceStorage;
56    private List<Identity> tearDownIdentityList;
57    private List<Space> tearDownSpaceList;
58  
59    public void setUp() throws Exception {
60      super.setUp();
61      identityStorage = getService(IdentityStorage.class);
62      spaceStorage = getService(SpaceStorage.class);
63      assertNotNull("identityStorage must not be null", identityStorage);
64      tearDownIdentityList = new ArrayList<Identity>();
65      tearDownSpaceList = new ArrayList<Space>();
66    }
67  
68    /**
69     * Tests {@link IdenityStorage#saveIdentity(Identity)}
70     *
71     */
72    @MaxQueryNumber(186)
73    public void testSaveIdentity() {
74      Identity tobeSavedIdentity = new Identity(OrganizationIdentityProvider.NAME, "identity1");
75      identityStorage.saveIdentity(tobeSavedIdentity);
76  
77      assertNotNull(tobeSavedIdentity.getId());
78  
79      final String updatedRemoteId = "identity-updated";
80  
81      tobeSavedIdentity.setRemoteId(updatedRemoteId);
82  
83      identityStorage.saveIdentity(tobeSavedIdentity);
84  
85      Identity gotIdentity = identityStorage.findIdentityById(tobeSavedIdentity.getId());
86  
87      assertEquals(updatedRemoteId, gotIdentity.getRemoteId());
88      tearDownIdentityList.add(gotIdentity);
89      
90    }
91  
92    /**
93     * Tests {@link IdenityStorage#processEnabledIdentity(Identity)}
94     */
95    @MaxQueryNumber(99)
96    public void testEnableIdentity() {
97      final String remoteUser = "user";
98      Identity identity = new Identity(OrganizationIdentityProvider.NAME, remoteUser);
99      identityStorage.saveIdentity(identity);
100 
101     String id = identity.getId();
102 
103     //
104     assertNotNull(identity.getId());
105     //
106     identityStorage.processEnabledIdentity(identity, false);
107 
108     identity = identityStorage.findIdentityById(id);
109     assertFalse(identity.isEnable());
110 
111     //
112     identityStorage.processEnabledIdentity(identity, true);
113 
114     identity = identityStorage.findIdentityById(id);
115     assertTrue(identity.isEnable());
116 
117     tearDownIdentityList.add(identity);
118   }
119 
120   /**
121    * Tests {@link IdenityStorage#deleteIdentity(Identity)}
122    *
123    */
124   @MaxQueryNumber(807)
125   public void testDeleteIdentity() {
126     final String username = "username";
127     Identity tobeSavedIdentity = new Identity(OrganizationIdentityProvider.NAME, username);
128     identityStorage.saveIdentity(tobeSavedIdentity);
129 
130     assertNotNull(tobeSavedIdentity.getId());
131 
132     identityStorage.deleteIdentity(tobeSavedIdentity);
133 
134     tobeSavedIdentity = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, username);
135     assertTrue("tobeSavedIdentity must be mark as deleted", tobeSavedIdentity.isDeleted());
136 
137     // Delete identity with loaded profile
138     {
139       tobeSavedIdentity = new Identity(OrganizationIdentityProvider.NAME, username);
140       identityStorage.saveIdentity(tobeSavedIdentity);
141       assertNotNull("tobeSavedIdentity.getId() must not be null.", tobeSavedIdentity.getId());
142       assertNull("tobeSavedIdentity.getProfile().getId() must be null.", tobeSavedIdentity.getProfile().getId());
143       Profile profile = identityStorage.loadProfile(tobeSavedIdentity.getProfile());
144       tobeSavedIdentity.setProfile(profile);
145       assertNotNull("tobeSavedIdentity.getProfile().getId() must not be null", tobeSavedIdentity.getProfile().getId());
146 
147       identityStorage.deleteIdentity(tobeSavedIdentity);
148       assertNotNull("tobeSavedIdentity.getId() must not be null", tobeSavedIdentity.getId());
149       try {
150         identityStorage.findIdentityById(tobeSavedIdentity.getId());
151       } catch (Exception e1) {
152         assert false : "can't update avatar" + e1 ;
153       }
154 
155     }
156   }
157 
158   /**
159    * Tests {@link IdenityStorage#findIdentityById(String)}
160    *
161    */
162   @MaxQueryNumber(90)
163   public void testFindIdentityById() {
164     final String remoteUser = "identity1";
165     Identity toSaveIdentity = new Identity(OrganizationIdentityProvider.NAME, remoteUser);
166     identityStorage.saveIdentity(toSaveIdentity);
167 
168     assertNotNull(toSaveIdentity.getId());
169 
170     Identity gotIdentityById = identityStorage.findIdentityById(toSaveIdentity.getId());
171 
172     assertNotNull(gotIdentityById);
173     assertEquals(toSaveIdentity.getId(), gotIdentityById.getId());
174     assertEquals(toSaveIdentity.getProviderId(), gotIdentityById.getProviderId());
175     assertEquals(toSaveIdentity.getRemoteId(), gotIdentityById.getRemoteId());
176 
177     Identity notFoundIdentityByRemoteid = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, "not-found");
178 
179     assertNull(notFoundIdentityByRemoteid);
180 
181     Identity gotIdentityByRemoteId = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, remoteUser);
182 
183     assertNotNull(gotIdentityByRemoteId);
184     assertEquals(gotIdentityByRemoteId.getId(), toSaveIdentity.getId());
185     assertEquals(gotIdentityByRemoteId.getProviderId(), toSaveIdentity.getProviderId());
186     assertEquals(gotIdentityByRemoteId.getRemoteId(), toSaveIdentity.getRemoteId());
187     
188     tearDownIdentityList.add(gotIdentityByRemoteId);
189   }
190 
191   /**
192    * Tests {@link IdenityStorage#findIdentity(String, String)}
193    *
194    */
195   @MaxQueryNumber(87)
196   public void testFindIdentity() {
197     final String userName = "username";
198 
199     Identity tobeSavedIdentity = new Identity(OrganizationIdentityProvider.NAME, userName);
200     identityStorage.saveIdentity(tobeSavedIdentity);
201     tearDownIdentityList.add(tobeSavedIdentity);
202 
203     Identity foundIdentity = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, userName);
204 
205     assertNotNull(foundIdentity);
206     assertNotNull(foundIdentity.getId());
207     assertEquals(OrganizationIdentityProvider.NAME, foundIdentity.getProviderId());
208     assertEquals(userName, foundIdentity.getRemoteId());
209     tearDownIdentityList.add(foundIdentity);
210   }
211 
212   /**
213    * Tests {@link IdenityStorage#saveProfile(Profile)}
214    *
215    */
216   @MaxQueryNumber(108)
217   public void testSaveProfile() {
218     final String userName = "username";
219     final String firstName = "FirstName";
220     final String lastName = "LastName";
221     Identity tobeSavedIdentity = new Identity(OrganizationIdentityProvider.NAME, userName);
222     identityStorage.saveIdentity(tobeSavedIdentity);
223     tearDownIdentityList.add(tobeSavedIdentity);
224 
225     Profile tobeSavedProfile = tobeSavedIdentity.getProfile();
226 
227     tobeSavedProfile.setProperty(Profile.USERNAME, userName);
228     tobeSavedProfile.setProperty(Profile.FIRST_NAME, firstName);
229     tobeSavedProfile.setProperty(Profile.LAST_NAME, lastName);
230 
231     assertTrue(tobeSavedProfile.hasChanged());
232     identityStorage.saveProfile(tobeSavedProfile);
233     assertFalse(tobeSavedProfile.hasChanged());
234 
235     assertNotNull(tobeSavedProfile.getId());
236 
237     assertEquals(userName, tobeSavedProfile.getProperty(Profile.USERNAME));
238     assertEquals(firstName, tobeSavedProfile.getProperty(Profile.FIRST_NAME));
239     assertEquals(lastName, tobeSavedProfile.getProperty(Profile.LAST_NAME));
240     assertEquals(firstName + " " + lastName, tobeSavedProfile.getFullName());
241     tearDownIdentityList.add(identityStorage.findIdentity(OrganizationIdentityProvider.NAME, userName));
242   }
243 
244   /**
245    * Tests {@link IdenityStorage#loadProfile(Profile)}
246    *
247    */
248   @MaxQueryNumber(210)
249   public void testLoadProfile() throws Exception {
250     final String username = "username";
251     Identity tobeSavedIdentity = new Identity(OrganizationIdentityProvider.NAME, username);
252     identityStorage.saveIdentity(tobeSavedIdentity);
253     tearDownIdentityList.add(tobeSavedIdentity);
254     Profile tobeSavedProfile = tobeSavedIdentity.getProfile();
255     tobeSavedProfile.setProperty(Profile.USERNAME, username);
256 
257     assertTrue(tobeSavedProfile.hasChanged());
258     tobeSavedProfile = identityStorage.loadProfile(tobeSavedProfile);
259     assertFalse(tobeSavedProfile.hasChanged());
260 
261     assertNotNull(tobeSavedProfile.getId());
262     assertEquals(username, tobeSavedProfile.getProperty(Profile.USERNAME));
263     
264     // Test in case loading an user has dot characters in name.
265     InputStream inputStream = getClass().getResourceAsStream("/eXo-Social.png");
266     AvatarAttachment avatarAttachment = new AvatarAttachment(null, "avatar", "png", inputStream, null, System.currentTimeMillis());
267     BannerAttachment bannerAttachment = new BannerAttachment(null, "banner", "png", inputStream, null, System.currentTimeMillis());
268     String userDotName = "user.name";
269     Identity identity = new Identity(OrganizationIdentityProvider.NAME, userDotName);
270     Profile profile = new Profile(identity);
271     identity.setProfile(profile);
272     profile.setProperty(Profile.AVATAR, avatarAttachment);
273     profile.setProperty(Profile.BANNER, bannerAttachment);
274 
275     identityStorage.saveIdentity(identity);
276     identityStorage.saveProfile(profile);
277 
278     identityStorage.loadProfile(profile);
279 
280     String gotAvatarURL = profile.getAvatarUrl();
281     assertNotNull(gotAvatarURL);
282     assertEquals(LinkProvider.buildAvatarURL(OrganizationIdentityProvider.NAME, userDotName), gotAvatarURL);
283 
284     String gotBannerURL = profile.getBannerUrl();
285     assertNotNull(gotBannerURL);
286     assertEquals(LinkProvider.buildBannerURL(OrganizationIdentityProvider.NAME, userDotName), gotBannerURL);
287 
288     tearDownIdentityList.add(identityStorage.findIdentity(OrganizationIdentityProvider.NAME, userDotName));
289 
290     tearDownIdentityList.add(identityStorage.findIdentity(OrganizationIdentityProvider.NAME, username));
291   }
292 
293   @MaxQueryNumber(99)
294   public void testLoadProfileByReloadCreatedProfileNode() throws Exception {
295     String providerId = "organization";
296     String remoteId = "username";
297     Identity identity = new Identity(providerId, remoteId);
298 
299     identityStorage.saveIdentity(identity);
300     tearDownIdentityList.add(identity);
301     String profileId;
302     //this code snippet will create profile node for test case
303     {
304       //create new profile in db without data (lazy creating)
305       Profile profile = new Profile(identity);
306       assertFalse(profile.hasChanged());
307       profile = identityStorage.loadProfile(profile);
308       assertFalse(profile.hasChanged());
309       profileId = profile.getId();
310     }
311 
312     //here is the testcase
313     {
314       Profile profile = new Profile(identity);
315       assertFalse(profile.hasChanged());
316       profile = identityStorage.loadProfile(profile);
317       assertFalse(profile.hasChanged());
318       assertEquals(profileId, profile.getId());
319     }
320   }
321 
322 
323   @MaxQueryNumber(108)
324   public void testFindIdentityByExistName() throws Exception {
325     String providerId = "organization";
326     String remoteId = "username";
327 
328     Identity identity = new Identity(providerId, remoteId);
329     identityStorage.saveIdentity(identity);
330     tearDownIdentityList.add(identity);
331 
332     Profile profile = new Profile(identity);
333     profile.setProperty(Profile.FIRST_NAME, "FirstName");
334     profile.setProperty(Profile.LAST_NAME, "LastName");
335     profile.setProperty(Profile.FULL_NAME, "FirstName" + " " + "LastName");
336     identityStorage.saveProfile(profile);
337     identity.setProfile(profile);
338     tearDownIdentityList.add(identity);
339     final ProfileFilter filter = new ProfileFilter();
340     filter.setName("First");
341     final List<Identity> result = identityStorage.getIdentitiesByProfileFilter(providerId, filter, 0, 1, false);
342     assertEquals(1, result.size());
343   }
344 
345   @MaxQueryNumber(1080)
346   public void testFindManyIdentitiesByExistName() throws Exception {
347     final String providerId = "organization";
348 
349     final int total = 10;
350     for (int i = 0; i <  total; i++) {
351       String remoteId = "username" + i;
352       Identity identity = new Identity(providerId, remoteId+i);
353       identityStorage.saveIdentity(identity);
354       tearDownIdentityList.add(identity);
355 
356       Profile profile = new Profile(identity);
357       profile.setProperty(Profile.FIRST_NAME, "FirstName"+ i);
358       profile.setProperty(Profile.LAST_NAME, "LastName" + i);
359       profile.setProperty(Profile.FULL_NAME, "FirstName" + i + " " + "LastName" + i);
360       identityStorage.saveProfile(profile);
361       identity.setProfile(profile);
362     }
363 
364     final ProfileFilter filter = new ProfileFilter();
365     filter.setName("FirstName");
366     final List<Identity> result = identityStorage.getIdentitiesByProfileFilter(providerId, filter, 0, total, false);
367     assertEquals(total, result.size());
368   }
369 
370   @MaxQueryNumber(1080)
371   public void testGetIdentitiesSorted() throws Exception {
372     final int total = 10;
373     String remoteIdPrefix = "username";
374     for (int i = 0; i < total; i++) {
375       String remoteId = remoteIdPrefix + i;
376       Identity identity = new Identity(OrganizationIdentityProvider.NAME, remoteId + i);
377       identityStorage.saveIdentity(identity);
378       tearDownIdentityList.add(identity);
379 
380       Profile profile = new Profile(identity);
381       profile.setProperty(Profile.FIRST_NAME, "FirstName" + i);
382       profile.setProperty(Profile.LAST_NAME, "LastName" + i);
383       profile.setProperty(Profile.FULL_NAME, "FirstName" + i + " " + "LastName" + i);
384       identityStorage.saveProfile(profile);
385       identity.setProfile(profile);
386     }
387 
388     List<Identity> result = identityStorage.getIdentities(OrganizationIdentityProvider.NAME, 0, Integer.MAX_VALUE);
389     List<String> identitiesList =
390                                 result.stream().map(identity -> identity.getProfile().getFullName()).collect(Collectors.toList());
391 
392     assertTrue(identitiesList.size() >= total);
393     Iterator<String> iterator = identitiesList.iterator();
394     while (iterator.hasNext()) {
395       String username = (String) iterator.next();
396       if (!username.startsWith(remoteIdPrefix)) {
397         iterator.remove();
398       }
399     }
400     List<String> identitiesListBackup = new ArrayList<>(identitiesList);
401     Collections.sort(identitiesList);
402     assertEquals("List '" + identitiesList + "' is not sorted", identitiesList, identitiesListBackup);
403   }
404 
405   @MaxQueryNumber(99)
406   public void testFindIdentityByNotExistName() throws Exception {
407     String providerId = "organization";
408     String remoteId = "username";
409 
410     Identity identity = new Identity(providerId, remoteId);
411     identityStorage.saveIdentity(identity);
412     tearDownIdentityList.add(identity);
413 
414     Profile profile = new Profile(identity);
415     profile.setProperty(Profile.FIRST_NAME, "FirstName");
416     profile.setProperty(Profile.LAST_NAME, "LastName");
417     profile.setProperty(Profile.FULL_NAME, "FirstName" + " " + "LastName");
418     identityStorage.saveProfile(profile);
419     identity.setProfile(profile);
420     final ProfileFilter filter = new ProfileFilter();
421     filter.setName("notfound");
422     final List<Identity> result = identityStorage.getIdentitiesByProfileFilter(providerId, filter, 0, 1, false);
423     assertEquals(0, result.size());
424   }
425   /**
426    * Tests {@link IdenityStorage#getIdentitiesByFirstCharaterOfNameCount(String, char)}
427    * 
428    */
429   @MaxQueryNumber(1200)
430   public void testGetIdentitiesByFirstCharacterOfNameCount() throws Exception {
431     populateData();
432     final ProfileFilter filter = new ProfileFilter();
433     filter.setFirstCharacterOfName('F');
434     int idsCount = identityStorage.getIdentitiesByFirstCharacterOfNameCount("organization", filter);
435     assertEquals("Number of identity must be " + idsCount, 0, idsCount);
436     filter.setFirstCharacterOfName('L');
437     idsCount = identityStorage.getIdentitiesByFirstCharacterOfNameCount("organization", filter);
438     assertEquals("Number of identity must be " + idsCount, 5, idsCount);
439     
440     //disable username1
441     Identity identity = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, "username1");
442     identityStorage.processEnabledIdentity(identity, false);
443     assertEquals(4, identityStorage.getIdentitiesByFirstCharacterOfNameCount("organization", filter));
444     
445     //enable username1
446     identityStorage.processEnabledIdentity(identity, true);
447     assertEquals(5, identityStorage.getIdentitiesByFirstCharacterOfNameCount("organization", filter));
448   }
449 
450   /**
451    * Tests {@link IdenityStorage#getIdentitiesByFirstCharaterOfName(String, char, int, int, boolean)}
452    * 
453    */
454   @MaxQueryNumber(1100)
455   public void testGetIdentitiesByFirstCharacterOfName() throws Exception {
456     populateData();    
457     final ProfileFilter filter = new ProfileFilter();
458     filter.setFirstCharacterOfName('F');
459     assertEquals(0, identityStorage.getIdentitiesByFirstCharacterOfName("organization", filter, 0, 1, false).size());
460     filter.setFirstCharacterOfName('L');
461     assertEquals(5, identityStorage.getIdentitiesByFirstCharacterOfName("organization", filter, 0, 10, false).size());
462   }
463   
464   /**
465    * Tests {@link IdenityStorage#getIdentitiesByProfileFilterCount(String, ProfileFilter)}
466    * 
467    */
468   @MaxQueryNumber(2000)
469   public void testGetIdentitiesByProfileFilterCount() throws Exception {
470     populateData();
471 
472     ProfileFilter pf = new ProfileFilter();
473     int idsCount = identityStorage.getIdentitiesByProfileFilterCount("organization", pf);
474     assertEquals(5, idsCount);
475     
476     pf.setPosition("developer");
477     pf.setName("FirstName");
478     
479     idsCount = identityStorage.getIdentitiesByProfileFilterCount("organization", pf);
480     assertEquals(5, idsCount);
481     
482     pf.setName("LastN");
483     idsCount = identityStorage.getIdentitiesByProfileFilterCount("organization", pf);
484     assertEquals(5, idsCount);
485     
486     //disable username1
487     Identity identity = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, "username1");
488     identityStorage.processEnabledIdentity(identity, false);
489     assertEquals(4, identityStorage.getIdentitiesByProfileFilterCount("organization", pf));
490     
491     //enable username1
492     identityStorage.processEnabledIdentity(identity, true);
493     assertEquals(5, identityStorage.getIdentitiesByProfileFilterCount("organization", pf));
494   }
495   
496   /**
497    * Tests {@link IdenityStorage#getIdentitiesByProfileFilterCount(String, ProfileFilter, int, int, boolean)}
498    * 
499    */
500   @MaxQueryNumber(670)
501   public void testGetIdentitiesByProfileFilterAccessList() throws Exception {
502     populateData();
503     ProfileFilter pf = new ProfileFilter();
504     
505     List<Identity> identities = identityStorage.getIdentitiesByProfileFilter("organization", pf, 0, 20, false);
506     assertEquals("Number of identities must be " + identities.size(), 5, identities.size());
507     
508     pf.setPosition("developer");
509     pf.setName("FirstName");
510     identities = identityStorage.getIdentitiesByProfileFilter("organization", pf, 0, 20, false);
511     assertEquals("Number of identities must be " + identities.size(), 5, identities.size());
512     
513     try {
514       identities = identityStorage.getIdentitiesByProfileFilter("organization", pf, -1, 20, false);
515     } catch (Exception ext) {
516       assert false : "Can not get Identity by profile filter. " + ext ;
517     } 
518     
519     try {
520       identities = identityStorage.getIdentitiesByProfileFilter("organization", pf, 0, -1, false);
521     } catch (Exception ext) {
522       assert false : "Can not get Identity by profile filter. " + ext ;
523     } 
524     
525     try {
526       identities = identityStorage.getIdentitiesByProfileFilter("organization", pf, 30, 40, false);
527     } catch (Exception ext) {
528       assert false : "Can not get Identity by profile filter. " + ext ;
529     } 
530   }
531   
532   /**
533    * Tests {@link IdenityStorage#findIdentityByProfileFilterCount(String, ProfileFilter)}
534    * 
535    */
536   @MaxQueryNumber(264)
537   public void testUpdateIdentity() throws Exception {
538     String providerId = OrganizationIdentityProvider.NAME;
539     String newProviderId = "space";
540     String userName = "userIdentity1";
541     Identity identity = populateIdentity(userName, true);
542     assertNotNull("Identity must not be null", identity);
543     assertEquals("Identity status must be " + identity.isDeleted(), false, identity.isDeleted());
544     identity.setDeleted(true);
545     identityStorage.updateIdentity(identity);
546     Identity updatedIdentity = identityStorage.findIdentity(providerId, userName);
547     assertEquals("Identity status must be " + updatedIdentity.isDeleted(), true, updatedIdentity.isDeleted());
548     identity.setProviderId(newProviderId);
549     identity.setDeleted(false);
550     identityStorage.updateIdentity(identity);
551     updatedIdentity = identityStorage.findIdentity(newProviderId, userName);
552     tearDownIdentityList.add(updatedIdentity);
553     assertEquals("Identity status must be " + updatedIdentity.isDeleted(), false, updatedIdentity.isDeleted());
554     assertEquals("Identity provider id must be " + updatedIdentity.getProviderId(), newProviderId, updatedIdentity.getProviderId());
555   }
556   
557   /**
558    *  Tests {@link IdenityStorage#getIdentitiesCount(String)}
559    */
560   @MaxQueryNumber(765)
561   public void testGetIdentitiesCount() throws Exception {
562     int numberUser = 10;
563     int numberDisableUser = 5;
564     // create user
565     List<Identity> identities = new ArrayList<Identity>();
566     for (int i = 0; i < numberUser; i++) {
567       Identity identity = new Identity(OrganizationIdentityProvider.NAME, "user" + i);
568       identityStorage.saveIdentity(identity);
569       identities.add(identity);
570       tearDownIdentityList.add(identity);
571     }
572     assertEquals(10, identityStorage.getIdentitiesCount(OrganizationIdentityProvider.NAME));
573     // disable users
574     for (int i = 0; i < numberDisableUser; i++) {
575       Identity identity = identities.get(i);
576       identityStorage.processEnabledIdentity(identity, false);
577     }
578     assertEquals(numberUser - numberDisableUser, identityStorage.getIdentitiesCount(OrganizationIdentityProvider.NAME));
579   }
580 
581   @MaxQueryNumber(2635)
582   public void testGetSpaceMemberByProfileFilter() throws Exception {
583     populateData();
584     populateUser("username4");
585     populateUser("username1");
586 
587     Space space = new Space();
588     space.setApp("app");
589     space.setDisplayName("my space");
590     space.setPrettyName(space.getDisplayName());
591     space.setRegistration(Space.OPEN);
592     space.setDescription("add new space ");
593     space.setType(DefaultSpaceApplicationHandler.NAME);
594     space.setVisibility(Space.PUBLIC);
595     space.setPriority(Space.INTERMEDIATE_PRIORITY);
596     space.setGroupId(SpaceUtils.createGroup(space.getPrettyName(), "username4"));
597     space.setUrl(space.getPrettyName());
598     String[] managers = new String[] {};
599     String[] members = new String[] {"username1", "username2", "username3"};
600     String[] invitedUsers = new String[] {};
601     String[] pendingUsers = new String[] {};
602     space.setInvitedUsers(invitedUsers);
603     space.setPendingUsers(pendingUsers);
604     space.setManagers(managers);
605     space.setMembers(members);
606 
607     spaceStorage.saveSpace(space, true);
608     tearDownSpaceList.add(space);
609     
610     ProfileFilter profileFilter = new ProfileFilter();
611     
612     List<Identity> identities = identityStorage.getSpaceMemberIdentitiesByProfileFilter(space, profileFilter, Type.MEMBER, 0, 2);
613     assertEquals(2, identities.size());
614 
615     Identity username1Identity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, "username1", true);
616     tearDownIdentityList.add(username1Identity);
617     tearDownIdentityList.add(identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, "username4", true));
618     profileFilter.setViewerIdentity(username1Identity);
619     assertEquals(2, identityStorage.countSpaceMemberIdentitiesByProfileFilter(space, profileFilter, Type.MEMBER));
620 
621     addUserToGroupWithMembership("username4", space.getGroupId(), MembershipTypeHandler.ANY_MEMBERSHIP_TYPE);
622     identities = identityStorage.getSpaceMemberIdentitiesByProfileFilter(space, new ProfileFilter(), Type.MANAGER, 0, 10);
623     assertEquals(1, identities.size());
624   }
625 
626   @MaxQueryNumber(126)
627   public void testGetAvatarInputStreamById() throws Exception {
628     InputStream inputStream = getClass().getResourceAsStream("/eXo-Social.png");
629     AvatarAttachment avatarAttachment = new AvatarAttachment(null, "avatar", "png", inputStream, null, System.currentTimeMillis());
630     
631     /*
632       test on identity with @OrganizationIdentityProvider.NAME as providerId.
633      */
634     String userName = "userIdentity2";
635     Identity identity = populateIdentity(userName);
636     identityStorage.saveIdentity(identity);
637     tearDownIdentityList.add(identity);
638 
639     // within this instruction the profile is created implicitly and it does not have an avatar
640     String identityId = identity.getId();
641     assertNotNull(identityId);
642     InputStream stream = identityStorage.getAvatarInputStreamById(identity);
643     assertNull(stream);
644     
645     Profile profile = new Profile(identity);
646     profile.setProperty(Profile.AVATAR, avatarAttachment);
647     identityStorage.updateIdentity(identity);
648     identityStorage.saveProfile(profile);
649     profile = identityStorage.loadProfile(profile);
650     // we load the profile to check if the avatar is well attached to it, as well as @Profile.avatarLastUpdated value
651     Long avatarLastUpdated = profile.getAvatarLastUpdated();
652     assertNotNull(avatarLastUpdated);
653 
654     // Make sure that the upcoming update will not occur at the exact same time than the first update
655     Thread.sleep(10);
656 
657     // we re-attach the the avatar to the profile to be sure that @Profile.avatarLastUpdated value is updated
658     profile.setProperty(Profile.AVATAR, avatarAttachment);
659     identityStorage.updateProfile(profile);
660     Profile profile1 = identityStorage.loadProfile(profile);
661     Long avatarLastUpdated1 = profile1.getAvatarLastUpdated();
662     assertNotNull(avatarLastUpdated1);
663     assertNotSame(avatarLastUpdated1, avatarLastUpdated);
664     assertTrue(avatarLastUpdated1 > avatarLastUpdated);
665     
666     stream = identityStorage.getAvatarInputStreamById(identity);
667     assertNotNull(stream);
668     
669     /*
670       test on identity with @SpaceIdentityProvider.NAME as providerId.
671      */
672     Space space = this.getSpaceInstance(1);
673     spaceStorage.saveSpace(space, true);
674     String remoteId = space.getPrettyName();
675     assertNotNull(remoteId);
676     identity = new Identity(SpaceIdentityProvider.NAME, remoteId);
677     identityStorage.saveIdentity(identity);
678     tearDownIdentityList.add(identity);
679 
680     assertNotNull(identity.getId());
681     assertNotNull(identity.getRemoteId());
682     stream = identityStorage.getAvatarInputStreamById(identity);
683     // the space does not have an avatar
684     assertNull(stream);
685     // we set the avatar to the space
686     space.setAvatarAttachment(avatarAttachment);
687     spaceStorage.saveSpace(space, false);
688     space = spaceStorage.getSpaceByPrettyName(remoteId);
689     
690     identity = new Identity(SpaceIdentityProvider.NAME, space.getPrettyName());
691     profile = new Profile(identity);
692     // we set the avatar to the corresponding space profile
693     profile.setProperty(Profile.AVATAR, avatarAttachment);
694     identityStorage.saveIdentity(identity);
695     identityStorage.saveProfile(profile);
696     profile = identityStorage.loadProfile(profile);
697     avatarLastUpdated = profile.getAvatarLastUpdated();
698     assertNotNull(avatarLastUpdated);
699 
700     // Make sure that the upcoming update will not occur at the exact same time than the first update
701     Thread.sleep(10);
702 
703     profile.setProperty(Profile.AVATAR, avatarAttachment);
704     identityStorage.updateProfile(profile);
705     profile = identityStorage.loadProfile(profile);
706     avatarLastUpdated1 = profile.getAvatarLastUpdated();
707     assertNotNull(avatarLastUpdated1);
708     assertNotSame(avatarLastUpdated1, avatarLastUpdated);
709     // we check that the  @Profile.avatarLastUpdated is updated with greater value
710     assertTrue(avatarLastUpdated1 > avatarLastUpdated);
711     
712     tearDownIdentityList.add(identity);
713     stream = identityStorage.getAvatarInputStreamById(identity);
714     assertNotNull(stream);
715   }
716 
717   @MaxQueryNumber(141)
718   public void testGetBannerInputStreamById() throws Exception {
719     InputStream inputStream = getClass().getResourceAsStream("/eXo-Social.png");
720     BannerAttachment bannerAttachment = new BannerAttachment(null, "banner", "png", inputStream, null, System.currentTimeMillis());
721 
722     /*
723       test on identity with @OrganizationIdentityProvider.NAME as providerId.
724      */
725     String userName = "userIdentity3";
726     Identity identity = populateIdentity(userName);
727     identityStorage.saveIdentity(identity);
728     tearDownIdentityList.add(identity);
729 
730     // within this instruction the profile is created implicitly and it does not have an banner
731     String identityId = identity.getId();
732     assertNotNull(identityId);
733     InputStream stream = identityStorage.getBannerInputStreamById(identity);
734     assertNull(stream);
735 
736     Profile profile = new Profile(identity);
737     profile.setProperty(Profile.BANNER, bannerAttachment);
738     identityStorage.updateIdentity(identity);
739     identityStorage.saveProfile(profile);
740     profile = identityStorage.loadProfile(profile);
741     // we load the profile to check if the banner is well attached to it, as well as @Profile.bannerLastUpdated value
742     Long bannerLastUpdated = profile.getBannerLastUpdated();
743     assertNotNull(bannerLastUpdated);
744 
745     // Make sure that the upcoming update will not occur at the exact same time than the first update
746     Thread.sleep(10);
747 
748     // we re-attach the the banner to the profile to be sure that @Profile.bannerLastUpdated value is updated
749     profile.setProperty(Profile.BANNER, bannerAttachment);
750     identityStorage.updateProfile(profile);
751     Profile profile1 = identityStorage.loadProfile(profile);
752     Long bannerLastUpdated1 = profile1.getBannerLastUpdated();
753     assertNotNull(bannerLastUpdated1);
754     assertNotSame(bannerLastUpdated1, bannerLastUpdated);
755     assertTrue(bannerLastUpdated1 > bannerLastUpdated);
756 
757     stream = identityStorage.getBannerInputStreamById(identity);
758     assertNotNull(stream);
759 
760     /*
761       test on identity with @SpaceIdentityProvider.NAME as providerId.
762      */
763     Space space = this.getSpaceInstance(1);
764     spaceStorage.saveSpace(space, true);
765     String remoteId = space.getPrettyName();
766     assertNotNull(remoteId);
767     identity = new Identity(SpaceIdentityProvider.NAME, remoteId);
768     identityStorage.saveIdentity(identity);
769     assertNotNull(identity.getId());
770     assertNotNull(identity.getRemoteId());
771     stream = identityStorage.getBannerInputStreamById(identity);
772     // the space does not have an banner
773     assertNull(stream);
774     // we set the banner to the space
775     space.setBannerAttachment(bannerAttachment);
776     spaceStorage.saveSpace(space, false);
777     space = spaceStorage.getSpaceByPrettyName(remoteId);
778 
779     identity = new Identity(SpaceIdentityProvider.NAME, space.getPrettyName());
780     profile = new Profile(identity);
781     // we set the banner to the corresponding space profile
782     profile.setProperty(Profile.BANNER, bannerAttachment);
783     identityStorage.saveIdentity(identity);
784     identityStorage.saveProfile(profile);
785     profile = identityStorage.loadProfile(profile);
786     bannerLastUpdated = profile.getBannerLastUpdated();
787     assertNotNull(bannerLastUpdated);
788 
789     // Make sure that the upcoming update will not occur at the exact same time than the first update
790     Thread.sleep(10);
791 
792     profile.setProperty(Profile.BANNER, bannerAttachment);
793     identityStorage.updateProfile(profile);
794     profile = identityStorage.loadProfile(profile);
795     bannerLastUpdated1 = profile.getBannerLastUpdated();
796     assertNotNull(bannerLastUpdated1);
797     assertNotSame(bannerLastUpdated1, bannerLastUpdated);
798     // we check that the  @Profile.bannerLastUpdated is updated with greater value
799     assertTrue(bannerLastUpdated1 > bannerLastUpdated);
800 
801     tearDownIdentityList.add(identity);
802     stream = identityStorage.getBannerInputStreamById(identity);
803     assertNotNull(stream);
804   }
805 
806   @MaxQueryNumber(24)
807   public void testUpdateProfile() throws Exception {
808     String userName = "userIdentity4";
809     Identity identity = populateIdentity(userName);
810     identityStorage.saveIdentity(identity);
811     tearDownIdentityList.add(identity);
812 
813     Profile profile = identity.getProfile();
814     profile.setProperty(Profile.GENDER, "male");
815     profile.setProperty(Profile.POSITION, "developer");
816     identityStorage.updateProfile(profile);
817 
818     identity = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, userName);
819     assertNotNull(identity);
820     assertNotNull(identity.getProfile());
821     assertEquals("male", identity.getProfile().getGender());
822     assertEquals("developer", identity.getProfile().getPosition());
823 
824     profile.setProperty(Profile.POSITION, null);
825     identityStorage.updateProfile(profile);
826 
827     identity = identityStorage.findIdentity(OrganizationIdentityProvider.NAME, userName);
828     assertNotNull(identity);
829     assertNotNull(identity.getProfile());
830     assertEquals("male", identity.getProfile().getGender());
831     assertEquals(null, identity.getProfile().getPosition());
832   }
833   
834   /**
835    * Populate one identity with remoteId.
836    * 
837    * @param remoteId
838    * @return
839    */
840   private Identity populateIdentity(String remoteId) {
841     return populateIdentity(remoteId, false);
842   }
843 
844   /**
845    * Populates one identity with remoteId.
846    *
847    * @param remoteId
848    * @param addedToTearDown
849    * @return
850    */
851   private Identity populateIdentity(String remoteId, boolean addedToTearDown) {
852     String providerId = "organization";
853     Identity identity = new Identity(providerId, remoteId);
854     identityStorage.saveIdentity(identity);
855 
856     Profile profile = new Profile(identity);
857     profile.setProperty(Profile.FIRST_NAME, remoteId);
858     profile.setProperty(Profile.LAST_NAME, "gtn");
859     profile.setProperty(Profile.FULL_NAME, remoteId + " " +  "gtn");
860     profile.setProperty(Profile.POSITION, "developer");
861     profile.setProperty(Profile.GENDER, "male");
862     identityStorage.saveProfile(profile);
863 
864     identity.setProfile(profile);
865     if (addedToTearDown) {
866       tearDownIdentityList.add(identity);
867     }
868     return identity;
869   }
870   
871   private void populateData() {
872     populateData(5);
873   }
874   
875   private void populateData(int number) {
876     String providerId = "organization";
877     for (int i = 0; i < number; i++) {
878       String remoteId = "username" + i;
879       Identity identity = new Identity(providerId, remoteId);
880       identityStorage.saveIdentity(identity);
881       tearDownIdentityList.add(identity);
882 
883       Profile profile = new Profile(identity);
884       profile.setProperty(Profile.FIRST_NAME, "FirstName" + i);
885       profile.setProperty(Profile.LAST_NAME, "LastName" + i);
886       profile.setProperty(Profile.FULL_NAME, "FirstName" + i + " " +  "LastName" + i);
887       profile.setProperty("position", "developer");
888       profile.setProperty("gender", "male");
889       identity.setProfile(profile);
890       identityStorage.saveProfile(profile);
891     }
892   }
893   
894   private User populateUser(String name) {
895     OrganizationService os = SpaceUtils.getOrganizationService();
896     User user = os.getUserHandler().createUserInstance(name);
897     
898     try {
899       os.getUserHandler().createUser(user, false);
900     } catch (Exception e) {
901       return null;
902     }
903     return user;
904   }
905   
906   /**
907    * Gets an instance of Space.
908    *
909    * @param number
910    * @return an instance of space
911    */
912   private Space getSpaceInstance(int number) {
913     Space space = new Space();
914     space.setApp("app1,app2");
915     space.setDisplayName("my space " + number);
916     space.setPrettyName(space.getDisplayName());
917     space.setRegistration(Space.OPEN);
918     space.setDescription("add new space " + number);
919     space.setType(DefaultSpaceApplicationHandler.NAME);
920     space.setVisibility(Space.PUBLIC);
921     space.setPriority(Space.INTERMEDIATE_PRIORITY);
922     space.setGroupId("/spaces/space" + number);
923     String[] managers = new String[] {"demo", "tom"};
924     String[] members = new String[] {"raul", "ghost", "dragon"};
925     String[] invitedUsers = new String[] {"register1", "mary"};
926     String[] pendingUsers = new String[] {"jame", "paul", "hacker"};
927     space.setInvitedUsers(invitedUsers);
928     space.setPendingUsers(pendingUsers);
929     space.setManagers(managers);
930     space.setMembers(members);
931     space.setUrl(space.getPrettyName());
932     return space;
933   }
934   
935   private static void addUserToGroupWithMembership(String remoteId, String groupId, String membership) {
936     OrganizationService organizationService = SpaceUtils.getOrganizationService();
937     try {
938       // TODO: checks whether user is already manager?
939       MembershipHandler membershipHandler = organizationService.getMembershipHandler();
940       Membership found = membershipHandler.findMembershipByUserGroupAndType(remoteId, groupId, membership);
941       if (found != null) {
942         return;
943       }
944       User user = organizationService.getUserHandler().findUserByName(remoteId);
945       MembershipType membershipType = organizationService.getMembershipTypeHandler().findMembershipType(membership);
946       GroupHandler groupHandler = organizationService.getGroupHandler();
947       Group existingGroup = groupHandler.findGroupById(groupId);
948       membershipHandler.linkMembership(user, existingGroup, membershipType, true);
949       persist();
950     } catch (Exception e) {
951       return;
952     }
953   }
954 }