Skip to content

Commit

Permalink
Create lists table and list schema
Browse files Browse the repository at this point in the history
Create the lists table
  • Loading branch information
SimonLab committed Oct 5, 2022
1 parent bff37c1 commit e75e79e
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
37 changes: 37 additions & 0 deletions lib/app/list.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
defmodule App.List do
use Ecto.Schema
import Ecto.Changeset
alias App.{Item, Person, Repo}
alias __MODULE__

schema "lists" do
field :name, :string

belongs_to :people, Person, references: :person_id, foreign_key: :person_id
many_to_many(:items, Item, join_through: "items_lists")

timestamps()
end

@doc false
def changeset(list, attrs \\ %{}) do
list
|> cast(attrs, [:person_id, :name])
|> validate_required([:person_id, :name])
|> unique_constraint([:name, :person_id], name: :lists_name_person_id_index)
end

def create_list(attrs) do
%List{}
|> changeset(attrs)
|> Repo.insert()
end

def get_list!(id), do: Repo.get!(List, id)

def update_list(%List{} = list, attrs) do
list
|> List.changeset(attrs)
|> Repo.update()
end
end
31 changes: 31 additions & 0 deletions priv/repo/migrations/20221005142257_add_list.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
defmodule App.Repo.Migrations.AddList do
use Ecto.Migration

def change do
execute("CREATE EXTENSION IF NOT EXISTS citext")

create table(:lists) do
add(:name, :citext)
add(:person_id, references(:people, column: :person_id))

timestamps()
end

create(
unique_index(:lists, [:name, :person_id],
name: :lists_name_person_id_index
)
)

create table(:items_lists, primary_key: false) do
add(:item_id, references(:items, on_delete: :delete_all))
add(:list_id, references(:tags, on_delete: :delete_all))

timestamps()
end

# create a unique index on item_id and list_id to avoid
# adding an item multiple time to the same list
create(unique_index(:items_lists, [:item_id, :list_id]))
end
end
62 changes: 62 additions & 0 deletions test/app/list_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
defmodule App.ListTest do
use App.DataCase
alias App.{Person, List}

setup [:create_person]

describe "Test constraints and requirements for List schema" do
test "valid list changeset" do
changeset = List.changeset(%List{}, %{person_id: 1, name: "list 1"})

assert changeset.valid?
end

test "invalid list changeset when person_id value missing" do
changeset = List.changeset(%List{}, %{name: "list 1"})
refute changeset.valid?
end

test "invalid list changeset when name value missing" do
changeset = List.changeset(%List{}, %{person_id: 1})
refute changeset.valid?
end
end

describe "Save list in Postgres" do
@valid_attrs %{person_id: 1, name: "list 1"}
@invalid_attrs %{name: nil}

test "get_list!/1 returns the list with given id" do
{:ok, list} = List.create_list(@valid_attrs)
assert List.get_list!(list.id).name == list.name
end

test "create_list/1 with invalid data returns error changeset" do
assert {:error, %Ecto.Changeset{}} = List.create_list(@invalid_attrs)
end

test "create_list/1 returns invalid changeset when trying to insert a duplicate name" do
assert {:ok, _list} = List.create_list(@valid_attrs)

assert {:error, _changeset} = List.create_list(@valid_attrs)
end
end

describe "Update list in Postgres" do
@valid_attrs %{person_id: 1, name: "list 1"}
@valid_update_attrs %{person_id: 1, name: "list 1 updated"}

test "update_list/2 update the list name" do
assert {:ok, list} = List.create_list(@valid_attrs)

assert {:ok, list_updated} = List.update_list(list, @valid_update_attrs)

assert list_updated.name == "list 1 updated"
end
end

defp create_person(_) do
person = Person.create_person(%{"person_id" => 1, "name" => "guest"})
%{person: person}
end
end

0 comments on commit e75e79e

Please sign in to comment.