Skip to content

Commit c396c17

Browse files
committed
fix: feedback
1 parent 66859ae commit c396c17

File tree

6 files changed

+111
-90
lines changed

6 files changed

+111
-90
lines changed

Diff for: lib/statsig.ex

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ defmodule Statsig do
6767

6868
defp log_exposures(%User{} = user, %EvaluationResult{} = result, type) do
6969
[primary | secondary] = result.exposures
70+
7071
event =
7172
base_event(user, secondary, type)
7273
|> Map.put(:metadata, primary)

Diff for: lib/statsig/evaluator.ex

+12-9
Original file line numberDiff line numberDiff line change
@@ -425,32 +425,35 @@ defmodule Statsig.Evaluator do
425425
hash
426426
end
427427

428-
defp get_user_id(%User{userID: id}, "userID"), do: to_string(id)
428+
defp get_user_id(%User{} = user, "userID"), do: to_string(user.user_id)
429429

430-
defp get_user_id(%User{customIDs: custom_ids}, prop),
431-
do: try_get_with_lower(custom_ids, prop) |> to_string()
430+
defp get_user_id(%User{} = user, prop),
431+
do: try_get_with_lower(user.custom_ids || %{}, prop) |> to_string()
432432

433433
defp get_user_field(%User{} = user, prop) do
434434
case try_get_with_lower(%{
435-
user.userID => user.userID,
435+
user.userID => user.user_id,
436436
"email" => user.email,
437437
"ip" => user.ip,
438-
"userAgent" => user.userAgent,
438+
"userAgent" => user.user_agent,
439439
"country" => user.country,
440440
"locale" => user.locale,
441-
"appVersion" => user.appVersion
441+
"appVersion" => user.app_version
442442
}, prop) do
443443
nil -> try_get_with_lower(user.custom || %{}, prop)
444444
found -> found
445445
end
446446
|> case do
447-
nil -> try_get_with_lower(user.privateAttributes || %{}, prop)
447+
nil -> try_get_with_lower(user.private_attributes || %{}, prop)
448448
found -> found
449449
end
450450
end
451451

452-
defp get_env_field(%User{statsigEnvironment: env}, field) when not is_nil(env),
453-
do: try_get_with_lower(env, field) |> to_string()
452+
defp get_env_field(%User{} = user, field) do
453+
user.statsig_environment
454+
|> Map.get(field)
455+
|> to_string()
456+
end
454457

455458
defp get_env_field(_, _), do: nil
456459

Diff for: lib/statsig/user.ex

+53-36
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,77 @@
11
defmodule Statsig.User do
22
@derive {Jason.Encoder, only: [
3-
:userID,
4-
:customIDs,
3+
:user_id,
4+
:custom_ids,
55
:email,
66
:ip,
7-
:userAgent,
7+
:user_agent,
88
:country,
99
:locale,
10-
:appVersion,
10+
:app_version,
1111
:custom,
12-
:statsigEnvironment
12+
:statsig_environment
1313
]}
1414

1515
@type custom_value :: String.t() | number() | boolean() | nil
1616
@type custom_attributes :: %{optional(String.t()) => custom_value()}
1717

1818
@type t :: %__MODULE__{
19-
userID: String.t() | nil,
20-
customIDs: %{optional(String.t()) => String.t()} | nil,
19+
user_id: String.t() | nil,
20+
custom_ids: %{optional(String.t()) => String.t()} | nil,
2121
email: String.t() | nil,
2222
ip: String.t() | nil,
23-
userAgent: String.t() | nil,
23+
user_agent: String.t() | nil,
2424
country: String.t() | nil,
2525
locale: String.t() | nil,
26-
appVersion: String.t() | nil,
26+
app_version: String.t() | nil,
2727
custom: custom_attributes() | nil,
28-
privateAttributes: custom_attributes() | nil,
29-
statsigEnvironment: map() | nil
28+
private_attributes: custom_attributes() | nil,
29+
statsig_environment: map() | nil
3030
}
3131

32-
defstruct userID: nil,
33-
customIDs: nil,
34-
email: nil,
35-
ip: nil,
36-
userAgent: nil,
37-
country: nil,
38-
locale: nil,
39-
appVersion: nil,
40-
custom: nil,
41-
privateAttributes: nil,
42-
statsigEnvironment: nil
43-
44-
def new(params \\ %{}) do
45-
unless Map.get(params, "userID") || Map.get(params, :userID) ||
46-
Map.get(params, "customIDs") || Map.get(params, :customIDs) do
47-
raise ArgumentError, "Either userID or customIDs must be provided"
48-
end
32+
defstruct [
33+
:user_id,
34+
:custom_ids,
35+
:email,
36+
:ip,
37+
:user_agent,
38+
:country,
39+
:locale,
40+
:app_version,
41+
:custom,
42+
:private_attributes,
43+
:statsig_environment
44+
]
4945

50-
converted_params = for {key, val} <- params, into: %{} do
51-
cond do
52-
is_binary(key) -> {String.to_existing_atom(key), val}
53-
is_atom(key) -> {key, val}
54-
true -> {key, val}
55-
end
56-
end
46+
def new(user_id_or_custom_ids, params \\ [])
5747

58-
struct(__MODULE__, converted_params)
48+
def new(custom_ids = [_ | _], params) do
49+
struct(__MODULE__, Keyword.merge(params, custom_ids: custom_ids))
50+
end
51+
52+
def new(user_id, params) when is_binary(user_id) do
53+
struct(__MODULE__, Keyword.merge(params, user_id: user_id))
54+
end
55+
56+
def new(_, _), do: raise("You must provide a user id or custom ids")
57+
58+
defp new_from_params(params) do
59+
params =
60+
Keyword.new(params, fn
61+
{key, _v} = key_and_value when is_atom(key) -> key_and_value
62+
{key, value} when is_binary(key) -> {String.to_existing_atom(key), value}
63+
end)
64+
struct(__MODULE__, params)
65+
end
66+
67+
def encode_as(key) when is_atom(key) do
68+
case key do
69+
:user_id -> "userID"
70+
:custom_ids -> "customIDs"
71+
:user_agent -> "userAgent"
72+
:app_version -> "appVersion"
73+
:statsig_environment -> "statsigEnvironment"
74+
_ -> key |> Atom.to_string()
75+
end
5976
end
6077
end

Diff for: lib/statsig/utils.ex

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
defmodule Statsig.Utils do
22
alias Statsig.User
33

4-
def get_user_with_env(%User{statsigEnvironment: env} = user) when not is_nil(env),
4+
def get_user_with_env(%User{statsig_environment: env} = user) when not is_nil(env),
55
do: user
66

7-
def get_user_with_env(%User{} = user), do: put_env(user)
7+
def get_user_with_env(%User{} = user), do: put_statsig_env(user)
88

9-
def sanitize_user(%User{} = user), do: %User{user | privateAttributes: nil}
9+
def sanitize_user(%User{} = user), do: %User{user | private_attributes: nil}
1010

11-
defp put_env(%User{} = user) do
11+
defp put_statsig_env(%User{} = user) do
1212
case Application.get_env(:statsig, :env_tier) do
1313
nil -> user
14-
tier -> %User{user | statsigEnvironment: %{"tier" => tier}}
14+
tier -> %User{user | statsig_environment: %{"tier" => tier}}
1515
end
1616
end
1717
end

Diff for: mix.exs

+9-11
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,25 @@ defmodule Statsig.MixProject do
1414

1515
# Run "mix help compile.app" to learn about applications.
1616
def application do
17-
case Mix.env() do
18-
:test ->
19-
[extra_applications: [:logger, :jason]]
20-
_ ->
21-
[
22-
mod: {Statsig.Application, []},
23-
extra_applications: [:logger, :jason]
24-
]
25-
end
17+
[
18+
mod: {Statsig.Application, []},
19+
extra_applications: [:logger]
20+
]
2621
end
2722

2823
# Specifies which paths to compile per environment.
29-
defp elixirc_paths(:test), do: ["lib", "test/support", "test/statsig"]
24+
defp elixirc_paths(:test), do: ["lib", "test/support"]
3025
defp elixirc_paths(_), do: ["lib"]
3126

3227
# Run "mix help deps" to learn about dependencies.
3328
defp deps do
3429
[
3530
{:req, "~> 0.5"},
36-
{:jason, "~> 1.2"},
3731
{:ua_parser, "~> 1.8"}
3832
]
3933
end
34+
35+
defp aliases() do
36+
[test: "test --no-start"]
37+
end
4038
end

Diff for: test/statsig/user_test.exs

+31-29
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,77 @@ defmodule Statsig.UserTest do
33

44
alias Statsig.User
55

6-
describe "new/1" do
7-
test "accepts userID as string key" do
8-
user = User.new(%{"userID" => "123"})
9-
assert user.userID == "123"
6+
describe "new/2" do
7+
test "accepts string user_id as first argument" do
8+
user = User.new("123")
9+
assert user.user_id == "123"
1010
end
1111

12-
test "accepts userID as atom key" do
13-
user = User.new(%{userID: "123"})
14-
assert user.userID == "123"
12+
test "accepts string user_id with additional params" do
13+
user = User.new("123", email: "[email protected]")
14+
assert user.user_id == "123"
15+
assert user.email == "[email protected]"
1516
end
1617

17-
test "accepts customIDs as string key" do
18-
user = User.new(%{"customIDs" => %{"employee_id" => "456"}})
19-
assert user.customIDs == %{"employee_id" => "456"}
18+
test "accepts custom_ids list as first argument" do
19+
user = User.new([employee_id: "456"])
20+
assert user.custom_ids == [employee_id: "456"]
2021
end
2122

22-
test "accepts customIDs as atom key" do
23-
user = User.new(%{customIDs: %{"employee_id" => "456"}})
24-
assert user.customIDs == %{"employee_id" => "456"}
23+
test "accepts custom_ids with additional params" do
24+
user = User.new([employee_id: "456"], email: "[email protected]")
25+
assert user.custom_ids == [employee_id: "456"]
26+
assert user.email == "[email protected]"
2527
end
2628

27-
test "raises when neither userID nor customIDs is provided" do
28-
assert_raise ArgumentError, "Either userID or customIDs must be provided", fn ->
29-
User.new(%{email: "[email protected]"})
29+
test "raises when neither user_id nor custom_ids is provided" do
30+
assert_raise RuntimeError, "You must provide a user id or custom ids", fn ->
31+
User.new(%{})
3032
end
3133
end
3234
end
3335

3436
describe "JSON serialization" do
35-
test "excludes privateAttributes when encoding to JSON" do
37+
test "excludes private_attributes when encoding to JSON" do
3638
user = User.new(%{
37-
"userID" => "123",
39+
"user_id" => "123",
3840
"email" => "[email protected]",
39-
"privateAttributes" => %{"secret" => "value"}
41+
"private_attributes" => %{"secret" => "value"}
4042
})
4143

4244
json = Jason.encode!(user)
4345
decoded = Jason.decode!(json)
4446

45-
assert decoded["userID"] == "123"
47+
assert decoded["user_id"] == "123"
4648
assert decoded["email"] == "[email protected]"
47-
refute Map.has_key?(decoded, "privateAttributes")
49+
refute Map.has_key?(decoded, "private_attributes")
4850
end
4951

5052
test "includes all other fields when encoding to JSON" do
5153
user = User.new(%{
52-
"userID" => "123",
54+
"user_id" => "123",
5355
"email" => "[email protected]",
5456
"custom" => %{"is_employee" => true},
55-
"customIDs" => %{"employee_id" => "456"},
57+
"custom_ids" => [employee_id: "456"],
5658
"ip" => "1.2.3.4",
57-
"userAgent" => "Mozilla",
59+
"user_agent" => "Mozilla",
5860
"country" => "US",
5961
"locale" => "en-US",
60-
"appVersion" => "1.0.0"
62+
"app_version" => "1.0.0"
6163
})
6264

6365
json = Jason.encode!(user)
6466
decoded = Jason.decode!(json)
6567

66-
assert decoded["userID"] == "123"
68+
assert decoded["user_id"] == "123"
6769
assert decoded["email"] == "[email protected]"
6870
assert decoded["custom"] == %{"is_employee" => true}
69-
assert decoded["customIDs"] == %{"employee_id" => "456"}
71+
assert decoded["custom_ids"] == %{"employee_id" => "456"}
7072
assert decoded["ip"] == "1.2.3.4"
71-
assert decoded["userAgent"] == "Mozilla"
73+
assert decoded["user_agent"] == "Mozilla"
7274
assert decoded["country"] == "US"
7375
assert decoded["locale"] == "en-US"
74-
assert decoded["appVersion"] == "1.0.0"
76+
assert decoded["app_version"] == "1.0.0"
7577
end
7678
end
7779
end

0 commit comments

Comments
 (0)