diff --git a/lib/flagsmith_client.ex b/lib/flagsmith_client.ex index 4c25ac9..367a1bc 100644 --- a/lib/flagsmith_client.ex +++ b/lib/flagsmith_client.ex @@ -152,28 +152,30 @@ defmodule Flagsmith.Client do @spec get_identity_flags( Configuration.t() | Keyword.t(), String.t(), - list(map() | Schemas.Traits.Trait.t()) + list(map() | Schemas.Traits.Trait.t()), + boolean() ) :: {:ok, Schemas.Flags.t()} | {:error, term()} - def get_identity_flags(configuration_or_opts \\ [], identifier, traits) + def get_identity_flags(configuration_or_opts \\ [], identifier, traits, transient \\ false) def get_identity_flags( %Configuration{enable_local_evaluation: local?} = config, identifier, - traits + traits, + transient ) do case local? do true -> Flagsmith.Client.Poller.get_identity_flags(config, identifier, traits) - false -> get_identity_flags_request(config, identifier, traits) + false -> get_identity_flags_request(config, identifier, traits, transient) end end - def get_identity_flags(opts, identifier, traits) when is_list(opts), - do: get_identity_flags(new(opts), identifier, traits) + def get_identity_flags(opts, identifier, traits, transient) when is_list(opts), + do: get_identity_flags(new(opts), identifier, traits, transient) @doc false - def get_identity_flags_request(%Configuration{} = config, identifier, traits) do - query = build_identity_params(identifier, traits) + def get_identity_flags_request(%Configuration{} = config, identifier, traits, transient) do + query = build_identity_params(identifier, traits, transient) case Tesla.post(http_client(config), @api_paths.identities, query) do {:ok, %{status: status, body: body}} when status >= 200 and status < 300 -> @@ -375,15 +377,16 @@ defmodule Flagsmith.Client do feature_flag end - defp build_identity_params(identifier, [_ | _] = traits) do + defp build_identity_params(identifier, [_ | _] = traits, transient) do %{ identifier: identifier, - traits: Schemas.Traits.Trait.from(traits) + traits: Schemas.Traits.Trait.from(traits), + transient: transient } end - defp build_identity_params(identifier, _), - do: %{identifier: identifier} + defp build_identity_params(identifier, _, transient), + do: %{identifier: identifier, transient: transient} @doc false @spec auth_middleware(environment_key :: String.t()) :: diff --git a/lib/schemas/traits/trait.ex b/lib/schemas/traits/trait.ex index a72e3e4..4e8a12b 100644 --- a/lib/schemas/traits/trait.ex +++ b/lib/schemas/traits/trait.ex @@ -8,12 +8,13 @@ defmodule Flagsmith.Schemas.Traits.Trait do Ecto schema representing a Flagsmith trait definition. """ - @derive {Jason.Encoder, only: [:trait_key, :trait_value]} + @derive {Jason.Encoder, only: [:trait_key, :trait_value, :transient]} @primary_key {:id, :id, autogenerate: false} typed_embedded_schema do field(:trait_key, :string) field(:trait_value, __MODULE__.Value) + field(:transient, :boolean, default: false) end @doc false @@ -44,7 +45,7 @@ defmodule Flagsmith.Schemas.Traits.Trait do def from(%{} = params) do %__MODULE__{} - |> cast(params, [:trait_value, :trait_key, :id]) + |> cast(params, [:trait_value, :trait_key, :transient, :id]) |> validate_required([:trait_value]) |> apply_changes() end diff --git a/test/flagsmith_client_test.exs b/test/flagsmith_client_test.exs index 3655e3f..8e0df14 100644 --- a/test/flagsmith_client_test.exs +++ b/test/flagsmith_client_test.exs @@ -269,7 +269,7 @@ defmodule Flagsmith.Client.Test do expect(Tesla.Adapter.Mock, :call, fn tesla_env, _options -> assert_request( tesla_env, - body: "{\"identifier\":\"super1234324\"}", + body: "{\"transient\":false,\"identifier\":\"super1234324\"}", query: [], headers: [{@environment_header, config.environment_key}], url: Path.join([@api_url, @api_paths.identities]) <> "/", @@ -315,6 +315,50 @@ defmodule Flagsmith.Client.Test do # we also assert that no poller was initiated by making sure there's no pid assert :undefined = Flagsmith.Client.Poller.whereis(config.environment_key) end + + test "get_identity_flags for transient identity", %{config: config} do + # set expectation for the http call + expect(Tesla.Adapter.Mock, :call, fn tesla_env, _options -> + assert_request( + tesla_env, + body: "{\"transient\":true,\"identifier\":\"super1234324\"}", + query: [], + headers: [{@environment_header, config.environment_key}], + url: Path.join([@api_url, @api_paths.identities]) <> "/", + method: :post + ) + + {:ok, %Tesla.Env{status: 200, body: Test.Generators.map_identity()}} + end) + + Flagsmith.Client.get_identity_flags(config, "super1234324", [], true) + end + + test "get_identity_flags for transient traits", %{config: config} do + # set expectation for the http call + expect(Tesla.Adapter.Mock, :call, fn tesla_env, _options -> + assert_request( + tesla_env, + body: + "{\"transient\":false,\"identifier\":\"super1234324\",\"traits\":[{\"trait_key\":\"foo\",\"trait_value\":{\"value\":\"bar\",\"type\":\"string\"},\"transient\":false},{\"trait_key\":\"transient\",\"trait_value\":{\"value\":\"bar\",\"type\":\"string\"},\"transient\":true}]}", + query: [], + headers: [{@environment_header, config.environment_key}], + url: Path.join([@api_url, @api_paths.identities]) <> "/", + method: :post + ) + + {:ok, %Tesla.Env{status: 200, body: Test.Generators.map_identity()}} + end) + + Flagsmith.Client.get_identity_flags( + config, + "super1234324", + [ + %{trait_key: "foo", trait_value: "bar"}, + %{trait_key: "transient", trait_value: "bar", transient: true} + ] + ) + end end describe "failure tests" do