Skip to content

Commit

Permalink
improvement: test installer
Browse files Browse the repository at this point in the history
  • Loading branch information
zachdaniel committed Sep 11, 2024
1 parent 500c323 commit 71ddc59
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 7 deletions.
2 changes: 1 addition & 1 deletion lib/ash_authentication/igniter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule AshAuthentication.Igniter do
@spec add_secret_from_env(Igniter.t(), module(), Ash.Resource.t(), list(atom), atom()) ::
Igniter.t()
def add_secret_from_env(igniter, module, resource, path, env_key) do
otp_app = Igniter.Project.Application.app_name()
otp_app = Igniter.Project.Application.app_name(igniter)

func =
quote do
Expand Down
11 changes: 6 additions & 5 deletions lib/mix/tasks/ash_authentication.install.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ defmodule Mix.Tasks.AshAuthentication.Install do

@impl Igniter.Mix.Task
def igniter(igniter, argv) do
accounts_domain = Igniter.Code.Module.module_name("Accounts")
token_resource = Igniter.Code.Module.module_name("Accounts.Token")
user_resource = Igniter.Code.Module.module_name("Accounts.User")
secrets_module = Igniter.Code.Module.module_name("Secrets")
otp_app = Igniter.Project.Application.app_name()
accounts_domain = Igniter.Code.Module.module_name(igniter, "Accounts")
token_resource = Igniter.Code.Module.module_name(igniter, "Accounts.Token")
user_resource = Igniter.Code.Module.module_name(igniter, "Accounts.User")
secrets_module = Igniter.Code.Module.module_name(igniter, "Secrets")
otp_app = Igniter.Project.Application.app_name(igniter)

{igniter, resource_args, repo} = data_layer_args(igniter)

igniter
|> Igniter.Project.Formatter.import_dep(:ash_authentication)
|> Igniter.Project.Formatter.add_formatter_plugin(Spark.Formatter)
|> Igniter.compose_task(
"ash.gen.domain",
[inspect(accounts_domain), "--ignore-if-exists"] ++ argv ++ resource_args
Expand Down
3 changes: 2 additions & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"glob_ex": {:hex, :glob_ex, "0.1.8", "f7ef872877ca2ae7a792ab1f9ff73d9c16bf46ecb028603a8a3c5283016adc07", [:mix], [], "hexpm", "9e39d01729419a60a937c9260a43981440c43aa4cadd1fa6672fecd58241c464"},
"ham": {:hex, :ham, "0.3.0", "7cd031b4a55fba219c11553e7b13ba73bd86eab4034518445eff1e038cb9a44d", [:mix], [], "hexpm", "7d6c6b73d7a6a83233876cc1b06a4d9b5de05562b228effda4532f9a49852bf6"},
"hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
"igniter": {:hex, :igniter, "0.3.25", "cce36fd49b499d215d0605ee3bfeb8fabe2f86b70b2df24ef3a50797409bceee", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:rewrite, "~> 0.9", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "ffccb3c03cfdc8694be27a4c1d5615799ac140c27f32c74d1817171c4d411a62"},
"igniter": {:hex, :igniter, "0.3.35", "edd8db6234db7639eb2f954b45ab23db98b1fd0a940850f58db8900912a908bf", [:mix], [{:glob_ex, "~> 0.1.7", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:rewrite, "~> 0.9", [hex: :rewrite, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.4", [hex: :sourceror, repo: "hexpm", optional: false]}, {:spitfire, ">= 0.1.3 and < 1.0.0-0", [hex: :spitfire, repo: "hexpm", optional: false]}], "hexpm", "d2826d94d8c851e2bc8b920766815b3df4b184cab05eae8423e965363a2e02b1"},
"inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"},
"iterex": {:hex, :iterex, "0.1.2", "58f9b9b9a22a55cbfc7b5234a9c9c63eaac26d276b3db80936c0e1c60355a5a6", [:mix], [], "hexpm", "2e103b8bcc81757a9af121f6dc0df312c9a17220f302b1193ef720460d03029d"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
Expand All @@ -62,6 +62,7 @@
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"reactor": {:hex, :reactor, "0.9.1", "082f8e9b1fd7586c0a016c2fb533835fec7eaef5ffb0263abb4473106c20b1ca", [:mix], [{:igniter, "~> 0.2", [hex: :igniter, repo: "hexpm", optional: false]}, {:iterex, "~> 0.1", [hex: :iterex, repo: "hexpm", optional: false]}, {:libgraph, "~> 0.16", [hex: :libgraph, repo: "hexpm", optional: false]}, {:spark, "~> 2.0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.2", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7191ddf95fdd2b65770a57a2e38dd502a94909e51ac8daf497330e67fc032dc3"},
"rewrite": {:hex, :rewrite, "0.10.5", "6afadeae0b9d843b27ac6225e88e165884875e0aed333ef4ad3bf36f9c101bed", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "51cc347a4269ad3a1e7a2c4122dbac9198302b082f5615964358b4635ebf3d4f"},
"simple_sat": {:hex, :simple_sat, "0.1.3", "f650fc3c184a5fe741868b5ac56dc77fdbb428468f6dbf1978e14d0334497578", [:mix], [], "hexpm", "a54305066a356b7194dc81db2a89232bacdc0b3edaef68ed9aba28dcbc34887b"},
"sobelow": {:hex, :sobelow, "0.13.0", "218afe9075904793f5c64b8837cc356e493d88fddde126a463839351870b8d1e", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cd6e9026b85fc35d7529da14f95e85a078d9dd1907a9097b3ba6ac7ebbe34a0d"},
"sourceror": {:hex, :sourceror, "1.6.0", "9907884e1449a4bd7dbaabe95088ed4d9a09c3c791fb0103964e6316bc9448a7", [:mix], [], "hexpm", "e90aef8c82dacf32c89c8ef83d1416fc343cd3e5556773eeffd2c1e3f991f699"},
"spark": {:hex, :spark, "2.2.23", "78f0a1b0b713a91ad556fe9dc19ec92d977aaa0803cce2e255d90e58b9045c2a", [:mix], [{:igniter, ">= 0.2.6 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.2", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "a354b5cd7c3f021e3cd1da5a033b7643fe7b3c71c96b96d9f500a742f40c94db"},
Expand Down
198 changes: 198 additions & 0 deletions test/mix/tasks/ash_authentication.install_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
defmodule Mix.Tasks.AshAuthentication.InstallTest do
use ExUnit.Case

import Igniter.Test

test "installation creates a secrets module" do
test_project()
|> Igniter.Project.Deps.add_dep({:simple_sat, ">= 0.0.0"})

Check warning on line 8 in test/mix/tasks/ash_authentication.install_test.exs

View workflow job for this annotation

GitHub Actions / mix credo --strict

Nested modules could be aliased at the top of the invoking module.
|> Igniter.compose_task("ash_authentication.install")
|> assert_creates("lib/test/secrets.ex", """
defmodule Test.Secrets do
use AshAuthentication.Secret
def secret_for([:authentication, :tokens, :signing_secret], Test.Accounts.User, _opts) do
Application.fetch_env(:test, :token_signing_secret)
end
end
""")
end

test "installation adds the supervisor to the app" do
test_project()
|> Igniter.Project.Deps.add_dep({:simple_sat, ">= 0.0.0"})

Check warning on line 23 in test/mix/tasks/ash_authentication.install_test.exs

View workflow job for this annotation

GitHub Actions / mix credo --strict

Nested modules could be aliased at the top of the invoking module.
|> Igniter.compose_task("ash_authentication.install")
|> assert_has_patch("lib/test/application.ex", """
8 | children = [{AshAuthentication.Supervisor, [otp_app: :test]}]
""")
end

test "installation adds config files" do
test_project()
|> Igniter.Project.Deps.add_dep({:simple_sat, ">= 0.0.0"})

Check warning on line 32 in test/mix/tasks/ash_authentication.install_test.exs

View workflow job for this annotation

GitHub Actions / mix credo --strict

Nested modules could be aliased at the top of the invoking module.
|> Igniter.compose_task("ash_authentication.install")
|> assert_creates("config/runtime.exs", """
import Config
if config_env() == :prod do
config :test,
token_signing_secret:
System.get_env("TOKEN_SIGNING_SECRET") ||
raise("Missing environment variable `TOKEN_SIGNING_SECRET`!")
end
""")

# can't easily test this with the helpers we have.
# we can make `assert_creates` take a function potentially
# for now, this is simple enough that its almost testing `igniter`.
# |> assert_creates("config/dev.exs", """
# import Config
# config :test, token_signing_secret: "kDL+MmXw8E0xbN//xYTowcR1tt5yCLSu"
# """)
# |> assert_creates("config/test.exs", """
# import Config
# config :test, token_signing_secret: "7vg4IwKCttu/eMU3PYPLCjrl277OlNvr"
# """)
end

test "installation adds a user resource" do
test_project()
|> Igniter.Project.Deps.add_dep({:simple_sat, ">= 0.0.0"})

Check warning on line 60 in test/mix/tasks/ash_authentication.install_test.exs

View workflow job for this annotation

GitHub Actions / mix credo --strict

Nested modules could be aliased at the top of the invoking module.
|> Igniter.compose_task("ash_authentication.install")
|> assert_creates("lib/test/accounts/user.ex", """
defmodule Test.Accounts.User do
use Ash.Resource,
otp_app: :ash_authentication,
domain: Test.Accounts,
authorizers: [Ash.Policy.Authorizer],
data_layer: AshPostgres.DataLayer
postgres do
table("users")
repo(AshAuthentication.Repo)
end
authentication do
tokens do
enabled?(true)
token_resource(Test.Accounts.Token)
signing_secret(:token_signing_secret)
end
end
end
""")
end

test "instalation adds a user token resource" do
test_project()
|> Igniter.Project.Deps.add_dep({:simple_sat, ">= 0.0.0"})

Check warning on line 88 in test/mix/tasks/ash_authentication.install_test.exs

View workflow job for this annotation

GitHub Actions / mix credo --strict

Nested modules could be aliased at the top of the invoking module.
|> Igniter.compose_task("ash_authentication.install")
|> assert_creates("lib/test/accounts/token.ex", """
defmodule Test.Accounts.Token do
use Ash.Resource,
otp_app: :ash_authentication,
domain: Test.Accounts,
authorizers: [Ash.Policy.Authorizer],
data_layer: AshPostgres.DataLayer
attributes do
attribute :jti, :string do
primary_key?(true)
public?(true)
allow_nil?(false)
sensitive?(true)
end
attribute :subject, :string do
allow_nil?(false)
end
attribute :expires_at, :utc_datetime do
allow_nil?(false)
end
attribute :purpose, :string do
allow_nil?(false)
public?(true)
end
attribute :extra_data, :map do
public?(true)
end
timestamps()
end
postgres do
table("tokens")
repo(AshAuthentication.Repo)
end
actions do
read :expired do
filter(expr(expires_at < now()))
end
read :get_token do
get?(true)
argument(:token, :string, sensitive?: true)
argument(:jti, :string, sensitive?: true)
argument(:purpose, :string, sensitive?: false)
prepare(AshAuthentication.TokenResource.GetTokenPreparation)
end
read :revoked? do
argument(:token, :string, sensitive?: true)
argument(:jti, :string, sensitive?: true)
get?(true)
prepare(AshAuthentication.TokenResource.IsRevokedPreparation)
end
read :get_confirmation_changes do
argument(:jti, :string, allow_nil?: false, sensitive?: true)
get?(true)
prepare(AshAuthentication.TokenResource.GetConfirmationChangesPreparation)
end
create :revoke_token do
accept([:extra_data])
argument(:token, :string, allow_nil?: false, sensitive?: true)
change(AshAuthentication.TokenResource.RevokeTokenChange)
end
create :store_confirmation_changes do
accept([:extra_data, :purpose])
argument(:token, :string, allow_nil?: false, sensitive?: true)
change(AshAuthentication.TokenResource.StoreConfirmationChangesChange)
end
create :store_token do
accept([:extra_data, :purpose])
argument(:token, :string, allow_nil?: false, sensitive?: true)
change(AshAuthentication.TokenResource.StoreTokenChange)
end
destroy :expunge_expired do
change(filter(expr(expires_at < now())))
end
end
policies do
bypass AshAuthentication.Checks.AshAuthenticationInteraction do
authorize_if(always())
end
policies do
policy always() do
forbid_if(always())
end
end
end
end
""")
end
end

0 comments on commit 71ddc59

Please sign in to comment.