diff --git a/src/main/java/com/auth0/client/mgmt/AsyncRawEventsClient.java b/src/main/java/com/auth0/client/mgmt/AsyncRawEventsClient.java index 261c6a665..263e6d86d 100644 --- a/src/main/java/com/auth0/client/mgmt/AsyncRawEventsClient.java +++ b/src/main/java/com/auth0/client/mgmt/AsyncRawEventsClient.java @@ -109,9 +109,10 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO ResponseBody responseBody = response.body(); if (response.isSuccessful()) { future.complete(new ManagementApiHttpResponse<>( - Stream.fromSse( + Stream.fromSseWithEventDiscrimination( EventStreamSubscribeEventsResponseContent.class, - new ResponseBodyReader(response)), + new ResponseBodyReader(response), + "type"), response)); return; } diff --git a/src/main/java/com/auth0/client/mgmt/RawEventsClient.java b/src/main/java/com/auth0/client/mgmt/RawEventsClient.java index 63ec6d1d5..95a159b3d 100644 --- a/src/main/java/com/auth0/client/mgmt/RawEventsClient.java +++ b/src/main/java/com/auth0/client/mgmt/RawEventsClient.java @@ -100,8 +100,10 @@ public ManagementApiHttpResponse( - Stream.fromSse( - EventStreamSubscribeEventsResponseContent.class, new ResponseBodyReader(response)), + Stream.fromSseWithEventDiscrimination( + EventStreamSubscribeEventsResponseContent.class, + new ResponseBodyReader(response), + "type"), response); } String responseBodyString = responseBody != null ? responseBody.string() : "{}"; diff --git a/src/main/java/com/auth0/client/mgmt/core/SseEventParser.java b/src/main/java/com/auth0/client/mgmt/core/SseEventParser.java index 9badb0bec..f66a06267 100644 --- a/src/main/java/com/auth0/client/mgmt/core/SseEventParser.java +++ b/src/main/java/com/auth0/client/mgmt/core/SseEventParser.java @@ -74,6 +74,44 @@ public static T parseEventLevelUnion( } } + /** + * Parse an SSE event whose discriminator is not part of the SSE envelope shape (i.e. + * {@link #isEventLevelDiscrimination(String)} is {@code false}) but is also absent from the + * wire payload itself. Merges the SSE {@code event:} name into the root of the parsed + * {@code data:} object under {@code discriminatorProperty}, without overwriting a + * pre-existing value, then deserializes the merged object to the target type. + * + * @param eventType The SSE event type (from event: field) + * @param data The SSE data content (from data: field) + * @param unionClass The target union class + * @param discriminatorProperty The property name used for discrimination (e.g., "type") + * @param The target type + * @return The deserialized object + */ + public static T parseWithInjectedDiscriminator( + String eventType, String data, Class unionClass, String discriminatorProperty) { + Map parsedData = null; + if (data != null && !data.isEmpty()) { + try { + parsedData = ObjectMappers.JSON_MAPPER.readValue(data, new TypeReference>() {}); + } catch (Exception e) { + parsedData = null; + } + } + try { + if (parsedData == null) { + return parseDataLevelUnion(data, unionClass); + } + if (eventType != null) { + parsedData.putIfAbsent(discriminatorProperty, eventType); + } + String mergedJson = ObjectMappers.JSON_MAPPER.writeValueAsString(parsedData); + return ObjectMappers.JSON_MAPPER.readValue(mergedJson, unionClass); + } catch (Exception e) { + throw new RuntimeException("Failed to parse SSE event with injected discriminator", e); + } + } + /** * Parse an SSE event using data-level discrimination. *

diff --git a/src/main/java/com/auth0/client/mgmt/core/Stream.java b/src/main/java/com/auth0/client/mgmt/core/Stream.java index e17919b91..accde26a1 100644 --- a/src/main/java/com/auth0/client/mgmt/core/Stream.java +++ b/src/main/java/com/auth0/client/mgmt/core/Stream.java @@ -410,14 +410,7 @@ private boolean readNextMessage() { if (line.trim().isEmpty()) { if (eventDataBuffer.length() > 0 || currentEventType != null) { try { - // Use SseEventParser for event-level discrimination - nextItem = SseEventParser.parseEventLevelUnion( - currentEventType, - eventDataBuffer.toString(), - currentEventId, - currentRetry, - valueType, - discriminatorProperty); + nextItem = parseCurrentEvent(); hasNextItem = true; resetEventState(); return true; @@ -477,13 +470,7 @@ private boolean readNextMessage() { // Handle any remaining buffered data at end of stream if (eventDataBuffer.length() > 0 || currentEventType != null) { try { - nextItem = SseEventParser.parseEventLevelUnion( - currentEventType, - eventDataBuffer.toString(), - currentEventId, - currentRetry, - valueType, - discriminatorProperty); + nextItem = parseCurrentEvent(); hasNextItem = true; resetEventState(); return true; @@ -509,5 +496,15 @@ private void resetEventState() { currentEventId = null; currentRetry = null; } + + private T parseCurrentEvent() { + String data = eventDataBuffer.toString(); + if (SseEventParser.isEventLevelDiscrimination(discriminatorProperty)) { + return SseEventParser.parseEventLevelUnion( + currentEventType, data, currentEventId, currentRetry, valueType, discriminatorProperty); + } + return SseEventParser.parseWithInjectedDiscriminator( + currentEventType, data, valueType, discriminatorProperty); + } } } diff --git a/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserCreatedObjectIdentitiesItem.java b/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserCreatedObjectIdentitiesItem.java index 04ef0a9d5..86d8c4376 100644 --- a/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserCreatedObjectIdentitiesItem.java +++ b/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserCreatedObjectIdentitiesItem.java @@ -113,58 +113,56 @@ static final class Deserializer extends StdDeserializer - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserCreatedObjectIdentitiesItemCustom.class)); - } catch (RuntimeException e) { + if (value instanceof Map) { + Map map = (Map) value; + Object providerValue = map.get("provider"); + String provider = providerValue == null ? null : providerValue.toString(); + boolean isSocial = Boolean.TRUE.equals(map.get("isSocial")); + + if (isSocial) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserCreatedObjectIdentitiesItemSocial.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserCreatedObjectIdentitiesItemDatabase.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserCreatedObjectIdentitiesItemDatabaseProviderEnum.valueOf(provider) + .getEnumValue() + != EventStreamCloudEventUserCreatedObjectIdentitiesItemDatabaseProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserCreatedObjectIdentitiesItemDatabase.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserCreatedObjectIdentitiesItemEnterprise.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserCreatedObjectIdentitiesItemPasswordlessProviderEnum.valueOf( + provider) + .getEnumValue() + != EventStreamCloudEventUserCreatedObjectIdentitiesItemPasswordlessProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserCreatedObjectIdentitiesItemPasswordless.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserCreatedObjectIdentitiesItemPasswordless.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserCreatedObjectIdentitiesItemEnterpriseProviderEnum.valueOf(provider) + .getEnumValue() + != EventStreamCloudEventUserCreatedObjectIdentitiesItemEnterpriseProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserCreatedObjectIdentitiesItemEnterprise.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { try { return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserCreatedObjectIdentitiesItemSocial.class)); + value, EventStreamCloudEventUserCreatedObjectIdentitiesItemCustom.class)); } catch (RuntimeException e) { } } diff --git a/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserDeletedObjectIdentitiesItem.java b/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserDeletedObjectIdentitiesItem.java index 3326369f7..fe693cbc7 100644 --- a/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserDeletedObjectIdentitiesItem.java +++ b/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserDeletedObjectIdentitiesItem.java @@ -113,58 +113,56 @@ static final class Deserializer extends StdDeserializer - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserDeletedObjectIdentitiesItemCustom.class)); - } catch (RuntimeException e) { + if (value instanceof Map) { + Map map = (Map) value; + Object providerValue = map.get("provider"); + String provider = providerValue == null ? null : providerValue.toString(); + boolean isSocial = Boolean.TRUE.equals(map.get("isSocial")); + + if (isSocial) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserDeletedObjectIdentitiesItemSocial.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserDeletedObjectIdentitiesItemDatabase.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserDeletedObjectIdentitiesItemDatabaseProviderEnum.valueOf(provider) + .getEnumValue() + != EventStreamCloudEventUserDeletedObjectIdentitiesItemDatabaseProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserDeletedObjectIdentitiesItemDatabase.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserDeletedObjectIdentitiesItemEnterprise.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserDeletedObjectIdentitiesItemPasswordlessProviderEnum.valueOf( + provider) + .getEnumValue() + != EventStreamCloudEventUserDeletedObjectIdentitiesItemPasswordlessProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserDeletedObjectIdentitiesItemPasswordless.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserDeletedObjectIdentitiesItemPasswordless.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserDeletedObjectIdentitiesItemEnterpriseProviderEnum.valueOf(provider) + .getEnumValue() + != EventStreamCloudEventUserDeletedObjectIdentitiesItemEnterpriseProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserDeletedObjectIdentitiesItemEnterprise.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { try { return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserDeletedObjectIdentitiesItemSocial.class)); + value, EventStreamCloudEventUserDeletedObjectIdentitiesItemCustom.class)); } catch (RuntimeException e) { } } diff --git a/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserUpdatedObjectIdentitiesItem.java b/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserUpdatedObjectIdentitiesItem.java index ca95c9e69..f210a18c6 100644 --- a/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserUpdatedObjectIdentitiesItem.java +++ b/src/main/java/com/auth0/client/mgmt/types/EventStreamCloudEventUserUpdatedObjectIdentitiesItem.java @@ -113,58 +113,56 @@ static final class Deserializer extends StdDeserializer - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemCustom.class)); - } catch (RuntimeException e) { + if (value instanceof Map) { + Map map = (Map) value; + Object providerValue = map.get("provider"); + String provider = providerValue == null ? null : providerValue.toString(); + boolean isSocial = Boolean.TRUE.equals(map.get("isSocial")); + + if (isSocial) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemSocial.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabase.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabaseProviderEnum.valueOf(provider) + .getEnumValue() + != EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabaseProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabase.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemEnterprise.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserUpdatedObjectIdentitiesItemPasswordlessProviderEnum.valueOf( + provider) + .getEnumValue() + != EventStreamCloudEventUserUpdatedObjectIdentitiesItemPasswordlessProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemPasswordless.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { - try { - return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemPasswordless.class)); - } catch (RuntimeException e) { + if (provider != null + && EventStreamCloudEventUserUpdatedObjectIdentitiesItemEnterpriseProviderEnum.valueOf(provider) + .getEnumValue() + != EventStreamCloudEventUserUpdatedObjectIdentitiesItemEnterpriseProviderEnum.Value + .UNKNOWN) { + try { + return of(ObjectMappers.JSON_MAPPER.convertValue( + value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemEnterprise.class)); + } catch (RuntimeException e) { + } } - } - if (value instanceof Map - && ((Map) value).containsKey("connection") - && ((Map) value).containsKey("user_id") - && ((Map) value).containsKey("provider") - && ((Map) value).containsKey("isSocial")) { try { return of(ObjectMappers.JSON_MAPPER.convertValue( - value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemSocial.class)); + value, EventStreamCloudEventUserUpdatedObjectIdentitiesItemCustom.class)); } catch (RuntimeException e) { } } diff --git a/src/test/java/com/auth0/client/mgmt/EventsSubscribeSseTest.java b/src/test/java/com/auth0/client/mgmt/EventsSubscribeSseTest.java new file mode 100644 index 000000000..4fde4ef62 --- /dev/null +++ b/src/test/java/com/auth0/client/mgmt/EventsSubscribeSseTest.java @@ -0,0 +1,148 @@ +package com.auth0.client.mgmt; + +import com.auth0.client.mgmt.types.EventStreamCloudEventUserUpdatedObjectIdentitiesItem; +import com.auth0.client.mgmt.types.EventStreamCloudEventUserUpdatedObjectIdentitiesItemCustom; +import com.auth0.client.mgmt.types.EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabase; +import com.auth0.client.mgmt.types.EventStreamCloudEventUserUpdatedObjectIdentitiesItemEnterprise; +import com.auth0.client.mgmt.types.EventStreamCloudEventUserUpdatedObjectIdentitiesItemPasswordless; +import com.auth0.client.mgmt.types.EventStreamCloudEventUserUpdatedObjectIdentitiesItemSocial; +import com.auth0.client.mgmt.types.EventStreamSubscribeEventsEventTypeEnum; +import com.auth0.client.mgmt.types.EventStreamSubscribeEventsResponseContent; +import com.auth0.client.mgmt.types.SubscribeEventsRequestParameters; +import java.util.Arrays; +import java.util.Iterator; +import okhttp3.HttpUrl; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Regression coverage for the Events API SSE subscription: the event must resolve to its typed variant + */ +public class EventsSubscribeSseTest { + + private static final String USER_UPDATED_SSE_BODY = "event: user.updated\n" + "id: evt-anonymized-1\n" + + "data: {\"offset\":\"off-anonymized-1\",\"event\":{\"specversion\":\"1.0\",\"type\":\"user.updated\"," + + "\"source\":\"urn:auth0:example-test.eu.auth0.com\",\"id\":\"evt_test_1\"," + + "\"time\":\"2026-07-10T01:01:42.873Z\",\"data\":{\"object\":{" + + "\"user_id\":\"auth0|00000000-0000-0000-0000-000000000001\"," + + "\"email\":\"user@example.com\",\"email_verified\":true," + + "\"identities\":[{\"connection\":\"Example-Database\",\"isSocial\":false,\"provider\":\"auth0\"," + + "\"user_id\":\"00000000-0000-0000-0000-000000000001\"}]," + + "\"created_at\":\"2026-05-08T09:33:01.503Z\",\"updated_at\":\"2026-07-10T01:01:42.868Z\"}}," + + "\"a0tenant\":\"example-test\",\"a0stream\":\"test-stream\"}}\n\n"; + + private MockWebServer server; + private ManagementApi client; + + @BeforeEach + public void setup() throws Exception { + server = new MockWebServer(); + server.start(); + client = ManagementApi.builder() + .url(server.url("/").toString()) + .token("test-token") + .build(); + } + + @AfterEach + public void teardown() throws Exception { + server.shutdown(); + } + + @Test + public void subscribeResolvesUserUpdatedEventToTypedVariant() throws Exception { + server.enqueue(new MockResponse() + .setResponseCode(200) + .setHeader("Content-Type", "text/event-stream") + .setBody(USER_UPDATED_SSE_BODY)); + + Iterable response = client.events() + .subscribe(SubscribeEventsRequestParameters.builder() + .eventType(Arrays.asList(EventStreamSubscribeEventsEventTypeEnum.USER_UPDATED)) + .build()); + + RecordedRequest request = server.takeRequest(); + Assertions.assertEquals("GET", request.getMethod()); + HttpUrl requestUrl = request.getRequestUrl(); + Assertions.assertNotNull(requestUrl); + Assertions.assertEquals("user.updated", requestUrl.queryParameter("event_type")); + + Iterator iterator = response.iterator(); + Assertions.assertTrue(iterator.hasNext()); + EventStreamSubscribeEventsResponseContent event = iterator.next(); + Assertions.assertFalse(iterator.hasNext(), "expected exactly one event"); + + Assertions.assertFalse(event._isUnknown()); + Assertions.assertTrue(event.isUserUpdated()); + Assertions.assertTrue(event.getUserUpdated().isPresent()); + + Assertions.assertEquals("off-anonymized-1", event.getUserUpdated().get().getOffset()); + Assertions.assertEquals( + "auth0|00000000-0000-0000-0000-000000000001", + event.getUserUpdated().get().getEvent().getData().getObject().getUserId()); + + EventStreamCloudEventUserUpdatedObjectIdentitiesItem identity = event.getUserUpdated() + .get() + .getEvent() + .getData() + .getObject() + .getIdentities() + .get(0); + Object resolvedIdentity = + identity.visit(new EventStreamCloudEventUserUpdatedObjectIdentitiesItem.Visitor() { + @Override + public Object visit(EventStreamCloudEventUserUpdatedObjectIdentitiesItemCustom value) { + return value; + } + + @Override + public Object visit(EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabase value) { + return value; + } + + @Override + public Object visit(EventStreamCloudEventUserUpdatedObjectIdentitiesItemEnterprise value) { + return value; + } + + @Override + public Object visit(EventStreamCloudEventUserUpdatedObjectIdentitiesItemPasswordless value) { + return value; + } + + @Override + public Object visit(EventStreamCloudEventUserUpdatedObjectIdentitiesItemSocial value) { + return value; + } + }); + + Assertions.assertInstanceOf( + EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabase.class, resolvedIdentity); + EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabase database = + (EventStreamCloudEventUserUpdatedObjectIdentitiesItemDatabase) resolvedIdentity; + Assertions.assertEquals("Example-Database", database.getConnection()); + Assertions.assertEquals("auth0", database.getProvider().toString()); + } + + @Test + public void unrecognizedEventTypeFallsBackToUnknownWithoutThrowing() throws Exception { + String body = "event: user.teleported\n" + "data: {\"foo\":\"bar\"}\n\n"; + server.enqueue(new MockResponse() + .setResponseCode(200) + .setHeader("Content-Type", "text/event-stream") + .setBody(body)); + + Iterable response = client.events() + .subscribe(SubscribeEventsRequestParameters.builder().build()); + + Iterator iterator = response.iterator(); + Assertions.assertTrue(iterator.hasNext()); + EventStreamSubscribeEventsResponseContent event = Assertions.assertDoesNotThrow(iterator::next); + Assertions.assertTrue(event._isUnknown()); + } +}