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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,24 @@ Or you can pass it through when creating a client instance:
knock_client = MyApp.Knock.client(api_key: "sk_12345")
```

To use a branch, set the `branch` option in your configuration or client instance:

```elixir
config :my_app, MyApp.Knock,
api_key: "sk_12345"
branch: "my-feature-branch"

# OR

knock_client = MyApp.Knock.client(api_key: "sk_12345", branch: "my-feature-branch")
```

Alternatively, you can set it as an environment variable:

```bash
KNOCK_BRANCH="my-feature-branch"
```

## Usage

### Identifying users
Expand Down
26 changes: 25 additions & 1 deletion lib/knock.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,28 @@ defmodule Knock do
json_client: JSX
```

You can read more about the availble adapters in the [Tesla documentation](https://hexdocs.pm/tesla/readme.html#adapters)
You can read more about the available adapters in the [Tesla documentation](https://hexdocs.pm/tesla/readme.html#adapters)

To use a branch, set the `branch` option in your configuration or client instance.

```elixir
# config/runtime.exs

config :my_app, MyApp.KnockClient,
api_key: "sk_12345",
branch: "my-feature-branch"

# OR

knock_client = MyApp.Knock.client(api_key: "sk_12345", branch: "my-feature-branch")
```
"""

defmacro __using__(opts) do
quote do
@app_name Keyword.fetch!(unquote(opts), :otp_app)
@api_key_env_var "KNOCK_API_KEY"
@branch_env_var "KNOCK_BRANCH"

alias Knock.Client

Expand All @@ -72,6 +87,7 @@ defmodule Knock do
defp fetch_options(overrides) do
Application.get_env(@app_name, __MODULE__, [])
|> maybe_resolve_api_key()
|> maybe_resolve_branch()
|> Keyword.merge(overrides)
end

Expand All @@ -82,6 +98,14 @@ defmodule Knock do
_ -> Keyword.put(opts, :api_key, System.get_env(@api_key_env_var))
end
end

defp maybe_resolve_branch(opts) do
case Keyword.get(opts, :branch) do
branch when is_binary(branch) -> opts
{:system, var_name} -> Keyword.put(opts, :branch, System.get_env(var_name))
_ -> Keyword.put(opts, :branch, System.get_env(@branch_env_var))
end
end
end
end

Expand Down
9 changes: 8 additions & 1 deletion lib/knock/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ defmodule Knock.Api do
[
{"Authorization", "Bearer " <> config.api_key},
{"User-Agent", "knocklabs/knock-elixir@#{library_version()}"}
] ++ maybe_idempotency_key_header(Map.new(opts))}
] ++
maybe_idempotency_key_header(Map.new(opts)) ++
maybe_branch_header(config)}
]

Tesla.client(middleware, config.adapter)
Expand All @@ -101,4 +103,9 @@ defmodule Knock.Api do
do: [{"Idempotency-Key", to_string(key)}]

defp maybe_idempotency_key_header(_), do: []

defp maybe_branch_header(%{branch: branch}) when not is_nil(branch),
do: [{"X-Knock-Branch", to_string(branch)}]

defp maybe_branch_header(_), do: []
end
7 changes: 6 additions & 1 deletion lib/knock/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ defmodule Knock.Client do
```elixir
# Setup a client instance directly
client = Knock.Client.new(api_key: "sk_test_12345")

# With optional branch
client = Knock.Client.new(api_key: "sk_test_12345", branch: "my-feature-branch")
```
"""

@enforce_keys [:api_key]
defstruct host: "https://api.knock.app",
api_key: nil,
branch: nil,
adapter: Tesla.Adapter.Hackney,
json_client: Jason

Expand All @@ -22,6 +26,7 @@ defmodule Knock.Client do
@type t :: %__MODULE__{
host: String.t(),
api_key: String.t(),
branch: String.t() | nil,
adapter: atom(),
json_client: atom()
}
Expand All @@ -38,7 +43,7 @@ defmodule Knock.Client do

opts =
opts
|> Keyword.take([:host, :api_key, :adapter, :json_client])
|> Keyword.take([:host, :api_key, :branch, :adapter, :json_client])
|> Map.new()
|> maybe_set_adapter_default()

Expand Down
35 changes: 34 additions & 1 deletion test/knock_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ defmodule KnockTest do
assert knock.adapter == Tesla.Adapter.Hackney
assert knock.json_client == Jason
assert knock.host == "https://api.knock.app"
assert knock.branch == nil
end

test "it allows configuring a branch" do
knock = TestClient.client(api_key: "sk_test_12345", branch: "my-feature-branch")

assert knock.api_key == "sk_test_12345"
assert knock.branch == "my-feature-branch"
end

test "it will default to reading the api key from env vars" do
Expand All @@ -24,7 +32,18 @@ defmodule KnockTest do
assert knock.api_key == "sk_test_12345"
end

test "it can read from application config" do
test "it will default to reading the branch from env vars" do
System.put_env("KNOCK_API_KEY", "sk_test_12345")
System.put_env("KNOCK_BRANCH", "test-branch")

knock = TestClient.client()

assert knock.branch == "test-branch"

System.delete_env("KNOCK_BRANCH")
end

test "it can read the api key from application config" do
Application.put_env(:knock, KnockTest.TestClient,
api_key: "sk_test_12345",
foo: "bar"
Expand All @@ -35,6 +54,20 @@ defmodule KnockTest do
assert knock.api_key == "sk_test_12345"
end

test "it can read the branch from application config" do
Application.put_env(:knock, KnockTest.TestClient,
api_key: "sk_test_12345",
branch: "config-branch"
)

knock = TestClient.client()

assert knock.api_key == "sk_test_12345"
assert knock.branch == "config-branch"

Application.delete_env(:knock, KnockTest.TestClient)
end

test "if set, will use the Tesla default adapter if one is not provided" do
Application.put_env(:tesla, :adapter, Tesla.Adapter.Hackney)

Expand Down