diff --git a/providers/flagsmith/pom.xml b/providers/flagsmith/pom.xml
index f73f689d9e..e7c2a3e6e3 100644
--- a/providers/flagsmith/pom.xml
+++ b/providers/flagsmith/pom.xml
@@ -30,20 +30,20 @@
com.flagsmith
flagsmith-java-client
- 7.4.3
+ 8.1.1
com.squareup.okhttp3
- okhttp
- 4.12.0
+ okhttp-jvm
+ 5.0.0
com.squareup.okhttp3
mockwebserver
- 4.12.0
+ 5.0.0
test
diff --git a/providers/flagsmith/src/test/java/dev.openfeature.contrib.providers.flagsmith/FlagsmithProviderTest.java b/providers/flagsmith/src/test/java/dev.openfeature.contrib.providers.flagsmith/FlagsmithProviderTest.java
index e3a27c988c..505c9649af 100644
--- a/providers/flagsmith/src/test/java/dev.openfeature.contrib.providers.flagsmith/FlagsmithProviderTest.java
+++ b/providers/flagsmith/src/test/java/dev.openfeature.contrib.providers.flagsmith/FlagsmithProviderTest.java
@@ -1,5 +1,6 @@
package dev.openfeature.contrib.providers.flagsmith;
+import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -22,15 +23,16 @@
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import lombok.SneakyThrows;
+import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
-import okhttp3.mockwebserver.QueueDispatcher;
import okhttp3.mockwebserver.RecordedRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@@ -47,7 +49,7 @@ public class FlagsmithProviderTest {
public static MockWebServer mockFlagsmithErrorServer;
public static FlagsmithProvider flagsmithProvider;
- final QueueDispatcher dispatcher = new QueueDispatcher() {
+ final Dispatcher dispatcher = new Dispatcher() {
@SneakyThrows
@Override
public MockResponse dispatch(RecordedRequest request) {
@@ -70,7 +72,7 @@ public MockResponse dispatch(RecordedRequest request) {
}
};
- final QueueDispatcher errorDispatcher = new QueueDispatcher() {
+ final Dispatcher errorDispatcher = new Dispatcher() {
@SneakyThrows
@Override
public MockResponse dispatch(RecordedRequest request) {
@@ -212,6 +214,49 @@ void shouldDefaultEnvironmentRefreshIntervalSecondsTo60() {
assertEquals(Integer.valueOf(60), options.getEnvironmentRefreshIntervalSeconds());
}
+ @Test
+ void shouldMatchIdentitySegmentDuringLocalEvaluation() {
+ mockFlagsmithServer.setDispatcher(new Dispatcher() {
+ @SneakyThrows
+ @Override
+ public MockResponse dispatch(RecordedRequest request) {
+ if (request.getPath().startsWith("/environment-document/")) {
+ return new MockResponse()
+ .setBody(readMockResponse("identity-segment-environment-document.json"))
+ .addHeader("Content-Type", "application/json");
+ }
+ return new MockResponse().setResponseCode(404);
+ }
+ });
+
+ FlagsmithProvider localProvider = new FlagsmithProvider(FlagsmithProviderOptions.builder()
+ .apiKey("ser.API_KEY")
+ .baseUri(String.format("http://localhost:%s", mockFlagsmithServer.getPort()))
+ .localEvaluation(true)
+ .build());
+ try {
+ MutableContext matchingContext = new MutableContext();
+ matchingContext.setTargetingKey("matching-identity");
+
+ await().atMost(Duration.ofSeconds(5))
+ .untilAsserted(() -> assertEquals(
+ "matched",
+ localProvider
+ .getStringEvaluation("identity_feature", "fallback", matchingContext)
+ .getValue()));
+
+ MutableContext otherContext = new MutableContext();
+ otherContext.setTargetingKey("other-identity");
+ assertEquals(
+ "default",
+ localProvider
+ .getStringEvaluation("identity_feature", "fallback", otherContext)
+ .getValue());
+ } finally {
+ localProvider.shutdown();
+ }
+ }
+
@ParameterizedTest
@MethodSource("invalidOptions")
void shouldThrowAnExceptionWhenOptionsInvalid(FlagsmithProviderOptions options) {
diff --git a/providers/flagsmith/src/test/resources/mock_responses/identity-segment-environment-document.json b/providers/flagsmith/src/test/resources/mock_responses/identity-segment-environment-document.json
new file mode 100644
index 0000000000..9b5e8d1e6e
--- /dev/null
+++ b/providers/flagsmith/src/test/resources/mock_responses/identity-segment-environment-document.json
@@ -0,0 +1,44 @@
+{
+ "id": 18141,
+ "api_key": "ser.API_KEY",
+ "name": "Test environment",
+ "feature_states": [
+ {
+ "django_id": 188032,
+ "feature": {"id": 35352, "name": "identity_feature", "type": "STANDARD"},
+ "enabled": true,
+ "feature_state_value": "default",
+ "multivariate_feature_state_values": []
+ }
+ ],
+ "identity_overrides": [],
+ "project": {
+ "id": 7720,
+ "name": "Test project",
+ "segments": [
+ {
+ "id": 123,
+ "name": "identity-segment",
+ "rules": [
+ {
+ "type": "ALL",
+ "conditions": [
+ {"operator": "EQUAL", "property_": "$.identity.identifier", "value": "matching-identity"}
+ ],
+ "rules": []
+ }
+ ],
+ "feature_states": [
+ {
+ "django_id": 188033,
+ "feature": {"id": 35352, "name": "identity_feature", "type": "STANDARD"},
+ "enabled": true,
+ "feature_state_value": "matched",
+ "multivariate_feature_state_values": [],
+ "feature_segment": {"priority": 1}
+ }
+ ]
+ }
+ ]
+ }
+}