Skip to content

Commit bdeea90

Browse files
committed
chore: Add hook support to contract tests
1 parent 2459500 commit bdeea90

File tree

5 files changed

+85
-8
lines changed

5 files changed

+85
-8
lines changed

contract-tests/client_entity.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require 'net/http'
44
require 'launchdarkly-server-sdk'
55
require './big_segment_store_fixture'
6+
require './hook'
67
require 'http'
78

89
class ClientEntity
@@ -62,6 +63,12 @@ def initialize(log, config)
6263
}
6364
end
6465

66+
if config[:hooks]
67+
opts[:hooks] = config[:hooks][:hooks].map do |hook|
68+
Hook.new(hook[:name], hook[:callbackUri], hook[:data] || {})
69+
end
70+
end
71+
6572
startWaitTimeMs = config[:startWaitTimeMs] || 5_000
6673

6774
@client = LaunchDarkly::LDClient.new(

contract-tests/hook.rb

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
require 'ldclient-rb'
2+
3+
class Hook
4+
include LaunchDarkly::Interfaces::Hooks::Hook
5+
6+
#
7+
# @param name [String]
8+
# @param callback_uri [String]
9+
# @param data [Hash]
10+
#
11+
def initialize(name, callback_uri, data)
12+
@metadata = LaunchDarkly::Interfaces::Hooks::Metadata.new(name)
13+
@callback_uri = callback_uri
14+
@data = data
15+
@context_filter = LaunchDarkly::Impl::ContextFilter.new(false, [])
16+
end
17+
18+
def metadata
19+
@metadata
20+
end
21+
22+
#
23+
# @param hook_context [LaunchDarkly::Interfaces::Hooks::EvaluationContext]
24+
# @param data [Hash]
25+
#
26+
def before_evaluation(hook_context, data)
27+
payload = {
28+
evaluationHookContext: {
29+
flagKey: hook_context.key,
30+
context: @context_filter.filter(hook_context.context),
31+
defaultValue: hook_context.default_value,
32+
method: hook_context.method,
33+
},
34+
evaluationHookData: data,
35+
stage: 'beforeEvaluation',
36+
}
37+
result = HTTP.post(@callback_uri, json: payload)
38+
39+
(data || {}).merge(@data[:beforeEvaluation] || {})
40+
end
41+
42+
43+
#
44+
# @param hook_context [LaunchDarkly::Interfaces::Hooks::EvaluationContext]
45+
# @param data [Hash]
46+
# @param detail [LaunchDarkly::EvaluationDetail]
47+
#
48+
def after_evaluation(hook_context, data, detail)
49+
payload = {
50+
evaluationHookContext: {
51+
flagKey: hook_context.key,
52+
context: @context_filter.filter(hook_context.context),
53+
defaultValue: hook_context.default_value,
54+
method: hook_context.method,
55+
},
56+
evaluationHookData: data,
57+
evaluationDetail: {
58+
value: detail.value,
59+
variationIndex: detail.variation_index,
60+
reason: detail.reason,
61+
},
62+
stage: 'afterEvaluation',
63+
}
64+
HTTP.post(@callback_uri, json: payload)
65+
66+
(data || {}).merge(@data[:afterEvaluation] || {})
67+
end
68+
end

contract-tests/service.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
'polling-gzip',
4040
'inline-context',
4141
'anonymous-redaction',
42+
'evaluation-hooks',
4243
],
4344
}.to_json
4445
end

lib/ldclient-rb/interfaces.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -952,19 +952,19 @@ def initialize(name)
952952
class EvaluationContext
953953
attr_reader :key
954954
attr_reader :context
955-
attr_reader :value
955+
attr_reader :default_value
956956
attr_reader :method
957957

958958
#
959959
# @param key [String]
960960
# @param context [LaunchDarkly::LDContext]
961-
# @param value [any]
961+
# @param default_value [any]
962962
# @param method [Symbol]
963963
#
964-
def initialize(key, context, value, method)
964+
def initialize(key, context, default_value, method)
965965
@key = key
966966
@context = context
967-
@value = value
967+
@default_value = default_value
968968
@method = method
969969
end
970970
end

lib/ldclient-rb/ldclient.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ def variation(key, context, default)
244244
# @return [EvaluationDetail] an object describing the result
245245
#
246246
def variation_detail(key, context, default)
247+
context = Impl::Context::make_context(context)
247248
detail, _, _ = evaluate_with_hooks(key, context, default, :variation_detail) do
248249
evaluate_internal(key, context, default, true)
249250
end
@@ -263,8 +264,8 @@ def variation_detail(key, context, default)
263264
# ```
264265
#
265266
# @param key [String]
266-
# @param context [String]
267-
# @param default [String]
267+
# @param context [LDContext]
268+
# @param default [any]
268269
# @param method [Symbol]
269270
# @param &block [#call] Implicit passed block
270271
#
@@ -632,14 +633,15 @@ def create_default_data_source(sdk_key, config, diagnostic_accumulator)
632633
# @return [Array<EvaluationDetail, [LaunchDarkly::Impl::Model::FeatureFlag, nil], [String, nil]>]
633634
#
634635
def variation_with_flag(key, context, default)
636+
context = Impl::Context::make_context(context)
635637
evaluate_with_hooks(key, context, default, :variation_detail) do
636638
evaluate_internal(key, context, default, false)
637639
end
638640
end
639641

640642
#
641643
# @param key [String]
642-
# @param context [Hash, LDContext]
644+
# @param context [LDContext]
643645
# @param default [Object]
644646
# @param with_reasons [Boolean]
645647
#
@@ -656,7 +658,6 @@ def evaluate_internal(key, context, default, with_reasons)
656658
return detail, nil, "no context provided"
657659
end
658660

659-
context = Impl::Context::make_context(context)
660661
unless context.valid?
661662
@config.logger.error { "[LDClient] Context was invalid for evaluation of flag '#{key}' (#{context.error}); returning default value" }
662663
detail = Evaluator.error_result(EvaluationReason::ERROR_USER_NOT_SPECIFIED, default)

0 commit comments

Comments
 (0)