Skip to content

Commit e46e287

Browse files
claudeemyller
authored andcommitted
feat: add User-Agent header with SDK version
- Add user_agent/0 function to dynamically retrieve SDK version from Application.spec - Format: flagsmith-elixir-sdk/<version> or flagsmith-elixir-sdk/unknown as fallback - Add user_agent_middleware/0 to inject User-Agent header in all HTTP requests - Add comprehensive tests for User-Agent header functionality - Follows the pattern established in Go and Java Flagsmith SDKs Co-authored-by: Evandro Myller <evandro.myller@flagsmith.com> Signed-off-by: Evandro Myller <evandro.myller@flagsmith.com> Fixes #49
1 parent 587d126 commit e46e287

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

lib/flagsmith_client.ex

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ defmodule Flagsmith.Client do
88
@type tesla_header_list :: [{String.t(), String.t()}]
99
@type config_or_env :: Configuration.t() | Keyword.t() | Schemas.Environment.t()
1010

11+
@doc false
12+
@spec user_agent() :: String.t()
13+
def user_agent do
14+
case Application.spec(:flagsmith_engine, :vsn) do
15+
nil -> "flagsmith-elixir-sdk/unknown"
16+
vsn -> "flagsmith-elixir-sdk/#{vsn}"
17+
end
18+
end
19+
1120
@doc """
1221
Create a `t:Flagsmith.Configuration.t/0` struct with the desired settings to use
1322
in requests.
@@ -31,6 +40,7 @@ defmodule Flagsmith.Client do
3140
Tesla.client([
3241
base_url_middleware(api_url),
3342
auth_middleware(environment_key),
43+
user_agent_middleware(),
3444
Tesla.Middleware.JSON,
3545
{Tesla.Middleware.Retry, max_retries: retries},
3646
{Tesla.Middleware.Headers, custom_headers},
@@ -394,6 +404,12 @@ defmodule Flagsmith.Client do
394404
def auth_middleware(environment_key),
395405
do: {Tesla.Middleware.Headers, auth_header(environment_key)}
396406

407+
@doc false
408+
@spec user_agent_middleware() ::
409+
{Tesla.Middleware.Headers, tesla_header_list()}
410+
def user_agent_middleware(),
411+
do: {Tesla.Middleware.Headers, [{"user-agent", user_agent()}]}
412+
397413
@doc false
398414
@spec base_url_middleware(base_url :: String.t()) ::
399415
{Tesla.Middleware.BaseUrl, String.t()}

test/flagsmith_client_test.exs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,4 +437,37 @@ defmodule Flagsmith.Client.Test do
437437
Flagsmith.Client.get_flag(new_config, "some_flag")
438438
end
439439
end
440+
441+
describe "User-Agent header" do
442+
test "user_agent/0 returns version from application spec" do
443+
user_agent = Flagsmith.Client.user_agent()
444+
445+
# Should match the format "flagsmith-elixir-sdk/<version>" or "flagsmith-elixir-sdk/unknown"
446+
assert user_agent =~ ~r/^flagsmith-elixir-sdk\/.+$/
447+
448+
# In test environment, it should return the actual version from mix.exs
449+
# or "unknown" if not available
450+
case Application.spec(:flagsmith_engine, :vsn) do
451+
nil -> assert user_agent == "flagsmith-elixir-sdk/unknown"
452+
vsn -> assert user_agent == "flagsmith-elixir-sdk/#{vsn}"
453+
end
454+
end
455+
456+
test "HTTP client includes User-Agent header in requests", %{config: config} do
457+
expect(Tesla.Adapter.Mock, :call, fn tesla_env, _options ->
458+
# Assert that the User-Agent header is present
459+
user_agent_header = Enum.find(tesla_env.headers, fn {header, _} ->
460+
header == "user-agent"
461+
end)
462+
463+
assert user_agent_header != nil, "User-Agent header should be present"
464+
{_header, user_agent_value} = user_agent_header
465+
assert user_agent_value =~ ~r/^flagsmith-elixir-sdk\/.+$/
466+
467+
{:ok, %Tesla.Env{status: 200, body: Test.Generators.map_env()}}
468+
end)
469+
470+
Flagsmith.Client.get_environment(config)
471+
end
472+
end
440473
end

0 commit comments

Comments
 (0)