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