From 00ecbadeca7d9b4c7bf72c927157853f2719d488 Mon Sep 17 00:00:00 2001 From: miraikumiko Date: Sun, 6 Jul 2025 14:46:08 +0200 Subject: [PATCH] Update --- lib/nulla/accounts/user.ex | 4 +- lib/nulla/activities/activity.ex | 4 +- lib/nulla/actors/actor.ex | 4 +- lib/nulla/announces.ex | 104 ++++++++++++++++++ lib/nulla/announces/announce.ex | 33 ++++++ lib/nulla/likes.ex | 104 ++++++++++++++++++ lib/nulla/likes/like.ex | 33 ++++++ .../media_attachments/media_attachment.ex | 4 +- lib/nulla/notes/note.ex | 3 + lib/nulla/relations/relation.ex | 4 +- .../controllers/api/announce_controller.ex | 43 ++++++++ .../controllers/api/announce_json.ex | 23 ++++ .../controllers/api/like_controller.ex | 43 ++++++++ lib/nulla_web/controllers/api/like_json.ex | 23 ++++ lib/nulla_web/controllers/api/note_json.ex | 1 + lib/nulla_web/router.ex | 2 + .../20250702091405_create_notes.exs | 1 + .../20250702152953_create_relations.exs | 4 +- .../20250706092825_create_likes.exs | 17 +++ .../20250706120640_create_announces.exs | 17 +++ test/nulla/announces_test.exs | 78 +++++++++++++ test/nulla/likes_test.exs | 78 +++++++++++++ test/nulla/notes_test.exs | 5 + .../api/announce_controller_test.exs | 100 +++++++++++++++++ .../controllers/api/like_controller_test.exs | 97 ++++++++++++++++ .../controllers/api/note_controller_test.exs | 5 + test/support/fixtures/announces_fixtures.ex | 24 ++++ test/support/fixtures/likes_fixtures.ex | 24 ++++ test/support/fixtures/notes_fixtures.ex | 1 + 29 files changed, 871 insertions(+), 12 deletions(-) create mode 100644 lib/nulla/announces.ex create mode 100644 lib/nulla/announces/announce.ex create mode 100644 lib/nulla/likes.ex create mode 100644 lib/nulla/likes/like.ex create mode 100644 lib/nulla_web/controllers/api/announce_controller.ex create mode 100644 lib/nulla_web/controllers/api/announce_json.ex create mode 100644 lib/nulla_web/controllers/api/like_controller.ex create mode 100644 lib/nulla_web/controllers/api/like_json.ex create mode 100644 priv/repo/migrations/20250706092825_create_likes.exs create mode 100644 priv/repo/migrations/20250706120640_create_announces.exs create mode 100644 test/nulla/announces_test.exs create mode 100644 test/nulla/likes_test.exs create mode 100644 test/nulla_web/controllers/api/announce_controller_test.exs create mode 100644 test/nulla_web/controllers/api/like_controller_test.exs create mode 100644 test/support/fixtures/announces_fixtures.ex create mode 100644 test/support/fixtures/likes_fixtures.ex diff --git a/lib/nulla/accounts/user.ex b/lib/nulla/accounts/user.ex index ada11b7..f2c7fa9 100644 --- a/lib/nulla/accounts/user.ex +++ b/lib/nulla/accounts/user.ex @@ -47,9 +47,9 @@ defmodule Nulla.Accounts.User do end defp maybe_put_id(changeset) do - id_in_attrs = get_field(changeset, :id) + id = get_field(changeset, :id) - if is_nil(id_in_attrs) do + if is_nil(id) do change(changeset, id: Snowflake.next_id()) else changeset diff --git a/lib/nulla/activities/activity.ex b/lib/nulla/activities/activity.ex index 2201dbf..a98fd5e 100644 --- a/lib/nulla/activities/activity.ex +++ b/lib/nulla/activities/activity.ex @@ -26,9 +26,9 @@ defmodule Nulla.Activities.Activity do end defp maybe_put_id(changeset) do - id_in_attrs = get_field(changeset, :id) + id = get_field(changeset, :id) - if is_nil(id_in_attrs) do + if is_nil(id) do change(changeset, id: Snowflake.next_id()) else changeset diff --git a/lib/nulla/actors/actor.ex b/lib/nulla/actors/actor.ex index d11363e..66b79bd 100644 --- a/lib/nulla/actors/actor.ex +++ b/lib/nulla/actors/actor.ex @@ -85,9 +85,9 @@ defmodule Nulla.Actors.Actor do end defp maybe_put_id(changeset) do - id_in_attrs = get_field(changeset, :id) + id = get_field(changeset, :id) - if is_nil(id_in_attrs) do + if is_nil(id) do change(changeset, id: Snowflake.next_id()) else changeset diff --git a/lib/nulla/announces.ex b/lib/nulla/announces.ex new file mode 100644 index 0000000..c8d5fda --- /dev/null +++ b/lib/nulla/announces.ex @@ -0,0 +1,104 @@ +defmodule Nulla.Announces do + @moduledoc """ + The Announces context. + """ + + import Ecto.Query, warn: false + alias Nulla.Repo + + alias Nulla.Announces.Announce + + @doc """ + Returns the list of announces. + + ## Examples + + iex> list_announces() + [%Announce{}, ...] + + """ + def list_announces do + Repo.all(Announce) + end + + @doc """ + Gets a single announce. + + Raises `Ecto.NoResultsError` if the Announce does not exist. + + ## Examples + + iex> get_announce!(123) + %Announce{} + + iex> get_announce!(456) + ** (Ecto.NoResultsError) + + """ + def get_announce!(id), do: Repo.get!(Announce, id) + + @doc """ + Creates a announce. + + ## Examples + + iex> create_announce(%{field: value}) + {:ok, %Announce{}} + + iex> create_announce(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_announce(attrs \\ %{}) do + %Announce{} + |> Announce.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a announce. + + ## Examples + + iex> update_announce(announce, %{field: new_value}) + {:ok, %Announce{}} + + iex> update_announce(announce, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_announce(%Announce{} = announce, attrs) do + announce + |> Announce.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a announce. + + ## Examples + + iex> delete_announce(announce) + {:ok, %Announce{}} + + iex> delete_announce(announce) + {:error, %Ecto.Changeset{}} + + """ + def delete_announce(%Announce{} = announce) do + Repo.delete(announce) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking announce changes. + + ## Examples + + iex> change_announce(announce) + %Ecto.Changeset{data: %Announce{}} + + """ + def change_announce(%Announce{} = announce, attrs \\ %{}) do + Announce.changeset(announce, attrs) + end +end diff --git a/lib/nulla/announces/announce.ex b/lib/nulla/announces/announce.ex new file mode 100644 index 0000000..ce596c2 --- /dev/null +++ b/lib/nulla/announces/announce.ex @@ -0,0 +1,33 @@ +defmodule Nulla.Announces.Announce do + use Ecto.Schema + import Ecto.Changeset + alias Nulla.Snowflake + alias Nulla.Actors.Actor + alias Nulla.Notes.Note + + @primary_key {:id, :integer, autogenerate: false} + schema "announces" do + belongs_to :actor, Actor + belongs_to :note, Note + + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(announce, attrs) do + announce + |> cast(attrs, [:actor_id, :note_id]) + |> maybe_put_id() + |> validate_required([:actor_id, :note_id]) + end + + defp maybe_put_id(changeset) do + id = get_field(changeset, :id) + + if is_nil(id) do + change(changeset, id: Snowflake.next_id()) + else + changeset + end + end +end diff --git a/lib/nulla/likes.ex b/lib/nulla/likes.ex new file mode 100644 index 0000000..c89ee6b --- /dev/null +++ b/lib/nulla/likes.ex @@ -0,0 +1,104 @@ +defmodule Nulla.Likes do + @moduledoc """ + The Likes context. + """ + + import Ecto.Query, warn: false + alias Nulla.Repo + + alias Nulla.Likes.Like + + @doc """ + Returns the list of likes. + + ## Examples + + iex> list_likes() + [%Like{}, ...] + + """ + def list_likes do + Repo.all(Like) + end + + @doc """ + Gets a single like. + + Raises `Ecto.NoResultsError` if the Like does not exist. + + ## Examples + + iex> get_like!(123) + %Like{} + + iex> get_like!(456) + ** (Ecto.NoResultsError) + + """ + def get_like!(id), do: Repo.get!(Like, id) + + @doc """ + Creates a like. + + ## Examples + + iex> create_like(%{field: value}) + {:ok, %Like{}} + + iex> create_like(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_like(attrs \\ %{}) do + %Like{} + |> Like.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a like. + + ## Examples + + iex> update_like(like, %{field: new_value}) + {:ok, %Like{}} + + iex> update_like(like, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_like(%Like{} = like, attrs) do + like + |> Like.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a like. + + ## Examples + + iex> delete_like(like) + {:ok, %Like{}} + + iex> delete_like(like) + {:error, %Ecto.Changeset{}} + + """ + def delete_like(%Like{} = like) do + Repo.delete(like) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking like changes. + + ## Examples + + iex> change_like(like) + %Ecto.Changeset{data: %Like{}} + + """ + def change_like(%Like{} = like, attrs \\ %{}) do + Like.changeset(like, attrs) + end +end diff --git a/lib/nulla/likes/like.ex b/lib/nulla/likes/like.ex new file mode 100644 index 0000000..8d4ec0b --- /dev/null +++ b/lib/nulla/likes/like.ex @@ -0,0 +1,33 @@ +defmodule Nulla.Likes.Like do + use Ecto.Schema + import Ecto.Changeset + alias Nulla.Snowflake + alias Nulla.Actors.Actor + alias Nulla.Notes.Note + + @primary_key {:id, :integer, autogenerate: false} + schema "likes" do + belongs_to :actor, Actor + belongs_to :note, Note + + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(like, attrs) do + like + |> cast(attrs, [:actor_id, :note_id]) + |> maybe_put_id() + |> validate_required([:actor_id, :note_id]) + end + + defp maybe_put_id(changeset) do + id = get_field(changeset, :id) + + if is_nil(id) do + change(changeset, id: Snowflake.next_id()) + else + changeset + end + end +end diff --git a/lib/nulla/media_attachments/media_attachment.ex b/lib/nulla/media_attachments/media_attachment.ex index 21f8b5d..0c24a39 100644 --- a/lib/nulla/media_attachments/media_attachment.ex +++ b/lib/nulla/media_attachments/media_attachment.ex @@ -27,9 +27,9 @@ defmodule Nulla.MediaAttachments.MediaAttachment do end defp maybe_put_id(changeset) do - id_in_attrs = get_field(changeset, :id) + id = get_field(changeset, :id) - if is_nil(id_in_attrs) do + if is_nil(id) do change(changeset, id: Snowflake.next_id()) else changeset diff --git a/lib/nulla/notes/note.ex b/lib/nulla/notes/note.ex index 13c998d..93749d4 100644 --- a/lib/nulla/notes/note.ex +++ b/lib/nulla/notes/note.ex @@ -17,6 +17,7 @@ defmodule Nulla.Notes.Note do field :cc, {:array, :string} field :sensitive, :boolean, default: false field :content, :string + field :tag, {:array, :map} field :language, :string field :featured, :boolean, default: false @@ -39,6 +40,7 @@ defmodule Nulla.Notes.Note do :cc, :sensitive, :content, + :tag, :language, :featured, :actor_id @@ -53,6 +55,7 @@ defmodule Nulla.Notes.Note do :to, :cc, :content, + :tag, :language, :featured, :actor_id diff --git a/lib/nulla/relations/relation.ex b/lib/nulla/relations/relation.ex index f22a79d..66c55ca 100644 --- a/lib/nulla/relations/relation.ex +++ b/lib/nulla/relations/relation.ex @@ -64,9 +64,9 @@ defmodule Nulla.Relations.Relation do end defp maybe_put_id(changeset) do - id_in_attrs = get_field(changeset, :id) + id = get_field(changeset, :id) - if is_nil(id_in_attrs) do + if is_nil(id) do change(changeset, id: Snowflake.next_id()) else changeset diff --git a/lib/nulla_web/controllers/api/announce_controller.ex b/lib/nulla_web/controllers/api/announce_controller.ex new file mode 100644 index 0000000..e33b45b --- /dev/null +++ b/lib/nulla_web/controllers/api/announce_controller.ex @@ -0,0 +1,43 @@ +defmodule NullaWeb.Api.AnnounceController do + use NullaWeb, :controller + + alias Nulla.Announces + alias Nulla.Announces.Announce + + action_fallback NullaWeb.FallbackController + + def index(conn, _params) do + announces = Announces.list_announces() + render(conn, :index, announces: announces) + end + + def create(conn, %{"announce" => announce_params}) do + with {:ok, %Announce{} = announce} <- Announces.create_announce(announce_params) do + conn + |> put_status(:created) + |> put_resp_header("location", ~p"/api/announces/#{announce}") + |> render(:show, announce: announce) + end + end + + def show(conn, %{"id" => id}) do + announce = Announces.get_announce!(id) + render(conn, :show, announce: announce) + end + + def update(conn, %{"id" => id, "announce" => announce_params}) do + announce = Announces.get_announce!(id) + + with {:ok, %Announce{} = announce} <- Announces.update_announce(announce, announce_params) do + render(conn, :show, announce: announce) + end + end + + def delete(conn, %{"id" => id}) do + announce = Announces.get_announce!(id) + + with {:ok, %Announce{}} <- Announces.delete_announce(announce) do + send_resp(conn, :no_content, "") + end + end +end diff --git a/lib/nulla_web/controllers/api/announce_json.ex b/lib/nulla_web/controllers/api/announce_json.ex new file mode 100644 index 0000000..0ab49d2 --- /dev/null +++ b/lib/nulla_web/controllers/api/announce_json.ex @@ -0,0 +1,23 @@ +defmodule NullaWeb.Api.AnnounceJSON do + alias Nulla.Announces.Announce + + @doc """ + Renders a list of announces. + """ + def index(%{announces: announces}) do + %{data: for(announce <- announces, do: data(announce))} + end + + @doc """ + Renders a single announce. + """ + def show(%{announce: announce}) do + %{data: data(announce)} + end + + defp data(%Announce{} = announce) do + %{ + id: announce.id + } + end +end diff --git a/lib/nulla_web/controllers/api/like_controller.ex b/lib/nulla_web/controllers/api/like_controller.ex new file mode 100644 index 0000000..3e454c3 --- /dev/null +++ b/lib/nulla_web/controllers/api/like_controller.ex @@ -0,0 +1,43 @@ +defmodule NullaWeb.Api.LikeController do + use NullaWeb, :controller + + alias Nulla.Likes + alias Nulla.Likes.Like + + action_fallback NullaWeb.FallbackController + + def index(conn, _params) do + likes = Likes.list_likes() + render(conn, :index, likes: likes) + end + + def create(conn, %{"like" => like_params}) do + with {:ok, %Like{} = like} <- Likes.create_like(like_params) do + conn + |> put_status(:created) + |> put_resp_header("location", ~p"/api/likes/#{like}") + |> render(:show, like: like) + end + end + + def show(conn, %{"id" => id}) do + like = Likes.get_like!(id) + render(conn, :show, like: like) + end + + def update(conn, %{"id" => id, "like" => like_params}) do + like = Likes.get_like!(id) + + with {:ok, %Like{} = like} <- Likes.update_like(like, like_params) do + render(conn, :show, like: like) + end + end + + def delete(conn, %{"id" => id}) do + like = Likes.get_like!(id) + + with {:ok, %Like{}} <- Likes.delete_like(like) do + send_resp(conn, :no_content, "") + end + end +end diff --git a/lib/nulla_web/controllers/api/like_json.ex b/lib/nulla_web/controllers/api/like_json.ex new file mode 100644 index 0000000..657db9e --- /dev/null +++ b/lib/nulla_web/controllers/api/like_json.ex @@ -0,0 +1,23 @@ +defmodule NullaWeb.Api.LikeJSON do + alias Nulla.Likes.Like + + @doc """ + Renders a list of likes. + """ + def index(%{likes: likes}) do + %{data: for(like <- likes, do: data(like))} + end + + @doc """ + Renders a single like. + """ + def show(%{like: like}) do + %{data: data(like)} + end + + defp data(%Like{} = like) do + %{ + id: like.id + } + end +end diff --git a/lib/nulla_web/controllers/api/note_json.ex b/lib/nulla_web/controllers/api/note_json.ex index c329cb6..e9ecaa0 100644 --- a/lib/nulla_web/controllers/api/note_json.ex +++ b/lib/nulla_web/controllers/api/note_json.ex @@ -26,6 +26,7 @@ defmodule NullaWeb.Api.NoteJSON do cc: note.cc, sensitive: note.sensitive, content: note.content, + tag: note.tag, language: note.language } end diff --git a/lib/nulla_web/router.ex b/lib/nulla_web/router.ex index 7a6c409..503945f 100644 --- a/lib/nulla_web/router.ex +++ b/lib/nulla_web/router.ex @@ -71,6 +71,8 @@ defmodule NullaWeb.Router do resources "/notes", NoteController, except: [:new, :edit] resources "/media_attachments", MediaAttachmentController, except: [:new, :edit] resources "/relations", RelationController, except: [:new, :edit] + resources "/likes", LikeController, except: [:new, :edit] + resources "/announces", AnnounceController, except: [:new, :edit] resources "/activities", ActivityController, except: [:new, :edit] end diff --git a/priv/repo/migrations/20250702091405_create_notes.exs b/priv/repo/migrations/20250702091405_create_notes.exs index a605abb..7e4d38e 100644 --- a/priv/repo/migrations/20250702091405_create_notes.exs +++ b/priv/repo/migrations/20250702091405_create_notes.exs @@ -13,6 +13,7 @@ defmodule Nulla.Repo.Migrations.CreateNotes do add :cc, {:array, :string} add :sensitive, :boolean, default: false, null: false add :content, :string + add :tag, {:array, :map} add :language, :string add :featured, :boolean, default: false, null: false add :actor_id, references(:actors, on_delete: :delete_all) diff --git a/priv/repo/migrations/20250702152953_create_relations.exs b/priv/repo/migrations/20250702152953_create_relations.exs index 97368bd..efe6ba0 100644 --- a/priv/repo/migrations/20250702152953_create_relations.exs +++ b/priv/repo/migrations/20250702152953_create_relations.exs @@ -17,8 +17,8 @@ defmodule Nulla.Repo.Migrations.CreateRelations do add :requested, :boolean, default: false, null: false add :note, :string - add :local_actor_id, references(:actors, type: :bigint), null: false - add :remote_actor_id, references(:actors, type: :bigint), null: false + add :local_actor_id, references(:actors, on_delete: :delete_all), null: false + add :remote_actor_id, references(:actors, on_delete: :delete_all), null: false timestamps(type: :utc_datetime) end diff --git a/priv/repo/migrations/20250706092825_create_likes.exs b/priv/repo/migrations/20250706092825_create_likes.exs new file mode 100644 index 0000000..5d0c7e7 --- /dev/null +++ b/priv/repo/migrations/20250706092825_create_likes.exs @@ -0,0 +1,17 @@ +defmodule Nulla.Repo.Migrations.CreateLikes do + use Ecto.Migration + + def change do + create table(:likes, primary_key: false) do + add :id, :bigint, primary_key: true + add :actor_id, references(:actors, on_delete: :delete_all), null: false + add :note_id, references(:notes, on_delete: :delete_all), null: false + + timestamps(type: :utc_datetime) + end + + create index(:likes, [:actor_id]) + create index(:likes, [:note_id]) + create unique_index(:likes, [:actor_id, :note_id]) + end +end diff --git a/priv/repo/migrations/20250706120640_create_announces.exs b/priv/repo/migrations/20250706120640_create_announces.exs new file mode 100644 index 0000000..331381b --- /dev/null +++ b/priv/repo/migrations/20250706120640_create_announces.exs @@ -0,0 +1,17 @@ +defmodule Nulla.Repo.Migrations.CreateAnnounces do + use Ecto.Migration + + def change do + create table(:announces, primary_key: false) do + add :id, :bigint, primary_key: true + add :actor_id, references(:actors, on_delete: :delete_all), null: false + add :note_id, references(:notes, on_delete: :delete_all), null: false + + timestamps(type: :utc_datetime) + end + + create index(:announces, [:actor_id]) + create index(:announces, [:note_id]) + create unique_index(:announces, [:actor_id, :note_id]) + end +end diff --git a/test/nulla/announces_test.exs b/test/nulla/announces_test.exs new file mode 100644 index 0000000..f390f13 --- /dev/null +++ b/test/nulla/announces_test.exs @@ -0,0 +1,78 @@ +defmodule Nulla.AnnouncesTest do + use Nulla.DataCase + + alias Nulla.Announces + + describe "announces" do + alias Nulla.Announces.Announce + + import Nulla.ActorsFixtures + import Nulla.NotesFixtures + import Nulla.AnnouncesFixtures + + @invalid_attrs %{ + actor_id: nil, + note_id: nil + } + + test "list_announces/0 returns all announces" do + announce = announce_fixture() + assert Announces.list_announces() == [announce] + end + + test "get_announce!/1 returns the announce with given id" do + announce = announce_fixture() + assert Announces.get_announce!(announce.id) == announce + end + + test "create_announce/1 with valid data creates a announce" do + actor = actor_fixture() + note = note_fixture() + + valid_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + assert {:ok, %Announce{} = announce} = Announces.create_announce(valid_attrs) + assert is_integer(announce.actor_id) + assert is_integer(announce.note_id) + end + + test "create_announce/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Announces.create_announce(@invalid_attrs) + end + + test "update_announce/2 with valid data updates the announce" do + actor = actor_fixture() + note = note_fixture() + announce = announce_fixture() + + update_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + assert {:ok, %Announce{} = announce} = Announces.update_announce(announce, update_attrs) + assert is_integer(announce.actor_id) + assert is_integer(announce.note_id) + end + + test "update_announce/2 with invalid data returns error changeset" do + announce = announce_fixture() + assert {:error, %Ecto.Changeset{}} = Announces.update_announce(announce, @invalid_attrs) + assert announce == Announces.get_announce!(announce.id) + end + + test "delete_announce/1 deletes the announce" do + announce = announce_fixture() + assert {:ok, %Announce{}} = Announces.delete_announce(announce) + assert_raise Ecto.NoResultsError, fn -> Announces.get_announce!(announce.id) end + end + + test "change_announce/1 returns a announce changeset" do + announce = announce_fixture() + assert %Ecto.Changeset{} = Announces.change_announce(announce) + end + end +end diff --git a/test/nulla/likes_test.exs b/test/nulla/likes_test.exs new file mode 100644 index 0000000..3834045 --- /dev/null +++ b/test/nulla/likes_test.exs @@ -0,0 +1,78 @@ +defmodule Nulla.LikesTest do + use Nulla.DataCase + + alias Nulla.Likes + + describe "likes" do + alias Nulla.Likes.Like + + import Nulla.ActorsFixtures + import Nulla.NotesFixtures + import Nulla.LikesFixtures + + @invalid_attrs %{ + actor_id: nil, + note_id: nil + } + + test "list_likes/0 returns all likes" do + like = like_fixture() + assert Likes.list_likes() == [like] + end + + test "get_like!/1 returns the like with given id" do + like = like_fixture() + assert Likes.get_like!(like.id) == like + end + + test "create_like/1 with valid data creates a like" do + actor = actor_fixture() + note = note_fixture() + + valid_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + assert {:ok, %Like{} = like} = Likes.create_like(valid_attrs) + assert is_integer(like.actor_id) + assert is_integer(like.note_id) + end + + test "create_like/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Likes.create_like(@invalid_attrs) + end + + test "update_like/2 with valid data updates the like" do + actor = actor_fixture() + note = note_fixture() + like = like_fixture() + + update_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + assert {:ok, %Like{} = like} = Likes.update_like(like, update_attrs) + assert is_integer(like.actor_id) + assert is_integer(like.note_id) + end + + test "update_like/2 with invalid data returns error changeset" do + like = like_fixture() + assert {:error, %Ecto.Changeset{}} = Likes.update_like(like, @invalid_attrs) + assert like == Likes.get_like!(like.id) + end + + test "delete_like/1 deletes the like" do + like = like_fixture() + assert {:ok, %Like{}} = Likes.delete_like(like) + assert_raise Ecto.NoResultsError, fn -> Likes.get_like!(like.id) end + end + + test "change_like/1 returns a like changeset" do + like = like_fixture() + assert %Ecto.Changeset{} = Likes.change_like(like) + end + end +end diff --git a/test/nulla/notes_test.exs b/test/nulla/notes_test.exs index d200212..97936ac 100644 --- a/test/nulla/notes_test.exs +++ b/test/nulla/notes_test.exs @@ -13,6 +13,7 @@ defmodule Nulla.NotesTest do sensitive: nil, cc: nil, to: nil, + tag: nil, url: nil, language: nil, inReplyTo: nil, @@ -39,6 +40,7 @@ defmodule Nulla.NotesTest do sensitive: true, cc: ["option1", "option2"], to: ["option1", "option2"], + tag: [%{"key1" => "value1"}, %{"key2" => "value2"}], url: "some url", language: "some language", inReplyTo: "some inReplyTo", @@ -52,6 +54,7 @@ defmodule Nulla.NotesTest do assert note.sensitive == true assert note.cc == ["option1", "option2"] assert note.to == ["option1", "option2"] + assert note.tag == [%{"key1" => "value1"}, %{"key2" => "value2"}] assert note.url == "some url" assert note.language == "some language" assert note.inReplyTo == "some inReplyTo" @@ -73,6 +76,7 @@ defmodule Nulla.NotesTest do sensitive: false, cc: ["option1"], to: ["option1"], + tag: [%{"key1" => "value1"}], url: "some updated url", language: "some updated language", inReplyTo: "some updated inReplyTo", @@ -86,6 +90,7 @@ defmodule Nulla.NotesTest do assert note.sensitive == false assert note.cc == ["option1"] assert note.to == ["option1"] + assert note.tag == [%{"key1" => "value1"}] assert note.url == "some updated url" assert note.language == "some updated language" assert note.inReplyTo == "some updated inReplyTo" diff --git a/test/nulla_web/controllers/api/announce_controller_test.exs b/test/nulla_web/controllers/api/announce_controller_test.exs new file mode 100644 index 0000000..6a3e392 --- /dev/null +++ b/test/nulla_web/controllers/api/announce_controller_test.exs @@ -0,0 +1,100 @@ +defmodule NullaWeb.Api.AnnounceControllerTest do + use NullaWeb.ConnCase + + import Nulla.ActorsFixtures + import Nulla.NotesFixtures + import Nulla.AnnouncesFixtures + + alias Nulla.Announces.Announce + + @invalid_attrs %{ + actor_id: nil, + note_id: nil + } + + setup %{conn: conn} do + {:ok, conn: put_req_header(conn, "accept", "application/json")} + end + + describe "index" do + test "lists all announces", %{conn: conn} do + conn = get(conn, ~p"/api/announces") + assert json_response(conn, 200)["data"] == [] + end + end + + describe "create announce" do + test "renders announce when data is valid", %{conn: conn} do + actor = actor_fixture() + note = note_fixture() + + create_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + conn = post(conn, ~p"/api/announces", announce: create_attrs) + assert %{"id" => id} = json_response(conn, 201)["data"] + + conn = get(conn, ~p"/api/announces/#{id}") + + assert %{ + "id" => ^id + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = post(conn, ~p"/api/announces", announce: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "update announce" do + setup [:create_announce] + + test "renders announce when data is valid", %{ + conn: conn, + announce: %Announce{id: id} = announce + } do + actor = actor_fixture() + note = note_fixture() + + update_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + conn = put(conn, ~p"/api/announces/#{announce}", announce: update_attrs) + assert %{"id" => ^id} = json_response(conn, 200)["data"] + + conn = get(conn, ~p"/api/announces/#{id}") + + assert %{ + "id" => ^id + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn, announce: announce} do + conn = put(conn, ~p"/api/announces/#{announce}", announce: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "delete announce" do + setup [:create_announce] + + test "deletes chosen announce", %{conn: conn, announce: announce} do + conn = delete(conn, ~p"/api/announces/#{announce}") + assert response(conn, 204) + + assert_error_sent 404, fn -> + get(conn, ~p"/api/announces/#{announce}") + end + end + end + + defp create_announce(_) do + announce = announce_fixture() + %{announce: announce} + end +end diff --git a/test/nulla_web/controllers/api/like_controller_test.exs b/test/nulla_web/controllers/api/like_controller_test.exs new file mode 100644 index 0000000..32e90ea --- /dev/null +++ b/test/nulla_web/controllers/api/like_controller_test.exs @@ -0,0 +1,97 @@ +defmodule NullaWeb.Api.LikeControllerTest do + use NullaWeb.ConnCase + + import Nulla.ActorsFixtures + import Nulla.NotesFixtures + import Nulla.LikesFixtures + + alias Nulla.Likes.Like + + @invalid_attrs %{ + actor_id: nil, + note_id: nil + } + + setup %{conn: conn} do + {:ok, conn: put_req_header(conn, "accept", "application/json")} + end + + describe "index" do + test "lists all likes", %{conn: conn} do + conn = get(conn, ~p"/api/likes") + assert json_response(conn, 200)["data"] == [] + end + end + + describe "create like" do + test "renders like when data is valid", %{conn: conn} do + actor = actor_fixture() + note = note_fixture() + + create_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + conn = post(conn, ~p"/api/likes", like: create_attrs) + assert %{"id" => id} = json_response(conn, 201)["data"] + + conn = get(conn, ~p"/api/likes/#{id}") + + assert %{ + "id" => ^id + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn} do + conn = post(conn, ~p"/api/likes", like: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "update like" do + setup [:create_like] + + test "renders like when data is valid", %{conn: conn, like: %Like{id: id} = like} do + actor = actor_fixture() + note = note_fixture() + + update_attrs = %{ + actor_id: actor.id, + note_id: note.id + } + + conn = put(conn, ~p"/api/likes/#{like}", like: update_attrs) + assert %{"id" => ^id} = json_response(conn, 200)["data"] + + conn = get(conn, ~p"/api/likes/#{id}") + + assert %{ + "id" => ^id + } = json_response(conn, 200)["data"] + end + + test "renders errors when data is invalid", %{conn: conn, like: like} do + conn = put(conn, ~p"/api/likes/#{like}", like: @invalid_attrs) + assert json_response(conn, 422)["errors"] != %{} + end + end + + describe "delete like" do + setup [:create_like] + + test "deletes chosen like", %{conn: conn, like: like} do + conn = delete(conn, ~p"/api/likes/#{like}") + assert response(conn, 204) + + assert_error_sent 404, fn -> + get(conn, ~p"/api/likes/#{like}") + end + end + end + + defp create_like(_) do + like = like_fixture() + %{like: like} + end +end diff --git a/test/nulla_web/controllers/api/note_controller_test.exs b/test/nulla_web/controllers/api/note_controller_test.exs index fe2afce..52ca261 100644 --- a/test/nulla_web/controllers/api/note_controller_test.exs +++ b/test/nulla_web/controllers/api/note_controller_test.exs @@ -10,6 +10,7 @@ defmodule NullaWeb.Api.NoteControllerTest do sensitive: true, cc: ["option1", "option2"], to: ["option1", "option2"], + tag: [%{"key1" => "value1"}, %{"key2" => "value2"}], url: "some url", language: "some language", inReplyTo: "some inReplyTo", @@ -21,6 +22,7 @@ defmodule NullaWeb.Api.NoteControllerTest do sensitive: false, cc: ["option1"], to: ["option1"], + tag: [%{"key1" => "value1"}], url: "some updated url", language: "some updated language", inReplyTo: "some updated inReplyTo", @@ -32,6 +34,7 @@ defmodule NullaWeb.Api.NoteControllerTest do sensitive: nil, cc: nil, to: nil, + tag: nil, url: nil, language: nil, inReplyTo: nil, @@ -71,6 +74,7 @@ defmodule NullaWeb.Api.NoteControllerTest do "published" => "2025-07-01T09:17:00Z", "sensitive" => true, "to" => ["option1", "option2"], + "tag" => [%{"key1" => "value1"}, %{"key2" => "value2"}], "url" => "some url", "visibility" => "some visibility" } = json_response(conn, 200)["data"] @@ -100,6 +104,7 @@ defmodule NullaWeb.Api.NoteControllerTest do "published" => "2025-07-02T09:17:00Z", "sensitive" => false, "to" => ["option1"], + "tag" => [%{"key1" => "value1"}], "url" => "some updated url", "visibility" => "some updated visibility" } = json_response(conn, 200)["data"] diff --git a/test/support/fixtures/announces_fixtures.ex b/test/support/fixtures/announces_fixtures.ex new file mode 100644 index 0000000..68ee1d2 --- /dev/null +++ b/test/support/fixtures/announces_fixtures.ex @@ -0,0 +1,24 @@ +defmodule Nulla.AnnouncesFixtures do + import Nulla.ActorsFixtures + import Nulla.NotesFixtures + + @moduledoc """ + This module defines test helpers for creating + entities via the `Nulla.Announces` context. + """ + + @doc """ + Generate a announce. + """ + def announce_fixture(attrs \\ %{}) do + actor = actor_fixture() + note = note_fixture() + + {:ok, announce} = + attrs + |> Enum.into(%{actor_id: actor.id, note_id: note.id}) + |> Nulla.Announces.create_announce() + + announce + end +end diff --git a/test/support/fixtures/likes_fixtures.ex b/test/support/fixtures/likes_fixtures.ex new file mode 100644 index 0000000..ff1bcfd --- /dev/null +++ b/test/support/fixtures/likes_fixtures.ex @@ -0,0 +1,24 @@ +defmodule Nulla.LikesFixtures do + import Nulla.ActorsFixtures + import Nulla.NotesFixtures + + @moduledoc """ + This module defines test helpers for creating + entities via the `Nulla.Likes` context. + """ + + @doc """ + Generate a like. + """ + def like_fixture(attrs \\ %{}) do + actor = actor_fixture() + note = note_fixture() + + {:ok, like} = + attrs + |> Enum.into(%{actor_id: actor.id, note_id: note.id}) + |> Nulla.Likes.create_like() + + like + end +end diff --git a/test/support/fixtures/notes_fixtures.ex b/test/support/fixtures/notes_fixtures.ex index a3d34b1..ed1f752 100644 --- a/test/support/fixtures/notes_fixtures.ex +++ b/test/support/fixtures/notes_fixtures.ex @@ -22,6 +22,7 @@ defmodule Nulla.NotesFixtures do published: ~U[2025-07-01 09:17:00Z], sensitive: true, to: ["option1", "option2"], + tag: [%{"key1" => "value1"}, %{"key2" => "value2"}], url: "some url", visibility: "some visibility", actor_id: actor.id