Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit 91b0af8

Browse files
authored
Merge pull request #59 from launchdarkly/eb/ch15275/bad-operator-npe
treat unsupported operators as a non-match, don't throw NPE
2 parents 1612b1f + ae3696a commit 91b0af8

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

src/main/java/com/launchdarkly/client/Clause.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ boolean matchesUser(FeatureStore store, LDUser user) {
7575
}
7676

7777
private boolean matchAny(JsonPrimitive userValue) {
78-
for (JsonPrimitive v : values) {
79-
if (op.apply(userValue, v)) {
80-
return true;
78+
if (op != null) {
79+
for (JsonPrimitive v : values) {
80+
if (op.apply(userValue, v)) {
81+
return true;
82+
}
8183
}
8284
}
8385
return false;

src/test/java/com/launchdarkly/client/FeatureFlagTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package com.launchdarkly.client;
22

3+
import com.google.gson.Gson;
4+
import com.google.gson.JsonArray;
5+
import com.google.gson.JsonElement;
6+
import com.google.gson.JsonObject;
7+
8+
import org.junit.Assert;
39
import org.junit.Before;
410
import org.junit.Test;
511

@@ -13,6 +19,7 @@
1319
import static com.launchdarkly.client.VersionedDataKind.FEATURES;
1420
import static com.launchdarkly.client.VersionedDataKind.SEGMENTS;
1521
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertNotNull;
1623
import static org.junit.Assert.assertNull;
1724

1825
public class FeatureFlagTest {
@@ -243,6 +250,48 @@ public void clauseCanBeNegated() throws Exception {
243250
assertEquals(jbool(false), f.evaluate(user, featureStore).getValue());
244251
}
245252

253+
@Test
254+
public void clauseWithUnsupportedOperatorStringIsUnmarshalledWithNullOperator() throws Exception {
255+
// This just verifies that GSON will give us a null in this case instead of throwing an exception,
256+
// so we fail as gracefully as possible if a new operator type has been added in the application
257+
// and the SDK hasn't been upgraded yet.
258+
String badClauseJson = "{\"attribute\":\"name\",\"operator\":\"doesSomethingUnsupported\",\"values\":[\"x\"]}";
259+
Gson gson = new Gson();
260+
Clause clause = gson.fromJson(badClauseJson, Clause.class);
261+
assertNotNull(clause);
262+
263+
JsonElement json = gson.toJsonTree(clause);
264+
String expectedJson = "{\"attribute\":\"name\",\"values\":[\"x\"],\"negate\":false}";
265+
assertEquals(gson.fromJson(expectedJson, JsonElement.class), json);
266+
}
267+
268+
@Test
269+
public void clauseWithNullOperatorDoesNotMatch() throws Exception {
270+
Clause badClause = new Clause("name", null, Arrays.asList(js("Bob")), false);
271+
FeatureFlag f = booleanFlagWithClauses(badClause);
272+
LDUser user = new LDUser.Builder("key").name("Bob").build();
273+
274+
assertEquals(jbool(false), f.evaluate(user, featureStore).getValue());
275+
}
276+
277+
@Test
278+
public void clauseWithNullOperatorDoesNotStopSubsequentRuleFromMatching() throws Exception {
279+
Clause badClause = new Clause("name", null, Arrays.asList(js("Bob")), false);
280+
Rule badRule = new Rule(Arrays.asList(badClause), 1, null);
281+
Clause goodClause = new Clause("name", Operator.in, Arrays.asList(js("Bob")), false);
282+
Rule goodRule = new Rule(Arrays.asList(goodClause), 1, null);
283+
FeatureFlag f = new FeatureFlagBuilder("feature")
284+
.on(true)
285+
.rules(Arrays.asList(badRule, goodRule))
286+
.fallthrough(fallthroughVariation(0))
287+
.offVariation(0)
288+
.variations(jbool(false), jbool(true))
289+
.build();
290+
LDUser user = new LDUser.Builder("key").name("Bob").build();
291+
292+
assertEquals(jbool(true), f.evaluate(user, featureStore).getValue());
293+
}
294+
246295
@Test
247296
public void testSegmentMatchClauseRetrievesSegmentFromStore() throws Exception {
248297
Segment segment = new Segment.Builder("segkey")

0 commit comments

Comments
 (0)