1 package com.atlassian.sal.core.pluginsettings;
2
3 import com.google.common.collect.ImmutableMap;
4 import org.apache.commons.lang.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
64
65
66 @Test
67 public void putWithVeryLongKeyIsAcceptedBySalLayer() {
68 String previousValue = System.setProperty("atlassian.dev.mode", "false");
69 try {
70
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
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 }