Compare commits

...

8 Commits

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

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

@ -12,6 +12,12 @@ defmodule LinkShortenerWeb.Api.V1.LinkController do
end
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
conn
|> 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
alias LinkShortener.Links
alias LinkShortener.Links.Link
alias LinkShortener.Factories.UserFactory
import LinkShortener.LinksFixtures
@create_attrs %{
name: "some link name",
@ -23,31 +28,40 @@ defmodule LinkShortener.LinksTest do
shorten: nil,
}
describe "links" do
alias LinkShortener.Links.Link
import LinkShortener.LinksFixtures
setup do
{:ok, user: UserFactory.create_user()}
end
describe "links" do
test "new_one/1 returns the changeset" do
assert %Ecto.Changeset{} = Links.new_one()
end
test "create_one/1 with valid data creates a link" do
assert {:ok, %Link{} = link} = Links.create_one(@create_generated_attrs)
test "create_one/1 with valid data creates a link", %{user: user} do
assert {:ok, %Link{} = link} =
with_user(@create_generated_attrs, user)
|> Links.create_one()
assert link.name == "some link name"
assert link.url == "https://gitlab.com/KKlochko/link_shortener"
assert String.length(link.shorten) == 10
end
test "create_one/2 with valid data creates a link" do
assert {:ok, %Link{} = link} = Links.create_one(@create_generated_attrs, 5)
test "create_one/2 with valid data creates a link", %{user: user} do
assert {:ok, %Link{} = link} =
with_user(@create_generated_attrs, user)
|> Links.create_one(5)
assert link.name == "some link name"
assert link.url == "https://gitlab.com/KKlochko/link_shortener"
assert String.length(link.shorten) == 5
end
test "insert_one/1 with valid data creates a link" do
assert {:ok, %Link{} = link} = Links.insert_one(@create_attrs)
test "insert_one/1 with valid data creates a link", %{user: user} do
assert {:ok, %Link{} = link} =
with_user(@create_attrs, user)
|> Links.insert_one()
assert link.name == "some link name"
assert link.url == "https://gitlab.com/KKlochko/link_shortener"
assert link.shorten == "git_repo"
@ -103,4 +117,9 @@ defmodule LinkShortener.LinksTest do
assert_raise Ecto.NoResultsError, fn -> Links.get_one!(link.id) end
end
end
defp with_user(attrs, user) do
attrs
|> Map.put(:user_id, user.id)
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
use ExMachina
def user_factory do
def user_attrs_factory() do
%{
email: sequence(:email, &"user-#{&1}@mail.com"),
password: "some password"
}
end
def create_user() do
user_attrs_factory()
|> LinkShortener.AccountsFixtures.user_fixture()
end
end

@ -32,7 +32,7 @@ defmodule LinkShortener.AccountsFixtures do
end
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, token, _claims} = Guardian.encode_and_sign(user)

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

Loading…
Cancel
Save