View Javadoc
1   package com.atlassian.sal.core.pluginsettings;
2   
3   import com.google.common.collect.ImmutableMap;
4   import org.apache.commons.lang3.StringUtils;
5   import org.junit.Before;
6   import org.junit.Test;
7   
8   import java.util.Arrays;
9   import java.util.HashMap;
10  import java.util.List;
11  import java.util.Map;
12  import java.util.Properties;
13  
14  import static org.hamcrest.CoreMatchers.instanceOf;
15  import static org.junit.Assert.assertEquals;
16  import static org.junit.Assert.assertNull;
17  import static org.junit.Assert.assertThat;
18  import static org.junit.Assert.assertTrue;
19  
20  public class TestAbstractStringPluginSettings {
21      private PluginSettingsAcceptor acceptor;
22      private static final String KEY = "some key";
23  
24      @Before
25      public void setUp() {
26          acceptor = new PluginSettingsAcceptor();
27      }
28  
29      @Test
30      public void canStoreString() {
31          String value = "this is the value";
32  
33          acceptor.put(KEY, value);
34          assertEquals("Values should be equal.", value, acceptor.get(KEY));
35      }
36  
37      @Test(expected = IllegalArgumentException.class)
38      public void getWithNullKeyFails() {
39          acceptor.get(null);
40      }
41  
42      @Test
43      public void getWithLongKeyDoesNotCauseError() {
44          assertNull(acceptor.get(StringUtils.repeat("a", 101)));
45      }
46  
47      @Test
48      public void getWithVeryLongKeyDoesNotCauseError() {
49          assertNull(acceptor.get(StringUtils.repeat("a", 256)));
50      }
51  
52      @Test(expected = IllegalArgumentException.class)
53      public void putWithNullKeyFails() {
54          acceptor.put(null, "foo");
55      }
56  
57      @Test
58      public void putWith100CharacterKeyIsAlwaysAccepted() {
59          acceptor.put(StringUtils.repeat("a", 100), "foo");
60      }
61  
62      /**
63       * The SAL layer accepts this key. The underlying storage layer
64       * may fail in a real application.
65       */
66      @Test
67      public void putWithVeryLongKeyIsAcceptedBySalLayer() {
68          String previousValue = System.setProperty("atlassian.dev.mode", "false");
69          try {
70              // A new instance to pick up the system property
71              acceptor = new PluginSettingsAcceptor();
72              acceptor.put(StringUtils.repeat("a", 255), "foo");
73          } finally {
74              System.setProperty("atlassian.dev.mode", StringUtils.defaultString(previousValue));
75          }
76      }
77  
78      @Test(expected = IllegalArgumentException.class)
79      public void putWithOverlyLongKeyFails() {
80          acceptor.put(StringUtils.repeat("a", 256), "foo");
81      }
82  
83      @Test(expected = IllegalArgumentException.class)
84      public void putWithLongKeyFailsInDevMode() {
85          String previousValue = System.setProperty("atlassian.dev.mode", "true");
86          try {
87              // A new instance to pick up the system property
88              acceptor = new PluginSettingsAcceptor();
89              acceptor.put(StringUtils.repeat("a", 101), "foo");
90          } finally {
91              System.setProperty("atlassian.dev.mode", StringUtils.defaultString(previousValue));
92          }
93      }
94  
95      @Test
96      public void canStoreSpecialCharsString() {
97          String value = "this\tis\bthe\nvalue\rand\ffun";
98  
99          acceptor.put(KEY, value);
100         assertEquals("Values should be equal.", value, acceptor.get(KEY));
101     }
102 
103     @Test
104     public void canStoreList() {
105         final List<String> original = Arrays.asList("Beanz Meanz Heinz", "Sic 'em Rex!");
106 
107         acceptor.put(KEY, original);
108 
109         final Object actual = acceptor.get(KEY);
110 
111         assertThat(actual, instanceOf(List.class));
112 
113         final List<?> returned = (List<?>) actual;
114 
115         assertEquals("The List returned from PluginSettings should match the original List", original, returned);
116     }
117 
118     @Test
119     public void canStoreListWithSpecialChars() {
120         final List<String> original = Arrays.asList("At\tfirst\bwhen\nI\rsee\fyou cry", "\tit\bmakes\nme\rsmile\f");
121 
122         acceptor.put(KEY, original);
123 
124         final Object actual = acceptor.get(KEY);
125 
126         assertThat(actual, instanceOf(List.class));
127 
128         final List<?> returned = (List<?>) actual;
129 
130         assertEquals("The List returned from PluginSettings should match the original List", original, returned);
131     }
132 
133     @Test
134     public void canStoreMap() {
135         final Map<String, String> original = new HashMap<String, String>();
136         final String[] first = {"antzpantz", "Sic 'em Rex!"};
137         final String[] second = {"homestar", "Lookin' at a thing in a bag"};
138         final String[] third = {"he-man", "By the power of Greyskull!!!"};
139 
140         mapPut(original, first);
141         mapPut(original, second);
142         mapPut(original, third);
143 
144         acceptor.put(KEY, original);
145 
146         final Object actual = acceptor.get(KEY);
147 
148         assertThat(actual, instanceOf(Map.class));
149 
150         final Map<?, ?> returned = (Map<?, ?>) actual;
151 
152         assertEquals("The Map returned from PluginSettings should match the original Map", original, returned);
153     }
154 
155     @Test
156     public void canStoreMapWithSpecialCharsValue() {
157         final Map<String, String> original = new HashMap<String, String>();
158         final String[] first = {"one", "one\tthing\bI\ndon't\rknow\fwhy"};
159         final String[] second = {"two", "I\tdoesn't\beven\nmatter\rhow\fhard you try"};
160 
161         mapPut(original, first);
162         mapPut(original, second);
163 
164         acceptor.put(KEY, original);
165 
166         final Object actual = acceptor.get(KEY);
167 
168         assertThat(actual, instanceOf(Map.class));
169 
170         final Map<?, ?> returned = (Map<?, ?>) actual;
171 
172         assertEquals("The Map returned from PluginSettings should match the original Map", original, returned);
173     }
174 
175     @Test
176     public void canStoreEmptyMap() {
177         final Map<String, String> value = new HashMap<String, String>();
178         acceptor.put(KEY, value);
179         final Object actual = acceptor.get(KEY);
180         assertThat(actual, instanceOf(Map.class));
181         assertTrue(((Map<?, ?>) actual).isEmpty());
182     }
183 
184     @Test
185     public void canStoreMapWithKeyMappedToEmptyValue() {
186         final Map<String, String> original = ImmutableMap.of("first", "");
187 
188         acceptor.put(KEY, original);
189 
190         final Object actual = acceptor.get(KEY);
191 
192         assertThat(actual, instanceOf(Map.class));
193 
194         final Map<?, ?> returned = (Map<?, ?>) actual;
195 
196         assertEquals("The Map returned from PluginSettings should match the original Map", original, returned);
197 
198     }
199 
200     @Test
201     public void canStoreMapWithEmptyStringAsKey() {
202         final Map<String, String> original = ImmutableMap.of("", "first value");
203 
204         acceptor.put(KEY, original);
205 
206         final Object actual = acceptor.get(KEY);
207 
208         assertThat(actual, instanceOf(Map.class));
209 
210         final Map<?, ?> returned = (Map<?, ?>) actual;
211 
212         assertEquals("The Map returned from PluginSettings should match the original Map", original, returned);
213 
214     }
215 
216     @Test
217     public void canStoreMapWithEmptyStringAsKeyAndValue() {
218         final Map<String, String> original = ImmutableMap.of("", "");
219 
220         acceptor.put(KEY, original);
221 
222         final Object actual = acceptor.get(KEY);
223 
224         assertThat(actual, instanceOf(Map.class));
225 
226         final Map<?, ?> returned = (Map<?, ?>) actual;
227 
228         assertEquals("The Map returned from PluginSettings should match the original Map", original, returned);
229 
230     }
231 
232     @Test
233     public void canStoreProperties() {
234         final Properties value = new Properties();
235         final String[] first = {"antzpantz", "Sic 'em Rex!"};
236         final String[] second = {"homestar", "Lookin' at a thing in a bag"};
237         final String[] third = {"he-man", "By the power of Greyskull!!!"};
238 
239         propertiesPut(value, first);
240         propertiesPut(value, second);
241         propertiesPut(value, third);
242 
243         acceptor.put(KEY, value);
244 
245         final Object actual = acceptor.get(KEY);
246 
247         assertThat(actual, instanceOf(Properties.class));
248 
249         final Properties real = (Properties) actual;
250 
251         assertPropertiesEntryEquals("Propertis should contain the same value for each key", real, first);
252         assertPropertiesEntryEquals("Propertis should contain the same value for each key", real, second);
253         assertPropertiesEntryEquals("Propertis should contain the same value for each key", real, third);
254     }
255 
256     @Test
257     public void canStorePropertiesWithSpecialCharsInKeys() {
258         String key1 = "this\tis\bthe\nkey\rsample\fhohoho1";
259         String value1 = "value1";
260 
261         String key2 = "this\tis\bthe\nkey\rsample\fhohoho2";
262         List<String> value2 = Arrays.asList("value2");
263 
264         String key3 = "this\tis\bthe\nkey\rsample\fhohoho3";
265         Map<String, String> value3 = new HashMap<String, String>();
266         value3.put(key3 + "inner1", "value3inner1");
267         value3.put(key3 + "inner2", "value3inner2");
268 
269         String key4 = "this\tis\bthe\nkey\rsample\fhohoho4";
270         Properties value4 = new Properties();
271         value4.setProperty(key4 + "inner1", "value4inner1");
272         value4.setProperty(key4 + "inner2", "value4inner2");
273 
274         acceptor.put(key1, value1);
275         acceptor.put(key2, value2);
276         acceptor.put(key3, value3);
277         acceptor.put(key4, value4);
278 
279         assertEquals("Values should be equal.", value1, acceptor.get(key1));
280         assertEquals("Values should be equal.", value2, acceptor.get(key2));
281         assertEquals("Values should be equal.", value3, acceptor.get(key3));
282         assertEquals("Values should be equal.", value4, acceptor.get(key4));
283     }
284 
285     @Test
286     public void putNewValueShouldReturnNull() {
287         List<String> value = Arrays.asList("one", "two", "three");
288         assertNull(acceptor.put(KEY, value));
289     }
290 
291     @Test
292     public void putValueReplacingExistingValueShouldReturnOldValue() {
293         List<String> oldValue = Arrays.asList("two", "three", "four");
294         acceptor.put(KEY, oldValue);
295         List<String> value = Arrays.asList("one", "two", "three");
296         assertEquals(oldValue, acceptor.put(KEY, value));
297     }
298 
299     @Test
300     public void removeNonExistingValueShouldReturnNull() {
301         assertNull(acceptor.remove(KEY));
302     }
303 
304     @Test
305     public void removeExistingValueShouldReturnValueBeingRemoved() {
306         List<String> oldValue = Arrays.asList("two", "three", "four");
307         acceptor.put(KEY, oldValue);
308         assertEquals(oldValue, acceptor.remove(KEY));
309     }
310 
311     @Test(expected = IllegalArgumentException.class)
312     public void removeWithNullKeyFails() {
313         acceptor.remove(null);
314     }
315 
316     @Test
317     public void removeWithLongKeyDoesNotFail() {
318         assertNull(acceptor.remove(StringUtils.repeat("a", 101)));
319     }
320 
321     @Test
322     public void removeWithVeryLongKeyDoesNotFail() {
323         assertNull(acceptor.remove(StringUtils.repeat("a", 256)));
324     }
325 
326     private void assertPropertiesEntryEquals(String errMsg, Properties real, String[] kvPair) {
327         assertEquals(errMsg, kvPair[1], real.getProperty(kvPair[0]));
328     }
329 
330     private static void propertiesPut(Properties properties, String[] values) {
331         properties.setProperty(values[0], values[1]);
332     }
333 
334     private static void mapPut(Map<String, String> map, String[] values) {
335         map.put(values[0], values[1]);
336     }
337 
338 
339     private static final class PluginSettingsAcceptor extends AbstractStringPluginSettings {
340         private final Map<String, String> backingStore = new HashMap<String, String>();
341 
342         protected void putActual(String key, String val) {
343             backingStore.put(key, val);
344         }
345 
346         protected String getActual(String key) {
347             return backingStore.get(key);
348         }
349 
350         protected void removeActual(String key) {
351             backingStore.remove(key);
352         }
353     }
354 }