Skip to content

Commit

Permalink
Ensure assignment date is in ISO8601 format (FF-1933) (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
leoromanovsky committed Apr 16, 2024
1 parent b8f086b commit edc28d8
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 14 deletions.
2 changes: 1 addition & 1 deletion eppo/build.gradle
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = "cloud.eppo"
version = "1.0.7"
version = "1.0.8"

android {
compileSdk 33
Expand Down
16 changes: 11 additions & 5 deletions eppo/src/main/java/cloud/eppo/android/EppoClient.java
Expand Up @@ -39,7 +39,8 @@ public class EppoClient {
// Useful for testing in situations where we want to mock the http client
private static EppoHttpClient httpClientOverride = null;

private EppoClient(Application application, String apiKey, String host, AssignmentLogger assignmentLogger, boolean isGracefulMode) {
private EppoClient(Application application, String apiKey, String host, AssignmentLogger assignmentLogger,
boolean isGracefulMode) {
EppoHttpClient httpClient = httpClientOverride == null ? new EppoHttpClient(host, apiKey) : httpClientOverride;
ConfigurationStore configStore = new ConfigurationStore(application);
requestor = new ConfigurationRequestor(configStore, httpClient);
Expand Down Expand Up @@ -133,7 +134,7 @@ protected EppoValue getTypedAssignment(String subjectKey, String flagKey, Subjec
String allocationKey = rule.getAllocationKey();
Allocation allocation = flag.getAllocations().get(allocationKey);
if (allocation == null) {
Log.w(TAG, "unexpected unknown allocation key \""+allocationKey+"\"");
Log.w(TAG, "unexpected unknown allocation key \"" + allocationKey + "\"");
return null;
}

Expand All @@ -157,9 +158,14 @@ protected EppoValue getTypedAssignment(String subjectKey, String flagKey, Subjec
variationToLog = typedValue.stringValue();
}

Assignment assignment = new Assignment(experimentKey,
flagKey, allocationKey, variationToLog,
subjectKey, Utils.getISODate(new Date()), subjectAttributes);
Assignment assignment = Assignment.createWithCurrentDate(
experimentKey,
flagKey,
allocationKey,
variationToLog,
subjectKey,
subjectAttributes
);
assignmentLogger.logAssignment(assignment);
}

Expand Down
17 changes: 15 additions & 2 deletions eppo/src/main/java/cloud/eppo/android/logging/Assignment.java
@@ -1,6 +1,9 @@
package cloud.eppo.android.logging;

import cloud.eppo.android.dto.SubjectAttributes;
import cloud.eppo.android.util.Utils;

import java.util.Date;

public class Assignment {
private String experiment;
Expand All @@ -18,8 +21,7 @@ public Assignment(
String variation,
String subject,
String timestamp,
SubjectAttributes subjectAttributes
) {
SubjectAttributes subjectAttributes) {
this.experiment = experiment;
this.featureFlag = featureFlag;
this.allocation = allocation;
Expand All @@ -29,6 +31,17 @@ public Assignment(
this.subjectAttributes = subjectAttributes;
}

public static Assignment createWithCurrentDate(
String experiment,
String featureFlag,
String allocation,
String variation,
String subject,
SubjectAttributes subjectAttributes) {
return new Assignment(experiment, featureFlag, allocation, variation, subject,
Utils.getISODate(new Date()), subjectAttributes);
}

public String getExperiment() {
return experiment;
}
Expand Down
10 changes: 4 additions & 6 deletions eppo/src/main/java/cloud/eppo/android/util/Utils.java
Expand Up @@ -6,10 +6,9 @@
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.Locale;

import cloud.eppo.android.dto.ShardRange;

Expand Down Expand Up @@ -50,10 +49,9 @@ public static void validateNotEmptyOrNull(String input, String errorMessage) {
}

public static String getISODate(Date date) {
TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(tz);
return df.format(date);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
dateFormat.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
return dateFormat.format(date);
}

public static SharedPreferences getSharedPrefs(Context context) {
Expand Down
62 changes: 62 additions & 0 deletions eppo/src/test/java/cloud/eppo/android/UtilsTest.java
@@ -0,0 +1,62 @@
package cloud.eppo.android;

import org.junit.Test;
import static org.junit.Assert.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import cloud.eppo.android.util.Utils;

public class UtilsTest {

@Test
public void testGetISODate() {
String isoDate = Utils.getISODate(new Date());
assertNotNull("ISO date should not be null", isoDate);

// Verify the format
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
Date date = dateFormat.parse(isoDate);
assertNotNull("Parsed date should not be null", date);

// Optionally, verify the date is not too far from the current time
long currentTime = System.currentTimeMillis();
long parsedTime = date.getTime();
assertTrue("The parsed date should be within a reasonable range of the current time",
Math.abs(currentTime - parsedTime) < 10000); // for example, within 10 seconds
} catch (ParseException e) {
fail("Parsing the ISO date failed: " + e.getMessage());
}
}

@Test
public void testGetCurrentDateISOInDifferentLocale() {
// Arrange
Locale defaultLocale = Locale.getDefault();
try {
// Set locale to Arabic
Locale.setDefault(new Locale("ar"));
String isoDate = Utils.getISODate(new Date());

// Act
// Check if the date is in the correct ISO 8601 format
// This is a simple regex check to see if the string follows the
// YYYY-MM-DDTHH:MM:SSZ pattern
boolean isISO8601 = isoDate.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z");

// Assert
assertTrue("Date should be in ISO 8601 format", isISO8601);

} catch (Exception e) {
fail("Test failed with exception: " + e.getMessage());
} finally {
// Reset locale back to original
Locale.setDefault(defaultLocale);
}
}
}

0 comments on commit edc28d8

Please sign in to comment.