1   package com.atlassian.user.impl.cache.properties;
2   
3   import com.atlassian.cache.Cache;
4   import com.atlassian.cache.CacheFactory;
5   import com.atlassian.cache.memory.MemoryCacheManager;
6   import com.atlassian.user.Entity;
7   import com.atlassian.user.EntityException;
8   import com.atlassian.user.impl.DefaultUser;
9   import com.atlassian.user.impl.memory.properties.MemoryPropertySetFactory;
10  import com.atlassian.user.properties.PropertySetFactory;
11  import com.mockobjects.dynamic.C;
12  import com.mockobjects.dynamic.Mock;
13  import com.opensymphony.module.propertyset.PropertySet;
14  import junit.framework.TestCase;
15  
16  import java.util.Collections;
17  
18  /**
19   * Test the CachingPropertySetFactory.  Initially must test that changes to the property sets are written to the
20   * cache, rather than being assumed to be updated in the cache by using the same object.
21   */
22  public class TestCachingPropertySetFactory extends TestCase
23  {
24      // Unfortunately I found some of the class very hard to test with mock objects and other
25      // bits very hard to test with real objects.  So I use each in different tests.
26      // It would probably be easier to test everything with mocks if the creation of the
27      // CachedPropertySet was done by a factory.
28      private MemoryPropertySetFactory realUnderlyingFactory;
29      private CacheFactory realUnderlyingCacheFactory;
30  
31      private Mock mockUnderlyingFactory;
32      private Mock mockCacheFactory;
33      private Mock mockCache;
34  
35      protected void setUp() throws Exception
36      {
37          super.setUp();
38          realUnderlyingFactory = new MemoryPropertySetFactory();
39          realUnderlyingCacheFactory = new MemoryCacheManager();
40  
41          mockUnderlyingFactory = new Mock(PropertySetFactory.class);
42          mockCacheFactory = new Mock(CacheFactory.class);
43          mockCache = new Mock(Cache.class);
44      }
45  
46  
47      protected void tearDown() throws Exception
48      {
49          super.tearDown();
50          realUnderlyingFactory = null;
51          realUnderlyingCacheFactory = null;
52  
53          mockUnderlyingFactory = null;
54          mockCacheFactory = null;
55          mockCache = null;
56      }
57  
58      public void testPropertyModificationsAreVisibleInCache() throws EntityException
59      {
60          PropertySetFactory factory = new CachingPropertySetFactory(realUnderlyingFactory, realUnderlyingCacheFactory);
61  
62          Entity testUser = new DefaultUser("testUser");
63          PropertySet returnedPropertySet = factory.getPropertySet(testUser);
64          Cache cache = realUnderlyingCacheFactory.getCache(realUnderlyingFactory.getClass().getName() + ".propertysets");
65          assertNotNull(cache.get(testUser.getName()));
66          returnedPropertySet.setString("key", "value");
67          PropertySet cachedPropertySet = (PropertySet) cache.get(testUser.getName());
68          assertNotNull(cachedPropertySet);
69          assertEquals(cachedPropertySet.getString("key"), "value");
70      }
71  
72  
73      public void testPropertySetIsRecachedOnWrite() throws EntityException
74      {
75          PropertySetFactory factory = new CachingPropertySetFactory(realUnderlyingFactory, realUnderlyingCacheFactory);
76  
77          Entity testUser = new DefaultUser("testUser");
78          PropertySet returnedPropertySet = factory.getPropertySet(testUser);
79          Cache cache = realUnderlyingCacheFactory.getCache(realUnderlyingFactory.getClass().getName() + ".propertysets");
80          assertNotNull(cache.get(testUser.getName()));
81          cache.remove(testUser.getName());
82          returnedPropertySet.setString("key", "value");
83          PropertySet recachedPropertySet = (PropertySet) cache.get(testUser.getName());
84          assertNotNull(recachedPropertySet);
85          assertEquals(recachedPropertySet.getString("key"), "value");
86  
87      }
88  
89      public void testUnderlyingPropertySetIsNotRetrievedOnSecondRead() throws EntityException
90      {
91          PropertySetFactory factory = new CachingPropertySetFactory((PropertySetFactory) mockUnderlyingFactory.proxy(),
92              (CacheFactory) mockCacheFactory.proxy());
93  
94          Entity testUser = new DefaultUser("testUser");
95          CachedPropertySet wrappedPropertySet = new CachedPropertySet();
96          wrappedPropertySet.init(Collections.EMPTY_MAP, Collections.EMPTY_MAP);
97  
98          mockCacheFactory.reset();
99          mockCacheFactory.matchAndReturn("getCache", C.ANY_ARGS, mockCache.proxy());
100         mockCache.expectAndReturn("get", C.same(testUser.getName()), wrappedPropertySet);
101         // note, no call to underlying factory.
102         factory.getPropertySet(testUser);
103 
104         verifyMocks();
105     }
106 
107     private void verifyMocks()
108     {
109         mockCache.verify();
110         mockCacheFactory.verify();
111         mockUnderlyingFactory.verify();
112     }
113 }