Skip to content

Commit 8f5614d

Browse files
Abhi591rohitesh-wingify
authored andcommitted
fix: failing segmentor tests
1 parent 3466108 commit 8f5614d

27 files changed

+3936
-38
lines changed

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,16 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
[1.1.0] - 2024-06-07
7+
[1.2.0] - 2024-06-17
88

99
### Fixed
10-
Send event properties as third param in trackEvent() call
10+
- Fixed segmentation evaluator issues where `contains` and `Greater than equal to` operator were not working as expected.
11+
- Added unit test cases for the segmentation evaluator and decision maker
12+
13+
`[1.1.0] - 2024-06-07
14+
15+
### Fixed
16+
Send event properties as third param in trackEvent() call`
1117

1218
[1.0.0] - 2024-05-31
1319

pom.xml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ limitations under the License. -->
1919

2020
<groupId>com.vwo.sdk</groupId>
2121
<artifactId>vwo-fme-java-sdk</artifactId>
22-
<version>1.1.0</version>
22+
<version>1.2.1</version>
2323
<packaging>jar</packaging>
2424

2525
<name>VWO FME Java SDK</name>
@@ -305,12 +305,12 @@ limitations under the License. -->
305305
<dependency>
306306
<groupId>com.fasterxml.jackson.core</groupId>
307307
<artifactId>jackson-annotations</artifactId>
308-
<version>2.13.2</version>
308+
<version>2.15.2</version>
309309
</dependency>
310310
<dependency>
311311
<groupId>com.fasterxml.jackson.core</groupId>
312312
<artifactId>jackson-databind</artifactId>
313-
<version>2.13.2.2</version>
313+
<version>2.15.2</version>
314314
</dependency>
315315
<dependency>
316316
<groupId>org.junit.jupiter</groupId>
@@ -335,11 +335,6 @@ limitations under the License. -->
335335
<artifactId>gson</artifactId>
336336
<version>2.8.9</version> <!-- Make sure to use the latest version -->
337337
</dependency>
338-
<dependency>
339-
<groupId>com.fasterxml.jackson.core</groupId>
340-
<artifactId>jackson-databind</artifactId>
341-
<version>2.12.3</version>
342-
</dependency>
343338
<dependency>
344339
<groupId>com.github.eprst</groupId>
345340
<artifactId>murmur3</artifactId>

src/main/java/com/vwo/VWOClient.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ public Map<String, Boolean> trackEvent(String eventName, VWOContext context) {
202202
* @param attributeValue - The value of the attribute to set.
203203
* @param context User context
204204
*/
205-
public void setAttribute(String attributeKey, String attributeValue, VWOContext context) {
205+
public void setAttribute(String attributeKey, Object attributeValue, VWOContext context) {
206206
String apiName = "setAttribute";
207207
try {
208208
LoggerService.log(LogLevelEnum.DEBUG, "API_CALLED", new HashMap<String, String>() {{
@@ -218,14 +218,14 @@ public void setAttribute(String attributeKey, String attributeValue, VWOContext
218218
throw new IllegalArgumentException("TypeError: attributeKey should be a string");
219219
}
220220

221-
if (!DataTypeUtil.isString(attributeValue)) {
221+
if (!DataTypeUtil.isString(attributeValue) && !DataTypeUtil.isNumber(attributeValue) && !DataTypeUtil.isBoolean(attributeValue)) {
222222
LoggerService.log(LogLevelEnum.ERROR, "API_INVALID_PARAM", new HashMap<String, String>() {{
223223
put("apiName", apiName);
224224
put("key", "eventName");
225225
put("type", DataTypeUtil.getType(attributeValue));
226-
put("correctType", "String");
226+
put("correctType", "String, Number, Boolean");
227227
}});
228-
throw new IllegalArgumentException("TypeError: attributeValue should be a string");
228+
throw new IllegalArgumentException("TypeError: attributeValue should be a string, number or boolean");
229229
}
230230

231231
if (context == null || context.getId() == null || context.getId().isEmpty()) {

src/main/java/com/vwo/api/SetAttributeAPI.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class SetAttributeAPI {
3232
* @param attributeValue The value of the attribute to set.
3333
* @param context The user context model containing user-specific data.
3434
*/
35-
public static void setAttribute(Settings settings, String attributeKey, String attributeValue, VWOContext context) {
35+
public static void setAttribute(Settings settings, String attributeKey, Object attributeValue, VWOContext context) {
3636
createAndSendImpressionForSetAttribute(settings, attributeKey, attributeValue, context);
3737
}
3838

@@ -49,7 +49,7 @@ public static void setAttribute(Settings settings, String attributeKey, String a
4949
private static void createAndSendImpressionForSetAttribute(
5050
Settings settings,
5151
String attributeKey,
52-
String attributeValue,
52+
Object attributeValue,
5353
VWOContext context
5454
) {
5555
// Get base properties for the event

src/main/java/com/vwo/packages/network_layer/client/NetworkClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ public ResponseModel GET(RequestModel requestModel){
6464
String contentType = connection.getHeaderField("Content-Type");
6565

6666
if (statusCode != 200 || !contentType.contains("application/json")) {
67-
String error = "Invalid response. Status Code: " + statusCode + ", Response : " + connection.getResponseMessage();
67+
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
68+
String error = "Invalid response " + in.readLine()+ ", Status Code: " + statusCode + ", Response : " + connection.getResponseMessage();
6869
responseModel.setError(new Exception(error));
6970
return responseModel;
7071
}

src/main/java/com/vwo/packages/segmentation_evaluator/core/SegmentationManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ public void setContextualData(Settings settings, Feature feature, VWOContext con
6565
this.evaluator.settings = settings;
6666
this.evaluator.feature = feature;
6767

68+
// if user agent and ipAddress both are null or empty, return
69+
if ((context.getUserAgent() == null || context.getUserAgent().isEmpty()) && (context.getIpAddress() == null || context.getIpAddress().isEmpty())) {
70+
return;
71+
}
72+
6873
// If gateway service is required and the base URL is not the default one, fetch the data from the gateway service
6974
if (feature.getIsGatewayServiceRequired() && !UrlService.getBaseUrl().contains(Constants.HOST_NAME) && (context.getVwo() == null)) {
7075
Map<String, String> queryParams = new HashMap<>();

src/main/java/com/vwo/packages/segmentation_evaluator/enums/SegmentOperandRegexEnum.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ public enum SegmentOperandRegexEnum {
2424
REGEX_MATCH("^regex\\((.*)\\)"),
2525
STARTING_STAR("^\\*"),
2626
ENDING_STAR("\\*$"),
27-
GREATER_THAN_MATCH("^gt((\\d+\\.?\\d*)|(\\.\\d+))"),
28-
GREATER_THAN_EQUAL_TO_MATCH("^gte((\\d+\\.?\\d*)|(\\.\\d+))"),
29-
LESS_THAN_MATCH("^lt((\\d+\\.?\\d*)|(\\.\\d+))"),
30-
LESS_THAN_EQUAL_TO_MATCH("^lte((\\d+\\.?\\d*)|(\\.\\d+))");
27+
GREATER_THAN_MATCH("^gt\\((\\d+\\.?\\d*|\\.\\d+)\\)"),
28+
GREATER_THAN_EQUAL_TO_MATCH("^gte\\((\\d+\\.?\\d*|\\.\\d+)\\)"),
29+
LESS_THAN_MATCH("^lt\\((\\d+\\.?\\d*|\\.\\d+)\\)"),
30+
LESS_THAN_EQUAL_TO_MATCH("^lte\\((\\d+\\.?\\d*|\\.\\d+)\\)");
3131

3232
private final String regex;
3333

src/main/java/com/vwo/packages/segmentation_evaluator/evaluators/SegmentEvaluator.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public boolean some(JsonNode dslNodes, Map<String, Object> customVariables) {
118118
String featureIdKey = featureIdKeys.next();
119119
String featureIdValue = featureIdObject.get(featureIdKey).asText();
120120

121-
if (featureIdValue.equals("on")) {
121+
if (featureIdValue.equals("on") || featureIdValue.equals("off")) {
122122
List<Feature> features = settings.getFeatures();
123123
Feature feature = features.stream()
124124
.filter(f -> f.getId() == Integer.parseInt(featureIdKey))
@@ -128,6 +128,9 @@ public boolean some(JsonNode dslNodes, Map<String, Object> customVariables) {
128128
if (feature != null) {
129129
String featureKey = feature.getKey();
130130
boolean result = checkInUserStorage(settings, featureKey, context);
131+
if (featureIdValue.equals("off")) {
132+
return !result;
133+
}
131134
return result;
132135
} else {
133136
LoggerService.log(LogLevelEnum.DEBUG, "Feature not found with featureIdKey: " + featureIdKey);

src/main/java/com/vwo/packages/segmentation_evaluator/evaluators/SegmentOperandEvaluator.java

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package com.vwo.packages.segmentation_evaluator.evaluators;
1717

18+
import java.text.DecimalFormat;
1819
import java.util.HashMap;
1920
import java.util.Map;
2021
import java.util.regex.Matcher;
@@ -71,11 +72,23 @@ public Boolean evaluateCustomVariableDSL(JsonNode dslOperandValue, Map<String, O
7172
} else {
7273
// Process other types of operands
7374
Object tagValue = properties.get(operandKey);
75+
if (tagValue == null) {
76+
tagValue = "";
77+
}
7478
tagValue = preProcessTagValue(tagValue.toString());
7579
Map<String, Object> preProcessOperandValue = preProcessOperandValue(operandValue);
7680
Map<String, Object> processedValues = processValues(preProcessOperandValue.get("operandValue"), tagValue);
77-
tagValue = processedValues.get("tagValue");
81+
82+
// Convert numeric values to strings if processing wildcard pattern
7883
SegmentOperandValueEnum operandType = (SegmentOperandValueEnum) preProcessOperandValue.get("operandType");
84+
if (operandType == SegmentOperandValueEnum.STARTING_ENDING_STAR_VALUE ||
85+
operandType == SegmentOperandValueEnum.STARTING_STAR_VALUE ||
86+
operandType == SegmentOperandValueEnum.ENDING_STAR_VALUE ||
87+
operandType == SegmentOperandValueEnum.REGEX_VALUE) {
88+
processedValues.put("tagValue", processedValues.get("tagValue").toString());
89+
}
90+
91+
tagValue = processedValues.get("tagValue");
7992
return extractResult(operandType, processedValues.get("operandValue").toString().trim().replace("\"", ""), tagValue.toString());
8093
}
8194
}
@@ -162,23 +175,38 @@ public String preProcessTagValue(String tagValue) {
162175
}
163176

164177
private Map<String, Object> processValues(Object operandValue, Object tagValue) {
165-
// Convert operand and tag values to floats
166-
Double processedOperandValue;
167-
Double processedTagValue;
168178
Map<String, Object> result = new HashMap<>();
179+
180+
// Process operandValue
181+
result.put("operandValue", convertValue(operandValue));
182+
183+
// Process tagValue
184+
result.put("tagValue", convertValue(tagValue));
185+
186+
return result;
187+
}
188+
189+
private String convertValue(Object value) {
190+
// Check if the value is a boolean
191+
if (value instanceof Boolean) {
192+
return value.toString(); // Convert boolean to "true" or "false"
193+
}
194+
169195
try {
170-
processedOperandValue = Double.parseDouble(operandValue.toString());
171-
processedTagValue = Double.parseDouble(tagValue.toString());
196+
// Attempt to convert to a numeric value
197+
double numericValue = Double.parseDouble(value.toString());
198+
// Check if the numeric value is actually an integer
199+
if (numericValue == (int) numericValue) {
200+
return String.valueOf((int) numericValue); // Remove '.0' by converting to int
201+
} else {
202+
// Format float to avoid scientific notation for large numbers
203+
DecimalFormat df = new DecimalFormat("#.##############"); // Adjust the pattern as needed
204+
return df.format(numericValue);
205+
}
172206
} catch (NumberFormatException e) {
173-
// Return original values if conversion fails
174-
result.put("operandValue", operandValue);
175-
result.put("tagValue", tagValue);
176-
return result;
207+
// Return the value as-is if it's not a number
208+
return value.toString();
177209
}
178-
// Convert numeric values back to strings
179-
result.put("operandValue", processedOperandValue.toString());
180-
result.put("tagValue", processedTagValue.toString());
181-
return result;
182210
}
183211

184212
/**

src/main/java/com/vwo/packages/segmentation_evaluator/utils/SegmentUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,15 @@ public static boolean checkValuePresent(Map<String, List<String>> expectedMap, M
3535
for (String key : actualMap.keySet()) {
3636
if (expectedMap.containsKey(key)) {
3737
List<String> expectedValues = expectedMap.get(key);
38+
// convert expectedValues to lowercase
39+
expectedValues.replaceAll(String::toLowerCase);
3840
String actualValue = actualMap.get(key);
3941

4042
// Handle wildcard patterns for all keys
4143
for (String val : expectedValues) {
4244
if (val.startsWith("wildcard(") && val.endsWith(")")) {
4345
String wildcardPattern = val.substring(9, val.length() - 1); // Extract pattern from wildcard string
44-
Pattern regex = Pattern.compile(wildcardPattern.replace("*", ".*")); // Convert wildcard pattern to regex
46+
Pattern regex = Pattern.compile(wildcardPattern.replace("*", ".*"), Pattern.CASE_INSENSITIVE); // Convert wildcard pattern to regex
4547
Matcher matcher = regex.matcher(actualValue);
4648
if (matcher.matches()) {
4749
return true; // Match found, return true

0 commit comments

Comments
 (0)