Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci(nl): enable notification listener #188

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions pkg/decision/composite_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,14 @@ func (s CompositeService) GetFeatureDecision(featureDecisionContext FeatureDecis
if featureDecision.Variation != nil {
featureInfo["featureEnabled"] = featureDecision.Variation.FeatureEnabled
}

notificationType := notification.Feature
variable := featureDecisionContext.Variable
if variable.ID != "" && variable.Key != "" {
featureInfo["variableKey"] = variable.Key
featureInfo["variableType"] = variable.Type

notificationType = notification.FeatureVariable
variableValue := variable.DefaultValue

if featureDecision.Variation != nil {
Expand Down Expand Up @@ -119,13 +122,9 @@ func (s CompositeService) GetFeatureDecision(featureDecisionContext FeatureDecis
}
}

decisionInfo := map[string]interface{}{
"feature": featureInfo,
}

decisionNotification := notification.DecisionNotification{
DecisionInfo: decisionInfo,
Type: notification.Feature,
DecisionInfo: featureInfo,
Type: notificationType,
UserContext: userContext,
}
if err = s.notificationCenter.Send(notification.Decision, decisionNotification); err != nil {
Expand All @@ -141,12 +140,12 @@ func (s CompositeService) GetExperimentDecision(experimentDecisionContext Experi
return experimentDecision, err
}

// if
if s.notificationCenter != nil && experimentDecision.Variation != nil {
decisionInfo := map[string]interface{}{
"experimentKey": experimentDecisionContext.Experiment.Key,
"variationKey": experimentDecision.Variation.Key,
}

decisionNotification := notification.DecisionNotification{
DecisionInfo: decisionInfo,
Type: notification.ABTest,
Expand Down
20 changes: 10 additions & 10 deletions pkg/decision/composite_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ func (s *CompositeServiceFeatureTestSuite) TestDecisionListenersNotificationWith
decisionService.GetFeatureDecision(s.decisionContext, s.testUserContext)
s.Equal(numberOfCalls, 1)

expectedDecisionInfo := map[string]interface{}{"feature": map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
expectedDecisionInfo := map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
"sourceInfo": map[string]string{"experimentKey": "my_test_feature_3333", "variationKey": "2222"},
"variableKey": "Key", "variableType": entities.Double, "variableValue": 23.34}}
"variableKey": "Key", "variableType": entities.Double, "variableValue": 23.34}

s.Equal(expectedDecisionInfo, note.DecisionInfo)

Expand Down Expand Up @@ -159,9 +159,9 @@ func (s *CompositeServiceFeatureTestSuite) TestDecisionListenersNotificationWith
decisionService.GetFeatureDecision(s.decisionContext, s.testUserContext)
s.Equal(numberOfCalls, 1)

expectedDecisionInfo := map[string]interface{}{"feature": map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
expectedDecisionInfo := map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
"sourceInfo": map[string]string{"experimentKey": "my_test_feature_3333", "variationKey": "2222"},
"variableKey": "Key", "variableType": entities.Integer, "variableValue": 23}}
"variableKey": "Key", "variableType": entities.Integer, "variableValue": 23}

s.Equal(expectedDecisionInfo, note.DecisionInfo)

Expand Down Expand Up @@ -197,9 +197,9 @@ func (s *CompositeServiceFeatureTestSuite) TestDecisionListenersNotificationWith
decisionService.GetFeatureDecision(s.decisionContext, s.testUserContext)
s.Equal(numberOfCalls, 1)

expectedDecisionInfo := map[string]interface{}{"feature": map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
expectedDecisionInfo := map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
"sourceInfo": map[string]string{"experimentKey": "my_test_feature_3333", "variationKey": "2222"},
"variableKey": "Key", "variableType": entities.Boolean, "variableValue": true}}
"variableKey": "Key", "variableType": entities.Boolean, "variableValue": true}

s.Equal(expectedDecisionInfo, note.DecisionInfo)

Expand Down Expand Up @@ -235,9 +235,9 @@ func (s *CompositeServiceFeatureTestSuite) TestDecisionListenersNotificationWith
decisionService.GetFeatureDecision(s.decisionContext, s.testUserContext)
s.Equal(numberOfCalls, 1)

expectedDecisionInfo := map[string]interface{}{"feature": map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
expectedDecisionInfo := map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
"sourceInfo": map[string]string{"experimentKey": "my_test_feature_3333", "variationKey": "2222"},
"variableKey": "Key", "variableType": entities.Double, "variableValue": "string"}}
"variableKey": "Key", "variableType": entities.Double, "variableValue": "string"}

s.Equal(expectedDecisionInfo, note.DecisionInfo)

Expand Down Expand Up @@ -268,8 +268,8 @@ func (s *CompositeServiceFeatureTestSuite) TestDecisionListenersNotificationWith
decisionService.GetFeatureDecision(s.decisionContext, s.testUserContext)
s.Equal(numberOfCalls, 1)

expectedDecisionInfo := map[string]interface{}{"feature": map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
"sourceInfo": map[string]string{"experimentKey": "my_test_feature_3333", "variationKey": "2222"}}}
expectedDecisionInfo := map[string]interface{}{"featureEnabled": false, "featureKey": "my_test_feature_3333", "source": FeatureTest,
"sourceInfo": map[string]string{"experimentKey": "my_test_feature_3333", "variationKey": "2222"}}

s.Equal(expectedDecisionInfo, note.DecisionInfo)
}
Expand Down
8 changes: 6 additions & 2 deletions pkg/notification/entities.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ const (
ABTest DecisionNotificationType = "ab-test"
// Feature is used when the decision is returned as part of evaluating a feature
Feature DecisionNotificationType = "feature"
// FeatureTest is used when the decision is returned as part of evaluating a feature test
FeatureTest DecisionNotificationType = "feature-test"
// FeatureVariable is used when the decision is returned as part of evaluating a feature with a variable
FeatureVariable DecisionNotificationType = "feature-variable"
// LogEvent notification type
LogEvent Type = "log_event_notification"
)
Expand All @@ -56,6 +60,6 @@ type ProjectConfigUpdateNotification struct {

// LogEventNotification is the notification triggered before log event is dispatched.
type LogEventNotification struct {
Type Type
LogEvent interface{}
Type Type
LogEvent interface{}
}
58 changes: 32 additions & 26 deletions tests/integration/optlyplugins/test_composite_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package optlyplugins

import (
"github.com/optimizely/go-sdk/pkg/decision"
"github.com/optimizely/go-sdk/pkg/entities"
"github.com/optimizely/go-sdk/pkg/notification"
"github.com/optimizely/go-sdk/tests/integration/models"
)
Expand Down Expand Up @@ -49,34 +50,36 @@ func (c *TestCompositeService) AddListeners(listeners map[string]int) {

// GetListenersCalled - Returns listeners called
func (c *TestCompositeService) GetListenersCalled() []models.DecisionListener {
return c.listenersCalled
listenerCalled := c.listenersCalled
c.listenersCalled = nil
return listenerCalled
}

func (c *TestCompositeService) decisionNotificationCallback(notification notification.DecisionNotification) {
func (c *TestCompositeService) decisionNotificationCallback(notify notification.DecisionNotification) {

model := models.DecisionListener{}
model.Type = notification.Type
model.UserID = notification.UserContext.ID
if notification.UserContext.Attributes == nil {
model.Type = notify.Type
model.UserID = notify.UserContext.ID
if notify.UserContext.Attributes == nil {
model.Attributes = make(map[string]interface{})
} else {
model.Attributes = notification.UserContext.Attributes
model.Attributes = notify.UserContext.Attributes
}

decisionInfoDict := getDecisionInfoForNotification(notification)
decisionInfoDict := getDecisionInfoForNotification(notify)
model.DecisionInfo = decisionInfoDict
c.listenersCalled = append(c.listenersCalled, model)
}

func getDecisionInfoForNotification(notification notification.DecisionNotification) map[string]interface{} {
func getDecisionInfoForNotification(notify notification.DecisionNotification) map[string]interface{} {
decisionInfoDict := make(map[string]interface{})

updateSourceInfo := func(source string) {
decisionInfoDict["source_info"] = make(map[string]interface{})
if source == "feature-test" {
if sourceInfo, ok := notification.DecisionInfo["source_info"].(map[string]interface{}); ok {
if experimentKey, ok := sourceInfo["experiment_key"].(string); ok {
if variationKey, ok := sourceInfo["variation_key"].(string); ok {
decisionInfoDict["source_info"] = map[string]interface{}{}
if source == string(decision.FeatureTest) {
if sourceInfo, ok := notify.DecisionInfo["sourceInfo"].(map[string]string); ok {
if experimentKey, ok := sourceInfo["experimentKey"]; ok {
if variationKey, ok := sourceInfo["variationKey"]; ok {
dict := make(map[string]interface{})
dict["experiment_key"] = experimentKey
dict["variation_key"] = variationKey
Expand All @@ -87,33 +90,36 @@ func getDecisionInfoForNotification(notification notification.DecisionNotificati
}
}

switch notificationType := notification.Type; notificationType {
case "ab-test", "feature-test":
decisionInfoDict["experiment_key"] = notification.DecisionInfo["experimentKey"]
decisionInfoDict["variation_key"] = notification.DecisionInfo["variationKey"]
switch notificationType := notify.Type; notificationType {
case notification.ABTest, notification.FeatureTest:
decisionInfoDict["experiment_key"] = notify.DecisionInfo["experimentKey"]
decisionInfoDict["variation_key"] = notify.DecisionInfo["variationKey"]
break
case "feature":
decisionInfoDict = notification.DecisionInfo["feature"].(map[string]interface{})
case notification.Feature:
source := ""
if decisionSource, ok := decisionInfoDict["source"].(decision.Source); ok {
if decisionSource, ok := notify.DecisionInfo["source"].(decision.Source); ok {
source = string(decisionSource)
} else {
source = decisionInfoDict["source"].(string)
}
decisionInfoDict["source"] = source
decisionInfoDict["feature_enabled"] = notify.DecisionInfo["featureEnabled"].(bool)
decisionInfoDict["feature_key"] = notify.DecisionInfo["featureKey"].(string)

updateSourceInfo(source)
case "feature-variable":
decisionInfoDict = notification.DecisionInfo["feature"].(map[string]interface{})
case notification.FeatureVariable:
source := ""
if decisionSource, ok := decisionInfoDict["source"].(decision.Source); ok {
if decisionSource, ok := notify.DecisionInfo["source"].(decision.Source); ok {
source = string(decisionSource)
} else {
source = decisionInfoDict["source"].(string)
}
decisionInfoDict["source"] = source
decisionInfoDict["variable_key"] = notification.DecisionInfo["variable_key"]
decisionInfoDict["variable_type"] = notification.DecisionInfo["variable_type"]
decisionInfoDict["variable_value"] = notification.DecisionInfo["variable_value"]
decisionInfoDict["variable_key"] = notify.DecisionInfo["variableKey"]
decisionInfoDict["variable_type"] = string(notify.DecisionInfo["variableType"].(entities.VariableType))
decisionInfoDict["variable_value"] = notify.DecisionInfo["variableValue"]
decisionInfoDict["feature_enabled"] = notify.DecisionInfo["featureEnabled"].(bool)
decisionInfoDict["feature_key"] = notify.DecisionInfo["featureKey"].(string)
updateSourceInfo(source)
default:
}
Expand Down
4 changes: 0 additions & 4 deletions tests/integration/support/steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ func (c *ScenarioCtx) InTheResponseKeyShouldBeObject(argumentType, value string)
if value == "NULL" && c.apiResponse.ListenerCalled == nil {
return nil
}
// @TODO: Revert this to test listener called
return nil
default:
break
}
Expand All @@ -180,8 +178,6 @@ func (c *ScenarioCtx) InTheResponseShouldMatch(argumentType string, value *gherk
if subset.Check(requestListenersCalled, c.apiResponse.ListenerCalled) {
return nil
}
// @TODO: Revert this to test listener called
return nil
default:
break
}
Expand Down