Compare commits

..

8 Commits

@ -2,12 +2,15 @@ defmodule LinkShortener.Accounts.User do
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
alias LinkShortener.Links.Link
schema "users" do schema "users" do
field :email, :string field :email, :string
field :password, :string, virtual: true, redact: true field :password, :string, virtual: true, redact: true
field :hashed_password, :string, redact: true field :hashed_password, :string, redact: true
field :current_password, :string, virtual: true, redact: true field :current_password, :string, virtual: true, redact: true
field :confirmed_at, :utc_datetime field :confirmed_at, :utc_datetime
has_many :links, Link
timestamps(type: :utc_datetime) timestamps(type: :utc_datetime)
end end

@ -3,10 +3,13 @@ defmodule LinkShortener.Links.Link do
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query import Ecto.Query
alias LinkShortener.Accounts.User
schema "links" do schema "links" do
field :name, :string field :name, :string
field :url, :string field :url, :string
field :shorten, :string field :shorten, :string
belongs_to :user, User
timestamps() timestamps()
end end
@ -14,8 +17,8 @@ defmodule LinkShortener.Links.Link do
@doc false @doc false
def changeset(link, attrs) do def changeset(link, attrs) do
link link
|> cast(attrs, [:name, :url, :shorten]) |> cast(attrs, [:name, :url, :shorten, :user_id])
|> validate_required([:url, :shorten]) |> validate_required([:url, :shorten, :user_id])
|> unique_constraint(:shorten) |> unique_constraint(:shorten)
end end
end end

@ -12,6 +12,12 @@ defmodule LinkShortenerWeb.Api.V1.LinkController do
end end
def create(conn, %{"link" => link_params}) do def create(conn, %{"link" => link_params}) do
user = Guardian.Plug.current_resource(conn)
link_params =
link_params
|> Map.put("user_id", user.id)
with {:ok, %Link{} = link} <- Links.insert_one(link_params) do with {:ok, %Link{} = link} <- Links.insert_one(link_params) do
conn conn
|> put_status(:created) |> put_status(:created)

@ -0,0 +1,11 @@
defmodule LinkShortener.Repo.Migrations.AddRelationshipBetweenUsersAndLinks do
use Ecto.Migration
def change do
alter table(:links) do
add :user_id, references(:users, on_delete: :delete_all), null: false
end
create index(:links, [:user_id])
end
end

@ -2,6 +2,11 @@ defmodule LinkShortener.LinksTest do
use LinkShortener.DataCase use LinkShortener.DataCase
alias LinkShortener.Links alias LinkShortener.Links
alias LinkShortener.Links.Link
alias LinkShortener.Factories.UserFactory
import LinkShortener.LinksFixtures
@create_attrs %{ @create_attrs %{
name: "some link name", name: "some link name",
@ -23,31 +28,40 @@ defmodule LinkShortener.LinksTest do
shorten: nil, shorten: nil,
} }
describe "links" do setup do
alias LinkShortener.Links.Link {:ok, user: UserFactory.create_user()}
end
import LinkShortener.LinksFixtures
describe "links" do
test "new_one/1 returns the changeset" do test "new_one/1 returns the changeset" do
assert %Ecto.Changeset{} = Links.new_one() assert %Ecto.Changeset{} = Links.new_one()
end end
test "create_one/1 with valid data creates a link" do test "create_one/1 with valid data creates a link", %{user: user} do
assert {:ok, %Link{} = link} = Links.create_one(@create_generated_attrs) assert {:ok, %Link{} = link} =
with_user(@create_generated_attrs, user)
|> Links.create_one()
assert link.name == "some link name" assert link.name == "some link name"
assert link.url == "https://gitlab.com/KKlochko/link_shortener" assert link.url == "https://gitlab.com/KKlochko/link_shortener"
assert String.length(link.shorten) == 10 assert String.length(link.shorten) == 10
end end
test "create_one/2 with valid data creates a link" do test "create_one/2 with valid data creates a link", %{user: user} do
assert {:ok, %Link{} = link} = Links.create_one(@create_generated_attrs, 5) assert {:ok, %Link{} = link} =
with_user(@create_generated_attrs, user)
|> Links.create_one(5)
assert link.name == "some link name" assert link.name == "some link name"
assert link.url == "https://gitlab.com/KKlochko/link_shortener" assert link.url == "https://gitlab.com/KKlochko/link_shortener"
assert String.length(link.shorten) == 5 assert String.length(link.shorten) == 5
end end
test "insert_one/1 with valid data creates a link" do test "insert_one/1 with valid data creates a link", %{user: user} do
assert {:ok, %Link{} = link} = Links.insert_one(@create_attrs) assert {:ok, %Link{} = link} =
with_user(@create_attrs, user)
|> Links.insert_one()
assert link.name == "some link name" assert link.name == "some link name"
assert link.url == "https://gitlab.com/KKlochko/link_shortener" assert link.url == "https://gitlab.com/KKlochko/link_shortener"
assert link.shorten == "git_repo" assert link.shorten == "git_repo"
@ -103,4 +117,9 @@ defmodule LinkShortener.LinksTest do
assert_raise Ecto.NoResultsError, fn -> Links.get_one!(link.id) end assert_raise Ecto.NoResultsError, fn -> Links.get_one!(link.id) end
end end
end end
defp with_user(attrs, user) do
attrs
|> Map.put(:user_id, user.id)
end
end end

@ -0,0 +1,39 @@
defmodule LinkShortener.Factories.LinkFactory do
use ExMachina
alias LinkShortener.Links
alias LinkShortener.Factories.UserFactory
def link_attrs_factory() do
%{
name: sequence(:name, &"name-#{&1}"),
url: "https://gitlab.com/KKlochko/link_shortener",
shorten: sequence(:shorten, &"shorten#{&1}"),
}
end
@doc """
Create a link that has a static url, a random name and a random shorten.
If there are no user_id in attrs, then a new user will be created.
"""
def create_link(attrs \\ %{}) do
{:ok, link} =
link_attrs_factory()
|> put_new_user_id()
|> Map.merge(attrs)
|> Links.create_one()
link
end
defp put_new_user_id(attrs) do
if Map.has_key?(attrs, :user_id) do
attrs
else
user = UserFactory.create_user()
attrs
|> Map.put(:user_id, user.id)
end
end
end

@ -1,10 +1,15 @@
defmodule LinkShortener.Factories.UserFactory do defmodule LinkShortener.Factories.UserFactory do
use ExMachina use ExMachina
def user_factory do def user_attrs_factory() do
%{ %{
email: sequence(:email, &"user-#{&1}@mail.com"), email: sequence(:email, &"user-#{&1}@mail.com"),
password: "some password" password: "some password"
} }
end end
def create_user() do
user_attrs_factory()
|> LinkShortener.AccountsFixtures.user_fixture()
end
end end

@ -32,7 +32,7 @@ defmodule LinkShortener.AccountsFixtures do
end end
def user_token_fixture(attrs \\ %{}) do def user_token_fixture(attrs \\ %{}) do
user_params = UserFactory.user_factory() user_params = UserFactory.user_attrs_factory()
{:ok, %User{} = user} = Accounts.register_user(user_params) {:ok, %User{} = user} = Accounts.register_user(user_params)
{:ok, token, _claims} = Guardian.encode_and_sign(user) {:ok, token, _claims} = Guardian.encode_and_sign(user)

@ -4,21 +4,12 @@ defmodule LinkShortener.LinksFixtures do
entities via the `LinkShortener.Links` context. entities via the `LinkShortener.Links` context.
""" """
alias LinkShortener.Links alias LinkShortener.Factories.LinkFactory
@doc """ @doc """
Generate a link. Generate a link.
""" """
def link_fixture(attrs \\ %{}) do def link_fixture(attrs \\ %{}) do
{:ok, link} = LinkFactory.create_link(attrs)
attrs
|> Enum.into(%{
name: "some name",
url: "https://gitlab.com/KKlochko/link_shortener",
shorten: "api-article",
})
|> Links.create_one()
link
end end
end end

Loading…
Cancel
Save