This commit is contained in:
Graham McIntire 2025-12-21 11:31:08 -06:00
parent ba463dc5a2
commit 20d2d8dbd8
No known key found for this signature in database
14 changed files with 120 additions and 123 deletions

View file

@ -1,6 +1,6 @@
[ [
import_deps: [:ecto, :ecto_sql, :phoenix], import_deps: [:ecto, :ecto_sql, :phoenix],
subdirectories: ["priv/*/migrations"], subdirectories: ["priv/*/migrations"],
plugins: [Phoenix.LiveView.HTMLFormatter], plugins: [Styler, Phoenix.LiveView.HTMLFormatter],
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"] inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"]
] ]

View file

@ -7,30 +7,6 @@
# General application configuration # General application configuration
import Config import Config
config :towerops,
ecto_repos: [Towerops.Repo],
generators: [timestamp_type: :utc_datetime, binary_id: true]
# Configure the endpoint
config :towerops, ToweropsWeb.Endpoint,
url: [host: "localhost"],
adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: ToweropsWeb.ErrorHTML, json: ToweropsWeb.ErrorJSON],
layout: false
],
pubsub_server: Towerops.PubSub,
live_view: [signing_salt: "Uh1ABfdI"]
# Configure the mailer
#
# By default it uses the "Local" adapter which stores the emails
# locally. You can see the emails in your browser, at "/dev/mailbox".
#
# For production it's recommended to configure a different adapter
# at the `config/runtime.exs`.
config :towerops, Towerops.Mailer, adapter: Swoosh.Adapters.Local
# Configure esbuild (the version is required) # Configure esbuild (the version is required)
config :esbuild, config :esbuild,
version: "0.25.4", version: "0.25.4",
@ -41,6 +17,14 @@ config :esbuild,
env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]} env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
] ]
# Configure Elixir's Logger
config :logger, :default_formatter,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason
# Configure tailwind (the version is required) # Configure tailwind (the version is required)
config :tailwind, config :tailwind,
version: "4.1.12", version: "4.1.12",
@ -52,14 +36,30 @@ config :tailwind,
cd: Path.expand("..", __DIR__) cd: Path.expand("..", __DIR__)
] ]
# Configure Elixir's Logger # Configure the mailer
config :logger, :default_formatter, #
format: "$time $metadata[$level] $message\n", # By default it uses the "Local" adapter which stores the emails
metadata: [:request_id] # locally. You can see the emails in your browser, at "/dev/mailbox".
#
# For production it's recommended to configure a different adapter
# at the `config/runtime.exs`.
config :towerops, Towerops.Mailer, adapter: Swoosh.Adapters.Local
# Use Jason for JSON parsing in Phoenix # Configure the endpoint
config :phoenix, :json_library, Jason config :towerops, ToweropsWeb.Endpoint,
url: [host: "localhost"],
adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: ToweropsWeb.ErrorHTML, json: ToweropsWeb.ErrorJSON],
layout: false
],
pubsub_server: Towerops.PubSub,
live_view: [signing_salt: "Uh1ABfdI"]
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
config :towerops,
ecto_repos: [Towerops.Repo],
generators: [timestamp_type: :utc_datetime, binary_id: true]
import_config "#{config_env()}.exs" import_config "#{config_env()}.exs"

View file

@ -1,5 +1,26 @@
import Config import Config
# Do not include metadata nor timestamps in development logs
config :logger, :default_formatter, format: "[$level] $message\n"
# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime
# Set a higher stacktrace during development. Avoid configuring such
# in production as building large stacktraces may be expensive.
config :phoenix, :stacktrace_depth, 20
config :phoenix_live_view,
# Include debug annotations and locations in rendered markup.
# Changing this configuration will require mix clean and a full recompile.
debug_heex_annotations: true,
debug_attributes: true,
# Enable helpful, but potentially expensive runtime checks
enable_expensive_runtime_checks: true
# Disable swoosh api client as it is only required for production adapters.
config :swoosh, :api_client, false
# Configure your database # Configure your database
config :towerops, Towerops.Repo, config :towerops, Towerops.Repo,
username: "postgres", username: "postgres",
@ -69,24 +90,3 @@ config :towerops, ToweropsWeb.Endpoint,
# Enable dev routes for dashboard and mailbox # Enable dev routes for dashboard and mailbox
config :towerops, dev_routes: true config :towerops, dev_routes: true
# Do not include metadata nor timestamps in development logs
config :logger, :default_formatter, format: "[$level] $message\n"
# Set a higher stacktrace during development. Avoid configuring such
# in production as building large stacktraces may be expensive.
config :phoenix, :stacktrace_depth, 20
# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime
config :phoenix_live_view,
# Include debug annotations and locations in rendered markup.
# Changing this configuration will require mix clean and a full recompile.
debug_heex_annotations: true,
debug_attributes: true,
# Enable helpful, but potentially expensive runtime checks
enable_expensive_runtime_checks: true
# Disable swoosh api client as it is only required for production adapters.
config :swoosh, :api_client, false

View file

@ -1,5 +1,14 @@
import Config import Config
# Do not print debug messages in production
config :logger, level: :info
# Configure Swoosh API Client
config :swoosh, api_client: Swoosh.ApiClient.Req
# Disable Swoosh Local Memory Storage
config :swoosh, local: false
# Note we also include the path to a cache manifest # Note we also include the path to a cache manifest
# containing the digested version of static files. This # containing the digested version of static files. This
# manifest is generated by the `mix assets.deploy` task, # manifest is generated by the `mix assets.deploy` task,
@ -14,17 +23,7 @@ config :towerops, ToweropsWeb.Endpoint,
force_ssl: [rewrite_on: [:x_forwarded_proto]], force_ssl: [rewrite_on: [:x_forwarded_proto]],
exclude: [ exclude: [
# paths: ["/health"], # paths: ["/health"],
# Runtime production configuration, including reading
# of environment variables, is done on config/runtime.exs.
hosts: ["localhost", "127.0.0.1"] hosts: ["localhost", "127.0.0.1"]
] ]
# Configure Swoosh API Client
config :swoosh, api_client: Swoosh.ApiClient.Req
# Disable Swoosh Local Memory Storage
config :swoosh, local: false
# Do not print debug messages in production
config :logger, level: :info
# Runtime production configuration, including reading
# of environment variables, is done on config/runtime.exs.

View file

@ -20,8 +20,7 @@ if System.get_env("PHX_SERVER") do
config :towerops, ToweropsWeb.Endpoint, server: true config :towerops, ToweropsWeb.Endpoint, server: true
end end
config :towerops, ToweropsWeb.Endpoint, config :towerops, ToweropsWeb.Endpoint, http: [port: String.to_integer(System.get_env("PORT", "4000"))]
http: [port: String.to_integer(System.get_env("PORT", "4000"))]
if config_env() == :prod do if config_env() == :prod do
database_url = database_url =
@ -33,14 +32,6 @@ if config_env() == :prod do
maybe_ipv6 = if System.get_env("ECTO_IPV6") in ~w(true 1), do: [:inet6], else: [] maybe_ipv6 = if System.get_env("ECTO_IPV6") in ~w(true 1), do: [:inet6], else: []
config :towerops, Towerops.Repo,
# ssl: true,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
# For machines with several cores, consider starting multiple pools of `pool_size`
# pool_count: 4,
socket_options: maybe_ipv6
# The secret key base is used to sign/encrypt cookies and other secrets. # The secret key base is used to sign/encrypt cookies and other secrets.
# A default value is used in config/dev.exs and config/test.exs but you # A default value is used in config/dev.exs and config/test.exs but you
# want to use a different value for prod and you most likely don't want # want to use a different value for prod and you most likely don't want
@ -55,7 +46,13 @@ if config_env() == :prod do
host = System.get_env("PHX_HOST") || "example.com" host = System.get_env("PHX_HOST") || "example.com"
config :towerops, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY") config :towerops, Towerops.Repo,
# ssl: true,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
# For machines with several cores, consider starting multiple pools of `pool_size`
# pool_count: 4,
socket_options: maybe_ipv6
config :towerops, ToweropsWeb.Endpoint, config :towerops, ToweropsWeb.Endpoint,
url: [host: host, port: 443, scheme: "https"], url: [host: host, port: 443, scheme: "https"],
@ -68,6 +65,8 @@ if config_env() == :prod do
], ],
secret_key_base: secret_key_base secret_key_base: secret_key_base
config :towerops, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY")
# ## SSL Support # ## SSL Support
# #
# To get SSL working, you will need to add the `https` key # To get SSL working, you will need to add the `https` key

View file

@ -1,5 +1,25 @@
import Config import Config
# Print only warnings and errors during test
config :logger, level: :warning
# Initialize plugs at runtime for faster test compilation
config :phoenix, :plug_init_mode, :runtime
# Sort query params output of verified routes for robust url comparisons
config :phoenix,
sort_verified_routes_query_params: true
# Enable helpful, but potentially expensive runtime checks
config :phoenix_live_view,
enable_expensive_runtime_checks: true
# Disable swoosh api client as it is only required for production adapters
config :swoosh, :api_client, false
# In test we don't send emails
config :towerops, Towerops.Mailer, adapter: Swoosh.Adapters.Test
# Configure your database # Configure your database
# #
# The MIX_TEST_PARTITION environment variable can be used # The MIX_TEST_PARTITION environment variable can be used
@ -19,23 +39,3 @@ config :towerops, ToweropsWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4002], http: [ip: {127, 0, 0, 1}, port: 4002],
secret_key_base: "XDSSqVUtRXUjEfzxefIAaPIzBfonpNMOrCRyP1a0kjPzzyOpVNSRmMBVae/bwTqj", secret_key_base: "XDSSqVUtRXUjEfzxefIAaPIzBfonpNMOrCRyP1a0kjPzzyOpVNSRmMBVae/bwTqj",
server: false server: false
# In test we don't send emails
config :towerops, Towerops.Mailer, adapter: Swoosh.Adapters.Test
# Disable swoosh api client as it is only required for production adapters
config :swoosh, :api_client, false
# Print only warnings and errors during test
config :logger, level: :warning
# Initialize plugs at runtime for faster test compilation
config :phoenix, :plug_init_mode, :runtime
# Enable helpful, but potentially expensive runtime checks
config :phoenix_live_view,
enable_expensive_runtime_checks: true
# Sort query params output of verified routes for robust url comparisons
config :phoenix,
sort_verified_routes_query_params: true

View file

@ -1,3 +1,4 @@
defmodule Towerops.Mailer do defmodule Towerops.Mailer do
@moduledoc false
use Swoosh.Mailer, otp_app: :towerops use Swoosh.Mailer, otp_app: :towerops
end end

View file

@ -23,10 +23,11 @@ defmodule ToweropsWeb do
quote do quote do
use Phoenix.Router, helpers: false use Phoenix.Router, helpers: false
# Import common connection and controller functions to use in pipelines
import Plug.Conn
import Phoenix.Controller import Phoenix.Controller
import Phoenix.LiveView.Router import Phoenix.LiveView.Router
# Import common connection and controller functions to use in pipelines
import Plug.Conn
end end
end end
@ -39,7 +40,6 @@ defmodule ToweropsWeb do
def controller do def controller do
quote do quote do
use Phoenix.Controller, formats: [:html, :json] use Phoenix.Controller, formats: [:html, :json]
use Gettext, backend: ToweropsWeb.Gettext use Gettext, backend: ToweropsWeb.Gettext
import Plug.Conn import Plug.Conn

View file

@ -29,6 +29,7 @@ defmodule ToweropsWeb.CoreComponents do
use Phoenix.Component use Phoenix.Component
use Gettext, backend: ToweropsWeb.Gettext use Gettext, backend: ToweropsWeb.Gettext
alias Phoenix.HTML.FormField
alias Phoenix.LiveView.JS alias Phoenix.LiveView.JS
@doc """ @doc """
@ -166,8 +167,7 @@ defmodule ToweropsWeb.CoreComponents do
values: ~w(checkbox color date datetime-local email file month number password values: ~w(checkbox color date datetime-local email file month number password
search select tel text textarea time url week hidden) search select tel text textarea time url week hidden)
attr :field, Phoenix.HTML.FormField, attr :field, FormField, doc: "a form field struct retrieved from the form, for example: @form[:email]"
doc: "a form field struct retrieved from the form, for example: @form[:email]"
attr :errors, :list, default: [] attr :errors, :list, default: []
attr :checked, :boolean, doc: "the checked flag for checkbox inputs" attr :checked, :boolean, doc: "the checked flag for checkbox inputs"
@ -177,11 +177,10 @@ defmodule ToweropsWeb.CoreComponents do
attr :class, :any, default: nil, doc: "the input class to use over defaults" attr :class, :any, default: nil, doc: "the input class to use over defaults"
attr :error_class, :any, default: nil, doc: "the input error class to use over defaults" attr :error_class, :any, default: nil, doc: "the input error class to use over defaults"
attr :rest, :global, attr :rest, :global, include: ~w(accept autocomplete capture cols disabled form list max maxlength min minlength
include: ~w(accept autocomplete capture cols disabled form list max maxlength min minlength
multiple pattern placeholder readonly required rows size step) multiple pattern placeholder readonly required rows size step)
def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do def input(%{field: %FormField{} = field} = assigns) do
errors = if Phoenix.Component.used_input?(field), do: field.errors, else: [] errors = if Phoenix.Component.used_input?(field), do: field.errors, else: []
assigns assigns
@ -452,8 +451,7 @@ defmodule ToweropsWeb.CoreComponents do
to: selector, to: selector,
time: 300, time: 300,
transition: transition:
{"transition-all ease-out duration-300", {"transition-all ease-out duration-300", "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
"opacity-100 translate-y-0 sm:scale-100"} "opacity-100 translate-y-0 sm:scale-100"}
) )
end end

View file

@ -1,5 +1,7 @@
defmodule ToweropsWeb.Telemetry do defmodule ToweropsWeb.Telemetry do
@moduledoc false
use Supervisor use Supervisor
import Telemetry.Metrics import Telemetry.Metrics
def start_link(arg) do def start_link(arg) do
@ -71,8 +73,7 @@ defmodule ToweropsWeb.Telemetry do
), ),
summary("towerops.repo.query.idle_time", summary("towerops.repo.query.idle_time",
unit: {:native, :millisecond}, unit: {:native, :millisecond},
description: description: "The time the connection spent waiting before being checked out for the query"
"The time the connection spent waiting before being checked out for the query"
), ),
# VM Metrics # VM Metrics

10
mix.exs
View file

@ -52,12 +52,7 @@ defmodule Towerops.MixProject do
{:esbuild, "~> 0.10", runtime: Mix.env() == :dev}, {:esbuild, "~> 0.10", runtime: Mix.env() == :dev},
{:tailwind, "~> 0.3", runtime: Mix.env() == :dev}, {:tailwind, "~> 0.3", runtime: Mix.env() == :dev},
{:heroicons, {:heroicons,
github: "tailwindlabs/heroicons", github: "tailwindlabs/heroicons", tag: "v2.2.0", sparse: "optimized", app: false, compile: false, depth: 1},
tag: "v2.2.0",
sparse: "optimized",
app: false,
compile: false,
depth: 1},
{:swoosh, "~> 1.16"}, {:swoosh, "~> 1.16"},
{:req, "~> 0.5"}, {:req, "~> 0.5"},
{:telemetry_metrics, "~> 1.0"}, {:telemetry_metrics, "~> 1.0"},
@ -65,7 +60,8 @@ defmodule Towerops.MixProject do
{:gettext, "~> 1.0"}, {:gettext, "~> 1.0"},
{:jason, "~> 1.2"}, {:jason, "~> 1.2"},
{:dns_cluster, "~> 0.2.0"}, {:dns_cluster, "~> 0.2.0"},
{:bandit, "~> 1.5"} {:bandit, "~> 1.5"},
{:styler, "~> 1.10", only: [:dev, :test], runtime: false}
] ]
end end

View file

@ -34,6 +34,7 @@
"plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"}, "plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"},
"postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"}, "postgrex": {:hex, :postgrex, "0.21.1", "2c5cc830ec11e7a0067dd4d623c049b3ef807e9507a424985b8dcf921224cd88", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "27d8d21c103c3cc68851b533ff99eef353e6a0ff98dc444ea751de43eb48bdac"},
"req": {:hex, :req, "0.5.16", "99ba6a36b014458e52a8b9a0543bfa752cb0344b2a9d756651db1281d4ba4450", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "974a7a27982b9b791df84e8f6687d21483795882a7840e8309abdbe08bb06f09"}, "req": {:hex, :req, "0.5.16", "99ba6a36b014458e52a8b9a0543bfa752cb0344b2a9d756651db1281d4ba4450", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "974a7a27982b9b791df84e8f6687d21483795882a7840e8309abdbe08bb06f09"},
"styler": {:hex, :styler, "1.10.0", "343f1f7bb19a8893c2841a9ae90665b68d2edf6cc37b964a5099e60c78815c2e", [:mix], [], "hexpm", "6a78876611869466139e63722df4cbbb56b18a842d88c19f23ca844d914ad91a"},
"swoosh": {:hex, :swoosh, "1.19.9", "4eb2c471b8cf06adbdcaa1d57a0ad53c0ed9348ce8586a06cc491f9f0dbcb553", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, "~> 6.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "516898263a64925c31723c56bc7999a26e97b04e869707f681f4c9bca7ee1688"}, "swoosh": {:hex, :swoosh, "1.19.9", "4eb2c471b8cf06adbdcaa1d57a0ad53c0ed9348ce8586a06cc491f9f0dbcb553", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:idna, "~> 6.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5.10 or ~> 0.6 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "516898263a64925c31723c56bc7999a26e97b04e869707f681f4c9bca7ee1688"},
"tailwind": {:hex, :tailwind, "0.4.1", "e7bcc222fe96a1e55f948e76d13dd84a1a7653fb051d2a167135db3b4b08d3e9", [:mix], [], "hexpm", "6249d4f9819052911120dbdbe9e532e6bd64ea23476056adb7f730aa25c220d1"}, "tailwind": {:hex, :tailwind, "0.4.1", "e7bcc222fe96a1e55f948e76d13dd84a1a7653fb051d2a167135db3b4b08d3e9", [:mix], [], "hexpm", "6249d4f9819052911120dbdbe9e532e6bd64ea23476056adb7f730aa25c220d1"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},

View file

@ -19,15 +19,15 @@ defmodule ToweropsWeb.ConnCase do
using do using do
quote do quote do
use ToweropsWeb, :verified_routes
import Phoenix.ConnTest
import Plug.Conn
import ToweropsWeb.ConnCase
# The default endpoint for testing # The default endpoint for testing
@endpoint ToweropsWeb.Endpoint @endpoint ToweropsWeb.Endpoint
use ToweropsWeb, :verified_routes
# Import conveniences for testing with connections # Import conveniences for testing with connections
import Plug.Conn
import Phoenix.ConnTest
import ToweropsWeb.ConnCase
end end
end end

View file

@ -16,14 +16,16 @@ defmodule Towerops.DataCase do
use ExUnit.CaseTemplate use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox
using do using do
quote do quote do
alias Towerops.Repo
import Ecto import Ecto
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query import Ecto.Query
import Towerops.DataCase import Towerops.DataCase
alias Towerops.Repo
end end
end end
@ -36,8 +38,8 @@ defmodule Towerops.DataCase do
Sets up the sandbox based on the test tags. Sets up the sandbox based on the test tags.
""" """
def setup_sandbox(tags) do def setup_sandbox(tags) do
pid = Ecto.Adapters.SQL.Sandbox.start_owner!(Towerops.Repo, shared: not tags[:async]) pid = Sandbox.start_owner!(Towerops.Repo, shared: not tags[:async])
on_exit(fn -> Ecto.Adapters.SQL.Sandbox.stop_owner(pid) end) on_exit(fn -> Sandbox.stop_owner(pid) end)
end end
@doc """ @doc """