Skip to content

Commit 9352ac4

Browse files
Adding missing unit tests related to notification listener (#289)
1 parent 4e28052 commit 9352ac4

File tree

5 files changed

+339
-6
lines changed

5 files changed

+339
-6
lines changed

core-api/src/main/java/com/optimizely/ab/Optimizely.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ <T extends Object> T getFeatureVariableValueForType(@Nonnull String featureKey,
690690

691691
Object convertedValue = convertStringToType(variableValue, variableType);
692692

693-
DecisionNotification decisionNotification = DecisionNotification.newFeatureVariableBuilder()
693+
DecisionNotification decisionNotification = DecisionNotification.newFeatureVariableDecisionNotificationBuilder()
694694
.withUserId(userId)
695695
.withAttributes(copiedAttributes)
696696
.withFeatureKey(featureKey)

core-api/src/main/java/com/optimizely/ab/notification/DecisionNotification.java

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.optimizely.ab.notification;
1818

1919

20+
import com.optimizely.ab.OptimizelyRuntimeException;
2021
import com.optimizely.ab.bucketing.FeatureDecision;
2122
import com.optimizely.ab.config.FeatureVariable;
2223
import com.optimizely.ab.config.Variation;
@@ -26,9 +27,20 @@
2627
import java.util.HashMap;
2728
import java.util.Map;
2829

29-
import static com.optimizely.ab.notification.DecisionNotification.ExperimentDecisionNotificationBuilder.EXPERIMENT_KEY;
30-
import static com.optimizely.ab.notification.DecisionNotification.ExperimentDecisionNotificationBuilder.VARIATION_KEY;
31-
30+
/**
31+
* DecisionNotification encapsulates the arguments and responses when using the following methods:
32+
*
33+
* activate {@link com.optimizely.ab.Optimizely#activate}
34+
* getEnabledFeatures {@link com.optimizely.ab.Optimizely#getEnabledFeatures}
35+
* getFeatureVariableBoolean {@link com.optimizely.ab.Optimizely#getFeatureVariableBoolean}
36+
* getFeatureVariableDouble {@link com.optimizely.ab.Optimizely#getFeatureVariableDouble}
37+
* getFeatureVariableInteger {@link com.optimizely.ab.Optimizely#getFeatureVariableInteger}
38+
* getFeatureVariableString {@link com.optimizely.ab.Optimizely#getFeatureVariableString}
39+
* getVariation {@link com.optimizely.ab.Optimizely#getVariation}
40+
* isFeatureEnabled {@link com.optimizely.ab.Optimizely#isFeatureEnabled}
41+
*
42+
* @see <a href="https://docs.developers.optimizely.com/full-stack/docs/register-notification-listeners">Notification Listeners</a>
43+
*/
3244
public final class DecisionNotification {
3345
protected String type;
3446
protected String userId;
@@ -108,6 +120,14 @@ public ExperimentDecisionNotificationBuilder withVariation(Variation variation)
108120
}
109121

110122
public DecisionNotification build() {
123+
if (type == null) {
124+
throw new OptimizelyRuntimeException("type not set");
125+
}
126+
127+
if (experimentKey == null) {
128+
throw new OptimizelyRuntimeException("experimentKey not set");
129+
}
130+
111131
decisionInfo = new HashMap<>();
112132
decisionInfo.put(EXPERIMENT_KEY, experimentKey);
113133
decisionInfo.put(VARIATION_KEY, variation != null ? variation.getKey() : null);
@@ -169,11 +189,22 @@ public FeatureDecisionNotificationBuilder withFeatureEnabled(Boolean featureEnab
169189
}
170190

171191
public DecisionNotification build() {
192+
if (source == null) {
193+
throw new OptimizelyRuntimeException("source not set");
194+
}
195+
196+
if (featureKey == null) {
197+
throw new OptimizelyRuntimeException("featureKey not set");
198+
}
199+
200+
if (featureEnabled == null) {
201+
throw new OptimizelyRuntimeException("featureEnabled not set");
202+
}
203+
172204
decisionInfo = new HashMap<>();
173205
decisionInfo.put(FEATURE_KEY, featureKey);
174206
decisionInfo.put(FEATURE_ENABLED, featureEnabled);
175207
decisionInfo.put(SOURCE, source.toString());
176-
177208
decisionInfo.put(SOURCE_INFO, sourceInfo.get());
178209

179210
return new DecisionNotification(
@@ -184,7 +215,7 @@ public DecisionNotification build() {
184215
}
185216
}
186217

187-
public static FeatureVariableDecisionNotificationBuilder newFeatureVariableBuilder() {
218+
public static FeatureVariableDecisionNotificationBuilder newFeatureVariableDecisionNotificationBuilder() {
188219
return new FeatureVariableDecisionNotificationBuilder();
189220
}
190221

@@ -252,6 +283,22 @@ public FeatureVariableDecisionNotificationBuilder withVariableValue(Object varia
252283
}
253284

254285
public DecisionNotification build() {
286+
if (featureKey == null) {
287+
throw new OptimizelyRuntimeException("featureKey not set");
288+
}
289+
290+
if (featureEnabled == null) {
291+
throw new OptimizelyRuntimeException("featureEnabled not set");
292+
}
293+
294+
if (variableKey == null) {
295+
throw new OptimizelyRuntimeException("variableKey not set");
296+
}
297+
298+
if (variableType == null) {
299+
throw new OptimizelyRuntimeException("variableType not set");
300+
}
301+
255302
decisionInfo = new HashMap<>();
256303
decisionInfo.put(FEATURE_KEY, featureKey);
257304
decisionInfo.put(FEATURE_ENABLED, featureEnabled);
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/**
2+
*
3+
* Copyright 2019, Optimizely and contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.optimizely.ab.notification;
19+
20+
import com.optimizely.ab.OptimizelyRuntimeException;
21+
import com.optimizely.ab.bucketing.FeatureDecision;
22+
import com.optimizely.ab.config.FeatureVariable;
23+
import com.optimizely.ab.config.Variation;
24+
import org.junit.Before;
25+
import org.junit.Test;
26+
27+
import java.util.Collections;
28+
import java.util.HashMap;
29+
import java.util.Map;
30+
31+
import static org.junit.Assert.assertEquals;
32+
import static org.junit.Assert.assertFalse;
33+
import static org.junit.Assert.assertTrue;
34+
import static org.mockito.Mockito.mock;
35+
36+
public class DecisionNotificationTest {
37+
38+
private static final Boolean FEATURE_ENABLED = Boolean.FALSE;
39+
private static final String EXPERIMENT_KEY = "experimentKey";
40+
private static final String FEATURE_KEY = "featureKey";
41+
private static final String FEATURE_VARIABLE_KEY = "featureVariableKey";
42+
private static final String USER_ID = "userID";
43+
private static final Map<String, String> USER_ATTRIBUTES = Collections.singletonMap("user", "attr");
44+
private static final RolloutSourceInfo rolloutSourceInfo = mock(RolloutSourceInfo.class);
45+
private static final Variation VARIATION = mock(Variation.class);
46+
47+
private DecisionNotification experimentDecisionNotification;
48+
private DecisionNotification featureDecisionNotification;
49+
private DecisionNotification featureVariableDecisionNotification;
50+
51+
@Before
52+
public void setUp() {
53+
experimentDecisionNotification = DecisionNotification.newExperimentDecisionNotificationBuilder()
54+
.withUserId(USER_ID)
55+
.withAttributes(USER_ATTRIBUTES)
56+
.withExperimentKey(EXPERIMENT_KEY)
57+
.withVariation(VARIATION)
58+
.withType(NotificationCenter.DecisionNotificationType.AB_TEST.toString())
59+
.build();
60+
featureDecisionNotification = DecisionNotification.newFeatureDecisionNotificationBuilder()
61+
.withUserId(USER_ID)
62+
.withFeatureKey(FEATURE_KEY)
63+
.withFeatureEnabled(FEATURE_ENABLED)
64+
.withSource(FeatureDecision.DecisionSource.ROLLOUT)
65+
.withAttributes(USER_ATTRIBUTES)
66+
.withSourceInfo(rolloutSourceInfo)
67+
.build();
68+
featureVariableDecisionNotification = DecisionNotification.newFeatureVariableDecisionNotificationBuilder()
69+
.withUserId(USER_ID)
70+
.withFeatureKey(FEATURE_KEY)
71+
.withFeatureEnabled(Boolean.TRUE)
72+
.withVariableKey(FEATURE_VARIABLE_KEY)
73+
.withVariableType(FeatureVariable.VariableType.STRING)
74+
.withAttributes(USER_ATTRIBUTES)
75+
.build();
76+
}
77+
78+
@Test
79+
public void testGetType() {
80+
assertEquals(NotificationCenter.DecisionNotificationType.AB_TEST.toString(), experimentDecisionNotification.getType());
81+
assertEquals(NotificationCenter.DecisionNotificationType.FEATURE.toString(), featureDecisionNotification.getType());
82+
assertEquals(NotificationCenter.DecisionNotificationType.FEATURE_VARIABLE.toString(), featureVariableDecisionNotification.getType());
83+
}
84+
85+
@Test
86+
public void testGetUserId() {
87+
assertEquals(USER_ID, experimentDecisionNotification.getUserId());
88+
assertEquals(USER_ID, featureDecisionNotification.getUserId());
89+
assertEquals(USER_ID, featureVariableDecisionNotification.getUserId());
90+
}
91+
92+
@Test
93+
public void testGetAttributes() {
94+
assertEquals(USER_ATTRIBUTES, experimentDecisionNotification.getAttributes());
95+
assertEquals(USER_ATTRIBUTES, featureDecisionNotification.getAttributes());
96+
assertEquals(USER_ATTRIBUTES, featureVariableDecisionNotification.getAttributes());
97+
}
98+
99+
@Test
100+
public void testGetDecisionInfo() {
101+
// Assert for Experiment's DecisionInfo
102+
HashMap<String, String> expectedExperimentDecisionInfo = new HashMap<>();
103+
expectedExperimentDecisionInfo.put(DecisionNotification.ExperimentDecisionNotificationBuilder.EXPERIMENT_KEY, EXPERIMENT_KEY);
104+
expectedExperimentDecisionInfo.put(DecisionNotification.ExperimentDecisionNotificationBuilder.VARIATION_KEY, VARIATION.getKey());
105+
assertEquals(expectedExperimentDecisionInfo, experimentDecisionNotification.getDecisionInfo());
106+
107+
// Assert for Feature's DecisionInfo
108+
Map<String, ?> actualFeatureDecisionInfo = featureDecisionNotification.getDecisionInfo();
109+
assertFalse((Boolean) actualFeatureDecisionInfo.get(DecisionNotification.FeatureDecisionNotificationBuilder.FEATURE_ENABLED));
110+
assertEquals(FEATURE_KEY, actualFeatureDecisionInfo.get(DecisionNotification.FeatureDecisionNotificationBuilder.FEATURE_KEY));
111+
assertEquals(FeatureDecision.DecisionSource.ROLLOUT.toString(), actualFeatureDecisionInfo.get(DecisionNotification.FeatureDecisionNotificationBuilder.SOURCE));
112+
assertEquals(rolloutSourceInfo.get(), actualFeatureDecisionInfo.get(DecisionNotification.FeatureDecisionNotificationBuilder.SOURCE_INFO));
113+
114+
// Assert for Feature Variable's DecisionInfo
115+
Map<String, ?> actualFeatureVariableDecisionInfo = featureVariableDecisionNotification.getDecisionInfo();
116+
assertTrue((Boolean) actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.FEATURE_ENABLED));
117+
assertEquals(FEATURE_KEY, actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.FEATURE_KEY));
118+
assertEquals(FEATURE_VARIABLE_KEY, actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.VARIABLE_KEY));
119+
assertEquals(FeatureVariable.VariableType.STRING, actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.VARIABLE_TYPE));
120+
assertEquals(FeatureDecision.DecisionSource.ROLLOUT.toString(), actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.SOURCE));
121+
assertEquals(rolloutSourceInfo.get(), actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.SOURCE_INFO));
122+
}
123+
124+
@Test(expected = OptimizelyRuntimeException.class)
125+
public void nullTypeFailsExperimentNotificationBuild() {
126+
DecisionNotification.newExperimentDecisionNotificationBuilder()
127+
.withExperimentKey(EXPERIMENT_KEY)
128+
.build();
129+
}
130+
131+
@Test(expected = OptimizelyRuntimeException.class)
132+
public void nullExperimentKeyFailsExperimentNotificationBuild() {
133+
DecisionNotification.newExperimentDecisionNotificationBuilder()
134+
.withType(NotificationCenter.DecisionNotificationType.AB_TEST.toString())
135+
.build();
136+
}
137+
138+
@Test(expected = OptimizelyRuntimeException.class)
139+
public void nullSourceFailsFeatureNotificationBuild() {
140+
DecisionNotification.newFeatureDecisionNotificationBuilder()
141+
.withFeatureKey(FEATURE_KEY)
142+
.withFeatureEnabled(FEATURE_ENABLED)
143+
.build();
144+
}
145+
146+
@Test(expected = OptimizelyRuntimeException.class)
147+
public void nullFeatureKeyFailsFeatureNotificationBuild() {
148+
DecisionNotification.newFeatureDecisionNotificationBuilder()
149+
.withFeatureEnabled(FEATURE_ENABLED)
150+
.withSource(FeatureDecision.DecisionSource.ROLLOUT)
151+
.build();
152+
}
153+
154+
@Test(expected = OptimizelyRuntimeException.class)
155+
public void nullFeatureEnabledFailsFeatureNotificationBuild() {
156+
DecisionNotification.newFeatureDecisionNotificationBuilder()
157+
.withFeatureKey(FEATURE_KEY)
158+
.withSource(FeatureDecision.DecisionSource.ROLLOUT)
159+
.build();
160+
}
161+
162+
@Test(expected = OptimizelyRuntimeException.class)
163+
public void nullFeatureKeyFailsFeatureVariableNotificationBuild() {
164+
DecisionNotification.newFeatureVariableDecisionNotificationBuilder()
165+
.withFeatureEnabled(Boolean.TRUE)
166+
.withVariableKey(FEATURE_VARIABLE_KEY)
167+
.withVariableType(FeatureVariable.VariableType.STRING)
168+
.build();
169+
}
170+
171+
@Test(expected = OptimizelyRuntimeException.class)
172+
public void nullFeatureEnabledFailsFeatureVariableNotificationBuild() {
173+
DecisionNotification.newFeatureVariableDecisionNotificationBuilder()
174+
.withFeatureKey(FEATURE_KEY)
175+
.withVariableKey(FEATURE_VARIABLE_KEY)
176+
.withVariableType(FeatureVariable.VariableType.STRING)
177+
.build();
178+
}
179+
180+
@Test(expected = OptimizelyRuntimeException.class)
181+
public void nullVariableKeyFailsFeatureVariableNotificationBuild() {
182+
DecisionNotification.newFeatureVariableDecisionNotificationBuilder()
183+
.withFeatureKey(FEATURE_KEY)
184+
.withFeatureEnabled(Boolean.TRUE)
185+
.withVariableType(FeatureVariable.VariableType.STRING)
186+
.build();
187+
}
188+
189+
@Test(expected = OptimizelyRuntimeException.class)
190+
public void nullVariableTypeFailsFeatureVariableNotificationBuild() {
191+
DecisionNotification.newFeatureVariableDecisionNotificationBuilder()
192+
.withFeatureKey(FEATURE_KEY)
193+
.withFeatureEnabled(Boolean.TRUE)
194+
.withVariableKey(FEATURE_VARIABLE_KEY)
195+
.build();
196+
}
197+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
*
3+
* Copyright 2019, Optimizely and contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package com.optimizely.ab.notification;
19+
20+
import org.junit.Before;
21+
import org.junit.Test;
22+
23+
import java.util.HashMap;
24+
25+
import static org.junit.Assert.assertEquals;
26+
27+
public class FeatureTestSourceInfoTest {
28+
29+
private static final String EXPERIMENT_KEY = "featureTestKey";
30+
private static final String VARIATION_KEY = "featureTestVariationKey";
31+
32+
private FeatureTestSourceInfo featureSourceInfo;
33+
34+
@Before
35+
public void setUp() {
36+
featureSourceInfo = new FeatureTestSourceInfo(EXPERIMENT_KEY, VARIATION_KEY);
37+
}
38+
39+
@Test
40+
public void testGet() {
41+
HashMap<String, String> expectedSourceInfo = new HashMap<>();
42+
expectedSourceInfo.put("experimentKey", EXPERIMENT_KEY);
43+
expectedSourceInfo.put("variationKey", VARIATION_KEY);
44+
45+
assertEquals(expectedSourceInfo, featureSourceInfo.get());
46+
}
47+
}

0 commit comments

Comments
 (0)