diff --git a/lib/philomena/forums.ex b/lib/philomena/forums.ex new file mode 100644 index 00000000..4ba7a4c6 --- /dev/null +++ b/lib/philomena/forums.ex @@ -0,0 +1,392 @@ +defmodule Philomena.Forums do + @moduledoc """ + The Forums context. + """ + + import Ecto.Query, warn: false + alias Philomena.Repo + + alias Philomena.Forums.Forum + + @doc """ + Returns the list of forums. + + ## Examples + + iex> list_forums() + [%Forum{}, ...] + + """ + def list_forums do + Repo.all(Forum) + end + + @doc """ + Gets a single forum. + + Raises `Ecto.NoResultsError` if the Forum does not exist. + + ## Examples + + iex> get_forum!(123) + %Forum{} + + iex> get_forum!(456) + ** (Ecto.NoResultsError) + + """ + def get_forum!(id), do: Repo.get!(Forum, id) + + @doc """ + Creates a forum. + + ## Examples + + iex> create_forum(%{field: value}) + {:ok, %Forum{}} + + iex> create_forum(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_forum(attrs \\ %{}) do + %Forum{} + |> Forum.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a forum. + + ## Examples + + iex> update_forum(forum, %{field: new_value}) + {:ok, %Forum{}} + + iex> update_forum(forum, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_forum(%Forum{} = forum, attrs) do + forum + |> Forum.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a Forum. + + ## Examples + + iex> delete_forum(forum) + {:ok, %Forum{}} + + iex> delete_forum(forum) + {:error, %Ecto.Changeset{}} + + """ + def delete_forum(%Forum{} = forum) do + Repo.delete(forum) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking forum changes. + + ## Examples + + iex> change_forum(forum) + %Ecto.Changeset{source: %Forum{}} + + """ + def change_forum(%Forum{} = forum) do + Forum.changeset(forum, %{}) + end + + alias Philomena.Forums.Topic + + @doc """ + Returns the list of topics. + + ## Examples + + iex> list_topics() + [%Topic{}, ...] + + """ + def list_topics do + Repo.all(Topic) + end + + @doc """ + Gets a single topic. + + Raises `Ecto.NoResultsError` if the Topic does not exist. + + ## Examples + + iex> get_topic!(123) + %Topic{} + + iex> get_topic!(456) + ** (Ecto.NoResultsError) + + """ + def get_topic!(id), do: Repo.get!(Topic, id) + + @doc """ + Creates a topic. + + ## Examples + + iex> create_topic(%{field: value}) + {:ok, %Topic{}} + + iex> create_topic(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_topic(attrs \\ %{}) do + %Topic{} + |> Topic.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a topic. + + ## Examples + + iex> update_topic(topic, %{field: new_value}) + {:ok, %Topic{}} + + iex> update_topic(topic, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_topic(%Topic{} = topic, attrs) do + topic + |> Topic.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a Topic. + + ## Examples + + iex> delete_topic(topic) + {:ok, %Topic{}} + + iex> delete_topic(topic) + {:error, %Ecto.Changeset{}} + + """ + def delete_topic(%Topic{} = topic) do + Repo.delete(topic) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking topic changes. + + ## Examples + + iex> change_topic(topic) + %Ecto.Changeset{source: %Topic{}} + + """ + def change_topic(%Topic{} = topic) do + Topic.changeset(topic, %{}) + end + + alias Philomena.Forums.Post + + @doc """ + Returns the list of posts. + + ## Examples + + iex> list_posts() + [%Post{}, ...] + + """ + def list_posts do + Repo.all(Post) + end + + @doc """ + Gets a single post. + + Raises `Ecto.NoResultsError` if the Post does not exist. + + ## Examples + + iex> get_post!(123) + %Post{} + + iex> get_post!(456) + ** (Ecto.NoResultsError) + + """ + def get_post!(id), do: Repo.get!(Post, id) + + @doc """ + Creates a post. + + ## Examples + + iex> create_post(%{field: value}) + {:ok, %Post{}} + + iex> create_post(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_post(attrs \\ %{}) do + %Post{} + |> Post.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a post. + + ## Examples + + iex> update_post(post, %{field: new_value}) + {:ok, %Post{}} + + iex> update_post(post, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_post(%Post{} = post, attrs) do + post + |> Post.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a Post. + + ## Examples + + iex> delete_post(post) + {:ok, %Post{}} + + iex> delete_post(post) + {:error, %Ecto.Changeset{}} + + """ + def delete_post(%Post{} = post) do + Repo.delete(post) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking post changes. + + ## Examples + + iex> change_post(post) + %Ecto.Changeset{source: %Post{}} + + """ + def change_post(%Post{} = post) do + Post.changeset(post, %{}) + end + + alias Philomena.Forums.Subscription + + @doc """ + Returns the list of forum_subscriptions. + + ## Examples + + iex> list_forum_subscriptions() + [%Subscription{}, ...] + + """ + def list_forum_subscriptions do + Repo.all(Subscription) + end + + @doc """ + Gets a single subscription. + + Raises `Ecto.NoResultsError` if the Subscription does not exist. + + ## Examples + + iex> get_subscription!(123) + %Subscription{} + + iex> get_subscription!(456) + ** (Ecto.NoResultsError) + + """ + def get_subscription!(id), do: Repo.get!(Subscription, id) + + @doc """ + Creates a subscription. + + ## Examples + + iex> create_subscription(%{field: value}) + {:ok, %Subscription{}} + + iex> create_subscription(%{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def create_subscription(attrs \\ %{}) do + %Subscription{} + |> Subscription.changeset(attrs) + |> Repo.insert() + end + + @doc """ + Updates a subscription. + + ## Examples + + iex> update_subscription(subscription, %{field: new_value}) + {:ok, %Subscription{}} + + iex> update_subscription(subscription, %{field: bad_value}) + {:error, %Ecto.Changeset{}} + + """ + def update_subscription(%Subscription{} = subscription, attrs) do + subscription + |> Subscription.changeset(attrs) + |> Repo.update() + end + + @doc """ + Deletes a Subscription. + + ## Examples + + iex> delete_subscription(subscription) + {:ok, %Subscription{}} + + iex> delete_subscription(subscription) + {:error, %Ecto.Changeset{}} + + """ + def delete_subscription(%Subscription{} = subscription) do + Repo.delete(subscription) + end + + @doc """ + Returns an `%Ecto.Changeset{}` for tracking subscription changes. + + ## Examples + + iex> change_subscription(subscription) + %Ecto.Changeset{source: %Subscription{}} + + """ + def change_subscription(%Subscription{} = subscription) do + Subscription.changeset(subscription, %{}) + end +end diff --git a/lib/philomena/forums/forum.ex b/lib/philomena/forums/forum.ex new file mode 100644 index 00000000..2d4fc1da --- /dev/null +++ b/lib/philomena/forums/forum.ex @@ -0,0 +1,25 @@ +defmodule Philomena.Forums.Forum do + use Ecto.Schema + import Ecto.Changeset + + schema "forums" do + belongs_to :last_post, Philomena.Forums.Post + belongs_to :last_topic, Philomena.Forums.Topic + + field :name, :string + field :short_name, :string + field :description, :string + field :access_level, :string, default: "normal" + field :topic_count, :integer, default: 0 + field :post_count, :integer, default: 0 + + timestamps(inserted_at: :created_at) + end + + @doc false + def changeset(forum, attrs) do + forum + |> cast(attrs, []) + |> validate_required([]) + end +end diff --git a/lib/philomena/forums/post.ex b/lib/philomena/forums/post.ex new file mode 100644 index 00000000..60664ec7 --- /dev/null +++ b/lib/philomena/forums/post.ex @@ -0,0 +1,33 @@ +defmodule Philomena.Forums.Post do + use Ecto.Schema + import Ecto.Changeset + + schema "posts" do + belongs_to :user, Philomena.Users.User + belongs_to :topic, Philomena.Forums.Topic + belongs_to :deleted_by, Philomena.Users.User + + field :body, :string + field :edit_reason, :string + field :ip, EctoNetwork.INET + field :fingerprint, :string + field :user_agent, :string, default: "" + field :referrer, :string, default: "" + field :topic_position, :integer + field :hidden_from_users, :boolean, default: false + field :anonymous, :boolean, default: false + field :edited_at, :naive_datetime + field :deletion_reason, :string, default: "" + field :destroyed_content, :boolean, default: false + field :name_at_post_time, :string + + timestamps(inserted_at: :created_at) + end + + @doc false + def changeset(post, attrs) do + post + |> cast(attrs, []) + |> validate_required([]) + end +end diff --git a/lib/philomena/forums/subscription.ex b/lib/philomena/forums/subscription.ex new file mode 100644 index 00000000..d46646c6 --- /dev/null +++ b/lib/philomena/forums/subscription.ex @@ -0,0 +1,18 @@ +defmodule Philomena.Forums.Subscription do + use Ecto.Schema + import Ecto.Changeset + + @primary_key false + + schema "forum_subscriptions" do + belongs_to :forum, Philomena.Forums.Forum, primary_key: true + belongs_to :user, Philomena.Users.User, primary_key: true + end + + @doc false + def changeset(subscription, attrs) do + subscription + |> cast(attrs, []) + |> validate_required([]) + end +end diff --git a/lib/philomena/forums/topic.ex b/lib/philomena/forums/topic.ex new file mode 100644 index 00000000..e2da0d09 --- /dev/null +++ b/lib/philomena/forums/topic.ex @@ -0,0 +1,32 @@ +defmodule Philomena.Forums.Topic do + use Ecto.Schema + import Ecto.Changeset + + schema "topics" do + belongs_to :user, Philomena.Users.User + belongs_to :deleted_by, Philomena.Users.User + belongs_to :locked_by, Philomena.Users.User + belongs_to :last_post, Philomena.Forums.Post + + field :title, :string + field :post_count, :integer, default: 0 + field :view_count, :integer, default: 0 + field :sticky, :boolean, default: false + field :last_replied_to_at, :naive_datetime + field :locked_at, :naive_datetime + field :deletion_reason, :string + field :lock_reason, :string + field :slug, :string + field :anonymous, :boolean, default: false + field :hidden_from_users, :boolean, default: false + + timestamps(inserted_at: :created_at) + end + + @doc false + def changeset(topic, attrs) do + topic + |> cast(attrs, []) + |> validate_required([]) + end +end diff --git a/test/philomena/forums_test.exs b/test/philomena/forums_test.exs new file mode 100644 index 00000000..ab0fdf79 --- /dev/null +++ b/test/philomena/forums_test.exs @@ -0,0 +1,233 @@ +defmodule Philomena.ForumsTest do + use Philomena.DataCase + + alias Philomena.Forums + + describe "forums" do + alias Philomena.Forums.Forum + + @valid_attrs %{} + @update_attrs %{} + @invalid_attrs %{} + + def forum_fixture(attrs \\ %{}) do + {:ok, forum} = + attrs + |> Enum.into(@valid_attrs) + |> Forums.create_forum() + + forum + end + + test "list_forums/0 returns all forums" do + forum = forum_fixture() + assert Forums.list_forums() == [forum] + end + + test "get_forum!/1 returns the forum with given id" do + forum = forum_fixture() + assert Forums.get_forum!(forum.id) == forum + end + + test "create_forum/1 with valid data creates a forum" do + assert {:ok, %Forum{} = forum} = Forums.create_forum(@valid_attrs) + end + + test "create_forum/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Forums.create_forum(@invalid_attrs) + end + + test "update_forum/2 with valid data updates the forum" do + forum = forum_fixture() + assert {:ok, %Forum{} = forum} = Forums.update_forum(forum, @update_attrs) + end + + test "update_forum/2 with invalid data returns error changeset" do + forum = forum_fixture() + assert {:error, %Ecto.Changeset{}} = Forums.update_forum(forum, @invalid_attrs) + assert forum == Forums.get_forum!(forum.id) + end + + test "delete_forum/1 deletes the forum" do + forum = forum_fixture() + assert {:ok, %Forum{}} = Forums.delete_forum(forum) + assert_raise Ecto.NoResultsError, fn -> Forums.get_forum!(forum.id) end + end + + test "change_forum/1 returns a forum changeset" do + forum = forum_fixture() + assert %Ecto.Changeset{} = Forums.change_forum(forum) + end + end + + describe "topics" do + alias Philomena.Forums.Topic + + @valid_attrs %{} + @update_attrs %{} + @invalid_attrs %{} + + def topic_fixture(attrs \\ %{}) do + {:ok, topic} = + attrs + |> Enum.into(@valid_attrs) + |> Forums.create_topic() + + topic + end + + test "list_topics/0 returns all topics" do + topic = topic_fixture() + assert Forums.list_topics() == [topic] + end + + test "get_topic!/1 returns the topic with given id" do + topic = topic_fixture() + assert Forums.get_topic!(topic.id) == topic + end + + test "create_topic/1 with valid data creates a topic" do + assert {:ok, %Topic{} = topic} = Forums.create_topic(@valid_attrs) + end + + test "create_topic/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Forums.create_topic(@invalid_attrs) + end + + test "update_topic/2 with valid data updates the topic" do + topic = topic_fixture() + assert {:ok, %Topic{} = topic} = Forums.update_topic(topic, @update_attrs) + end + + test "update_topic/2 with invalid data returns error changeset" do + topic = topic_fixture() + assert {:error, %Ecto.Changeset{}} = Forums.update_topic(topic, @invalid_attrs) + assert topic == Forums.get_topic!(topic.id) + end + + test "delete_topic/1 deletes the topic" do + topic = topic_fixture() + assert {:ok, %Topic{}} = Forums.delete_topic(topic) + assert_raise Ecto.NoResultsError, fn -> Forums.get_topic!(topic.id) end + end + + test "change_topic/1 returns a topic changeset" do + topic = topic_fixture() + assert %Ecto.Changeset{} = Forums.change_topic(topic) + end + end + + describe "posts" do + alias Philomena.Forums.Post + + @valid_attrs %{} + @update_attrs %{} + @invalid_attrs %{} + + def post_fixture(attrs \\ %{}) do + {:ok, post} = + attrs + |> Enum.into(@valid_attrs) + |> Forums.create_post() + + post + end + + test "list_posts/0 returns all posts" do + post = post_fixture() + assert Forums.list_posts() == [post] + end + + test "get_post!/1 returns the post with given id" do + post = post_fixture() + assert Forums.get_post!(post.id) == post + end + + test "create_post/1 with valid data creates a post" do + assert {:ok, %Post{} = post} = Forums.create_post(@valid_attrs) + end + + test "create_post/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Forums.create_post(@invalid_attrs) + end + + test "update_post/2 with valid data updates the post" do + post = post_fixture() + assert {:ok, %Post{} = post} = Forums.update_post(post, @update_attrs) + end + + test "update_post/2 with invalid data returns error changeset" do + post = post_fixture() + assert {:error, %Ecto.Changeset{}} = Forums.update_post(post, @invalid_attrs) + assert post == Forums.get_post!(post.id) + end + + test "delete_post/1 deletes the post" do + post = post_fixture() + assert {:ok, %Post{}} = Forums.delete_post(post) + assert_raise Ecto.NoResultsError, fn -> Forums.get_post!(post.id) end + end + + test "change_post/1 returns a post changeset" do + post = post_fixture() + assert %Ecto.Changeset{} = Forums.change_post(post) + end + end + + describe "forum_subscriptions" do + alias Philomena.Forums.Subscription + + @valid_attrs %{} + @update_attrs %{} + @invalid_attrs %{} + + def subscription_fixture(attrs \\ %{}) do + {:ok, subscription} = + attrs + |> Enum.into(@valid_attrs) + |> Forums.create_subscription() + + subscription + end + + test "list_forum_subscriptions/0 returns all forum_subscriptions" do + subscription = subscription_fixture() + assert Forums.list_forum_subscriptions() == [subscription] + end + + test "get_subscription!/1 returns the subscription with given id" do + subscription = subscription_fixture() + assert Forums.get_subscription!(subscription.id) == subscription + end + + test "create_subscription/1 with valid data creates a subscription" do + assert {:ok, %Subscription{} = subscription} = Forums.create_subscription(@valid_attrs) + end + + test "create_subscription/1 with invalid data returns error changeset" do + assert {:error, %Ecto.Changeset{}} = Forums.create_subscription(@invalid_attrs) + end + + test "update_subscription/2 with valid data updates the subscription" do + subscription = subscription_fixture() + assert {:ok, %Subscription{} = subscription} = Forums.update_subscription(subscription, @update_attrs) + end + + test "update_subscription/2 with invalid data returns error changeset" do + subscription = subscription_fixture() + assert {:error, %Ecto.Changeset{}} = Forums.update_subscription(subscription, @invalid_attrs) + assert subscription == Forums.get_subscription!(subscription.id) + end + + test "delete_subscription/1 deletes the subscription" do + subscription = subscription_fixture() + assert {:ok, %Subscription{}} = Forums.delete_subscription(subscription) + assert_raise Ecto.NoResultsError, fn -> Forums.get_subscription!(subscription.id) end + end + + test "change_subscription/1 returns a subscription changeset" do + subscription = subscription_fixture() + assert %Ecto.Changeset{} = Forums.change_subscription(subscription) + end + end +end