Skip to content

Commit

Permalink
Create accounts via internal functions
Browse files Browse the repository at this point in the history
  • Loading branch information
oestrich committed Mar 7, 2019
1 parent e91d9d0 commit 9790f3f
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .projections.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"priv/repo/migrations": { "type": "migration" },
"lib/*.ex": { "alternate": "test/{}_test.exs" },
"test/*_test.exs": { "alternate": "lib/{}.ex" }
}
17 changes: 17 additions & 0 deletions lib/idea_portal/accounts.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule IdeaPortal.Accounts do
@moduledoc """
Context for user accounts
"""

alias IdeaPortal.Accounts.User
alias IdeaPortal.Repo

@doc """
Register an account
"""
def register(params) do
%User{}
|> User.create_changeset(params)
|> Repo.insert()
end
end
35 changes: 35 additions & 0 deletions lib/idea_portal/accounts/user.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
defmodule IdeaPortal.Accounts.User do
@moduledoc """
User schema
"""

use Ecto.Schema

import Ecto.Changeset

@type t :: %__MODULE__{}

schema "users" do
field(:email, :string)
field(:password_hash, :string)
field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true)

field(:first_name, :string)
field(:last_name, :string)
field(:phone_number, :string)

timestamps()
end

def create_changeset(struct, params) do
struct
|> cast(params, [:email, :password, :password_confirmation, :first_name, :last_name, :phone_number])
|> validate_required([:email, :first_name, :last_name])
|> validate_confirmation(:password)
|> validate_format(:email, ~r/.+@.+\..+/)
|> Stein.Accounts.hash_password()
|> validate_required([:password_hash])
|> unique_constraint(:email, name: :users_lower_email_index)
end
end
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ defmodule IdeaPortal.MixProject do
{:phoenix_live_reload, "~> 1.2", only: :dev},
{:phoenix_pubsub, "~> 1.1"},
{:plug_cowboy, "~> 2.0"},
{:postgrex, ">= 0.0.0"}
{:postgrex, ">= 0.0.0"},
{:stein, git: "https://github.com/smartlogic/stein.git"},
]
end

Expand Down
4 changes: 4 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
%{
"bcrypt_elixir": {:hex, :bcrypt_elixir, "2.0.1", "1061e2114aaac554c12e5c1e4608bf4aadaca839f30d1b85224272facd5e6427", [:make, :mix], [{:comeonin, "~> 5.1", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"comeonin": {:hex, :comeonin, "5.1.0", "dc7dc04cc2fd12ffee16ddf3f91e876ee1a686447be403baf6f89da38e215365", [:mix], [], "hexpm"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"cowboy": {:hex, :cowboy, "2.6.1", "f2e06f757c337b3b311f9437e6e072b678fcd71545a7b2865bdaa154d078593f", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"},
Expand All @@ -8,6 +10,7 @@
"decimal": {:hex, :decimal, "1.7.0", "30d6b52c88541f9a66637359ddf85016df9eb266170d53105f02e4a67e00c5aa", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.0.7", "44dda84ac6b17bbbdeb8ac5dfef08b7da253b37a453c34ab1a98de7f7e5fec7f", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_sql": {:hex, :ecto_sql, "3.0.5", "7e44172b4f7aca4469f38d7f6a3da394dbf43a1bcf0ca975e958cb957becd74e", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.6", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"elixir_make": {:hex, :elixir_make, "0.5.2", "96a28c79f5b8d34879cd95ebc04d2a0d678cfbbd3e74c43cb63a76adf0ee8054", [:mix], [], "hexpm"},
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
"gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
Expand All @@ -22,5 +25,6 @@
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.14.1", "63247d4a5ad6b9de57a0bac5d807e1c32d41e39c04b8a4156a26c63bcd8a2e49", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},
"stein": {:git, "https://github.com/smartlogic/stein.git", "0e4540bca905799c56e3ad89ad3eb15cfb759a0a", []},
"telemetry": {:hex, :telemetry, "0.3.0", "099a7f3ce31e4780f971b4630a3c22ec66d22208bc090fe33a2a3a6a67754a73", [:rebar3], [], "hexpm"},
}
18 changes: 18 additions & 0 deletions priv/repo/migrations/20190307162931_create_users.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule IdeaPortal.Repo.Migrations.CreateUsers do
use Ecto.Migration

def change do
create table("users") do
add(:email, :string, null: false)
add(:password_hash, :string, null: false)

add(:first_name, :string, null: false)
add(:last_name, :string, null: false)
add(:phone_number, :string, null: true)

timestamps()
end

create index(:users, ["lower(email)"], unique: true)
end
end
15 changes: 15 additions & 0 deletions test/idea_portal/accounts/user_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule IdeaPortal.Accounts.UserTest do
use ExUnit.Case

alias IdeaPortal.Accounts.User

describe "validations" do
test "email format" do
changeset = User.create_changeset(%User{}, %{email: "[email protected]"})
refute changeset.errors[:email]

changeset = User.create_changeset(%User{}, %{email: "userexample.com"})
assert changeset.errors[:email]
end
end
end
53 changes: 53 additions & 0 deletions test/idea_portal/accounts_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
defmodule IdeaPortal.AccountsTest do
use IdeaPortal.DataCase

alias IdeaPortal.Accounts

describe "registering an account" do
test "creating successfully" do
{:ok, account} = Accounts.register(%{
email: "[email protected]",
first_name: "John",
last_name: "Smith",
phone_number: "123-123-1234",
password: "password",
password_confirmation: "password"
})

assert account.email == "[email protected]"
assert account.password_hash
end

test "unique emails" do
{:ok, account} = Accounts.register(%{
email: "[email protected]",
first_name: "John",
last_name: "Smith",
phone_number: "123-123-1234",
password: "password",
password_confirmation: "password"
})

{:error, changeset} = Accounts.register(%{
email: account.email,
first_name: "John",
last_name: "Smith",
password: "password",
password_confirmation: "password"
})

assert changeset.errors[:email]
end

test "with errors" do
{:error, changeset} = Accounts.register(%{
email: "[email protected]",
phone_number: "123-123-1234",
password: "password",
password_confirmation: "password"
})

assert changeset.errors[:first_name]
end
end
end

0 comments on commit 9790f3f

Please sign in to comment.