1 package com.atlassian.sal.core.features;
2
3 import com.atlassian.sal.api.features.EnabledDarkFeatures;
4 import com.atlassian.sal.api.features.InvalidFeatureKeyException;
5 import com.atlassian.sal.api.features.MissingPermissionException;
6 import com.atlassian.sal.api.features.SiteDarkFeaturesStorage;
7 import com.atlassian.sal.api.user.UserKey;
8 import com.atlassian.sal.api.user.UserManager;
9 import com.atlassian.sal.api.user.UserProfile;
10 import com.google.common.collect.ImmutableSet;
11 import org.junit.Before;
12 import org.junit.Rule;
13 import org.junit.Test;
14 import org.junit.runner.RunWith;
15 import org.mockito.Mock;
16 import org.mockito.runners.MockitoJUnitRunner;
17
18 import java.security.Principal;
19
20 import static org.hamcrest.Matchers.*;
21 import static org.junit.Assert.*;
22 import static org.mockito.Mockito.*;
23
24 @RunWith(MockitoJUnitRunner.class)
25 public class TestDefaultDarkFeatureManager
26 {
27 private static final String FEATURE_FOO = "foo";
28 private static final String INVALID_FEATURE_KEY = "invalid feature key";
29 private static final String USER_NAME = "foobar";
30 private static final UserKey USER_KEY = new UserKey("foobarKey");
31
32 @Rule public final ClearSystemPropertyRule systemPropertyRule = new ClearSystemPropertyRule();
33 @Mock private UserManager userManager;
34 @Mock private Principal user;
35 @Mock private SiteDarkFeaturesStorage siteDarkFeaturesStorage;
36 @Mock private UserProfile profile;
37
38 @Before
39 public void setUp()
40 {
41 when(siteDarkFeaturesStorage.getEnabledDarkFeatures()).thenReturn(ImmutableSet.<String>of());
42 when(profile.getUsername()).thenReturn(USER_NAME);
43 when(profile.getUserKey()).thenReturn(USER_KEY);
44 }
45
46 @Test
47 public void systemFeatureEnabledForAllUsers()
48 {
49 enableDarkFeatureViaSystemProperty(FEATURE_FOO);
50 assertTrue(createFeatureManager().isFeatureEnabledForAllUsers(FEATURE_FOO));
51 }
52
53 @Test
54 public void systemFeatureNotEnabledForAllUsers()
55 {
56 assertNull(System.getProperty(FEATURE_FOO));
57 assertFalse(createFeatureManager().isFeatureEnabledForAllUsers(FEATURE_FOO));
58 }
59
60 @Test
61 public void invalidFeatureKeyIsNeverEnabledForAllUsers()
62 {
63 assertFalse(createFeatureManager().isFeatureEnabledForAllUsers(INVALID_FEATURE_KEY));
64 }
65
66 @Test
67 public void systemFeatureEnabledForAnonymous()
68 {
69 enableDarkFeatureViaSystemProperty(FEATURE_FOO);
70 final boolean featureEnabledForUser = createFeatureManager().isFeatureEnabledForUser(null, FEATURE_FOO);
71 assertThat(featureEnabledForUser, is(true));
72 }
73
74 @Test
75 public void systemFeatureDisabledForAnonymous()
76 {
77 final boolean featureEnabledForUser = createFeatureManager().isFeatureEnabledForUser(null, FEATURE_FOO);
78 assertThat(featureEnabledForUser, is(false));
79 }
80
81 @Test
82 public void systemFeatureEnabledForAuthenticatedUser()
83 {
84 enableDarkFeatureViaSystemProperty(FEATURE_FOO);
85 givenUserResolved();
86 final boolean featureEnabledForUser = createFeatureManager().isFeatureEnabledForUser(USER_KEY, FEATURE_FOO);
87 assertThat(featureEnabledForUser, is(true));
88 }
89
90 @Test
91 public void systemFeatureDisabledForAuthenticatedUser()
92 {
93 givenUserResolved();
94 final boolean featureEnabledForUser = createFeatureManager().isFeatureEnabledForUser(USER_KEY, FEATURE_FOO);
95 assertThat(featureEnabledForUser, is(false));
96 }
97
98 @Test(expected = IllegalArgumentException.class)
99 public void featureUndefinedForInvalidUser()
100 {
101 enableDarkFeatureViaSystemProperty(FEATURE_FOO);
102 givenUserNotResolved();
103 createFeatureManager().isFeatureEnabledForUser(USER_KEY, FEATURE_FOO);
104 }
105
106 @Test
107 public void enableFeatureForAllUsersViaSystemProperty()
108 {
109 enableDarkFeatureViaSystemProperty(FEATURE_FOO);
110 final EnabledDarkFeatures enabledDarkFeatures = createFeatureManager().getFeaturesEnabledForAllUsers();
111 assertThat(enabledDarkFeatures.getFeatureKeys(), hasItem(FEATURE_FOO));
112 }
113
114 @Test
115 public void enableFeatureForAllUsersDuringRuntime()
116 {
117 enableDarkFeatureForAllUsersDuringRuntime(FEATURE_FOO);
118 final EnabledDarkFeatures enabledDarkFeatures = createFeatureManager().getFeaturesEnabledForAllUsers();
119 assertThat(enabledDarkFeatures.getFeatureKeys(), hasItem(FEATURE_FOO));
120 }
121
122 @Test
123 public void enabledFeaturesForAnonymous()
124 {
125 enableDarkFeatureForAllUsersDuringRuntime(FEATURE_FOO);
126 final EnabledDarkFeatures enabledDarkFeatures = createFeatureManager().getFeaturesEnabledForUser(null);
127 assertThat(enabledDarkFeatures, is(not(nullValue())));
128 assertThat(enabledDarkFeatures.getFeatureKeys(), hasItem(FEATURE_FOO));
129 }
130
131 @Test
132 public void enabledFeaturesForAuthenticatedUser()
133 {
134 enableDarkFeatureForAllUsersDuringRuntime(FEATURE_FOO);
135 givenUserResolved();
136 final EnabledDarkFeatures enabledDarkFeatures = createFeatureManager().getFeaturesEnabledForUser(USER_KEY);
137 assertThat(enabledDarkFeatures, is(not(nullValue())));
138 assertThat(enabledDarkFeatures.getFeatureKeys(), hasItem(FEATURE_FOO));
139 }
140
141 @Test(expected = IllegalArgumentException.class)
142 public void enabledFeaturesUndefinedForInvalidUser()
143 {
144 givenUserNotResolved();
145 createFeatureManager().getFeaturesEnabledForUser(USER_KEY);
146 }
147
148 @Test
149 public void featureEnabledViaSystemFeature()
150 {
151 enableDarkFeatureViaSystemProperty(FEATURE_FOO);
152 assertTrue(createFeatureManager().isFeatureEnabledForCurrentUser(FEATURE_FOO));
153 }
154
155 @Test
156 public void featureNotEnabled()
157 {
158 assertNull(System.getProperty(FEATURE_FOO));
159 assertFalse(createFeatureManager().isFeatureEnabledForCurrentUser(FEATURE_FOO));
160 }
161
162 @Test
163 public void invalidFeatureKeyIsNeverEnabled()
164 {
165 assertFalse(createFeatureManager().isFeatureEnabledForCurrentUser(INVALID_FEATURE_KEY));
166 }
167
168 @Test
169 public void sysadminCanManageFeaturesForAllUsers()
170 {
171 givenUserIsAuthenticated();
172 givenUserIsSysadmin();
173 assertTrue(createFeatureManager().canManageFeaturesForAllUsers());
174 }
175
176 @Test
177 public void nonSysadminCannotManageFeaturesForAllUsers()
178 {
179 givenUserIsAuthenticated();
180 givenUserIsNotSysadmin();
181 assertFalse(createFeatureManager().canManageFeaturesForAllUsers());
182 }
183
184 @Test
185 public void anonymousCannotManageFeaturesForAllUsers()
186 {
187 givenUserIsNotAuthenticated();
188 assertFalse(createFeatureManager().canManageFeaturesForAllUsers());
189 }
190
191 @Test(expected = MissingPermissionException.class)
192 public void enableFeatureForAllUsersRequiresManagePermission()
193 {
194 try
195 {
196 givenUserIsNotAuthenticated();
197 createFeatureManager().enableFeatureForAllUsers(FEATURE_FOO);
198 }
199 finally
200 {
201 verifyZeroInteractions(siteDarkFeaturesStorage);
202 }
203 }
204
205 @Test(expected = InvalidFeatureKeyException.class)
206 public void enableFeatureForAllUsersRequiresValidFeatureKey()
207 {
208 try
209 {
210 createFeatureManager().enableFeatureForAllUsers(INVALID_FEATURE_KEY);
211 }
212 finally
213 {
214 verifyNoMoreInteractions(siteDarkFeaturesStorage);
215 }
216 }
217
218 @Test
219 public void enableFeatureForAllUsers()
220 {
221 givenUserCanManageFeaturesForAllUsers();
222 createFeatureManager().enableFeatureForAllUsers(FEATURE_FOO);
223 verify(siteDarkFeaturesStorage).enable(FEATURE_FOO);
224 }
225
226 @Test(expected = MissingPermissionException.class)
227 public void disableFeatureForAllUsersRequiresManagePermission()
228 {
229 try
230 {
231 givenUserIsNotAuthenticated();
232 createFeatureManager().disableFeatureForAllUsers(FEATURE_FOO);
233 }
234 finally
235 {
236 verifyZeroInteractions(siteDarkFeaturesStorage);
237 }
238 }
239
240 @Test(expected = InvalidFeatureKeyException.class)
241 public void disableFeatureForAllUsersRequiresValidFeatureKey()
242 {
243 try
244 {
245 createFeatureManager().disableFeatureForAllUsers(INVALID_FEATURE_KEY);
246 }
247 finally
248 {
249 verifyNoMoreInteractions(siteDarkFeaturesStorage);
250 }
251
252 }
253
254 @Test
255 public void disableFeatureForAllUsers()
256 {
257 givenUserCanManageFeaturesForAllUsers();
258 createFeatureManager().disableFeatureForAllUsers(FEATURE_FOO);
259 verify(siteDarkFeaturesStorage).disable(FEATURE_FOO);
260 }
261
262 private void givenUserCanManageFeaturesForAllUsers()
263 {
264 givenUserIsAuthenticated();
265 givenUserIsSysadmin();
266 }
267
268 private void givenUserNotResolved()
269 {
270 when(userManager.getUserProfile(USER_KEY)).thenReturn(null);
271 }
272
273 private void givenUserResolved()
274 {
275 when(userManager.getUserProfile(USER_KEY)).thenReturn(profile);
276 }
277
278 private void givenUserIsNotAuthenticated()
279 {
280 when(userManager.getRemoteUserKey()).thenReturn(null);
281 }
282
283 private void givenUserIsAuthenticated()
284 {
285 when(userManager.getRemoteUserKey()).thenReturn(USER_KEY);
286 }
287
288 private void givenUserIsSysadmin()
289 {
290 when(userManager.isSystemAdmin(USER_KEY)).thenReturn(Boolean.TRUE);
291 }
292
293 private void givenUserIsNotSysadmin()
294 {
295 when(userManager.isSystemAdmin(USER_KEY)).thenReturn(Boolean.FALSE);
296 }
297
298 private void enableDarkFeatureViaSystemProperty(final String systemPropertyKey)
299 {
300 systemPropertyRule.setPropertyWithDarkFeaturePrefix(systemPropertyKey, "true");
301 }
302
303 private void enableDarkFeatureForAllUsersDuringRuntime(final String darkFeatureKey)
304 {
305 when(siteDarkFeaturesStorage.getEnabledDarkFeatures()).thenReturn(ImmutableSet.of(darkFeatureKey));
306 }
307
308 private DefaultDarkFeatureManager createFeatureManager()
309 {
310 return new DefaultDarkFeatureManager(userManager, siteDarkFeaturesStorage);
311 }
312 }