package ldcomponents import ( "encoding/json" "net/http/httptest" "testing" "time" "github.com/launchdarkly/go-sdk-common/v3/ldattr" "github.com/launchdarkly/go-sdk-common/v3/lduser" "github.com/launchdarkly/go-sdk-common/v3/ldvalue" ldevents "github.com/launchdarkly/go-sdk-events/v2" "github.com/launchdarkly/go-server-sdk/v6/testhelpers/ldservices" "github.com/launchdarkly/go-test-helpers/v3/httphelpers" m "github.com/launchdarkly/go-test-helpers/v3/matchers" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // Note that we can't really test every event configuration option in these tests - they are tested in detail in // the ldevents package, but we do want to verify that the basic options are being passed to ldevents correctly. func TestEventProcessorBuilder(t *testing.T) { t.Run("AllAttributesPrivate", func(t *testing.T) { b := SendEvents() assert.False(t, b.allAttributesPrivate) b.AllAttributesPrivate(true) assert.True(t, b.allAttributesPrivate) b.AllAttributesPrivate(false) assert.False(t, b.allAttributesPrivate) }) t.Run("Capacity", func(t *testing.T) { b := SendEvents() assert.Equal(t, DefaultEventsCapacity, b.capacity) b.Capacity(333) assert.Equal(t, 333, b.capacity) }) t.Run("DiagnosticRecordingInterval", func(t *testing.T) { b := SendEvents() assert.Equal(t, DefaultDiagnosticRecordingInterval, b.diagnosticRecordingInterval) b.DiagnosticRecordingInterval(time.Hour) assert.Equal(t, time.Hour, b.diagnosticRecordingInterval) b.DiagnosticRecordingInterval(time.Second) assert.Equal(t, MinimumDiagnosticRecordingInterval, b.diagnosticRecordingInterval) }) t.Run("FlushInterval", func(t *testing.T) { b := SendEvents() assert.Equal(t, DefaultFlushInterval, b.flushInterval) b.FlushInterval(time.Hour) assert.Equal(t, time.Hour, b.flushInterval) }) t.Run("PrivateAttributes", func(t *testing.T) { b := SendEvents() assert.Len(t, b.privateAttributes, 0) b.PrivateAttributes("name", "/address/street") assert.Equal(t, []ldattr.Ref{ldattr.NewRef("name"), ldattr.NewRef("/address/street")}, b.privateAttributes) }) t.Run("ContextKeysCapacity", func(t *testing.T) { b := SendEvents() assert.Equal(t, DefaultContextKeysCapacity, b.contextKeysCapacity) b.ContextKeysCapacity(333) assert.Equal(t, 333, b.contextKeysCapacity) }) t.Run("ContextKeysFlushInterval", func(t *testing.T) { b := SendEvents() assert.Equal(t, DefaultContextKeysFlushInterval, b.contextKeysFlushInterval) b.ContextKeysFlushInterval(time.Hour) assert.Equal(t, time.Hour, b.contextKeysFlushInterval) }) } func TestDefaultEventsConfigWithoutDiagnostics(t *testing.T) { eventsHandler, requestsCh := httphelpers.RecordingHandler(ldservices.ServerSideEventsServiceHandler()) httphelpers.WithServer(eventsHandler, func(server *httptest.Server) { ep, err := SendEvents(). Build(makeTestContextWithBaseURIs(server.URL)) require.NoError(t, err) ef := ldevents.NewEventFactory(false, nil) ce := ef.NewCustomEventData("event-key", ldevents.Context(lduser.NewUser("key")), ldvalue.Null(), false, 0) ep.RecordCustomEvent(ce) ep.Flush() r := <-requestsCh var jsonData ldvalue.Value _ = json.Unmarshal(r.Body, &jsonData) assert.Equal(t, 2, jsonData.Count()) assert.Equal(t, ldvalue.String("index"), jsonData.GetByIndex(0).GetByKey("kind")) assert.Equal(t, ldvalue.String("custom"), jsonData.GetByIndex(1).GetByKey("kind")) }) } func TestDefaultEventsConfigWithDiagnostics(t *testing.T) { eventsHandler, requestsCh := httphelpers.RecordingHandler(ldservices.ServerSideEventsServiceHandler()) diagnosticsManager := ldevents.NewDiagnosticsManager( ldevents.NewDiagnosticID("sdk-key"), ldvalue.Null(), ldvalue.Null(), time.Now(), nil, ) httphelpers.WithServer(eventsHandler, func(server *httptest.Server) { context := makeTestContextWithBaseURIs(server.URL) context.DiagnosticsManager = diagnosticsManager _, err := SendEvents(). Build(context) require.NoError(t, err) r := <-requestsCh var jsonData ldvalue.Value _ = json.Unmarshal(r.Body, &jsonData) assert.Equal(t, ldvalue.String("diagnostic-init"), jsonData.GetByKey("kind")) }) } func TestEventsAllAttributesPrivate(t *testing.T) { eventsHandler, requestsCh := httphelpers.RecordingHandler(ldservices.ServerSideEventsServiceHandler()) httphelpers.WithServer(eventsHandler, func(server *httptest.Server) { ep, err := SendEvents(). AllAttributesPrivate(true). Build(makeTestContextWithBaseURIs(server.URL)) require.NoError(t, err) ef := ldevents.NewEventFactory(false, nil) ie := ef.NewIdentifyEventData(ldevents.Context(lduser.NewUserBuilder("user-key").Name("user-name").Build())) ep.RecordIdentifyEvent(ie) ep.Flush() r := <-requestsCh var jsonData ldvalue.Value _ = json.Unmarshal(r.Body, &jsonData) assert.Equal(t, 1, jsonData.Count()) event := jsonData.GetByIndex(0) m.In(t).Assert(event, m.AllOf( m.JSONProperty("kind").Should(m.Equal("identify")), m.JSONProperty("context").Should(m.AllOf( m.JSONProperty("key").Should(m.Equal("user-key")), m.JSONOptProperty("name").Should(m.BeNil()), m.JSONProperty("_meta").Should(m.JSONProperty("redactedAttributes").Should(m.JSONStrEqual(`["name"]`))), )), )) }) } func TestEventsCapacity(t *testing.T) { eventsHandler, requestsCh := httphelpers.RecordingHandler(ldservices.ServerSideEventsServiceHandler()) httphelpers.WithServer(eventsHandler, func(server *httptest.Server) { ep, err := SendEvents(). Capacity(1). Build(makeTestContextWithBaseURIs(server.URL)) require.NoError(t, err) ef := ldevents.NewEventFactory(false, nil) ie := ef.NewIdentifyEventData(ldevents.Context(lduser.NewUserBuilder("user-key").Name("user-name").Build())) ep.RecordIdentifyEvent(ie) ep.RecordIdentifyEvent(ie) // 2nd event will be dropped ep.Flush() r := <-requestsCh var jsonData ldvalue.Value _ = json.Unmarshal(r.Body, &jsonData) assert.Equal(t, 1, jsonData.Count()) }) } func TestEventsSomeAttributesPrivate(t *testing.T) { eventsHandler, requestsCh := httphelpers.RecordingHandler(ldservices.ServerSideEventsServiceHandler()) httphelpers.WithServer(eventsHandler, func(server *httptest.Server) { ep, err := SendEvents(). PrivateAttributes("name"). Build(makeTestContextWithBaseURIs(server.URL)) require.NoError(t, err) ef := ldevents.NewEventFactory(false, nil) ie := ef.NewIdentifyEventData(ldevents.Context(lduser.NewUserBuilder("user-key").Email("user-email").Name("user-name").Build())) ep.RecordIdentifyEvent(ie) ep.Flush() r := <-requestsCh var jsonData ldvalue.Value _ = json.Unmarshal(r.Body, &jsonData) assert.Equal(t, 1, jsonData.Count()) event := jsonData.GetByIndex(0) m.In(t).Assert(event, m.AllOf( m.JSONProperty("kind").Should(m.Equal("identify")), m.JSONProperty("context").Should(m.AllOf( m.JSONProperty("key").Should(m.Equal("user-key")), m.JSONProperty("email").Should(m.Equal("user-email")), m.JSONOptProperty("name").Should(m.BeNil()), m.JSONProperty("_meta").Should(m.JSONProperty("redactedAttributes").Should(m.JSONStrEqual(`["name"]`))), )), )) }) }