From 2e0ef6817556d1922eb023b84b82a46953b67abe Mon Sep 17 00:00:00 2001
From: Muhammad Rafif Elfazri <rafif.elfazri@gmail.com>
Date: Fri, 8 Jan 2021 21:33:20 +0700
Subject: [PATCH 1/6] Add record for thread_like

---
 diskuy_back/lib/diskuy/likes.ex               | 104 ++++++++++++++++++
 diskuy_back/lib/diskuy/likes/thread_like.ex   |  19 ++++
 .../controllers/thread_like_controller.ex     |  43 ++++++++
 .../lib/diskuy_web/views/thread_like_view.ex  |  18 +++
 .../20210108141754_create_thread_likes.exs    |  16 +++
 diskuy_back/test/diskuy/likes_test.exs        |  62 +++++++++++
 .../thread_like_controller_test.exs           |  86 +++++++++++++++
 7 files changed, 348 insertions(+)
 create mode 100644 diskuy_back/lib/diskuy/likes.ex
 create mode 100644 diskuy_back/lib/diskuy/likes/thread_like.ex
 create mode 100644 diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex
 create mode 100644 diskuy_back/lib/diskuy_web/views/thread_like_view.ex
 create mode 100644 diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs
 create mode 100644 diskuy_back/test/diskuy/likes_test.exs
 create mode 100644 diskuy_back/test/diskuy_web/controllers/thread_like_controller_test.exs

diff --git a/diskuy_back/lib/diskuy/likes.ex b/diskuy_back/lib/diskuy/likes.ex
new file mode 100644
index 0000000..62b6a52
--- /dev/null
+++ b/diskuy_back/lib/diskuy/likes.ex
@@ -0,0 +1,104 @@
+defmodule Diskuy.Likes do
+  @moduledoc """
+  The Likes context.
+  """
+
+  import Ecto.Query, warn: false
+  alias Diskuy.Repo
+
+  alias Diskuy.Likes.ThreadLike
+
+  @doc """
+  Returns the list of thread_likes.
+
+  ## Examples
+
+      iex> list_thread_likes()
+      [%ThreadLike{}, ...]
+
+  """
+  def list_thread_likes do
+    Repo.all(ThreadLike)
+  end
+
+  @doc """
+  Gets a single thread_like.
+
+  Raises `Ecto.NoResultsError` if the Thread like does not exist.
+
+  ## Examples
+
+      iex> get_thread_like!(123)
+      %ThreadLike{}
+
+      iex> get_thread_like!(456)
+      ** (Ecto.NoResultsError)
+
+  """
+  def get_thread_like!(id), do: Repo.get!(ThreadLike, id)
+
+  @doc """
+  Creates a thread_like.
+
+  ## Examples
+
+      iex> create_thread_like(%{field: value})
+      {:ok, %ThreadLike{}}
+
+      iex> create_thread_like(%{field: bad_value})
+      {:error, %Ecto.Changeset{}}
+
+  """
+  def create_thread_like(attrs \\ %{}) do
+    %ThreadLike{}
+    |> ThreadLike.changeset(attrs)
+    |> Repo.insert()
+  end
+
+  @doc """
+  Updates a thread_like.
+
+  ## Examples
+
+      iex> update_thread_like(thread_like, %{field: new_value})
+      {:ok, %ThreadLike{}}
+
+      iex> update_thread_like(thread_like, %{field: bad_value})
+      {:error, %Ecto.Changeset{}}
+
+  """
+  def update_thread_like(%ThreadLike{} = thread_like, attrs) do
+    thread_like
+    |> ThreadLike.changeset(attrs)
+    |> Repo.update()
+  end
+
+  @doc """
+  Deletes a thread_like.
+
+  ## Examples
+
+      iex> delete_thread_like(thread_like)
+      {:ok, %ThreadLike{}}
+
+      iex> delete_thread_like(thread_like)
+      {:error, %Ecto.Changeset{}}
+
+  """
+  def delete_thread_like(%ThreadLike{} = thread_like) do
+    Repo.delete(thread_like)
+  end
+
+  @doc """
+  Returns an `%Ecto.Changeset{}` for tracking thread_like changes.
+
+  ## Examples
+
+      iex> change_thread_like(thread_like)
+      %Ecto.Changeset{data: %ThreadLike{}}
+
+  """
+  def change_thread_like(%ThreadLike{} = thread_like, attrs \\ %{}) do
+    ThreadLike.changeset(thread_like, attrs)
+  end
+end
diff --git a/diskuy_back/lib/diskuy/likes/thread_like.ex b/diskuy_back/lib/diskuy/likes/thread_like.ex
new file mode 100644
index 0000000..e1627f8
--- /dev/null
+++ b/diskuy_back/lib/diskuy/likes/thread_like.ex
@@ -0,0 +1,19 @@
+defmodule Diskuy.Likes.ThreadLike do
+  use Ecto.Schema
+  import Ecto.Changeset
+
+  schema "thread_likes" do
+    field :user_id, :id
+    field :thread_id, :id
+
+    timestamps()
+  end
+
+  @doc false
+  def changeset(thread_like, attrs) do
+    thread_like
+    |> cast(attrs, [:user_id, :thread_id])
+    |> validate_required([:user_id, :thread_id])
+    |> unique_constraint(:user_thread_unique, name: :user_thread_unique)
+  end
+end
diff --git a/diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex b/diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex
new file mode 100644
index 0000000..71af234
--- /dev/null
+++ b/diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex
@@ -0,0 +1,43 @@
+defmodule DiskuyWeb.ThreadLikeController do
+  use DiskuyWeb, :controller
+
+  alias Diskuy.Likes
+  alias Diskuy.Likes.ThreadLike
+
+  action_fallback DiskuyWeb.FallbackController
+
+  def index(conn, _params) do
+    thread_likes = Likes.list_thread_likes()
+    render(conn, "index.json", thread_likes: thread_likes)
+  end
+
+  def create(conn, %{"thread_like" => thread_like_params}) do
+    with {:ok, %ThreadLike{} = thread_like} <- Likes.create_thread_like(thread_like_params) do
+      conn
+      |> put_status(:created)
+      |> put_resp_header("location", Routes.thread_like_path(conn, :show, thread_like))
+      |> render("show.json", thread_like: thread_like)
+    end
+  end
+
+  def show(conn, %{"id" => id}) do
+    thread_like = Likes.get_thread_like!(id)
+    render(conn, "show.json", thread_like: thread_like)
+  end
+
+  def update(conn, %{"id" => id, "thread_like" => thread_like_params}) do
+    thread_like = Likes.get_thread_like!(id)
+
+    with {:ok, %ThreadLike{} = thread_like} <- Likes.update_thread_like(thread_like, thread_like_params) do
+      render(conn, "show.json", thread_like: thread_like)
+    end
+  end
+
+  def delete(conn, %{"id" => id}) do
+    thread_like = Likes.get_thread_like!(id)
+
+    with {:ok, %ThreadLike{}} <- Likes.delete_thread_like(thread_like) do
+      send_resp(conn, :no_content, "")
+    end
+  end
+end
diff --git a/diskuy_back/lib/diskuy_web/views/thread_like_view.ex b/diskuy_back/lib/diskuy_web/views/thread_like_view.ex
new file mode 100644
index 0000000..7d50eca
--- /dev/null
+++ b/diskuy_back/lib/diskuy_web/views/thread_like_view.ex
@@ -0,0 +1,18 @@
+defmodule DiskuyWeb.ThreadLikeView do
+  use DiskuyWeb, :view
+  alias DiskuyWeb.ThreadLikeView
+
+  def render("index.json", %{thread_likes: thread_likes}) do
+    %{data: render_many(thread_likes, ThreadLikeView, "thread_like.json")}
+  end
+
+  def render("show.json", %{thread_like: thread_like}) do
+    %{data: render_one(thread_like, ThreadLikeView, "thread_like.json")}
+  end
+
+  def render("thread_like.json", %{thread_like: thread_like}) do
+    %{id: thread_like.id,
+      user_id: thread_like.user_id
+      thread_id_id:  thread_like.thread_id}
+  end
+end
diff --git a/diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs b/diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs
new file mode 100644
index 0000000..5134204
--- /dev/null
+++ b/diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs
@@ -0,0 +1,16 @@
+defmodule Diskuy.Repo.Migrations.CreateThreadLikes do
+  use Ecto.Migration
+
+  def change do
+    create table(:thread_likes) do
+      add :user_id, references(:users, on_delete: :delete_all)
+      add :thread_id, references(:threads, on_delete: :delete_all)
+
+      timestamps()
+    end
+
+    create index(:thread_likes, [:user_id])
+    create index(:thread_likes, [:thread_id])
+    create unique_index(:threads, [:user_id, :thread_id], name: :user_thread_unique)
+  end
+end
diff --git a/diskuy_back/test/diskuy/likes_test.exs b/diskuy_back/test/diskuy/likes_test.exs
new file mode 100644
index 0000000..71095d9
--- /dev/null
+++ b/diskuy_back/test/diskuy/likes_test.exs
@@ -0,0 +1,62 @@
+defmodule Diskuy.LikesTest do
+  use Diskuy.DataCase
+
+  alias Diskuy.Likes
+
+  describe "thread_likes" do
+    alias Diskuy.Likes.ThreadLike
+
+    @valid_attrs %{}
+    @update_attrs %{}
+    @invalid_attrs %{}
+
+    def thread_like_fixture(attrs \\ %{}) do
+      {:ok, thread_like} =
+        attrs
+        |> Enum.into(@valid_attrs)
+        |> Likes.create_thread_like()
+
+      thread_like
+    end
+
+    test "list_thread_likes/0 returns all thread_likes" do
+      thread_like = thread_like_fixture()
+      assert Likes.list_thread_likes() == [thread_like]
+    end
+
+    test "get_thread_like!/1 returns the thread_like with given id" do
+      thread_like = thread_like_fixture()
+      assert Likes.get_thread_like!(thread_like.id) == thread_like
+    end
+
+    test "create_thread_like/1 with valid data creates a thread_like" do
+      assert {:ok, %ThreadLike{} = thread_like} = Likes.create_thread_like(@valid_attrs)
+    end
+
+    test "create_thread_like/1 with invalid data returns error changeset" do
+      assert {:error, %Ecto.Changeset{}} = Likes.create_thread_like(@invalid_attrs)
+    end
+
+    test "update_thread_like/2 with valid data updates the thread_like" do
+      thread_like = thread_like_fixture()
+      assert {:ok, %ThreadLike{} = thread_like} = Likes.update_thread_like(thread_like, @update_attrs)
+    end
+
+    test "update_thread_like/2 with invalid data returns error changeset" do
+      thread_like = thread_like_fixture()
+      assert {:error, %Ecto.Changeset{}} = Likes.update_thread_like(thread_like, @invalid_attrs)
+      assert thread_like == Likes.get_thread_like!(thread_like.id)
+    end
+
+    test "delete_thread_like/1 deletes the thread_like" do
+      thread_like = thread_like_fixture()
+      assert {:ok, %ThreadLike{}} = Likes.delete_thread_like(thread_like)
+      assert_raise Ecto.NoResultsError, fn -> Likes.get_thread_like!(thread_like.id) end
+    end
+
+    test "change_thread_like/1 returns a thread_like changeset" do
+      thread_like = thread_like_fixture()
+      assert %Ecto.Changeset{} = Likes.change_thread_like(thread_like)
+    end
+  end
+end
diff --git a/diskuy_back/test/diskuy_web/controllers/thread_like_controller_test.exs b/diskuy_back/test/diskuy_web/controllers/thread_like_controller_test.exs
new file mode 100644
index 0000000..d8de7b4
--- /dev/null
+++ b/diskuy_back/test/diskuy_web/controllers/thread_like_controller_test.exs
@@ -0,0 +1,86 @@
+defmodule DiskuyWeb.ThreadLikeControllerTest do
+  use DiskuyWeb.ConnCase
+
+  alias Diskuy.Likes
+  alias Diskuy.Likes.ThreadLike
+
+  @create_attrs %{
+
+  }
+  @update_attrs %{
+
+  }
+  @invalid_attrs %{}
+
+  def fixture(:thread_like) do
+    {:ok, thread_like} = Likes.create_thread_like(@create_attrs)
+    thread_like
+  end
+
+  setup %{conn: conn} do
+    {:ok, conn: put_req_header(conn, "accept", "application/json")}
+  end
+
+  describe "index" do
+    test "lists all thread_likes", %{conn: conn} do
+      conn = get(conn, Routes.thread_like_path(conn, :index))
+      assert json_response(conn, 200)["data"] == []
+    end
+  end
+
+  describe "create thread_like" do
+    test "renders thread_like when data is valid", %{conn: conn} do
+      conn = post(conn, Routes.thread_like_path(conn, :create), thread_like: @create_attrs)
+      assert %{"id" => id} = json_response(conn, 201)["data"]
+
+      conn = get(conn, Routes.thread_like_path(conn, :show, id))
+
+      assert %{
+               "id" => id
+             } = json_response(conn, 200)["data"]
+    end
+
+    test "renders errors when data is invalid", %{conn: conn} do
+      conn = post(conn, Routes.thread_like_path(conn, :create), thread_like: @invalid_attrs)
+      assert json_response(conn, 422)["errors"] != %{}
+    end
+  end
+
+  describe "update thread_like" do
+    setup [:create_thread_like]
+
+    test "renders thread_like when data is valid", %{conn: conn, thread_like: %ThreadLike{id: id} = thread_like} do
+      conn = put(conn, Routes.thread_like_path(conn, :update, thread_like), thread_like: @update_attrs)
+      assert %{"id" => ^id} = json_response(conn, 200)["data"]
+
+      conn = get(conn, Routes.thread_like_path(conn, :show, id))
+
+      assert %{
+               "id" => id
+             } = json_response(conn, 200)["data"]
+    end
+
+    test "renders errors when data is invalid", %{conn: conn, thread_like: thread_like} do
+      conn = put(conn, Routes.thread_like_path(conn, :update, thread_like), thread_like: @invalid_attrs)
+      assert json_response(conn, 422)["errors"] != %{}
+    end
+  end
+
+  describe "delete thread_like" do
+    setup [:create_thread_like]
+
+    test "deletes chosen thread_like", %{conn: conn, thread_like: thread_like} do
+      conn = delete(conn, Routes.thread_like_path(conn, :delete, thread_like))
+      assert response(conn, 204)
+
+      assert_error_sent 404, fn ->
+        get(conn, Routes.thread_like_path(conn, :show, thread_like))
+      end
+    end
+  end
+
+  defp create_thread_like(_) do
+    thread_like = fixture(:thread_like)
+    %{thread_like: thread_like}
+  end
+end
-- 
GitLab


From be6be0bc7e18cbd4ff5b25f0229a275d5f8b44df Mon Sep 17 00:00:00 2001
From: Muhammad Rafif Elfazri <rafif.elfazri@gmail.com>
Date: Fri, 8 Jan 2021 21:42:45 +0700
Subject: [PATCH 2/6] Add record for post_like

---
 diskuy_back/lib/diskuy/likes.ex               | 96 +++++++++++++++++++
 diskuy_back/lib/diskuy/likes/post_like.ex     | 19 ++++
 .../controllers/post_like_controller.ex       | 43 +++++++++
 .../lib/diskuy_web/views/post_like_view.ex    | 18 ++++
 .../20210108143501_create_post_likes.exs      | 16 ++++
 diskuy_back/test/diskuy/likes_test.exs        | 57 +++++++++++
 .../controllers/post_like_controller_test.exs | 86 +++++++++++++++++
 7 files changed, 335 insertions(+)
 create mode 100644 diskuy_back/lib/diskuy/likes/post_like.ex
 create mode 100644 diskuy_back/lib/diskuy_web/controllers/post_like_controller.ex
 create mode 100644 diskuy_back/lib/diskuy_web/views/post_like_view.ex
 create mode 100644 diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs
 create mode 100644 diskuy_back/test/diskuy_web/controllers/post_like_controller_test.exs

diff --git a/diskuy_back/lib/diskuy/likes.ex b/diskuy_back/lib/diskuy/likes.ex
index 62b6a52..5f64c6d 100644
--- a/diskuy_back/lib/diskuy/likes.ex
+++ b/diskuy_back/lib/diskuy/likes.ex
@@ -101,4 +101,100 @@ defmodule Diskuy.Likes do
   def change_thread_like(%ThreadLike{} = thread_like, attrs \\ %{}) do
     ThreadLike.changeset(thread_like, attrs)
   end
+
+  alias Diskuy.Likes.PostLike
+
+  @doc """
+  Returns the list of post_likes.
+
+  ## Examples
+
+      iex> list_post_likes()
+      [%PostLike{}, ...]
+
+  """
+  def list_post_likes do
+    Repo.all(PostLike)
+  end
+
+  @doc """
+  Gets a single post_like.
+
+  Raises `Ecto.NoResultsError` if the Post like does not exist.
+
+  ## Examples
+
+      iex> get_post_like!(123)
+      %PostLike{}
+
+      iex> get_post_like!(456)
+      ** (Ecto.NoResultsError)
+
+  """
+  def get_post_like!(id), do: Repo.get!(PostLike, id)
+
+  @doc """
+  Creates a post_like.
+
+  ## Examples
+
+      iex> create_post_like(%{field: value})
+      {:ok, %PostLike{}}
+
+      iex> create_post_like(%{field: bad_value})
+      {:error, %Ecto.Changeset{}}
+
+  """
+  def create_post_like(attrs \\ %{}) do
+    %PostLike{}
+    |> PostLike.changeset(attrs)
+    |> Repo.insert()
+  end
+
+  @doc """
+  Updates a post_like.
+
+  ## Examples
+
+      iex> update_post_like(post_like, %{field: new_value})
+      {:ok, %PostLike{}}
+
+      iex> update_post_like(post_like, %{field: bad_value})
+      {:error, %Ecto.Changeset{}}
+
+  """
+  def update_post_like(%PostLike{} = post_like, attrs) do
+    post_like
+    |> PostLike.changeset(attrs)
+    |> Repo.update()
+  end
+
+  @doc """
+  Deletes a post_like.
+
+  ## Examples
+
+      iex> delete_post_like(post_like)
+      {:ok, %PostLike{}}
+
+      iex> delete_post_like(post_like)
+      {:error, %Ecto.Changeset{}}
+
+  """
+  def delete_post_like(%PostLike{} = post_like) do
+    Repo.delete(post_like)
+  end
+
+  @doc """
+  Returns an `%Ecto.Changeset{}` for tracking post_like changes.
+
+  ## Examples
+
+      iex> change_post_like(post_like)
+      %Ecto.Changeset{data: %PostLike{}}
+
+  """
+  def change_post_like(%PostLike{} = post_like, attrs \\ %{}) do
+    PostLike.changeset(post_like, attrs)
+  end
 end
diff --git a/diskuy_back/lib/diskuy/likes/post_like.ex b/diskuy_back/lib/diskuy/likes/post_like.ex
new file mode 100644
index 0000000..ce7ffef
--- /dev/null
+++ b/diskuy_back/lib/diskuy/likes/post_like.ex
@@ -0,0 +1,19 @@
+defmodule Diskuy.Likes.PostLike do
+  use Ecto.Schema
+  import Ecto.Changeset
+
+  schema "post_likes" do
+    field :user_id, :id
+    field :post_id, :id
+
+    timestamps()
+  end
+
+  @doc false
+  def changeset(post_like, attrs) do
+    post_like
+    |> cast(attrs, [:user_id, :post_id])
+    |> validate_required([:user_id, :post_id])
+    |> unique_constraint(:user_post_unique, name: :user_post_unique)
+  end
+end
diff --git a/diskuy_back/lib/diskuy_web/controllers/post_like_controller.ex b/diskuy_back/lib/diskuy_web/controllers/post_like_controller.ex
new file mode 100644
index 0000000..5237ccd
--- /dev/null
+++ b/diskuy_back/lib/diskuy_web/controllers/post_like_controller.ex
@@ -0,0 +1,43 @@
+defmodule DiskuyWeb.PostLikeController do
+  use DiskuyWeb, :controller
+
+  alias Diskuy.Likes
+  alias Diskuy.Likes.PostLike
+
+  action_fallback DiskuyWeb.FallbackController
+
+  def index(conn, _params) do
+    post_likes = Likes.list_post_likes()
+    render(conn, "index.json", post_likes: post_likes)
+  end
+
+  def create(conn, %{"post_like" => post_like_params}) do
+    with {:ok, %PostLike{} = post_like} <- Likes.create_post_like(post_like_params) do
+      conn
+      |> put_status(:created)
+      |> put_resp_header("location", Routes.post_like_path(conn, :show, post_like))
+      |> render("show.json", post_like: post_like)
+    end
+  end
+
+  def show(conn, %{"id" => id}) do
+    post_like = Likes.get_post_like!(id)
+    render(conn, "show.json", post_like: post_like)
+  end
+
+  def update(conn, %{"id" => id, "post_like" => post_like_params}) do
+    post_like = Likes.get_post_like!(id)
+
+    with {:ok, %PostLike{} = post_like} <- Likes.update_post_like(post_like, post_like_params) do
+      render(conn, "show.json", post_like: post_like)
+    end
+  end
+
+  def delete(conn, %{"id" => id}) do
+    post_like = Likes.get_post_like!(id)
+
+    with {:ok, %PostLike{}} <- Likes.delete_post_like(post_like) do
+      send_resp(conn, :no_content, "")
+    end
+  end
+end
diff --git a/diskuy_back/lib/diskuy_web/views/post_like_view.ex b/diskuy_back/lib/diskuy_web/views/post_like_view.ex
new file mode 100644
index 0000000..548860c
--- /dev/null
+++ b/diskuy_back/lib/diskuy_web/views/post_like_view.ex
@@ -0,0 +1,18 @@
+defmodule DiskuyWeb.PostLikeView do
+  use DiskuyWeb, :view
+  alias DiskuyWeb.PostLikeView
+
+  def render("index.json", %{post_likes: post_likes}) do
+    %{data: render_many(post_likes, PostLikeView, "post_like.json")}
+  end
+
+  def render("show.json", %{post_like: post_like}) do
+    %{data: render_one(post_like, PostLikeView, "post_like.json")}
+  end
+
+  def render("post_like.json", %{post_like: post_like}) do
+    %{id: post_like.id,
+      user_id: post_like.user_id
+      thread_id_id:  post_like.post_id}
+  end
+end
diff --git a/diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs b/diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs
new file mode 100644
index 0000000..d97f52b
--- /dev/null
+++ b/diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs
@@ -0,0 +1,16 @@
+defmodule Diskuy.Repo.Migrations.CreatePostLikes do
+  use Ecto.Migration
+
+  def change do
+    create table(:post_likes) do
+      add :user_id, references(:users, on_delete: :nothing)
+      add :post_id, references(:posts, on_delete: :nothing)
+
+      timestamps()
+    end
+
+    create index(:post_likes, [:user_id])
+    create index(:post_likes, [:post_id])
+    create unique_index(:threads, [:user_id, :post_id], name: :user_post_unique)
+  end
+end
diff --git a/diskuy_back/test/diskuy/likes_test.exs b/diskuy_back/test/diskuy/likes_test.exs
index 71095d9..1ad2668 100644
--- a/diskuy_back/test/diskuy/likes_test.exs
+++ b/diskuy_back/test/diskuy/likes_test.exs
@@ -59,4 +59,61 @@ defmodule Diskuy.LikesTest do
       assert %Ecto.Changeset{} = Likes.change_thread_like(thread_like)
     end
   end
+
+  describe "post_likes" do
+    alias Diskuy.Likes.PostLike
+
+    @valid_attrs %{}
+    @update_attrs %{}
+    @invalid_attrs %{}
+
+    def post_like_fixture(attrs \\ %{}) do
+      {:ok, post_like} =
+        attrs
+        |> Enum.into(@valid_attrs)
+        |> Likes.create_post_like()
+
+      post_like
+    end
+
+    test "list_post_likes/0 returns all post_likes" do
+      post_like = post_like_fixture()
+      assert Likes.list_post_likes() == [post_like]
+    end
+
+    test "get_post_like!/1 returns the post_like with given id" do
+      post_like = post_like_fixture()
+      assert Likes.get_post_like!(post_like.id) == post_like
+    end
+
+    test "create_post_like/1 with valid data creates a post_like" do
+      assert {:ok, %PostLike{} = post_like} = Likes.create_post_like(@valid_attrs)
+    end
+
+    test "create_post_like/1 with invalid data returns error changeset" do
+      assert {:error, %Ecto.Changeset{}} = Likes.create_post_like(@invalid_attrs)
+    end
+
+    test "update_post_like/2 with valid data updates the post_like" do
+      post_like = post_like_fixture()
+      assert {:ok, %PostLike{} = post_like} = Likes.update_post_like(post_like, @update_attrs)
+    end
+
+    test "update_post_like/2 with invalid data returns error changeset" do
+      post_like = post_like_fixture()
+      assert {:error, %Ecto.Changeset{}} = Likes.update_post_like(post_like, @invalid_attrs)
+      assert post_like == Likes.get_post_like!(post_like.id)
+    end
+
+    test "delete_post_like/1 deletes the post_like" do
+      post_like = post_like_fixture()
+      assert {:ok, %PostLike{}} = Likes.delete_post_like(post_like)
+      assert_raise Ecto.NoResultsError, fn -> Likes.get_post_like!(post_like.id) end
+    end
+
+    test "change_post_like/1 returns a post_like changeset" do
+      post_like = post_like_fixture()
+      assert %Ecto.Changeset{} = Likes.change_post_like(post_like)
+    end
+  end
 end
diff --git a/diskuy_back/test/diskuy_web/controllers/post_like_controller_test.exs b/diskuy_back/test/diskuy_web/controllers/post_like_controller_test.exs
new file mode 100644
index 0000000..c56e46c
--- /dev/null
+++ b/diskuy_back/test/diskuy_web/controllers/post_like_controller_test.exs
@@ -0,0 +1,86 @@
+defmodule DiskuyWeb.PostLikeControllerTest do
+  use DiskuyWeb.ConnCase
+
+  alias Diskuy.Likes
+  alias Diskuy.Likes.PostLike
+
+  @create_attrs %{
+
+  }
+  @update_attrs %{
+
+  }
+  @invalid_attrs %{}
+
+  def fixture(:post_like) do
+    {:ok, post_like} = Likes.create_post_like(@create_attrs)
+    post_like
+  end
+
+  setup %{conn: conn} do
+    {:ok, conn: put_req_header(conn, "accept", "application/json")}
+  end
+
+  describe "index" do
+    test "lists all post_likes", %{conn: conn} do
+      conn = get(conn, Routes.post_like_path(conn, :index))
+      assert json_response(conn, 200)["data"] == []
+    end
+  end
+
+  describe "create post_like" do
+    test "renders post_like when data is valid", %{conn: conn} do
+      conn = post(conn, Routes.post_like_path(conn, :create), post_like: @create_attrs)
+      assert %{"id" => id} = json_response(conn, 201)["data"]
+
+      conn = get(conn, Routes.post_like_path(conn, :show, id))
+
+      assert %{
+               "id" => id
+             } = json_response(conn, 200)["data"]
+    end
+
+    test "renders errors when data is invalid", %{conn: conn} do
+      conn = post(conn, Routes.post_like_path(conn, :create), post_like: @invalid_attrs)
+      assert json_response(conn, 422)["errors"] != %{}
+    end
+  end
+
+  describe "update post_like" do
+    setup [:create_post_like]
+
+    test "renders post_like when data is valid", %{conn: conn, post_like: %PostLike{id: id} = post_like} do
+      conn = put(conn, Routes.post_like_path(conn, :update, post_like), post_like: @update_attrs)
+      assert %{"id" => ^id} = json_response(conn, 200)["data"]
+
+      conn = get(conn, Routes.post_like_path(conn, :show, id))
+
+      assert %{
+               "id" => id
+             } = json_response(conn, 200)["data"]
+    end
+
+    test "renders errors when data is invalid", %{conn: conn, post_like: post_like} do
+      conn = put(conn, Routes.post_like_path(conn, :update, post_like), post_like: @invalid_attrs)
+      assert json_response(conn, 422)["errors"] != %{}
+    end
+  end
+
+  describe "delete post_like" do
+    setup [:create_post_like]
+
+    test "deletes chosen post_like", %{conn: conn, post_like: post_like} do
+      conn = delete(conn, Routes.post_like_path(conn, :delete, post_like))
+      assert response(conn, 204)
+
+      assert_error_sent 404, fn ->
+        get(conn, Routes.post_like_path(conn, :show, post_like))
+      end
+    end
+  end
+
+  defp create_post_like(_) do
+    post_like = fixture(:post_like)
+    %{post_like: post_like}
+  end
+end
-- 
GitLab


From 1ecf1f855b72d73637366e9650ad071870bb38dc Mon Sep 17 00:00:00 2001
From: Muhammad Rafif Elfazri <rafif.elfazri@gmail.com>
Date: Fri, 8 Jan 2021 22:10:02 +0700
Subject: [PATCH 3/6] Fix render view

---
 diskuy_back/lib/diskuy_web/views/post_like_view.ex   | 4 ++--
 diskuy_back/lib/diskuy_web/views/thread_like_view.ex | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/diskuy_back/lib/diskuy_web/views/post_like_view.ex b/diskuy_back/lib/diskuy_web/views/post_like_view.ex
index 548860c..c50e057 100644
--- a/diskuy_back/lib/diskuy_web/views/post_like_view.ex
+++ b/diskuy_back/lib/diskuy_web/views/post_like_view.ex
@@ -12,7 +12,7 @@ defmodule DiskuyWeb.PostLikeView do
 
   def render("post_like.json", %{post_like: post_like}) do
     %{id: post_like.id,
-      user_id: post_like.user_id
-      thread_id_id:  post_like.post_id}
+      user_id: post_like.user_id,
+      thread_id:  post_like.post_id}
   end
 end
diff --git a/diskuy_back/lib/diskuy_web/views/thread_like_view.ex b/diskuy_back/lib/diskuy_web/views/thread_like_view.ex
index 7d50eca..7b48301 100644
--- a/diskuy_back/lib/diskuy_web/views/thread_like_view.ex
+++ b/diskuy_back/lib/diskuy_web/views/thread_like_view.ex
@@ -12,7 +12,7 @@ defmodule DiskuyWeb.ThreadLikeView do
 
   def render("thread_like.json", %{thread_like: thread_like}) do
     %{id: thread_like.id,
-      user_id: thread_like.user_id
-      thread_id_id:  thread_like.thread_id}
+      user_id: thread_like.user_id,
+      thread_id:  thread_like.thread_id}
   end
 end
-- 
GitLab


From cf5507346a65089b68eb004e82e32b409b69cd74 Mon Sep 17 00:00:00 2001
From: Muhammad Rafif Elfazri <rafif.elfazri@gmail.com>
Date: Fri, 8 Jan 2021 23:00:29 +0700
Subject: [PATCH 4/6] Fix posts_like and thread_like migrations

---
 .../priv/repo/migrations/20210108141754_create_thread_likes.exs | 2 +-
 .../priv/repo/migrations/20210108143501_create_post_likes.exs   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs b/diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs
index 5134204..87d4629 100644
--- a/diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs
+++ b/diskuy_back/priv/repo/migrations/20210108141754_create_thread_likes.exs
@@ -11,6 +11,6 @@ defmodule Diskuy.Repo.Migrations.CreateThreadLikes do
 
     create index(:thread_likes, [:user_id])
     create index(:thread_likes, [:thread_id])
-    create unique_index(:threads, [:user_id, :thread_id], name: :user_thread_unique)
+    create unique_index(:thread_likes, [:user_id, :thread_id], name: :user_thread_unique)
   end
 end
diff --git a/diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs b/diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs
index d97f52b..82acc87 100644
--- a/diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs
+++ b/diskuy_back/priv/repo/migrations/20210108143501_create_post_likes.exs
@@ -11,6 +11,6 @@ defmodule Diskuy.Repo.Migrations.CreatePostLikes do
 
     create index(:post_likes, [:user_id])
     create index(:post_likes, [:post_id])
-    create unique_index(:threads, [:user_id, :post_id], name: :user_post_unique)
+    create unique_index(:post_likes, [:user_id, :post_id], name: :user_post_unique)
   end
 end
-- 
GitLab


From c8e47158d45510d582b90df0743d45b2e4b728a8 Mon Sep 17 00:00:00 2001
From: Muhammad Rafif Elfazri <rafif.elfazri@gmail.com>
Date: Fri, 8 Jan 2021 23:01:21 +0700
Subject: [PATCH 5/6] add get thread_like bi thread_id and user

---
 diskuy_back/lib/diskuy/likes.ex | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/diskuy_back/lib/diskuy/likes.ex b/diskuy_back/lib/diskuy/likes.ex
index 5f64c6d..4ca5897 100644
--- a/diskuy_back/lib/diskuy/likes.ex
+++ b/diskuy_back/lib/diskuy/likes.ex
@@ -37,6 +37,8 @@ defmodule Diskuy.Likes do
   """
   def get_thread_like!(id), do: Repo.get!(ThreadLike, id)
 
+  def get_thread_like_by_refer!(user_id, thread_id), do: Repo.get_by!(ThreadLike, [user_id: user_id, thread_id: thread_id])
+
   @doc """
   Creates a thread_like.
 
-- 
GitLab


From 2125ff4ee851354d8bd59e69d14014cbd1cc8274 Mon Sep 17 00:00:00 2001
From: Muhammad Rafif Elfazri <rafif.elfazri@gmail.com>
Date: Fri, 8 Jan 2021 23:02:08 +0700
Subject: [PATCH 6/6] Add like system by for thread

---
 .../controllers/thread_controller.ex          | 24 +++++++++++++++++++
 .../controllers/thread_like_controller.ex     |  8 +++++++
 diskuy_back/lib/diskuy_web/router.ex          |  6 +++++
 3 files changed, 38 insertions(+)

diff --git a/diskuy_back/lib/diskuy_web/controllers/thread_controller.ex b/diskuy_back/lib/diskuy_web/controllers/thread_controller.ex
index 0dc0736..d5d62a0 100644
--- a/diskuy_back/lib/diskuy_web/controllers/thread_controller.ex
+++ b/diskuy_back/lib/diskuy_web/controllers/thread_controller.ex
@@ -3,6 +3,8 @@ defmodule DiskuyWeb.ThreadController do
 
   alias Diskuy.Forum
   alias Diskuy.Forum.Thread
+  alias Diskuy.Likes
+  alias Diskuy.Likes.ThreadLike
   alias DiskuyWeb.Auth.Guardian
 
   action_fallback DiskuyWeb.FallbackController
@@ -41,6 +43,28 @@ defmodule DiskuyWeb.ThreadController do
     end
   end
 
+  def add_like(conn, %{"id" => id}) do
+    current_user = Guardian.Plug.current_resource(conn)
+    thread = Forum.get_thread!(id)
+
+    with {:ok, %ThreadLike{} = _thread_like} <- Likes.create_thread_like(%{"user_id" => current_user.id,
+                                                                           "thread_id" => id}),
+         {:ok, %Thread{} = thread} <- Forum.update_thread(thread, %{"points" => (thread.points+ 1)}) do
+         render(conn, "show.json", thread: thread)
+    end
+  end
+
+  def delete_like(conn, %{"id" => id}) do
+    current_user = Guardian.Plug.current_resource(conn)
+    thread = Forum.get_thread!(id)
+    thread_like = Likes.get_thread_like_by_refer!(id, current_user.id)
+
+    with {:ok, %ThreadLike{}} <- Likes.delete_thread_like(thread_like),
+         {:ok, %Thread{} = thread} <- Forum.update_thread(thread, %{"points" => (thread.points-1)}) do
+         render(conn, "show.json", thread: thread)
+    end
+  end
+
   defp put_user_id(conn, %{"thread" => thread_params}) do
     current_user = Guardian.Plug.current_resource(conn)
     new_params = Map.put(thread_params, "user_id", current_user.id)
diff --git a/diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex b/diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex
index 71af234..93b9bfa 100644
--- a/diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex
+++ b/diskuy_back/lib/diskuy_web/controllers/thread_like_controller.ex
@@ -3,6 +3,7 @@ defmodule DiskuyWeb.ThreadLikeController do
 
   alias Diskuy.Likes
   alias Diskuy.Likes.ThreadLike
+  alias DiskuyWeb.Auth.Guardian
 
   action_fallback DiskuyWeb.FallbackController
 
@@ -40,4 +41,11 @@ defmodule DiskuyWeb.ThreadLikeController do
       send_resp(conn, :no_content, "")
     end
   end
+
+  def check_like(conn, %{"id" => id}) do
+    current_user = Guardian.Plug.current_resource(conn)
+    thread_like = Likes.get_thread_like_by_refer!(id, current_user.id)
+    render(conn, "show.json", thread_like: thread_like)
+  end
+
 end
diff --git a/diskuy_back/lib/diskuy_web/router.ex b/diskuy_back/lib/diskuy_web/router.ex
index 36edd82..2926218 100644
--- a/diskuy_back/lib/diskuy_web/router.ex
+++ b/diskuy_back/lib/diskuy_web/router.ex
@@ -16,6 +16,12 @@ defmodule DiskuyWeb.Router do
     resources "/threads", ThreadController, except: [:new, :edit, :show, :index]
     resources "/topics", TopicController, except: [:new, :edit, :show, :index]
     resources "/post", PostController, except: [:new, :edit, :show, :index]
+    post "/threads/like/:id", ThreadController, :add_like
+    options "/threads/like/:id", ThreadController, :options
+    post "/threads/dislike/:id", ThreadController, :delete_like
+    options "/threads/dislike/:id", ThreadController, :options
+    get "/threads/checklike/:id", ThreadLikeController, :check_like
+    options "/threads/checklike/:id", ThreadLikeController, :options
   end
 
   scope "/api", DiskuyWeb do
-- 
GitLab