Skip to content

Commit 05678b4

Browse files
committed
chore: Add hook support to contract tests (#257)
1 parent 3cf16eb commit 05678b4

File tree

5 files changed

+86
-9
lines changed

5 files changed

+86
-9
lines changed

contract-tests/client_entity.rb

+7
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

+68
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 evaluation_series_context [LaunchDarkly::Interfaces::Hooks::EvaluationSeriesContext]
24+
# @param data [Hash]
25+
#
26+
def before_evaluation(evaluation_series_context, data)
27+
payload = {
28+
evaluationSeriesContext: {
29+
flagKey: evaluation_series_context.key,
30+
context: @context_filter.filter(evaluation_series_context.context),
31+
defaultValue: evaluation_series_context.default_value,
32+
method: evaluation_series_context.method,
33+
},
34+
evaluationSeriesData: 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 evaluation_series_context [LaunchDarkly::Interfaces::Hooks::EvaluationSeriesContext]
45+
# @param data [Hash]
46+
# @param detail [LaunchDarkly::EvaluationDetail]
47+
#
48+
def after_evaluation(evaluation_series_context, data, detail)
49+
payload = {
50+
evaluationSeriesContext: {
51+
flagKey: evaluation_series_context.key,
52+
context: @context_filter.filter(evaluation_series_context.context),
53+
defaultValue: evaluation_series_context.default_value,
54+
method: evaluation_series_context.method,
55+
},
56+
evaluationSeriesData: 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

+1
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

+5-5
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ def metadata
916916
# @return [Hash] Data to use when executing the next state of the hook in the evaluation series.
917917
#
918918
def before_evaluation(evaluation_series_context, data)
919-
{}
919+
data
920920
end
921921

922922
#
@@ -953,19 +953,19 @@ def initialize(name)
953953
class EvaluationSeriesContext
954954
attr_reader :key
955955
attr_reader :context
956-
attr_reader :value
956+
attr_reader :default_value
957957
attr_reader :method
958958

959959
#
960960
# @param key [String]
961961
# @param context [LaunchDarkly::LDContext]
962-
# @param value [any]
962+
# @param default_value [any]
963963
# @param method [Symbol]
964964
#
965-
def initialize(key, context, value, method)
965+
def initialize(key, context, default_value, method)
966966
@key = key
967967
@context = context
968-
@value = value
968+
@default_value = default_value
969969
@method = method
970970
end
971971
end

lib/ldclient-rb/ldclient.rb

+5-4
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ def variation(key, context, default)
245245
# @return [EvaluationDetail] an object describing the result
246246
#
247247
def variation_detail(key, context, default)
248+
context = Impl::Context::make_context(context)
248249
detail, _, _ = evaluate_with_hooks(key, context, default, :variation_detail) do
249250
evaluate_internal(key, context, default, true)
250251
end
@@ -264,8 +265,8 @@ def variation_detail(key, context, default)
264265
# ```
265266
#
266267
# @param key [String]
267-
# @param context [String]
268-
# @param default [String]
268+
# @param context [LDContext]
269+
# @param default [any]
269270
# @param method [Symbol]
270271
# @param &block [#call] Implicit passed block
271272
#
@@ -633,14 +634,15 @@ def create_default_data_source(sdk_key, config, diagnostic_accumulator)
633634
# @return [Array<EvaluationDetail, [LaunchDarkly::Impl::Model::FeatureFlag, nil], [String, nil]>]
634635
#
635636
def variation_with_flag(key, context, default)
637+
context = Impl::Context::make_context(context)
636638
evaluate_with_hooks(key, context, default, :variation_detail) do
637639
evaluate_internal(key, context, default, false)
638640
end
639641
end
640642

641643
#
642644
# @param key [String]
643-
# @param context [Hash, LDContext]
645+
# @param context [LDContext]
644646
# @param default [Object]
645647
# @param with_reasons [Boolean]
646648
#
@@ -657,7 +659,6 @@ def evaluate_internal(key, context, default, with_reasons)
657659
return detail, nil, "no context provided"
658660
end
659661

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

0 commit comments

Comments
 (0)