rox-rollout 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +45 -0
  3. data/.gitignore +8 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE +50 -0
  6. data/README_DEVELOP.md +19 -0
  7. data/Rakefile +16 -0
  8. data/_archive/.document +5 -0
  9. data/_archive/.rspec +1 -0
  10. data/_archive/Gemfile +15 -0
  11. data/_archive/Gemfile.lock +87 -0
  12. data/_archive/README.md +32 -0
  13. data/_archive/README.rdoc +19 -0
  14. data/_archive/Rakefile +50 -0
  15. data/_archive/lib/expr_function_definition.rb +52 -0
  16. data/_archive/lib/function_definition.rb +48 -0
  17. data/_archive/lib/function_token.rb +12 -0
  18. data/_archive/lib/object_extends.rb +12 -0
  19. data/_archive/lib/ruby_interpreter.rb +292 -0
  20. data/_archive/lib/stack.rb +48 -0
  21. data/_archive/lib/string_extends.rb +14 -0
  22. data/_archive/spec/ruby_interpreter_spec.rb +203 -0
  23. data/_archive/spec/spec_helper.rb +30 -0
  24. data/_archive/spec/stack_spec.rb +77 -0
  25. data/bin/console +14 -0
  26. data/bin/setup +8 -0
  27. data/e2e/container.rb +38 -0
  28. data/e2e/custom_props.rb +55 -0
  29. data/e2e/rox_e2e_test.rb +159 -0
  30. data/e2e/test_vars.rb +24 -0
  31. data/lib/rox.rb +5 -0
  32. data/lib/rox/core/client/buid.rb +82 -0
  33. data/lib/rox/core/client/device_properties.rb +45 -0
  34. data/lib/rox/core/client/internal_flags.rb +20 -0
  35. data/lib/rox/core/client/sdk_settings.rb +5 -0
  36. data/lib/rox/core/configuration/configuration.rb +5 -0
  37. data/lib/rox/core/configuration/configuration_fetched_args.rb +23 -0
  38. data/lib/rox/core/configuration/configuration_fetched_invoker.rb +37 -0
  39. data/lib/rox/core/configuration/configuration_parser.rb +85 -0
  40. data/lib/rox/core/configuration/fetcher_error.rb +13 -0
  41. data/lib/rox/core/configuration/fetcher_status.rb +10 -0
  42. data/lib/rox/core/configuration/models/experiment_model.rb +5 -0
  43. data/lib/rox/core/configuration/models/target_group_model.rb +5 -0
  44. data/lib/rox/core/consts/build.rb +8 -0
  45. data/lib/rox/core/consts/environment.rb +42 -0
  46. data/lib/rox/core/consts/property_type.rb +29 -0
  47. data/lib/rox/core/context/merged_context.rb +16 -0
  48. data/lib/rox/core/core.rb +131 -0
  49. data/lib/rox/core/entities/flag.rb +26 -0
  50. data/lib/rox/core/entities/flag_setter.rb +39 -0
  51. data/lib/rox/core/entities/variant.rb +56 -0
  52. data/lib/rox/core/impression/impression_args.rb +5 -0
  53. data/lib/rox/core/impression/impression_invoker.rb +41 -0
  54. data/lib/rox/core/impression/models/experiment.rb +14 -0
  55. data/lib/rox/core/impression/models/reporting_value.rb +5 -0
  56. data/lib/rox/core/logging/logging.rb +17 -0
  57. data/lib/rox/core/logging/no_op_logger.rb +11 -0
  58. data/lib/rox/core/network/configuration_fetch_result.rb +5 -0
  59. data/lib/rox/core/network/configuration_fetcher.rb +38 -0
  60. data/lib/rox/core/network/configuration_fetcher_base.rb +25 -0
  61. data/lib/rox/core/network/configuration_fetcher_roxy.rb +29 -0
  62. data/lib/rox/core/network/configuration_source.rb +9 -0
  63. data/lib/rox/core/network/request.rb +46 -0
  64. data/lib/rox/core/network/request_configuration_builder.rb +48 -0
  65. data/lib/rox/core/network/request_data.rb +5 -0
  66. data/lib/rox/core/network/response.rb +16 -0
  67. data/lib/rox/core/properties/custom_property.rb +18 -0
  68. data/lib/rox/core/properties/custom_property_type.rb +18 -0
  69. data/lib/rox/core/properties/device_property.rb +11 -0
  70. data/lib/rox/core/register/registerer.rb +35 -0
  71. data/lib/rox/core/reporting/error_reporter.rb +152 -0
  72. data/lib/rox/core/repositories/custom_property_repository.rb +61 -0
  73. data/lib/rox/core/repositories/experiment_repository.rb +21 -0
  74. data/lib/rox/core/repositories/flag_repository.rb +49 -0
  75. data/lib/rox/core/repositories/roxx/experiments_extensions.rb +82 -0
  76. data/lib/rox/core/repositories/roxx/properties_extensions.rb +26 -0
  77. data/lib/rox/core/repositories/target_group_repository.rb +17 -0
  78. data/lib/rox/core/roxx/core_stack.rb +22 -0
  79. data/lib/rox/core/roxx/evaluation_result.rb +28 -0
  80. data/lib/rox/core/roxx/node.rb +11 -0
  81. data/lib/rox/core/roxx/parser.rb +143 -0
  82. data/lib/rox/core/roxx/regular_expression_extensions.rb +33 -0
  83. data/lib/rox/core/roxx/string_tokenizer.rb +68 -0
  84. data/lib/rox/core/roxx/symbols.rb +14 -0
  85. data/lib/rox/core/roxx/token_type.rb +30 -0
  86. data/lib/rox/core/roxx/tokenized_expression.rb +119 -0
  87. data/lib/rox/core/roxx/value_compare_extensions.rb +137 -0
  88. data/lib/rox/core/security/signature_verifier.rb +18 -0
  89. data/lib/rox/core/utils/periodic_task.rb +12 -0
  90. data/lib/rox/core/utils/type_utils.rb +9 -0
  91. data/lib/rox/server/client/sdk_settings.rb +5 -0
  92. data/lib/rox/server/client/server_properties.rb +20 -0
  93. data/lib/rox/server/flags/rox_flag.rb +19 -0
  94. data/lib/rox/server/flags/rox_variant.rb +8 -0
  95. data/lib/rox/server/logging/server_logger.rb +35 -0
  96. data/lib/rox/server/rox_options.rb +27 -0
  97. data/lib/rox/server/rox_server.rb +83 -0
  98. data/lib/rox/version.rb +3 -0
  99. data/rox.gemspec +29 -0
  100. metadata +184 -0
@@ -0,0 +1,30 @@
1
+ require 'simplecov'
2
+
3
+ module SimpleCov::Configuration
4
+ def clean_filters
5
+ @filters = []
6
+ end
7
+ end
8
+
9
+ SimpleCov.configure do
10
+ clean_filters
11
+ load_adapter 'test_frameworks'
12
+ end
13
+
14
+ ENV["COVERAGE"] && SimpleCov.start do
15
+ add_filter "/.rvm/"
16
+ end
17
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+
20
+ require 'rspec'
21
+ require 'ruby_interpreter'
22
+ require 'stack'
23
+
24
+ # Requires supporting files with custom matchers and macros, etc,
25
+ # in ./support/ and its subdirectories.
26
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
27
+
28
+ RSpec.configure do |config|
29
+
30
+ end
@@ -0,0 +1,77 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'Stack' do
4
+ let(:stack) { Stack.new }
5
+
6
+ it 'should push item' do
7
+ stack.push 'a'
8
+ stack.push 'b'
9
+ expect(stack.to_s).to eq('a,b')
10
+ end
11
+
12
+ it 'should pop item' do
13
+ stack.push 'a'
14
+ stack.push 'b'
15
+ item = stack.pop
16
+
17
+ expect(stack.to_s).to eq('a')
18
+ expect(item).to eq('b')
19
+ end
20
+
21
+ it 'should raise exception on poping from emtpy stack' do
22
+ stack.clear
23
+ expect{ stack.pop }.to raise_error(Stack::EmptyError)
24
+ end
25
+
26
+ it 'can be cleared' do
27
+ stack.push 'a'
28
+ stack.clear
29
+ expect(stack.empty?).to eq(true)
30
+ end
31
+
32
+ it 'to_s display valid' do
33
+ stack.push 'a'
34
+ stack.push 'b'
35
+ stack.push 'c'
36
+ expect(stack.to_s).to eq('a,b,c')
37
+ end
38
+
39
+ it 'empty? handles' do
40
+ stack.clear
41
+ expect(stack.empty?).to eq(true)
42
+
43
+ stack.push 'a'
44
+ expect(stack.empty?).to eq(false)
45
+ end
46
+
47
+ it 'can return size' do
48
+ stack.clear
49
+ expect(stack.size).to eq(0)
50
+
51
+ stack.push 'a'
52
+ expect(stack.size).to eq(1)
53
+ end
54
+
55
+ it 'can poke at specific index' do
56
+ stack.push 'a'
57
+ stack.push 'b'
58
+ stack.poke 'c', 0
59
+ expect(stack.to_s).to eq('c,b')
60
+ end
61
+
62
+ it 'can insert value at index' do
63
+ stack.push 'a'
64
+ stack.push 'b'
65
+ stack.insert 'c', 1
66
+
67
+ expect(stack.to_s).to eq('a,c,b')
68
+ end
69
+
70
+ it 'can invert order of stack' do
71
+ stack.push 'a'
72
+ stack.push 'b'
73
+ stack.invert
74
+
75
+ expect(stack.to_s).to eq('b,a')
76
+ end
77
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rox"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/e2e/container.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'rox/server/flags/rox_flag'
2
+ require 'rox/server/flags/rox_variant'
3
+
4
+ module E2E
5
+ class Container
6
+ attr_accessor :simple_flag, :simple_flag_overwritten
7
+ attr_accessor :flag_for_impression, :flag_for_impression_with_experiment_and_context
8
+ attr_accessor :flag_custom_properties
9
+ attr_accessor :flag_target_groups_all, :flag_target_groups_any, :flag_target_groups_none
10
+ attr_accessor :variant_with_context
11
+ attr_accessor :variant, :variant_overwritten
12
+ attr_accessor :flag_for_dependency, :flag_colors_for_dependency, :flag_dependent, :flag_color_dependent_with_context
13
+
14
+ def initialize
15
+ @simple_flag = Rox::Server::RoxFlag.new(true)
16
+ @simple_flag_overwritten = Rox::Server::RoxFlag.new(true)
17
+
18
+ @flag_for_impression = Rox::Server::RoxFlag.new(false)
19
+ @flag_for_impression_with_experiment_and_context = Rox::Server::RoxFlag.new(false)
20
+
21
+ @flag_custom_properties = Rox::Server::RoxFlag.new
22
+
23
+ @flag_target_groups_all = Rox::Server::RoxFlag.new
24
+ @flag_target_groups_any = Rox::Server::RoxFlag.new
25
+ @flag_target_groups_none = Rox::Server::RoxFlag.new
26
+
27
+ @variant_with_context = Rox::Server::RoxVariant.new('red', ['red', 'blue', 'green'])
28
+
29
+ @variant = Rox::Server::RoxVariant.new('red', ['red', 'blue', 'green'])
30
+ @variant_overwritten = Rox::Server::RoxVariant.new('red', ['red', 'blue', 'green'])
31
+
32
+ @flag_for_dependency = Rox::Server::RoxFlag.new(false)
33
+ @flag_colors_for_dependency = Rox::Server::RoxVariant.new('White', ['White', 'Blue', 'Green', 'Yellow'])
34
+ @flag_dependent = Rox::Server::RoxFlag.new(false)
35
+ @flag_color_dependent_with_context = Rox::Server::RoxVariant.new('White', ['White', 'Blue', 'Green', 'Yellow'])
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ module E2E
2
+ class CustomProps
3
+ def self.create_custom_props
4
+ Rox::Server::RoxServer.set_custom_string_property('string_prop1', 'Hello')
5
+ Rox::Server::RoxServer.set_custom_string_property('string_prop2') do |context|
6
+ TestVars.is_computed_string_prop_called = true
7
+ 'World'
8
+ end
9
+
10
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop1', true)
11
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop2') do |context|
12
+ TestVars.is_computed_boolean_prop_called = true
13
+ false
14
+ end
15
+
16
+ Rox::Server::RoxServer.set_custom_int_property('int_prop1', 6)
17
+ Rox::Server::RoxServer.set_custom_int_property('int_prop2') do |context|
18
+ TestVars.is_computed_int_prop_called = true
19
+ 28
20
+ end
21
+
22
+ Rox::Server::RoxServer.set_custom_float_property('float_prop1', 3.14)
23
+ Rox::Server::RoxServer.set_custom_float_property('float_prop2') do |context|
24
+ TestVars.is_computed_float_prop_called = true
25
+ 1.618
26
+ end
27
+
28
+ Rox::Server::RoxServer.set_custom_semver_property('smvr_prop1', '9.11.2001')
29
+ Rox::Server::RoxServer.set_custom_semver_property('smvr_prop2') do |context|
30
+ TestVars.is_computed_semver_prop_called = true
31
+ '20.7.1969'
32
+ end
33
+
34
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_variant') do |context|
35
+ context['isDuckAndCover']
36
+ end
37
+
38
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand1') do |context|
39
+ TestVars.target_group1
40
+ end
41
+
42
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_operand2') do |context|
43
+ TestVars.target_group2
44
+ end
45
+
46
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_dependency') do |context|
47
+ TestVars.is_prop_for_target_group_for_dependency
48
+ end
49
+
50
+ Rox::Server::RoxServer.set_custom_boolean_property('bool_prop_target_group_for_variant_dependency') do |context|
51
+ context['isDuckAndCover']
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,159 @@
1
+ require "minitest/autorun"
2
+ require 'rox/server/rox_options'
3
+ require 'rox/server/rox_server'
4
+ require_relative 'container'
5
+ require_relative 'custom_props'
6
+ require_relative 'test_vars'
7
+
8
+ module E2E
9
+ class Logger
10
+ def debug(message, ex = nil)
11
+ puts 'Before Rox.Setup', message
12
+ end
13
+
14
+ def error(message, ex = nil)
15
+ puts 'Before Rox.Setup', message
16
+ end
17
+
18
+ def warn(message, ex = nil)
19
+ puts 'Before Rox.Setup', message
20
+ end
21
+ end
22
+
23
+ class RoxE2ETest < Minitest::Test
24
+ ENV['ROLLOUT_MODE'] = 'QA'
25
+
26
+ configuration_fetched_handler = proc do |e|
27
+ if !e.nil? && e.fetcher_status == Rox::Core::FetcherStatus::APPLIED_FROM_NETWORK
28
+ TestVars.configuration_fetched_count += 1
29
+ end
30
+ end
31
+
32
+ impression_handler = proc do |e|
33
+ if !e.nil? && !e.reporting_value.nil?
34
+ TestVars.is_impression_raised = true if e.reporting_value.name == 'flag_for_impression'
35
+ end
36
+ TestVars.impression_returned_args = e
37
+ end
38
+
39
+ option = Rox::Server::RoxOptions.new(
40
+ configuration_fetched_handler: configuration_fetched_handler,
41
+ impression_handler: impression_handler,
42
+ dev_mode_key: '67e39e708444aa953414e444',
43
+ logger: Logger.new
44
+ )
45
+
46
+ @@container = Container.new
47
+ Rox::Server::RoxServer.register('', @@container)
48
+ CustomProps.create_custom_props
49
+ Rox::Server::RoxServer.setup('5b82864ebc3aec37aff1fdd5', option).join
50
+
51
+ def test_simple_flag
52
+ assert_equal true, @@container.simple_flag.enabled?
53
+ end
54
+
55
+ def test_simple_flag_overwritten
56
+ assert_equal false, @@container.simple_flag_overwritten.enabled?
57
+ end
58
+
59
+ def test_variant
60
+ assert_equal 'red', @@container.variant.value
61
+ end
62
+
63
+ def test_variant_overwritten
64
+ assert_equal 'green', @@container.variant_overwritten.value
65
+ end
66
+
67
+ def test_all_custom_properties
68
+ assert_equal true, @@container.flag_custom_properties.enabled?
69
+
70
+ assert_equal true, TestVars.is_computed_boolean_prop_called
71
+ assert_equal true, TestVars.is_computed_float_prop_called
72
+ assert_equal true, TestVars.is_computed_int_prop_called
73
+ assert_equal true, TestVars.is_computed_semver_prop_called
74
+ assert_equal true, TestVars.is_computed_string_prop_called
75
+ end
76
+
77
+ def test_fetch_within_timeout
78
+ number_of_config_fetches = TestVars.configuration_fetched_count
79
+ timeout = 5
80
+ thread = Rox::Server::RoxServer.fetch
81
+ res = thread.join(timeout)
82
+
83
+ if res.nil?
84
+ flunk('timeout')
85
+ else
86
+ assert number_of_config_fetches < TestVars.configuration_fetched_count
87
+ end
88
+ end
89
+
90
+ def test_variant_with_context
91
+ some_positive_context = {'isDuckAndCover' => true}
92
+ some_negative_context = {'isDuckAndCover' => false}
93
+
94
+ assert_equal 'red', @@container.variant_with_context.value
95
+
96
+ assert_equal 'blue', @@container.variant_with_context.value(some_positive_context)
97
+ assert_equal 'red', @@container.variant_with_context.value(some_negative_context)
98
+ end
99
+
100
+ def test_target_groups_all_any_none
101
+ TestVars.target_group1 = true
102
+ TestVars.target_group2 = true
103
+
104
+ assert_equal true, @@container.flag_target_groups_all.enabled?
105
+ assert_equal true, @@container.flag_target_groups_any.enabled?
106
+ assert_equal false, @@container.flag_target_groups_none.enabled?
107
+
108
+ TestVars.target_group1 = false
109
+ assert_equal false, @@container.flag_target_groups_all.enabled?
110
+ assert_equal true, @@container.flag_target_groups_any.enabled?
111
+ assert_equal false, @@container.flag_target_groups_none.enabled?
112
+
113
+ TestVars.target_group2 = false
114
+ assert_equal false, @@container.flag_target_groups_all.enabled?
115
+ assert_equal false, @@container.flag_target_groups_any.enabled?
116
+ assert_equal true, @@container.flag_target_groups_none.enabled?
117
+ end
118
+
119
+ def test_impression_handler
120
+ @@container.flag_for_impression.enabled?
121
+ assert_equal true, TestVars.is_impression_raised
122
+ TestVars.is_impression_raised = false
123
+
124
+ context = {'var' => 'val'}
125
+ flag_impression_value = @@container.flag_for_impression_with_experiment_and_context.enabled?(context)
126
+ refute_nil TestVars.impression_returned_args
127
+ refute_nil TestVars.impression_returned_args.reporting_value
128
+ assert_equal 'true', TestVars.impression_returned_args.reporting_value.value
129
+ assert_equal true, flag_impression_value
130
+ assert_equal 'flag_for_impression_with_experiment_and_context', TestVars.impression_returned_args.reporting_value.name
131
+
132
+ refute_nil TestVars.impression_returned_args
133
+ refute_nil TestVars.impression_returned_args.experiment
134
+ assert_equal '5b8f85ecbc3aec37aff20841', TestVars.impression_returned_args.experiment.identifier
135
+ assert_equal 'flag for impression with experiment and context', TestVars.impression_returned_args.experiment.name
136
+
137
+ assert_equal 'val', TestVars.impression_returned_args.context['var']
138
+ end
139
+
140
+ def test_flag_dependency
141
+ TestVars.is_prop_for_target_group_for_dependency = true
142
+ assert_equal true, @@container.flag_for_dependency.enabled?
143
+ assert_equal false, @@container.flag_dependent.enabled?
144
+
145
+ TestVars.is_prop_for_target_group_for_dependency = false
146
+ assert_equal true, @@container.flag_dependent.enabled?
147
+ assert_equal false, @@container.flag_for_dependency.enabled?
148
+ end
149
+
150
+ def test_variant_dependency_with_context
151
+ some_positive_context = {'isDuckAndCover' => true}
152
+ some_negative_context = {'isDuckAndCover' => false}
153
+
154
+ assert_equal 'White', @@container.flag_color_dependent_with_context.value
155
+ assert_equal 'White', @@container.flag_color_dependent_with_context.value(some_negative_context)
156
+ assert_equal 'Yellow', @@container.flag_color_dependent_with_context.value(some_positive_context)
157
+ end
158
+ end
159
+ end
data/e2e/test_vars.rb ADDED
@@ -0,0 +1,24 @@
1
+ module E2E
2
+ module TestVars
3
+ class << self
4
+ attr_accessor :is_computed_boolean_prop_called, :is_computed_string_prop_called, :is_computed_int_prop_called, :is_computed_float_prop_called, :is_computed_semver_prop_called
5
+ attr_accessor :target_group1, :target_group2
6
+ attr_accessor :is_impression_raised, :is_prop_for_target_group_for_dependency
7
+
8
+ attr_accessor :configuration_fetched_count, :impression_returned_args
9
+ end
10
+
11
+ @is_computed_boolean_prop_called = false
12
+ @is_computed_string_prop_called = false
13
+ @is_computed_int_prop_called = false
14
+ @is_computed_float_prop_called = false
15
+ @is_computed_semver_prop_called = false
16
+ @target_group1 = false
17
+ @target_group2 = false
18
+ @is_impression_raised = false
19
+ @is_prop_for_target_group_for_dependency = false
20
+
21
+ @configuration_fetched_count = 0
22
+ @impression_returned_args = nil
23
+ end
24
+ end
data/lib/rox.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'rox/version'
2
+
3
+ module Rox
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,82 @@
1
+ require 'digest'
2
+ require 'json'
3
+ require 'rox/core/consts/property_type'
4
+
5
+ module Rox
6
+ module Core
7
+ class BUID
8
+ BUID_GENERATORS = [
9
+ PropertyType::PLATFORM,
10
+ PropertyType::APP_KEY,
11
+ PropertyType::LIB_VERSION,
12
+ PropertyType::API_VERSION,
13
+ PropertyType::CUSTOM_PROPERTIES,
14
+ PropertyType::FEATURE_FLAGS,
15
+ PropertyType::REMOTE_VARIABLES
16
+ ].freeze
17
+
18
+ def initialize(sdk_settings, device_properties, flag_repository, custom_property_repository)
19
+ @sdk_settings = sdk_settings
20
+ @device_properties = device_properties
21
+ @flag_repository = flag_repository
22
+ @custom_property_repository = custom_property_repository
23
+ @buid = nil
24
+ end
25
+
26
+ def value
27
+ properties = @device_properties.all_properties
28
+ values = []
29
+ BUID::BUID_GENERATORS.each do |pt, _|
30
+ values << properties[pt.name] if properties.include?(pt.name)
31
+ end
32
+
33
+ values << serialize_feature_flags
34
+ values << serialize_custom_properties
35
+
36
+ hash = Digest::MD5.hexdigest(values.join('|'))
37
+
38
+ @buid = hash.upcase
39
+ end
40
+
41
+ def query_string_parts
42
+ generators = BUID::BUID_GENERATORS.map {|pt, _| pt.name}
43
+
44
+ {
45
+ PropertyType::BUID.name => value,
46
+ PropertyType::BUID_GENERATORS_LIST.name => generators.join(','),
47
+ PropertyType::FEATURE_FLAGS.name => serialize_feature_flags,
48
+ PropertyType::REMOTE_VARIABLES.name => '[]',
49
+ PropertyType::CUSTOM_PROPERTIES.name => serialize_custom_properties,
50
+ }
51
+ end
52
+
53
+ def serialize_feature_flags
54
+ flags = []
55
+ @flag_repository.all_flags.each do |f|
56
+ flags << {
57
+ name: f.name,
58
+ defaultValue: f.default_value,
59
+ options: f.options
60
+ }
61
+ end
62
+ JSON.dump(flags)
63
+ end
64
+
65
+ def serialize_custom_properties
66
+ properties = []
67
+ @custom_property_repository.all_custom_properties.each do |p|
68
+ properties << {
69
+ name: p.name,
70
+ type: p.type.type,
71
+ externalType: p.type.external_type
72
+ }
73
+ end
74
+ JSON.dump(properties)
75
+ end
76
+
77
+ def to_s
78
+ @buid
79
+ end
80
+ end
81
+ end
82
+ end