Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions lib/open_feature/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ defmodule OpenFeature.Client do
}

try do
before_hooks(all_hooks, hook_context, opts)
hook_context = before_hooks(all_hooks, hook_context, opts)

short_circuit_if_not_ready(client)

Expand Down Expand Up @@ -341,10 +341,19 @@ defmodule OpenFeature.Client do
defp before_hooks(hooks, hook_context, opts) do
hook_hints = Keyword.get(opts, :hook_hints, %{})

Enum.each(hooks, fn
%Hook{before: nil} -> :ok
%Hook{before: before} -> before.(hook_context, hook_hints)
end)
context =
Enum.reduce(hooks, hook_context.context, fn
%Hook{before: nil}, context ->
context

%Hook{before: before}, context ->
case before.(hook_context, hook_hints) do
data when is_map(data) -> Map.merge(context, data)
_other -> context
end
end)

Map.put(hook_context, :context, context)
end

defp after_hooks(hooks, hook_context, evaluation_details, opts) do
Expand Down
31 changes: 31 additions & 0 deletions test/unit/open_feature/client_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,37 @@ defmodule OpenFeature.ClientTest do
assert_receive :hook_called
end

test "context from before hook is carried to after hook", %{client: client} do
parent = self()
context = %{key: "value"}
key = "key"
default = true

hook = %Hook{
before: fn _hook_context, _hints ->
send(parent, :before_hook_called)
%{key: "other data"}
end,
after: fn hook_context, _details, _hints ->
assert_receive :provider_called
assert hook_context.context[:key] == "other data"
send(parent, :after_hook_called)
end
}

expect(Provider, :resolve_value, 1, fn _provider, _type, _key, _default, _context ->
assert_receive :before_hook_called
send(parent, :provider_called)
{:ok, %ResolutionDetails{value: true}}
end)

client = Client.add_hooks(client, [hook])

Client.get_boolean_value(client, key, default, context: context)

assert_receive :after_hook_called
end

test "does not resolve value if an error occurs in before hooks", %{client: client} do
parent = self()
context = %{key: "value"}
Expand Down