Skip to content

Commit 5fd1bd3

Browse files
committed
User model conversion and tests
1 parent 829f61e commit 5fd1bd3

File tree

6 files changed

+163
-33
lines changed

6 files changed

+163
-33
lines changed

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ group :development, :test do
1515
gem 'pry-byebug'
1616
gem 'rubocop', '~> 1.57.1'
1717
end
18+
19+
gem "openfeature-sdk", "~> 0.4.0"

lib/devcycle-ruby-server-sdk.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
# APIs
2929
require 'devcycle-ruby-server-sdk/api/client'
30+
require 'devcycle-ruby-server-sdk/api/dev_cycle_provider'
3031

3132
require 'devcycle-ruby-server-sdk/localbucketing/options'
3233
require 'devcycle-ruby-server-sdk/localbucketing/local_bucketing'

lib/devcycle-ruby-server-sdk/api/client.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
module DevCycle
55
class Client
6+
attr_reader :open_feature_provider
67
def initialize(sdkKey, dvc_options = Options.new, wait_for_init = false)
78
if sdkKey.nil?
89
raise ArgumentError.new('Missing SDK key!')
@@ -26,11 +27,6 @@ def initialize(sdkKey, dvc_options = Options.new, wait_for_init = false)
2627
@open_feature_provider = DevCycleProvider.new(self)
2728
end
2829

29-
30-
def get_open_feature_provider
31-
return @open_feature_provider
32-
end
33-
3430
def close
3531
if @dvc_options.enable_cloud_bucketing
3632
@logger.info("Cloud Bucketing does not require closing.")
Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,95 @@
11
# frozen_string_literal: true
22

3-
class DevCycleProvider
3+
module DevCycle
4+
class Provider
5+
def initialize(client)
6+
unless client.is_a?(DevCycleClient) do
7+
fail ArgumentError('Client must be an instance of DevCycleClient')
8+
end
9+
@client = client
10+
end
11+
end
412

5-
def initialize(client)
6-
@client = client
7-
end
8-
def init
9-
# We handle all initialization on the DVC Client itself
10-
end
13+
def init
14+
# We handle all initialization on the DVC Client itself
15+
end
1116

12-
def shutdown
13-
@client.close()
14-
end
17+
def shutdown
18+
@client.close
19+
end
1520

16-
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
21+
def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil) end
1722

18-
end
23+
def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
24+
# Retrieve a string value from provider source
25+
end
1926

20-
def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
21-
# Retrieve a string value from provider source
22-
end
27+
def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
28+
# Retrieve a numeric value from provider source
29+
end
2330

24-
def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
25-
# Retrieve a numeric value from provider source
26-
end
31+
def fetch_integer_value(flag_key:, default_value:, evaluation_context: nil)
32+
# Retrieve a integer value from provider source
33+
end
2734

28-
def fetch_integer_value(flag_key:, default_value:, evaluation_context: nil)
29-
# Retrieve a integer value from provider source
30-
end
35+
def fetch_float_value(flag_key:, default_value:, evaluation_context: nil)
36+
# Retrieve a float value from provider source
37+
end
3138

32-
def fetch_float_value(flag_key:, default_value:, evaluation_context: nil)
33-
# Retrieve a float value from provider source
34-
end
39+
def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
40+
# Retrieve a hash value from provider source
41+
end
3542

36-
def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
37-
# Retrieve a hash value from provider source
43+
def self.user_from_openfeature_context(context)
44+
unless context.is_a?(OpenFeature::SDK::EvaluationContext)
45+
raise ArgumentError, "Invalid context type, expected OpenFeature::SDK::EvaluationContext but got #{context.class}"
46+
end
47+
args = {}
48+
if context.field('user_id')
49+
args.merge!(user_id: context.field('user_id'))
50+
elsif context.field('targeting_key')
51+
args.merge!(user_id: context.field('targeting_key'))
52+
end
53+
customData = {}
54+
privateCustomData = {}
55+
context.fields.each do |field, value|
56+
if field === 'user_id' || field === 'targeting_key'
57+
next
58+
end
59+
case field
60+
when 'email'
61+
args.merge!(email: value)
62+
when 'name'
63+
args.merge!(name: value)
64+
when 'language'
65+
args.merge!(language: value)
66+
when 'country'
67+
args.merge!(country: value)
68+
when 'appVersion'
69+
if value.is_a?(String)
70+
args.merge!(appVersion: value)
71+
end
72+
next
73+
when 'appBuild'
74+
if value.is_a?(Numeric)
75+
args.merge!(appBuild: value)
76+
end
77+
when 'customData'
78+
if value.is_a?(Hash)
79+
customData.merge!(value)
80+
end
81+
next
82+
when 'privateCustomData'
83+
if value.is_a?(Hash)
84+
privateCustomData.merge!(value)
85+
end
86+
else
87+
customData.merge!(field => value)
88+
end
89+
end
90+
args.merge!(customData: customData)
91+
args.merge!(privateCustomData: privateCustomData)
92+
User.new(**args)
93+
end
3894
end
39-
40-
4195
end

lib/devcycle-ruby-server-sdk/models/user.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
require 'date'
1414
require 'time'
1515
require 'oj'
16+
require 'open_feature/sdk'
1617

1718
module DevCycle
1819
class User

spec/devcycle_provider_spec.rb

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
context 'user_from_openfeature_context' do
6+
context 'user_id' do
7+
8+
it 'returns a user with the user_id from the context' do
9+
context = OpenFeature::SDK::EvaluationContext.new(user_id: 'user_id')
10+
user = DevCycle::Provider.user_from_openfeature_context(context)
11+
expect(user.user_id).to eq('user_id')
12+
end
13+
14+
it 'returns a user with the targeting_key from the context' do
15+
context = OpenFeature::SDK::EvaluationContext.new(targeting_key: 'targeting_key')
16+
user = DevCycle::Provider.user_from_openfeature_context(context)
17+
expect(user.user_id).to eq('targeting_key')
18+
end
19+
end
20+
context 'email' do
21+
it 'returns a user with a valid user_id and email' do
22+
context = OpenFeature::SDK::EvaluationContext.new(user_id: 'user_id', email: 'email')
23+
user = DevCycle::Provider.user_from_openfeature_context(context)
24+
expect(user.user_id).to eq('user_id')
25+
expect(user.email).to eq('email')
26+
end
27+
it 'returns a user with a valid targeting_key and email' do
28+
context = OpenFeature::SDK::EvaluationContext.new(targeting_key: 'targeting_key', email: 'email')
29+
user = DevCycle::Provider.user_from_openfeature_context(context)
30+
expect(user.user_id).to eq('targeting_key')
31+
expect(user.email).to eq('email')
32+
end
33+
end
34+
35+
context 'customData' do
36+
it 'returns a user with customData' do
37+
context = OpenFeature::SDK::EvaluationContext.new(user_id: 'user_id', customData: { 'key' => 'value' })
38+
user = DevCycle::Provider.user_from_openfeature_context(context)
39+
expect(user.user_id).to eq('user_id')
40+
expect(user.customData).to eq({ 'key' => 'value' })
41+
end
42+
end
43+
44+
context 'privateCustomData' do
45+
it 'returns a user with privateCustomData' do
46+
context = OpenFeature::SDK::EvaluationContext.new(user_id: 'user_id', privateCustomData: { 'key' => 'value' })
47+
user = DevCycle::Provider.user_from_openfeature_context(context)
48+
expect(user.user_id).to eq('user_id')
49+
expect(user.privateCustomData).to eq({ 'key' => 'value' })
50+
end
51+
end
52+
53+
context 'appVersion' do
54+
it 'returns a user with appVersion' do
55+
context = OpenFeature::SDK::EvaluationContext.new(user_id: 'user_id', appVersion: '1.0.0')
56+
user = DevCycle::Provider.user_from_openfeature_context(context)
57+
expect(user.user_id).to eq('user_id')
58+
expect(user.appVersion).to eq('1.0.0')
59+
end
60+
61+
it 'returns a user with appBuild' do
62+
context = OpenFeature::SDK::EvaluationContext.new(user_id: 'user_id', appBuild: 1)
63+
user = DevCycle::Provider.user_from_openfeature_context(context)
64+
expect(user.user_id).to eq('user_id')
65+
expect(user.appBuild).to eq(1)
66+
end
67+
end
68+
context 'randomFields' do
69+
it 'returns a user with customData fields mapped to any non-standard fields' do
70+
context = OpenFeature::SDK::EvaluationContext.new(user_id: 'user_id', randomField: 'value')
71+
user = DevCycle::Provider.user_from_openfeature_context(context)
72+
expect(user.user_id).to eq('user_id')
73+
expect(user.customData).to eq({ 'randomField' => 'value' })
74+
end
75+
end
76+
end

0 commit comments

Comments
 (0)