Add Styler

This commit is contained in:
Fabian Becker 2025-01-27 14:44:09 +01:00
parent c5b01954d7
commit df1b84d5f4
34 changed files with 198 additions and 193 deletions

View File

@ -1,6 +1,6 @@
[ [
import_deps: [:oban, :ecto, :ecto_sql, :phoenix], import_deps: [:oban, :ecto, :ecto_sql, :phoenix],
subdirectories: ["priv/*/migrations"], subdirectories: ["priv/*/migrations"],
plugins: [Phoenix.LiveView.HTMLFormatter], plugins: [Phoenix.LiveView.HTMLFormatter, Styler],
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,46 +7,23 @@
# General application configuration # General application configuration
import Config import Config
config :tradex, Oban,
engine: Oban.Engines.Basic,
notifier: Oban.Notifiers.Postgres,
queues: [default: 10],
repo: Tradex.Repo
config :tradex,
ecto_repos: [Tradex.Repo],
generators: [timestamp_type: :utc_datetime]
# Configures the endpoint
config :tradex, TradexWeb.Endpoint,
url: [host: "localhost"],
adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: TradexWeb.ErrorHTML, json: TradexWeb.ErrorJSON],
layout: false
],
pubsub_server: Tradex.PubSub,
live_view: [signing_salt: "i4cu1T7m"]
# Configures 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 :tradex, Tradex.Mailer, adapter: Swoosh.Adapters.Local
# Configure esbuild (the version is required) # Configure esbuild (the version is required)
config :esbuild, config :esbuild,
version: "0.17.11", version: "0.17.11",
tradex: [ tradex: [
args: args: ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../assets", __DIR__), cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)} env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
] ]
# Configures Elixir's Logger
config :logger, :console,
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: "3.4.3", version: "3.4.3",
@ -59,14 +36,36 @@ config :tailwind,
cd: Path.expand("../assets", __DIR__) cd: Path.expand("../assets", __DIR__)
] ]
# Configures Elixir's Logger config :tradex, Oban,
config :logger, :console, engine: Oban.Engines.Basic,
format: "$time $metadata[$level] $message\n", notifier: Oban.Notifiers.Postgres,
metadata: [:request_id] queues: [default: 10],
repo: Tradex.Repo
# Use Jason for JSON parsing in Phoenix # Configures the mailer
config :phoenix, :json_library, Jason #
# 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 :tradex, Tradex.Mailer, adapter: Swoosh.Adapters.Local
# Configures the endpoint
config :tradex, TradexWeb.Endpoint,
url: [host: "localhost"],
adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: TradexWeb.ErrorHTML, json: TradexWeb.ErrorJSON],
layout: false
],
pubsub_server: Tradex.PubSub,
live_view: [signing_salt: "i4cu1T7m"]
config :tradex,
# 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.
ecto_repos: [Tradex.Repo],
generators: [timestamp_type: :utc_datetime]
import_config "#{config_env()}.exs" import_config "#{config_env()}.exs"

View File

@ -1,38 +1,48 @@
import Config import Config
# Do not include metadata nor timestamps in development logs
config :logger, :console, 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 HEEx debug annotations as HTML comments in rendered markup
debug_heex_annotations: 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 :tradex, Tradex.Repo, config :tradex, Tradex.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "tradex_dev",
stacktrace: true,
show_sensitive_data_on_connection_error: true,
pool_size: 10
# For development, we disable any cache and enable # For development, we disable any cache and enable
# debugging and code reloading. # debugging and code reloading.
# #
# The watchers configuration can be used to run external # The watchers configuration can be used to run external
# watchers to your application. For example, we can use it # watchers to your application. For example, we can use it
# to bundle .js and .css sources.
config :tradex, TradexWeb.Endpoint,
# Binding to loopback ipv4 address prevents access from other machines.
# Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
http: [ip: {127, 0, 0, 1}, port: 4000],
check_origin: false,
code_reloader: true,
debug_errors: true,
secret_key_base: "IMdo6qGMCe4KxTZHusF2cNLuwIoqvRwfM+WgmZIEP+T/fVdg1VSIU1nCPV7ee2SX",
watchers: [
esbuild: {Esbuild, :install_and_run, [:tradex, ~w(--sourcemap=inline --watch)]},
tailwind: {Tailwind, :install_and_run, [:tradex, ~w(--watch)]}
]
# ## SSL Support # ## SSL Support
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "tradex_dev",
stacktrace: true,
# to bundle .js and .css sources.
# #
# In order to use HTTPS in development, a self-signed # In order to use HTTPS in development, a self-signed
show_sensitive_data_on_connection_error: true,
pool_size: 10
config :tradex, TradexWeb.Endpoint,
# Binding to loopback ipv4 address prevents access from other machines.
# certificate can be generated by running the following # certificate can be generated by running the following
# Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
# Mix task: # Mix task:
# #
# mix phx.gen.cert # mix phx.gen.cert
@ -44,6 +54,17 @@ config :tradex, TradexWeb.Endpoint,
# https: [ # https: [
# port: 4001, # port: 4001,
# cipher_suite: :strong, # cipher_suite: :strong,
http: [ip: {127, 0, 0, 1}, port: 4000],
check_origin: false,
code_reloader: true,
debug_errors: true,
secret_key_base: "IMdo6qGMCe4KxTZHusF2cNLuwIoqvRwfM+WgmZIEP+T/fVdg1VSIU1nCPV7ee2SX",
watchers: [
esbuild: {Esbuild, :install_and_run, [:tradex, ~w(--sourcemap=inline --watch)]},
tailwind: {Tailwind, :install_and_run, [:tradex, ~w(--watch)]}
]
# Watch static and templates for browser reloading.
# keyfile: "priv/cert/selfsigned_key.pem", # keyfile: "priv/cert/selfsigned_key.pem",
# certfile: "priv/cert/selfsigned.pem" # certfile: "priv/cert/selfsigned.pem"
# ], # ],
@ -52,7 +73,6 @@ config :tradex, TradexWeb.Endpoint,
# configured to run both http and https servers on # configured to run both http and https servers on
# different ports. # different ports.
# Watch static and templates for browser reloading.
config :tradex, TradexWeb.Endpoint, config :tradex, TradexWeb.Endpoint,
live_reload: [ live_reload: [
patterns: [ patterns: [
@ -64,22 +84,3 @@ config :tradex, TradexWeb.Endpoint,
# Enable dev routes for dashboard and mailbox # Enable dev routes for dashboard and mailbox
config :tradex, dev_routes: true config :tradex, dev_routes: true
# Do not include metadata nor timestamps in development logs
config :logger, :console, 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 HEEx debug annotations as HTML comments in rendered markup
debug_heex_annotations: 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,20 +1,21 @@
import Config import Config
# Note we also include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the `mix assets.deploy` task,
# which you should run after static files are built and
# before starting your production server.
config :tradex, TradexWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json"
# Configures Swoosh API Client
config :swoosh, api_client: Swoosh.ApiClient.Finch, finch_name: Tradex.Finch
# Disable Swoosh Local Memory Storage
config :swoosh, local: false
# Do not print debug messages in production # Do not print debug messages in production
config :logger, level: :info config :logger, level: :info
# Configures Swoosh API Client
config :swoosh, api_client: Swoosh.ApiClient.Finch, finch_name: Tradex.Finch
# Note we also include the path to a cache manifest
# containing the digested version of static files. This
# Disable Swoosh Local Memory Storage
# manifest is generated by the `mix assets.deploy` task,
# which you should run after static files are built and
# before starting your production server.
config :swoosh, local: false
config :tradex, TradexWeb.Endpoint, cache_static_manifest: "priv/static/cache_manifest.json"
# Runtime production configuration, including reading # Runtime production configuration, including reading
# of environment variables, is done on config/runtime.exs. # of environment variables, is done on config/runtime.exs.

View File

@ -30,12 +30,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 :tradex, Tradex.Repo,
# ssl: true,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
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
@ -51,7 +45,11 @@ if config_env() == :prod do
host = System.get_env("PHX_HOST") || "example.com" host = System.get_env("PHX_HOST") || "example.com"
port = String.to_integer(System.get_env("PORT") || "4000") port = String.to_integer(System.get_env("PORT") || "4000")
config :tradex, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY") config :tradex, Tradex.Repo,
# ssl: true,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
socket_options: maybe_ipv6
config :tradex, TradexWeb.Endpoint, config :tradex, TradexWeb.Endpoint,
url: [host: host, port: 443, scheme: "https"], url: [host: host, port: 443, scheme: "https"],
@ -65,6 +63,8 @@ if config_env() == :prod do
], ],
secret_key_base: secret_key_base secret_key_base: secret_key_base
config :tradex, :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,35 +1,8 @@
import Config import Config
config :tradex, Oban, testing: :manual
# Only in tests, remove the complexity from the password hashing algorithm # Only in tests, remove the complexity from the password hashing algorithm
config :bcrypt_elixir, :log_rounds, 1 config :bcrypt_elixir, :log_rounds, 1
# Configure your database
#
# The MIX_TEST_PARTITION environment variable can be used
# to provide built-in test partitioning in CI environment.
# Run `mix help test` for more information.
config :tradex, Tradex.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "tradex_test#{System.get_env("MIX_TEST_PARTITION")}",
pool: Ecto.Adapters.SQL.Sandbox,
pool_size: System.schedulers_online() * 2
# We don't run a server during test. If one is required,
# you can enable the server option below.
config :tradex, TradexWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4002],
secret_key_base: "pP8HLCaUfsAaCuJWdmHExGTUqj83ZvuIvjiWhCcXZx/FeGvxTukgbhirVEby/WHn",
server: false
# In test we don't send emails
config :tradex, Tradex.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 # Print only warnings and errors during test
config :logger, level: :warning config :logger, level: :warning
@ -39,3 +12,31 @@ config :phoenix, :plug_init_mode, :runtime
# Enable helpful, but potentially expensive runtime checks # Enable helpful, but potentially expensive runtime checks
config :phoenix_live_view, config :phoenix_live_view,
enable_expensive_runtime_checks: true 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
#
# The MIX_TEST_PARTITION environment variable can be used
config :tradex, Oban, testing: :manual
# In test we don't send emails
# to provide built-in test partitioning in CI environment.
# Run `mix help test` for more information.
config :tradex, Tradex.Mailer, adapter: Swoosh.Adapters.Test
config :tradex, Tradex.Repo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "tradex_test#{System.get_env("MIX_TEST_PARTITION")}",
pool: Ecto.Adapters.SQL.Sandbox,
# We don't run a server during test. If one is required,
# you can enable the server option below.
pool_size: System.schedulers_online() * 2
config :tradex, TradexWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4002],
secret_key_base: "pP8HLCaUfsAaCuJWdmHExGTUqj83ZvuIvjiWhCcXZx/FeGvxTukgbhirVEby/WHn",
server: false

View File

@ -4,9 +4,11 @@ defmodule Tradex.Accounts do
""" """
import Ecto.Query, warn: false import Ecto.Query, warn: false
alias Tradex.Repo
alias Tradex.Accounts.{User, UserToken, UserNotifier} alias Tradex.Accounts.User
alias Tradex.Accounts.UserNotifier
alias Tradex.Accounts.UserToken
alias Tradex.Repo
## Database getters ## Database getters
@ -38,8 +40,7 @@ defmodule Tradex.Accounts do
nil nil
""" """
def get_user_by_email_and_password(email, password) def get_user_by_email_and_password(email, password) when is_binary(email) and is_binary(password) do
when is_binary(email) and is_binary(password) do
user = Repo.get_by(User, email: email) user = Repo.get_by(User, email: email)
if User.valid_password?(user, password), do: user if User.valid_password?(user, password), do: user
end end

View File

@ -1,5 +1,7 @@
defmodule Tradex.Accounts.User do defmodule Tradex.Accounts.User do
@moduledoc false
use Tradex.Schema use Tradex.Schema
import Ecto.Changeset import Ecto.Changeset
schema "users" do schema "users" do
@ -126,7 +128,7 @@ defmodule Tradex.Accounts.User do
Confirms the account by setting `confirmed_at`. Confirms the account by setting `confirmed_at`.
""" """
def confirm_changeset(user) do def confirm_changeset(user) do
now = DateTime.utc_now() |> DateTime.truncate(:second) now = DateTime.truncate(DateTime.utc_now(), :second)
change(user, confirmed_at: now) change(user, confirmed_at: now)
end end

View File

@ -1,4 +1,5 @@
defmodule Tradex.Accounts.UserNotifier do defmodule Tradex.Accounts.UserNotifier do
@moduledoc false
import Swoosh.Email import Swoosh.Email
alias Tradex.Mailer alias Tradex.Mailer

View File

@ -1,6 +1,9 @@
defmodule Tradex.Accounts.UserToken do defmodule Tradex.Accounts.UserToken do
@moduledoc false
use Tradex.Schema use Tradex.Schema
import Ecto.Query import Ecto.Query
alias Tradex.Accounts.UserToken alias Tradex.Accounts.UserToken
@hash_algorithm :sha256 @hash_algorithm :sha256

View File

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

View File

@ -1,4 +1,5 @@
defmodule Tradex.Schema do defmodule Tradex.Schema do
@moduledoc false
defmacro __using__(opts) do defmacro __using__(opts) do
quote do quote do
use Ecto.Schema use Ecto.Schema

View File

@ -23,10 +23,11 @@ defmodule TradexWeb 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

View File

@ -17,6 +17,7 @@ defmodule TradexWeb.CoreComponents do
use Phoenix.Component use Phoenix.Component
use Gettext, backend: TradexWeb.Gettext use Gettext, backend: TradexWeb.Gettext
alias Phoenix.HTML.FormField
alias Phoenix.LiveView.JS alias Phoenix.LiveView.JS
@doc """ @doc """
@ -278,8 +279,7 @@ defmodule TradexWeb.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
range search select tel text textarea time url week) range search select tel text textarea time url week)
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"
@ -287,11 +287,10 @@ defmodule TradexWeb.CoreComponents do
attr :options, :list, doc: "the options to pass to Phoenix.HTML.Form.options_for_select/2" attr :options, :list, doc: "the options to pass to Phoenix.HTML.Form.options_for_select/2"
attr :multiple, :boolean, default: false, doc: "the multiple flag for select inputs" attr :multiple, :boolean, default: false, doc: "the multiple flag for select inputs"
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
@ -604,8 +603,7 @@ defmodule TradexWeb.CoreComponents do
to: selector, to: selector,
time: 300, time: 300,
transition: transition:
{"transition-all transform ease-out duration-300", {"transition-all transform 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
@ -615,8 +613,7 @@ defmodule TradexWeb.CoreComponents do
to: selector, to: selector,
time: 200, time: 200,
transition: transition:
{"transition-all transform ease-in duration-200", {"transition-all transform ease-in duration-200", "opacity-100 translate-y-0 sm:scale-100",
"opacity-100 translate-y-0 sm:scale-100",
"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"} "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"}
) )
end end

View File

@ -1,4 +1,5 @@
defmodule TradexWeb.UserConfirmationInstructionsLive do defmodule TradexWeb.UserConfirmationInstructionsLive do
@moduledoc false
use TradexWeb, :live_view use TradexWeb, :live_view
alias Tradex.Accounts alias Tradex.Accounts

View File

@ -1,4 +1,5 @@
defmodule TradexWeb.UserConfirmationLive do defmodule TradexWeb.UserConfirmationLive do
@moduledoc false
use TradexWeb, :live_view use TradexWeb, :live_view
alias Tradex.Accounts alias Tradex.Accounts

View File

@ -1,4 +1,5 @@
defmodule TradexWeb.UserForgotPasswordLive do defmodule TradexWeb.UserForgotPasswordLive do
@moduledoc false
use TradexWeb, :live_view use TradexWeb, :live_view
alias Tradex.Accounts alias Tradex.Accounts

View File

@ -1,4 +1,5 @@
defmodule TradexWeb.UserLoginLive do defmodule TradexWeb.UserLoginLive do
@moduledoc false
use TradexWeb, :live_view use TradexWeb, :live_view
def render(assigns) do def render(assigns) do

View File

@ -1,4 +1,5 @@
defmodule TradexWeb.UserRegistrationLive do defmodule TradexWeb.UserRegistrationLive do
@moduledoc false
use TradexWeb, :live_view use TradexWeb, :live_view
alias Tradex.Accounts alias Tradex.Accounts

View File

@ -1,4 +1,5 @@
defmodule TradexWeb.UserResetPasswordLive do defmodule TradexWeb.UserResetPasswordLive do
@moduledoc false
use TradexWeb, :live_view use TradexWeb, :live_view
alias Tradex.Accounts alias Tradex.Accounts

View File

@ -1,4 +1,5 @@
defmodule TradexWeb.UserSettingsLive do defmodule TradexWeb.UserSettingsLive do
@moduledoc false
use TradexWeb, :live_view use TradexWeb, :live_view
alias Tradex.Accounts alias Tradex.Accounts

View File

@ -1,5 +1,7 @@
defmodule TradexWeb.Telemetry do defmodule TradexWeb.Telemetry do
@moduledoc false
use Supervisor use Supervisor
import Telemetry.Metrics import Telemetry.Metrics
def start_link(arg) do def start_link(arg) do
@ -70,8 +72,7 @@ defmodule TradexWeb.Telemetry do
), ),
summary("tradex.repo.query.idle_time", summary("tradex.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

View File

@ -1,8 +1,9 @@
defmodule TradexWeb.UserAuth do defmodule TradexWeb.UserAuth do
@moduledoc false
use TradexWeb, :verified_routes use TradexWeb, :verified_routes
import Plug.Conn
import Phoenix.Controller import Phoenix.Controller
import Plug.Conn
alias Tradex.Accounts alias Tradex.Accounts

10
mix.exs
View File

@ -45,12 +45,7 @@ defmodule Tradex.MixProject do
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev}, {:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
{:tailwind, "~> 0.2", runtime: Mix.env() == :dev}, {:tailwind, "~> 0.2", runtime: Mix.env() == :dev},
{:heroicons, {:heroicons,
github: "tailwindlabs/heroicons", github: "tailwindlabs/heroicons", tag: "v2.1.1", sparse: "optimized", app: false, compile: false, depth: 1},
tag: "v2.1.1",
sparse: "optimized",
app: false,
compile: false,
depth: 1},
{:swoosh, "~> 1.5"}, {:swoosh, "~> 1.5"},
{:finch, "~> 0.13"}, {:finch, "~> 0.13"},
{:telemetry_metrics, "~> 1.0"}, {:telemetry_metrics, "~> 1.0"},
@ -61,7 +56,8 @@ defmodule Tradex.MixProject do
{:bandit, "~> 1.5"}, {:bandit, "~> 1.5"},
{:uuidv7, "~> 1.0"}, {:uuidv7, "~> 1.0"},
{:igniter, "~> 0.5"}, {:igniter, "~> 0.5"},
{:oban, "~> 2.19"} {:oban, "~> 2.19"},
{:styler, "~> 1.2", only: [:dev, :test], runtime: false}
] ]
end end

View File

@ -42,6 +42,7 @@
"rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"}, "rewrite": {:hex, :rewrite, "1.1.2", "f5a5d10f5fed1491a6ff48e078d4585882695962ccc9e6c779bae025d1f92eda", [:mix], [{:glob_ex, "~> 0.1", [hex: :glob_ex, repo: "hexpm", optional: false]}, {:sourceror, "~> 1.0", [hex: :sourceror, repo: "hexpm", optional: false]}, {:text_diff, "~> 0.1", [hex: :text_diff, repo: "hexpm", optional: false]}], "hexpm", "7f8b94b1e3528d0a47b3e8b7bfeca559d2948a65fa7418a9ad7d7712703d39d4"},
"sourceror": {:hex, :sourceror, "1.7.1", "599d78f4cc2be7d55c9c4fd0a8d772fd0478e3a50e726697c20d13d02aa056d4", [:mix], [], "hexpm", "cd6f268fe29fa00afbc535e215158680a0662b357dc784646d7dff28ac65a0fc"}, "sourceror": {:hex, :sourceror, "1.7.1", "599d78f4cc2be7d55c9c4fd0a8d772fd0478e3a50e726697c20d13d02aa056d4", [:mix], [], "hexpm", "cd6f268fe29fa00afbc535e215158680a0662b357dc784646d7dff28ac65a0fc"},
"spitfire": {:hex, :spitfire, "0.1.4", "8fe0df66e735323e4f2a56e719603391b160dd68efd922cadfbb85a2cf6c68af", [:mix], [], "hexpm", "d40d850f4ede5235084876246756b90c7bcd12994111d57c55e2e1e23ac3fe61"}, "spitfire": {:hex, :spitfire, "0.1.4", "8fe0df66e735323e4f2a56e719603391b160dd68efd922cadfbb85a2cf6c68af", [:mix], [], "hexpm", "d40d850f4ede5235084876246756b90c7bcd12994111d57c55e2e1e23ac3fe61"},
"styler": {:hex, :styler, "1.3.3", "5196fc9e9bf1254af4337b051103d38532c2f500b0f01bc6f53f56ee678f65e6", [:mix], [], "hexpm", "c275f73f2ff1b7dfafb03a0f8cf3e928709a235a2b049162b40168f53ba3a07c"},
"swoosh": {:hex, :swoosh, "1.17.6", "27ff070f96246e35b7105ab1c52b2b689f523a3cb83ed9faadb2f33bd653ccba", [: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]}, {: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 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9798f3e72165f40c950f6762c06dab68afcdcf616138fc4a07965c09c250e1e2"}, "swoosh": {:hex, :swoosh, "1.17.6", "27ff070f96246e35b7105ab1c52b2b689f523a3cb83ed9faadb2f33bd653ccba", [: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]}, {: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 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9798f3e72165f40c950f6762c06dab68afcdcf616138fc4a07965c09c250e1e2"},
"tailwind": {:hex, :tailwind, "0.2.4", "5706ec47182d4e7045901302bf3a333e80f3d1af65c442ba9a9eed152fb26c2e", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "c6e4a82b8727bab593700c998a4d98cf3d8025678bfde059aed71d0000c3e463"}, "tailwind": {:hex, :tailwind, "0.2.4", "5706ec47182d4e7045901302bf3a333e80f3d1af65c442ba9a9eed152fb26c2e", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "c6e4a82b8727bab593700c998a4d98cf3d8025678bfde059aed71d0000c3e463"},
"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,14 @@ defmodule TradexWeb.ConnCase do
using do using do
quote do quote do
use TradexWeb, :verified_routes
import Phoenix.ConnTest
import Plug.Conn
import TradexWeb.ConnCase
# The default endpoint for testing # The default endpoint for testing
@endpoint TradexWeb.Endpoint @endpoint TradexWeb.Endpoint
use TradexWeb, :verified_routes
# Import conveniences for testing with connections # Import conveniences for testing with connections
import Plug.Conn
import Phoenix.ConnTest
import TradexWeb.ConnCase
end end
end end

View File

@ -16,14 +16,16 @@ defmodule Tradex.DataCase do
use ExUnit.CaseTemplate use ExUnit.CaseTemplate
alias Ecto.Adapters.SQL.Sandbox
using do using do
quote do quote do
alias Tradex.Repo
import Ecto import Ecto
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query import Ecto.Query
import Tradex.DataCase import Tradex.DataCase
alias Tradex.Repo
end end
end end
@ -36,8 +38,8 @@ defmodule Tradex.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!(Tradex.Repo, shared: not tags[:async]) pid = Sandbox.start_owner!(Tradex.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 """

View File

@ -1,10 +1,11 @@
defmodule Tradex.AccountsTest do defmodule Tradex.AccountsTest do
use Tradex.DataCase use Tradex.DataCase
alias Tradex.Accounts
import Tradex.AccountsFixtures import Tradex.AccountsFixtures
alias Tradex.Accounts.{User, UserToken}
alias Tradex.Accounts
alias Tradex.Accounts.User
alias Tradex.Accounts.UserToken
describe "get_user_by_email/1" do describe "get_user_by_email/1" do
test "does not return the user if the email does not exist" do test "does not return the user if the email does not exist" do

View File

@ -56,13 +56,9 @@ defmodule TradexWeb.UserSessionControllerTest do
test "login following registration", %{conn: conn, user: user} do test "login following registration", %{conn: conn, user: user} do
conn = conn =
conn post(conn, ~p"/users/log_in", %{
|> post(~p"/users/log_in", %{
"_action" => "registered", "_action" => "registered",
"user" => %{ "user" => %{"email" => user.email, "password" => valid_user_password()}
"email" => user.email,
"password" => valid_user_password()
}
}) })
assert redirected_to(conn) == ~p"/" assert redirected_to(conn) == ~p"/"
@ -71,13 +67,9 @@ defmodule TradexWeb.UserSessionControllerTest do
test "login following password update", %{conn: conn, user: user} do test "login following password update", %{conn: conn, user: user} do
conn = conn =
conn post(conn, ~p"/users/log_in", %{
|> post(~p"/users/log_in", %{
"_action" => "password_updated", "_action" => "password_updated",
"user" => %{ "user" => %{"email" => user.email, "password" => valid_user_password()}
"email" => user.email,
"password" => valid_user_password()
}
}) })
assert redirected_to(conn) == ~p"/users/settings" assert redirected_to(conn) == ~p"/users/settings"

View File

@ -55,9 +55,7 @@ defmodule TradexWeb.UserConfirmationLiveTest do
"User confirmation link is invalid or it has expired" "User confirmation link is invalid or it has expired"
# when logged in # when logged in
conn = conn = log_in_user(build_conn(), user)
build_conn()
|> log_in_user(user)
{:ok, lv, _html} = live(conn, ~p"/users/confirm/#{token}") {:ok, lv, _html} = live(conn, ~p"/users/confirm/#{token}")

View File

@ -45,9 +45,7 @@ defmodule TradexWeb.UserLoginLiveTest do
{:ok, lv, _html} = live(conn, ~p"/users/log_in") {:ok, lv, _html} = live(conn, ~p"/users/log_in")
form = form =
form(lv, "#login_form", form(lv, "#login_form", user: %{email: "test@email.com", password: "123456", remember_me: true})
user: %{email: "test@email.com", password: "123456", remember_me: true}
)
conn = submit_form(form, conn) conn = submit_form(form, conn)

View File

@ -39,9 +39,7 @@ defmodule TradexWeb.UserResetPasswordLiveTest do
result = result =
lv lv
|> element("#reset_password_form") |> element("#reset_password_form")
|> render_change( |> render_change(user: %{"password" => "secret12", "password_confirmation" => "secret123456"})
user: %{"password" => "secret12", "password_confirmation" => "secret123456"}
)
assert result =~ "should be at least 12 character" assert result =~ "should be at least 12 character"
assert result =~ "does not match password" assert result =~ "does not match password"

View File

@ -1,10 +1,11 @@
defmodule TradexWeb.UserSettingsLiveTest do defmodule TradexWeb.UserSettingsLiveTest do
use TradexWeb.ConnCase, async: true use TradexWeb.ConnCase, async: true
alias Tradex.Accounts
import Phoenix.LiveViewTest import Phoenix.LiveViewTest
import Tradex.AccountsFixtures import Tradex.AccountsFixtures
alias Tradex.Accounts
describe "Settings page" do describe "Settings page" do
test "renders settings page", %{conn: conn} do test "renders settings page", %{conn: conn} do
{:ok, _lv, html} = {:ok, _lv, html} =

View File

@ -1,10 +1,11 @@
defmodule TradexWeb.UserAuthTest do defmodule TradexWeb.UserAuthTest do
use TradexWeb.ConnCase, async: true use TradexWeb.ConnCase, async: true
import Tradex.AccountsFixtures
alias Phoenix.LiveView alias Phoenix.LiveView
alias Tradex.Accounts alias Tradex.Accounts
alias TradexWeb.UserAuth alias TradexWeb.UserAuth
import Tradex.AccountsFixtures
@remember_me_cookie "_tradex_web_user_remember_me" @remember_me_cookie "_tradex_web_user_remember_me"
@ -139,7 +140,7 @@ defmodule TradexWeb.UserAuthTest do
end end
test "assigns nil to current_user assign if there isn't a user_token", %{conn: conn} do test "assigns nil to current_user assign if there isn't a user_token", %{conn: conn} do
session = conn |> get_session() session = get_session(conn)
{:cont, updated_socket} = {:cont, updated_socket} =
UserAuth.on_mount(:mount_current_user, %{}, session, %LiveView.Socket{}) UserAuth.on_mount(:mount_current_user, %{}, session, %LiveView.Socket{})
@ -173,7 +174,7 @@ defmodule TradexWeb.UserAuthTest do
end end
test "redirects to login page if there isn't a user_token", %{conn: conn} do test "redirects to login page if there isn't a user_token", %{conn: conn} do
session = conn |> get_session() session = get_session(conn)
socket = %LiveView.Socket{ socket = %LiveView.Socket{
endpoint: TradexWeb.Endpoint, endpoint: TradexWeb.Endpoint,
@ -200,7 +201,7 @@ defmodule TradexWeb.UserAuthTest do
end end
test "doesn't redirect if there is no authenticated user", %{conn: conn} do test "doesn't redirect if there is no authenticated user", %{conn: conn} do
session = conn |> get_session() session = get_session(conn)
assert {:cont, _updated_socket} = assert {:cont, _updated_socket} =
UserAuth.on_mount( UserAuth.on_mount(