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

feat(OptimizelyConfig): Add new fields to OptimizelyConfig #285

Merged
merged 21 commits into from
Aug 12, 2021

Conversation

ozayr-zaviar
Copy link
Contributor

@ozayr-zaviar ozayr-zaviar commented Jul 29, 2021

Summary

The following new public properties are added to OptimizelyConfig:

  • sdkKey
  • environmentKey
  • attributes
  • audiences
  • events
  • experimentRules and deliveryRules to OptimizelyFeature
  • audiences to OptimizelyExperiment

Test plan

All FSC tests OPTIMIZELY_CONFIG_V2 tests should pass.
https://travis-ci.com/github/optimizely/fullstack-sdk-compatibility-suite/builds/235036023

@coveralls
Copy link

coveralls commented Jul 29, 2021

Coverage Status

Coverage increased (+0.009%) to 99.486% when pulling 4edf298 on uzair/opt-config-v2 into bc46127 on master.

optly_typed_audiences = []

@project_config.audiences.each do |old_audience|
next unless old_audience['id'] != '$opt_dummy_audience'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure, this is the right assumption. it may come in the middle of the array.

optly_typed_audiences.push(
'id' => type_audience['id'],
'name' => type_audience['name'],
'conditions' => type_audience['conditions'].to_json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be string

config = {
'sdk_key' => @project_config.sdk_key,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sdkKey

'attributes' => get_attributes_list(@project_config.attributes),
'audiences' => @audiences,
'events' => get_events_list(@project_config.events),
'environment_key' => @project_config.environment_key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be camelcase.

}
)
end
end

def get_attributes_list(attributes)
attributes.reduce([]) do |attributes_list, attribute|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map makes more sense here as you are transforming an array to another array

end

def get_events_list(events)
events.reduce([]) do |events_list, event|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use map here instead of reduce

end

def lookup_name_from_id(audience_id, audiences_map)
name = audiences_map[audience_id] || audience_id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check if only audiences_map[audience_id] || audience_id works?

name
end

def stringify_conditions(conditions, audiences_map)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks complex. It will be great if you can add detailed comments inside the method with each branch condition.

end

def replace_ids_with_names(conditions, audiences_map)
if !conditions.empty?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT! Could use ternary operator here?

Comment on lines 260 to 268
experiments.each do |experiment|
optly_exp = {
'id' => experiment['id'],
'key' => experiment['key'],
'variationsMap' => get_variation_map(feature_id, experiment, feature_variables_map),
'audiences' => replace_ids_with_names(experiment.fetch('audienceConditions', []), audiences_id_map) || ''
}
delivery_rules.push(optly_exp)
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use experiment.map and directly assign to delivery_rules

@audiences = []
type_audiences = @project_config.typed_audiences
optly_typed_audiences = []
id_lookup_dict = {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume it holds audiences only, if yes, the name should reflect that.

Comment on lines 26 to 27
type_audiences = @project_config.typed_audiences
optly_typed_audiences = []
Copy link
Contributor

@zashraf1985 zashraf1985 Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats the difference between type_audiences and optly_typed_audiences. It should be clear from the variable names that why there are two arrays being used. Actually you dont even need to use type_audiences one. You can use #project_config.typed_audiences directly to loop below. optly_typed_audiences does not sound consistent with others as no other variable are prefixed with optly. You should use typed_audiences to hold temp audiences and directly reference @project_config.typed_audiences to loop through the original array.

Comment on lines 94 to 98
experiments_key_map = {}
experiments_id_map.each do |_, experiment|
experiments_key_map[experiment['key']] = experiment
end
experiments_key_map
Copy link
Contributor

@zashraf1985 zashraf1985 Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could probably use reduce here?

@keppel2
Copy link

keppel2 commented Aug 11, 2021

A passing continuous integration (CI) can be helpful for reviews, but I will check to see if there is anything I can help with.

'featureEnabled' => variation['featureEnabled'],
'variablesMap' => get_merged_variables_map(variation, feature_id, feature_variables_map)
}
# variation_object['featureEnabled'] = variation['featureEnabled'] if @project_config.feature_experiment?(experiment['id']) || @project_config.rollout_experiment?(experiment['id'])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like doing so will help with rubocop.

@keppel2
Copy link

keppel2 commented Aug 11, 2021

rkeppel@unknown- ruby-sdk % rubocop
Inspecting 85 files
.............................................C..............................C.....C..

Offenses:

lib/optimizely/optimizely_config.rb:109:1: C: Layout/CommentIndentation: Incorrect indentation detected (column 0 instead of 8).
#         variation_object['featureEnabled'] = variation['featureEnabled'] if @project_config.feature_experiment?(experiment['id']) || @project_config.rollout_experiment?(experiment['id'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
spec/optimizely_config_spec.rb:764:1: C: Layout/EmptyLinesAroundBlockBody: Extra empty line detected at block body end.
spec/spec_params.rb:1428:8: C: Layout/MultilineArrayBraceLayout: The closing array brace must be on the line after the last array element when the opening brace is on a separate line from the first array element.
      }],
       ^

85 files inspected, 3 offenses detected
rkeppel@unknown- ruby-sdk % echo $?
1

@keppel2
Copy link

keppel2 commented Aug 11, 2021

rubocop worked for me on my MacBook. You can run it before pushing in changes to see if it will pass.

@keppel2
Copy link

keppel2 commented Aug 11, 2021

diff --git a/lib/optimizely/optimizely_config.rb b/lib/optimizely/optimizely_config.rb
index 6537ccc..9226ea9 100644
--- a/lib/optimizely/optimizely_config.rb
+++ b/lib/optimizely/optimizely_config.rb
@@ -106,7 +106,6 @@ module Optimizely
           'featureEnabled' => variation['featureEnabled'],
           'variablesMap' => get_merged_variables_map(variation, feature_id, feature_variables_map)
         }
-#         variation_object['featureEnabled'] = variation['featureEnabled'] if @project_config.feature_experiment?(experiment['id']) || @project_config.rollout_experiment?(experiment['id'])
         variations_map.update(variation['key'] => variation_object)
       end
     end
diff --git a/spec/optimizely_config_spec.rb b/spec/optimizely_config_spec.rb
index a0b372a..07ba5ae 100644
--- a/spec/optimizely_config_spec.rb
+++ b/spec/optimizely_config_spec.rb
@@ -761,7 +761,6 @@ describe Optimizely::OptimizelyConfig do
       result = optimizely_config.send(:replace_ids_with_names, audience_condition, audiences_map)
       expect(result).to eq(expected_audience_outputs[index])
     end
-
   end
 
   it 'should return correct config revision' do
diff --git a/spec/spec_params.rb b/spec/spec_params.rb
index eab7ad8..4647f4e 100644
--- a/spec/spec_params.rb
+++ b/spec/spec_params.rb
@@ -1425,7 +1425,8 @@ module OptimizelySpec
         'variables' => [],
         'id' => '2027',
         'key' => 'flag_1'
-      }],
+      }
+    ],
     'experiments' => [],
     'audiences' => [
       {

This seems to quiet rubocop.

@keppel2
Copy link

keppel2 commented Aug 11, 2021

FEATURE_ENABLED is a known issue @msohailhussain . This appears to be the only thing wrong in the FSC.

@keppel2
Copy link

keppel2 commented Aug 11, 2021

Looks good--nice job with passing the PR tests.

@keppel2
Copy link

keppel2 commented Aug 11, 2021

Fullstack-prod-suite seems stuck in travis. Another push may wake it up.

Copy link
Contributor

@zashraf1985 zashraf1985 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Added a few more minor comments. Preapproving based on the assumption that those comments will be addressed before merging

audience_id_lookup_dict[typed_audience['id']] = typed_audience['id']
end

@project_config.audiences.each do |old_audience|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Why name it old_audience. why cant you just call it audience?

@@ -111,10 +161,107 @@ def get_features_map(all_experiments_map)
'value' => variable['defaultValue']
}
)
end
end,
'experimentRules' => feature['experimentIds'].reduce([]) do |experiments_map, experiment_id|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use map here. you are transforming array into an array here, not reducing to a value or object.

Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
A couple of comments about deprecation suggested.

lib/optimizely/optimizely_config.rb Show resolved Hide resolved
config = {
'sdkKey' => @project_config.sdk_key,
'datafile' => @project_config.datafile,
'experimentsMap' => experiments_map_object,
Copy link
Contributor

@jaeopt jaeopt Aug 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a note about key-conflict issue on top of 'experimentsMap':

// This experimentsMap is for experiments of legacy projects only.
// For flag projects, experiment keys are not guaranteed to be unique
// across multiple flags, so this map may not include all experiments
// when keys conflict.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a period at the end of the first sentence - "This experimentsMap is for experiments of legacy projects only"

@keppel2 keppel2 self-requested a review August 11, 2021 22:31
Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deprecation message should be changed

Comment on lines 155 to 158
# This experimentsMap is for experiments of legacy projects only.
# For flag projects, experiment keys are not guaranteed to be unique
# across multiple flags, so this map may not include all experiments
# when keys conflict. Use experimentRules and deliveryRules instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message should be chanaged to:
"This experimentsMap is deprecated. Use experimentRules and deliveryRules instead."

The one at top level ("experimentsMap" in OptimizleyConfig) looks good.

Copy link
Contributor

@jaeopt jaeopt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@msohailhussain msohailhussain merged commit 3a30a00 into master Aug 12, 2021
@msohailhussain msohailhussain deleted the uzair/opt-config-v2 branch August 12, 2021 23:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants