From 37a933b6ef858ae0f3a9574d2a85611a2225f311 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 05:18:42 +0800 Subject: [PATCH 01/18] refactor(cms-macros): missing doc --- lib/groupher_server/cms/helper/macros.ex | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 1bec4b5f4..c6baeb282 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -13,7 +13,13 @@ defmodule GroupherServer.CMS.Helper.Macros do e.g: belongs_to(:post, Post, foreign_key: :post_id) - NOTE: should do migration to DB manually + NOTE: should do migration to DB manually: + 数据库层面的 migration 需要手动添加,参考: + + add(:post_id, references(:cms_posts, on_delete: :delete_all)) + add(:job_id, references(:cms_jobs, on_delete: :delete_all)) + add(:repo_id, references(:cms_jobs, on_delete: :delete_all)) + ... """ defmacro article_belongs_to() do @article_threads From ee00b19c8c8bfcdea4e29595e79f395136aa419d Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 12:44:57 +0800 Subject: [PATCH 02/18] refactor: wip --- lib/groupher_server/cms/abuse_report.ex | 2 +- lib/groupher_server/cms/article_collect.ex | 2 +- lib/groupher_server/cms/article_comment.ex | 2 +- .../cms/article_pinned_comment.ex | 2 +- lib/groupher_server/cms/article_upvote.ex | 2 +- .../cms/article_user_emotion.ex | 2 +- lib/groupher_server/cms/helper/macros.ex | 72 ++++++++++++++++++- lib/groupher_server/cms/pinned_article.ex | 2 +- lib/groupher_server/cms/post.ex | 51 +++++-------- 9 files changed, 93 insertions(+), 44 deletions(-) diff --git a/lib/groupher_server/cms/abuse_report.ex b/lib/groupher_server/cms/abuse_report.ex index 24a10cf60..3cfa93f7b 100644 --- a/lib/groupher_server/cms/abuse_report.ex +++ b/lib/groupher_server/cms/abuse_report.ex @@ -31,7 +31,7 @@ defmodule GroupherServer.CMS.AbuseReport do field(:deal_with, :string) - article_belongs_to() + article_belongs_to_fields() timestamps(type: :utc_datetime) end diff --git a/lib/groupher_server/cms/article_collect.ex b/lib/groupher_server/cms/article_collect.ex index 92b9f7c78..8b04079f6 100644 --- a/lib/groupher_server/cms/article_collect.ex +++ b/lib/groupher_server/cms/article_collect.ex @@ -23,7 +23,7 @@ defmodule GroupherServer.CMS.ArticleCollect do belongs_to(:user, User, foreign_key: :user_id) embeds_many(:collect_folders, CollectFolder, on_replace: :delete) - article_belongs_to() + article_belongs_to_fields() timestamps(type: :utc_datetime) end diff --git a/lib/groupher_server/cms/article_comment.ex b/lib/groupher_server/cms/article_comment.ex index 850e275f5..8069b0102 100644 --- a/lib/groupher_server/cms/article_comment.ex +++ b/lib/groupher_server/cms/article_comment.ex @@ -77,7 +77,7 @@ defmodule GroupherServer.CMS.ArticleComment do has_many(:upvotes, {"articles_comments_upvotes", ArticleCommentUpvote}) - article_belongs_to() + article_belongs_to_fields() timestamps(type: :utc_datetime) end diff --git a/lib/groupher_server/cms/article_pinned_comment.ex b/lib/groupher_server/cms/article_pinned_comment.ex index 14c64b810..7cbd585bf 100644 --- a/lib/groupher_server/cms/article_pinned_comment.ex +++ b/lib/groupher_server/cms/article_pinned_comment.ex @@ -24,7 +24,7 @@ defmodule GroupherServer.CMS.ArticlePinnedComment do schema "articles_pinned_comments" do belongs_to(:article_comment, ArticleComment, foreign_key: :article_comment_id) - article_belongs_to() + article_belongs_to_fields() timestamps(type: :utc_datetime) end diff --git a/lib/groupher_server/cms/article_upvote.ex b/lib/groupher_server/cms/article_upvote.ex index f8447da10..a09ea50bb 100644 --- a/lib/groupher_server/cms/article_upvote.ex +++ b/lib/groupher_server/cms/article_upvote.ex @@ -22,7 +22,7 @@ defmodule GroupherServer.CMS.ArticleUpvote do field(:thread, :string) belongs_to(:user, User, foreign_key: :user_id) - article_belongs_to() + article_belongs_to_fields() timestamps(type: :utc_datetime) end diff --git a/lib/groupher_server/cms/article_user_emotion.ex b/lib/groupher_server/cms/article_user_emotion.ex index 5198a26ac..f620c5091 100644 --- a/lib/groupher_server/cms/article_user_emotion.ex +++ b/lib/groupher_server/cms/article_user_emotion.ex @@ -41,7 +41,7 @@ defmodule GroupherServer.CMS.ArticleUserEmotion do belongs_to(:user, Accounts.User, foreign_key: :user_id) emotion_fields() - article_belongs_to() + article_belongs_to_fields() timestamps(type: :utc_datetime) end diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index c6baeb282..d009e58a2 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -13,7 +13,8 @@ defmodule GroupherServer.CMS.Helper.Macros do e.g: belongs_to(:post, Post, foreign_key: :post_id) - NOTE: should do migration to DB manually: + MIGRATION: + should do migration to DB manually: 数据库层面的 migration 需要手动添加,参考: add(:post_id, references(:cms_posts, on_delete: :delete_all)) @@ -21,7 +22,7 @@ defmodule GroupherServer.CMS.Helper.Macros do add(:repo_id, references(:cms_jobs, on_delete: :delete_all)) ... """ - defmacro article_belongs_to() do + defmacro article_belongs_to_fields() do @article_threads |> Enum.map(fn thread -> quote do @@ -33,4 +34,71 @@ defmodule GroupherServer.CMS.Helper.Macros do end end) end + + @doc """ + article_comments related fields + + MIGRATION: + should do migration to DB manually: + 数据库层面的 migration 需要手动添加,参考: + + TABLE: "article_comments" + ----- + add(:[article]_id, references(:cms_[article]s, on_delete: :delete_all)) + + TABLE: "cms_[article]s" + ----- + add(:article_comments_participators_count, :integer, default: 0) + add(:article_comments_count, :integer, default: 0) + add(:article_comments_participators, :map) + """ + defmacro article_comment_fields() do + quote do + field(:article_comments_participators_count, :integer, default: 0) + field(:article_comments_count, :integer, default: 0) + has_many(:article_comments, {"articles_comments", ArticleComment}) + # 评论参与者,只保留最近 5 个 + embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete) + end + end + + @doc """ + viewer has xxx fields for each article + + those fields is virtual, do not need DB migration + """ + defmacro viewer_has_fields() do + quote do + field(:viewer_has_viewed, :boolean, default: false, virtual: true) + field(:viewer_has_upvoted, :boolean, default: false, virtual: true) + field(:viewer_has_collected, :boolean, default: false, virtual: true) + field(:viewer_has_reported, :boolean, default: false, virtual: true) + end + end + + @doc """ + aritlce's upvote and collect feature + + MIGRATION: + should do migration to DB manually: + 数据库层面的 migration 需要手动添加,参考: + + TABLE: "cms_[article]s" + ----- + add(:upvotes_count, :integer, default: 0) + add(:collects_count, :integer, default: 0) + """ + defmacro upvote_and_collect_fields() do + quote do + has_many(:upvotes, {"article_upvotes", ArticleUpvote}) + field(:upvotes_count, :integer, default: 0) + + has_many(:collects, {"article_collects", ArticleCollect}) + field(:collects_count, :integer, default: 0) + end + end + + # TODO: + # reference_articles + # related_articles end diff --git a/lib/groupher_server/cms/pinned_article.ex b/lib/groupher_server/cms/pinned_article.ex index 43fea5d31..4cfcdbf66 100644 --- a/lib/groupher_server/cms/pinned_article.ex +++ b/lib/groupher_server/cms/pinned_article.ex @@ -21,7 +21,7 @@ defmodule GroupherServer.CMS.PinnedArticle do belongs_to(:community, Community, foreign_key: :community_id) field(:thread, :string) - article_belongs_to() + article_belongs_to_fields() timestamps(type: :utc_datetime) end diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index 42c0d045e..cab75a0d6 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -12,19 +12,21 @@ defmodule GroupherServer.CMS.Post do alias CMS.{ Embeds, Author, - ArticleComment, Community, - PostComment, - Tag, + ArticleComment, ArticleUpvote, - ArticleCollect + ArticleCollect, + PostComment, + Tag } alias Helper.HTML - @timestamps_opts [type: :utc_datetime_usec] @required_fields ~w(title body digest length)a - @optional_fields ~w(original_community_id link_addr copy_right link_addr link_icon article_comments_count article_comments_participators_count upvotes_count collects_count mark_delete)a + @article_comment_fields ~w(article_comments_count article_comments_participators_count)a + @upvote_and_collect_fields ~w(upvotes_count collects_count)a + @optional_fields ~w(original_community_id link_addr copy_right link_addr link_icon mark_delete)a ++ + @article_comment_fields ++ @upvote_and_collect_fields @type t :: %Post{} schema "cms_posts" do @@ -40,34 +42,14 @@ defmodule GroupherServer.CMS.Post do belongs_to(:author, Author) embeds_one(:meta, Embeds.ArticleMeta, on_replace: :update) - # NOTE: this one is tricky, pin is dynamic changed when return by func: add_pin_contents_ifneed - # field(:pin, :boolean, default_value: false, virtual: true) field(:is_pinned, :boolean, default: false, virtual: true) field(:mark_delete, :boolean, default: false) - field(:viewer_has_viewed, :boolean, default: false, virtual: true) - field(:viewer_has_upvoted, :boolean, default: false, virtual: true) - field(:viewer_has_collected, :boolean, default: false, virtual: true) - field(:viewer_has_reported, :boolean, default: false, virtual: true) - - has_many(:upvotes, {"article_upvotes", ArticleUpvote}) - field(:upvotes_count, :integer, default: 0) - - has_many(:collects, {"article_collects", ArticleCollect}) - field(:collects_count, :integer, default: 0) - - # TODO - # 相关文章 - # has_may(:related_post, ...) + # TODO: remove after legacy data migrated has_many(:comments, {"posts_comments", PostComment}) - has_many(:article_comments, {"articles_comments", ArticleComment}) - field(:article_comments_count, :integer, default: 0) - field(:article_comments_participators_count, :integer, default: 0) - # 评论参与者,只保留最近 5 个 - embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete) - embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) + belongs_to(:original_community, Community) # The keys are inflected from the schema names! # see https://hexdocs.pm/ecto/Ecto.Schema.html @@ -81,8 +63,6 @@ defmodule GroupherServer.CMS.Post do on_replace: :delete ) - belongs_to(:original_community, Community) - many_to_many( :communities, Community, @@ -90,6 +70,10 @@ defmodule GroupherServer.CMS.Post do on_replace: :delete ) + viewer_has_fields() + upvote_and_collect_fields() + article_comment_fields() + # timestamps(type: :utc_datetime) # for paged test to diff # timestamps(type: :utc_datetime_usec) @@ -112,15 +96,12 @@ defmodule GroupherServer.CMS.Post do |> generl_changeset end - defp generl_changeset(content) do - content + defp generl_changeset(changeset) do + changeset |> validate_length(:title, min: 3, max: 50) |> cast_embed(:emotions, with: &Embeds.ArticleEmotion.changeset/2) |> validate_length(:body, min: 3, max: 10_000) |> validate_length(:link_addr, min: 5, max: 400) |> HTML.safe_string(:body) - - # |> foreign_key_constraint(:posts_tags, name: :posts_tags_tag_id_fkey) - # |> foreign_key_constraint(name: :posts_tags_tag_id_fkey) end end From 636bdae75352c95711fe40a89122c97d6fd50636 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 13:22:04 +0800 Subject: [PATCH 03/18] refactor: wip --- lib/groupher_server/application.ex | 2 -- .../cms/embeds/article_meta.ex | 2 -- lib/groupher_server/cms/helper/macros.ex | 9 ++++-- lib/groupher_server/cms/post.ex | 28 +++++++++++-------- lib/helper/scheduler.ex | 3 +- .../accounts/collect_folder_test.exs | 1 - .../cms/articles/job_pin_test.exs | 1 - .../cms/articles/post_pin_test.exs | 1 - .../cms/articles/repo_pin_test.exs | 1 - .../cms/comments/post_comment_test.exs | 1 - .../cms/paged_articles/paged_posts_test.exs | 1 - 11 files changed, 23 insertions(+), 27 deletions(-) diff --git a/lib/groupher_server/application.ex b/lib/groupher_server/application.ex index b7fccf212..ca13da300 100644 --- a/lib/groupher_server/application.ex +++ b/lib/groupher_server/application.ex @@ -7,8 +7,6 @@ defmodule GroupherServer.Application do @spec start(any, any) :: {:error, any} | {:ok, pid} def start(_type, _args) do import Supervisor.Spec - import Cachex.Spec - alias Helper.Cache # Define workers and child supervisors to be supervised diff --git a/lib/groupher_server/cms/embeds/article_meta.ex b/lib/groupher_server/cms/embeds/article_meta.ex index 1cd79d77c..bddd20745 100644 --- a/lib/groupher_server/cms/embeds/article_meta.ex +++ b/lib/groupher_server/cms/embeds/article_meta.ex @@ -6,8 +6,6 @@ defmodule GroupherServer.CMS.Embeds.ArticleMeta do use Accessible import Ecto.Changeset - alias GroupherServer.CMS - @optional_fields ~w(is_edited is_comment_locked upvoted_user_ids collected_user_ids viewed_user_ids reported_user_ids reported_count)a @default_meta %{ diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index d009e58a2..8343c099f 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -3,9 +3,12 @@ defmodule GroupherServer.CMS.Helper.Macros do macros for define article related fields in CMS models """ - alias GroupherServer.CMS + alias GroupherServer.{CMS, Accounts} - @article_threads CMS.Community.article_threads() + alias Accounts.User + alias CMS.{Community, ArticleComment, ArticleUpvote, ArticleCollect} + + @article_threads Community.article_threads() @doc """ generate belongs to fields for given thread @@ -58,7 +61,7 @@ defmodule GroupherServer.CMS.Helper.Macros do field(:article_comments_count, :integer, default: 0) has_many(:article_comments, {"articles_comments", ArticleComment}) # 评论参与者,只保留最近 5 个 - embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete) + embeds_many(:article_comments_participators, User, on_replace: :delete) end end diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index cab75a0d6..1313f293c 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -6,22 +6,15 @@ defmodule GroupherServer.CMS.Post do use Accessible import Ecto.Changeset + import GroupherServer.CMS.Helper.Macros - alias GroupherServer.{CMS, Accounts} - - alias CMS.{ - Embeds, - Author, - Community, - ArticleComment, - ArticleUpvote, - ArticleCollect, - PostComment, - Tag - } + alias GroupherServer.CMS + alias CMS.{Embeds, Author, Community, PostComment, Tag} alias Helper.HTML + @timestamps_opts [type: :utc_datetime_usec] + @required_fields ~w(title body digest length)a @article_comment_fields ~w(article_comments_count article_comments_participators_count)a @upvote_and_collect_fields ~w(upvotes_count collects_count)a @@ -39,6 +32,17 @@ defmodule GroupherServer.CMS.Post do field(:length, :integer) field(:views, :integer, default: 0) + # general_article_fields + # - author_field + # - article_comment_fields + # - aritle_meta_field + # - pin + # - mark_delete + # - emotion + # - upvote_and_collect_fields + # - viewer_has_fields + # - timestamp + belongs_to(:author, Author) embeds_one(:meta, Embeds.ArticleMeta, on_replace: :update) diff --git a/lib/helper/scheduler.ex b/lib/helper/scheduler.ex index fd95b4747..4783155e6 100644 --- a/lib/helper/scheduler.ex +++ b/lib/helper/scheduler.ex @@ -3,8 +3,7 @@ defmodule Helper.Scheduler do cron-like job scheduler """ use Quantum.Scheduler, otp_app: :groupher_server - - alias Helper.Cache + # alias Helper.Cache @doc """ clear all the cache in Cachex diff --git a/test/groupher_server/accounts/collect_folder_test.exs b/test/groupher_server/accounts/collect_folder_test.exs index 93774b6d6..398ab0c13 100644 --- a/test/groupher_server/accounts/collect_folder_test.exs +++ b/test/groupher_server/accounts/collect_folder_test.exs @@ -215,7 +215,6 @@ defmodule GroupherServer.Test.Accounts.CollectFolder do assert result.total_count == 0 end - @tag :wip2 test "add post to exsit colect-folder should update meta", ~m(user post post2 job)a do {:ok, folder} = Accounts.create_collect_folder(%{title: "test folder"}, user) diff --git a/test/groupher_server/cms/articles/job_pin_test.exs b/test/groupher_server/cms/articles/job_pin_test.exs index 3e1654979..9faa1f69a 100644 --- a/test/groupher_server/cms/articles/job_pin_test.exs +++ b/test/groupher_server/cms/articles/job_pin_test.exs @@ -39,7 +39,6 @@ defmodule GroupherServer.Test.CMS.Artilces.JobPin do assert reason |> Keyword.get(:code) == ecode(:too_much_pinned_article) end - @tag :wip2 test "can not pin a non-exsit job", ~m(community)a do assert {:error, _} = CMS.pin_article(:job, 8848, community.id) end diff --git a/test/groupher_server/cms/articles/post_pin_test.exs b/test/groupher_server/cms/articles/post_pin_test.exs index 26775596e..5b016c4e7 100644 --- a/test/groupher_server/cms/articles/post_pin_test.exs +++ b/test/groupher_server/cms/articles/post_pin_test.exs @@ -39,7 +39,6 @@ defmodule GroupherServer.Test.CMS.Artilces.PostPin do assert reason |> Keyword.get(:code) == ecode(:too_much_pinned_article) end - @tag :wip2 test "can not pin a non-exsit post", ~m(community)a do assert {:error, _} = CMS.pin_article(:post, 8848, community.id) end diff --git a/test/groupher_server/cms/articles/repo_pin_test.exs b/test/groupher_server/cms/articles/repo_pin_test.exs index 7577847dd..b253a185d 100644 --- a/test/groupher_server/cms/articles/repo_pin_test.exs +++ b/test/groupher_server/cms/articles/repo_pin_test.exs @@ -39,7 +39,6 @@ defmodule GroupherServer.Test.CMS.Artilces.RepoPin do assert reason |> Keyword.get(:code) == ecode(:too_much_pinned_article) end - @tag :wip2 test "can not pin a non-exsit repo", ~m(community)a do assert {:error, _} = CMS.pin_article(:repo, 8848, community.id) end diff --git a/test/groupher_server/cms/comments/post_comment_test.exs b/test/groupher_server/cms/comments/post_comment_test.exs index 1333ee4ca..69210d99a 100644 --- a/test/groupher_server/cms/comments/post_comment_test.exs +++ b/test/groupher_server/cms/comments/post_comment_test.exs @@ -350,7 +350,6 @@ defmodule GroupherServer.Test.CMS.Comments.PostComment do assert results.total_count == total_count + 1 end - @tag :wip2 test "paged article comments folded flag should be false", ~m(user post)a do total_count = 30 page_number = 1 diff --git a/test/groupher_server_web/query/cms/paged_articles/paged_posts_test.exs b/test/groupher_server_web/query/cms/paged_articles/paged_posts_test.exs index 6d88fbfed..f8e3c0ea9 100644 --- a/test/groupher_server_web/query/cms/paged_articles/paged_posts_test.exs +++ b/test/groupher_server_web/query/cms/paged_articles/paged_posts_test.exs @@ -124,7 +124,6 @@ defmodule GroupherServer.Test.Query.PagedArticles.PagedPosts do variables = %{filter: %{}} results = guest_conn |> query_result(@query, variables, "pagedPosts") inserted_timestamps = results["entries"] |> Enum.map(& &1["inserted_at"]) - # IO.inspect(inserted_timestamps, label: "inserted_timestamps") {:ok, first_inserted_time, 0} = inserted_timestamps |> List.first() |> DateTime.from_iso8601() From e17911a6bf8c1102bf40cfb4b71347a6fd68dcbe Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 13:49:23 +0800 Subject: [PATCH 04/18] refactor: wip, macro in macro --- lib/groupher_server/cms/helper/macros.ex | 7 +++++++ lib/groupher_server/cms/post.ex | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 8343c099f..948d545f6 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -101,6 +101,13 @@ defmodule GroupherServer.CMS.Helper.Macros do end end + defmacro general_article_fields do + quote do + upvote_and_collect_fields() + viewer_has_fields() + end + end + # TODO: # reference_articles # related_articles diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index 1313f293c..4735a3312 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -74,8 +74,9 @@ defmodule GroupherServer.CMS.Post do on_replace: :delete ) - viewer_has_fields() - upvote_and_collect_fields() + general_article_fields() + # viewer_has_fields() + # upvote_and_collect_fields() article_comment_fields() # timestamps(type: :utc_datetime) From 6cc5d42e090cd5d63fdb740d6bd81c4ad7909e0b Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 14:01:05 +0800 Subject: [PATCH 05/18] refactor: general_article_fields wip --- lib/groupher_server/cms/helper/macros.ex | 10 ++++++++++ lib/groupher_server/cms/post.ex | 19 ++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 948d545f6..f7d45a4a2 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -103,8 +103,18 @@ defmodule GroupherServer.CMS.Helper.Macros do defmacro general_article_fields do quote do + field(:views, :integer, default: 0) + field(:is_pinned, :boolean, default: false, virtual: true) + field(:mark_delete, :boolean, default: false) + + embeds_one(:meta, CMS.Embeds.ArticleMeta, on_replace: :update) + belongs_to(:original_community, CMS.Community) + embeds_one(:emotions, CMS.Embeds.ArticleEmotion, on_replace: :update) + upvote_and_collect_fields() viewer_has_fields() + article_comment_fields() + timestamps() end end diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index 4735a3312..10cd5a341 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -30,7 +30,7 @@ defmodule GroupherServer.CMS.Post do field(:link_icon, :string) field(:copy_right, :string) field(:length, :integer) - field(:views, :integer, default: 0) + # field(:views, :integer, default: 0) # general_article_fields # - author_field @@ -43,17 +43,17 @@ defmodule GroupherServer.CMS.Post do # - viewer_has_fields # - timestamp - belongs_to(:author, Author) - embeds_one(:meta, Embeds.ArticleMeta, on_replace: :update) + # belongs_to(:author, Author) + # embeds_one(:meta, Embeds.ArticleMeta, on_replace: :update) - field(:is_pinned, :boolean, default: false, virtual: true) - field(:mark_delete, :boolean, default: false) + # field(:is_pinned, :boolean, default: false, virtual: true) + # field(:mark_delete, :boolean, default: false) # TODO: remove after legacy data migrated has_many(:comments, {"posts_comments", PostComment}) - embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) - belongs_to(:original_community, Community) + # embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) + # belongs_to(:original_community, Community) # The keys are inflected from the schema names! # see https://hexdocs.pm/ecto/Ecto.Schema.html @@ -75,14 +75,11 @@ defmodule GroupherServer.CMS.Post do ) general_article_fields() - # viewer_has_fields() - # upvote_and_collect_fields() - article_comment_fields() # timestamps(type: :utc_datetime) # for paged test to diff # timestamps(type: :utc_datetime_usec) - timestamps() + # timestamps() end @doc false From 243c4d91df21e5addf5581e5a70079222ea50e5d Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 14:12:12 +0800 Subject: [PATCH 06/18] refactor: general_article_fields wip --- lib/groupher_server/cms/helper/macros.ex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index f7d45a4a2..9fc26357f 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -6,7 +6,7 @@ defmodule GroupherServer.CMS.Helper.Macros do alias GroupherServer.{CMS, Accounts} alias Accounts.User - alias CMS.{Community, ArticleComment, ArticleUpvote, ArticleCollect} + alias CMS.{Author, Community, ArticleComment, ArticleUpvote, ArticleCollect} @article_threads Community.article_threads() @@ -103,6 +103,8 @@ defmodule GroupherServer.CMS.Helper.Macros do defmacro general_article_fields do quote do + belongs_to(:author, Author) + field(:views, :integer, default: 0) field(:is_pinned, :boolean, default: false, virtual: true) field(:mark_delete, :boolean, default: false) From 588c6a5c8f7865626196a6e0130bb16c63abd6d3 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 14:33:32 +0800 Subject: [PATCH 07/18] refactor: general_article_fields wip --- lib/groupher_server/cms/helper/macros.ex | 21 +++++++++++++---- lib/groupher_server/cms/post.ex | 30 +++--------------------- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 9fc26357f..ed3d51435 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -101,6 +101,19 @@ defmodule GroupherServer.CMS.Helper.Macros do end end + @doc """ + common casting fields for general_article_fields + """ + def general_article_fields(:cast) do + [ + :article_comments_count, + :article_comments_participators_count, + :upvotes_count, + :collects_count, + :mark_delete + ] + end + defmacro general_article_fields do quote do belongs_to(:author, Author) @@ -116,11 +129,11 @@ defmodule GroupherServer.CMS.Helper.Macros do upvote_and_collect_fields() viewer_has_fields() article_comment_fields() + + # TODO: + # reference_articles + # related_articles timestamps() end end - - # TODO: - # reference_articles - # related_articles end diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index 10cd5a341..ff472772d 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -16,10 +16,9 @@ defmodule GroupherServer.CMS.Post do @timestamps_opts [type: :utc_datetime_usec] @required_fields ~w(title body digest length)a - @article_comment_fields ~w(article_comments_count article_comments_participators_count)a - @upvote_and_collect_fields ~w(upvotes_count collects_count)a - @optional_fields ~w(original_community_id link_addr copy_right link_addr link_icon mark_delete)a ++ - @article_comment_fields ++ @upvote_and_collect_fields + @article_cast_fields general_article_fields(:cast) + @optional_fields ~w(original_community_id link_addr copy_right link_addr link_icon)a ++ + @article_cast_fields @type t :: %Post{} schema "cms_posts" do @@ -30,24 +29,6 @@ defmodule GroupherServer.CMS.Post do field(:link_icon, :string) field(:copy_right, :string) field(:length, :integer) - # field(:views, :integer, default: 0) - - # general_article_fields - # - author_field - # - article_comment_fields - # - aritle_meta_field - # - pin - # - mark_delete - # - emotion - # - upvote_and_collect_fields - # - viewer_has_fields - # - timestamp - - # belongs_to(:author, Author) - # embeds_one(:meta, Embeds.ArticleMeta, on_replace: :update) - - # field(:is_pinned, :boolean, default: false, virtual: true) - # field(:mark_delete, :boolean, default: false) # TODO: remove after legacy data migrated has_many(:comments, {"posts_comments", PostComment}) @@ -75,11 +56,6 @@ defmodule GroupherServer.CMS.Post do ) general_article_fields() - - # timestamps(type: :utc_datetime) - # for paged test to diff - # timestamps(type: :utc_datetime_usec) - # timestamps() end @doc false From 9a799f871dca0a9f0544d9e6132331561a7f7b9e Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 14:48:31 +0800 Subject: [PATCH 08/18] refactor: add doc for general_article_fields --- lib/groupher_server/cms/helper/macros.ex | 53 +++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index ed3d51435..55a2c9b77 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -90,6 +90,10 @@ defmodule GroupherServer.CMS.Helper.Macros do ----- add(:upvotes_count, :integer, default: 0) add(:collects_count, :integer, default: 0) + + ## TABLE: "article_upvotes" and TABLE: "article_collects" + ----- + add(:[article]_id, references(:cms_[article]s, on_delete: :delete_all)) """ defmacro upvote_and_collect_fields() do quote do @@ -114,6 +118,52 @@ defmodule GroupherServer.CMS.Helper.Macros do ] end + @doc """ + + MIGRATION: + + TABLE: "cms_[article]s" + ----- + # for :author + add(:author_id, references(:cms_authors, on_delete: :delete_all), null: false) + create(index(:cms_[article]s, [:author_id])) + + # for :views + add(:views, :integer, default: 0) + + # for :mark_delete + add(:mark_delete, :boolean, default: false) + + # for :meta + add(:meta, :map) + + # for :emotion + add(:emotions, :map) + + # for :original_community + add(:original_community_id, references(:communities, on_delete: :delete_all)) + + # for :upvote and :collect + add(:upvotes_count, :integer, default: 0) + add(:collects_count, :integer, default: 0) + + # for :article_comment + add(:article_comments_participators_count, :integer, default: 0) + add(:article_comments_count, :integer, default: 0) + add(:article_comments_participators, :map) + + # for table contains macro "article_belongs_to_fields": + # TABLE: "abuse_reports" + # TABLE: "article_collects" + # TABLE: "article_upvotes" + # TABLE: "articles_comments" + # TABLE: "articles_pinned_comments" + # TABLE: "articles_users_emotions" + # TABLE: "pinned_articles" + ----- + add(:[article]_id, references(:cms_[article]s, on_delete: :delete_all)) + + """ defmacro general_article_fields do quote do belongs_to(:author, Author) @@ -123,9 +173,10 @@ defmodule GroupherServer.CMS.Helper.Macros do field(:mark_delete, :boolean, default: false) embeds_one(:meta, CMS.Embeds.ArticleMeta, on_replace: :update) - belongs_to(:original_community, CMS.Community) embeds_one(:emotions, CMS.Embeds.ArticleEmotion, on_replace: :update) + belongs_to(:original_community, CMS.Community) + upvote_and_collect_fields() viewer_has_fields() article_comment_fields() From 9428574de42fa65fb0739e80a9392f8ff72a2b7f Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 14:52:47 +0800 Subject: [PATCH 09/18] refactor: fmt --- lib/groupher_server/cms/helper/macros.ex | 1 + lib/groupher_server/cms/post.ex | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 55a2c9b77..0a0ebed2e 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -110,6 +110,7 @@ defmodule GroupherServer.CMS.Helper.Macros do """ def general_article_fields(:cast) do [ + :original_community_id, :article_comments_count, :article_comments_participators_count, :upvotes_count, diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index ff472772d..10d802673 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -9,7 +9,7 @@ defmodule GroupherServer.CMS.Post do import GroupherServer.CMS.Helper.Macros alias GroupherServer.CMS - alias CMS.{Embeds, Author, Community, PostComment, Tag} + alias CMS.{Embeds, Community, PostComment, Tag} alias Helper.HTML @@ -17,8 +17,7 @@ defmodule GroupherServer.CMS.Post do @required_fields ~w(title body digest length)a @article_cast_fields general_article_fields(:cast) - @optional_fields ~w(original_community_id link_addr copy_right link_addr link_icon)a ++ - @article_cast_fields + @optional_fields ~w(link_addr copy_right link_addr link_icon)a ++ @article_cast_fields @type t :: %Post{} schema "cms_posts" do @@ -33,9 +32,6 @@ defmodule GroupherServer.CMS.Post do # TODO: remove after legacy data migrated has_many(:comments, {"posts_comments", PostComment}) - # embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) - # belongs_to(:original_community, Community) - # The keys are inflected from the schema names! # see https://hexdocs.pm/ecto/Ecto.Schema.html many_to_many( From 553cf121f61454855dd2597799537e9841f616a1 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 14:55:12 +0800 Subject: [PATCH 10/18] refactor: job --- lib/groupher_server/cms/job.ex | 35 +++++----------------------------- 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/lib/groupher_server/cms/job.ex b/lib/groupher_server/cms/job.ex index 12af61469..3f1ace3f0 100644 --- a/lib/groupher_server/cms/job.ex +++ b/lib/groupher_server/cms/job.ex @@ -6,6 +6,7 @@ defmodule GroupherServer.CMS.Job do use Accessible import Ecto.Changeset + import GroupherServer.CMS.Helper.Macros alias GroupherServer.{CMS, Accounts} alias CMS.{Author, Embeds, ArticleComment, Community, Tag, ArticleUpvote, ArticleCollect} @@ -13,7 +14,9 @@ defmodule GroupherServer.CMS.Job do @timestamps_opts [type: :utc_datetime_usec] @required_fields ~w(title company company_logo body digest length)a - @optional_fields ~w(original_community_id desc company_link link_addr copy_right salary exp education field finance scale article_comments_count article_comments_participators_count upvotes_count collects_count mark_delete)a + @article_cast_fields general_article_fields(:cast) + @optional_fields ~w(original_community_id desc company_link link_addr copy_right salary exp education field finance scale)a ++ + @article_cast_fields @type t :: %Job{} schema "cms_jobs" do @@ -23,10 +26,6 @@ defmodule GroupherServer.CMS.Job do field(:company_link, :string) field(:desc, :string) field(:body, :string) - belongs_to(:author, Author) - field(:views, :integer, default: 0) - - embeds_one(:meta, Embeds.ArticleMeta, on_replace: :update) field(:link_addr, :string) field(:copy_right, :string) @@ -41,29 +40,6 @@ defmodule GroupherServer.CMS.Job do field(:digest, :string) field(:length, :integer) - # NOTE: this one is tricky, pin is dynamic changed when return by func: add_pin_contents_ifneed - field(:is_pinned, :boolean, default: false, virtual: true) - field(:mark_delete, :boolean, default: false) - - has_many(:upvotes, {"article_upvotes", ArticleUpvote}) - field(:upvotes_count, :integer, default: 0) - - field(:viewer_has_viewed, :boolean, default: false, virtual: true) - field(:viewer_has_upvoted, :boolean, default: false, virtual: true) - field(:viewer_has_collected, :boolean, default: false, virtual: true) - field(:viewer_has_reported, :boolean, default: false, virtual: true) - - has_many(:collects, {"article_collects", ArticleCollect}) - field(:collects_count, :integer, default: 0) - - has_many(:article_comments, {"articles_comments", ArticleComment}) - field(:article_comments_count, :integer, default: 0) - field(:article_comments_participators_count, :integer, default: 0) - # 评论参与者,只保留最近 5 个 - embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete) - - embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) - many_to_many( :tags, Tag, @@ -83,8 +59,7 @@ defmodule GroupherServer.CMS.Job do on_replace: :delete ) - # timestamps(type: :utc_datetime) - timestamps() + general_article_fields() end @doc false From 005664938d60085f0d27335c73ec99ca664413b6 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 15:01:34 +0800 Subject: [PATCH 11/18] refactor: job fix --- lib/groupher_server/cms/job.ex | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/groupher_server/cms/job.ex b/lib/groupher_server/cms/job.ex index 3f1ace3f0..fcb53dc8a 100644 --- a/lib/groupher_server/cms/job.ex +++ b/lib/groupher_server/cms/job.ex @@ -15,8 +15,8 @@ defmodule GroupherServer.CMS.Job do @timestamps_opts [type: :utc_datetime_usec] @required_fields ~w(title company company_logo body digest length)a @article_cast_fields general_article_fields(:cast) - @optional_fields ~w(original_community_id desc company_link link_addr copy_right salary exp education field finance scale)a ++ - @article_cast_fields + @optional_fields @article_cast_fields ++ + ~w(desc company_link link_addr copy_right salary exp education field finance scale)a @type t :: %Job{} schema "cms_jobs" do @@ -50,8 +50,6 @@ defmodule GroupherServer.CMS.Job do on_replace: :delete ) - belongs_to(:original_community, Community) - many_to_many( :communities, Community, From a075f3f6aa178934adc1751023b69445dc424262 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 15:08:24 +0800 Subject: [PATCH 12/18] refactor: repo --- lib/groupher_server/cms/repo.ex | 49 ++----------------- .../schema/cms/mutations/repo.ex | 1 + 2 files changed, 6 insertions(+), 44 deletions(-) diff --git a/lib/groupher_server/cms/repo.ex b/lib/groupher_server/cms/repo.ex index b3be371b0..fea28dfe4 100644 --- a/lib/groupher_server/cms/repo.ex +++ b/lib/groupher_server/cms/repo.ex @@ -6,26 +6,18 @@ defmodule GroupherServer.CMS.Repo do use Accessible import Ecto.Changeset + import GroupherServer.CMS.Helper.Macros alias GroupherServer.{CMS, Accounts} - alias CMS.{ - Author, - Embeds, - ArticleComment, - Community, - RepoContributor, - RepoLang, - Tag, - ArticleUpvote, - ArticleCollect - } + alias CMS.{Embeds, Community, RepoContributor, RepoLang, Tag} alias Helper.HTML @timestamps_opts [type: :utc_datetime_usec] @required_fields ~w(title owner_name owner_url repo_url desc readme star_count issues_count prs_count fork_count watch_count)a - @optional_fields ~w(original_community_id last_sync homepage_url release_tag license upvotes_count collects_count mark_delete article_comments_count article_comments_participators_count)a + @article_cast_fields general_article_fields(:cast) + @optional_fields @article_cast_fields ++ ~w(last_sync homepage_url release_tag license)a @type t :: %Repo{} schema "cms_repos" do @@ -47,39 +39,9 @@ defmodule GroupherServer.CMS.Repo do field(:license, :string) field(:release_tag, :string) embeds_one(:primary_language, RepoLang, on_replace: :delete) - embeds_many(:contributors, RepoContributor, on_replace: :delete) - - field(:views, :integer, default: 0) - - embeds_one(:meta, Embeds.ArticleMeta, on_replace: :update) - embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) - - belongs_to(:author, Author) - - # NOTE: this one is tricky, pin is dynamic changed when return by func: add_pin_contents_ifneed - field(:is_pinned, :boolean, default: false, virtual: true) - field(:mark_delete, :boolean, default: false) - - field(:viewer_has_viewed, :boolean, default: false, virtual: true) - field(:viewer_has_upvoted, :boolean, default: false, virtual: true) - field(:viewer_has_collected, :boolean, default: false, virtual: true) - field(:viewer_has_reported, :boolean, default: false, virtual: true) - - has_many(:upvotes, {"article_upvotes", ArticleUpvote}) - field(:upvotes_count, :integer, default: 0) - - has_many(:collects, {"article_collects", ArticleCollect}) - field(:collects_count, :integer, default: 0) - field(:last_sync, :utc_datetime) - has_many(:article_comments, {"articles_comments", ArticleComment}) - field(:article_comments_count, :integer, default: 0) - field(:article_comments_participators_count, :integer, default: 0) - # 评论参与者,只保留最近 5 个 - embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete) - many_to_many( :tags, Tag, @@ -98,8 +60,7 @@ defmodule GroupherServer.CMS.Repo do on_replace: :delete ) - # timestamps(type: :utc_datetime) - timestamps() + general_article_fields() end @doc false diff --git a/lib/groupher_server_web/schema/cms/mutations/repo.ex b/lib/groupher_server_web/schema/cms/mutations/repo.ex index e316893cc..de09b4f0b 100644 --- a/lib/groupher_server_web/schema/cms/mutations/repo.ex +++ b/lib/groupher_server_web/schema/cms/mutations/repo.ex @@ -74,6 +74,7 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Repo do article_pin_mutation(:repo) article_mark_delete_mutation(:repo) article_delete_mutation(:repo) + article_emotion_mutation(:repo) article_report_mutation(:repo) ############# end From 9bc2629966555d8687135f439174206fa861b4d9 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 15:15:24 +0800 Subject: [PATCH 13/18] refactor: repo fix && missing tests --- lib/groupher_server/cms/repo.ex | 2 - .../comments/repo_comment_emotions_test.exs | 199 ++++++ .../comments/repo_comment_replies_test.exs | 213 +++++++ .../cms/comments/repo_comment_test.exs | 566 ++++++++++++++++++ .../cms/emotions/repo_emotions_test.exs | 177 ++++++ 5 files changed, 1155 insertions(+), 2 deletions(-) create mode 100644 test/groupher_server/cms/comments/repo_comment_emotions_test.exs create mode 100644 test/groupher_server/cms/comments/repo_comment_replies_test.exs create mode 100644 test/groupher_server/cms/comments/repo_comment_test.exs create mode 100644 test/groupher_server/cms/emotions/repo_emotions_test.exs diff --git a/lib/groupher_server/cms/repo.ex b/lib/groupher_server/cms/repo.ex index fea28dfe4..141f40cc3 100644 --- a/lib/groupher_server/cms/repo.ex +++ b/lib/groupher_server/cms/repo.ex @@ -51,8 +51,6 @@ defmodule GroupherServer.CMS.Repo do on_replace: :delete ) - belongs_to(:original_community, Community) - many_to_many( :communities, Community, diff --git a/test/groupher_server/cms/comments/repo_comment_emotions_test.exs b/test/groupher_server/cms/comments/repo_comment_emotions_test.exs new file mode 100644 index 000000000..e3d8afbad --- /dev/null +++ b/test/groupher_server/cms/comments/repo_comment_emotions_test.exs @@ -0,0 +1,199 @@ +defmodule GroupherServer.Test.CMS.Comments.RepoCommentEmotions do + @moduledoc false + + use GroupherServer.TestTools + + alias Helper.ORM + alias GroupherServer.CMS + + alias CMS.{ArticleComment, Embeds, ArticleCommentUserEmotion} + + @default_emotions Embeds.ArticleCommentEmotion.default_emotions() + + setup do + {:ok, user} = db_insert(:user) + {:ok, user2} = db_insert(:user) + {:ok, user3} = db_insert(:user) + + {:ok, repo} = db_insert(:repo) + + {:ok, ~m(user user2 user3 repo)a} + end + + describe "[emotion in paged article comment]" do + test "login user should got viewer has emotioned status", ~m(repo user)a do + total_count = 0 + page_number = 10 + page_size = 20 + + all_comment = + Enum.reduce(0..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:repo, repo.id, "commment", user) + acc ++ [comment] + end) + + first_comment = List.first(all_comment) + + {:ok, _} = CMS.emotion_to_comment(first_comment.id, :downvote, user) + {:ok, _} = CMS.emotion_to_comment(first_comment.id, :beer, user) + {:ok, _} = CMS.emotion_to_comment(first_comment.id, :popcorn, user) + + {:ok, paged_comments} = + CMS.paged_article_comments( + :repo, + repo.id, + %{page: page_number, size: page_size}, + :replies, + user + ) + + target = Enum.find(paged_comments.entries, &(&1.id == first_comment.id)) + + assert target.emotions.downvote_count == 1 + assert user_exist_in?(user, target.emotions.latest_downvote_users) + assert target.emotions.viewer_has_downvoteed + + assert target.emotions.beer_count == 1 + assert user_exist_in?(user, target.emotions.latest_beer_users) + assert target.emotions.viewer_has_beered + + assert target.emotions.popcorn_count == 1 + assert user_exist_in?(user, target.emotions.latest_popcorn_users) + assert target.emotions.viewer_has_popcorned + end + end + + describe "[basic article comment emotion]" do + test "comment has default emotions after created", ~m(repo user)a do + parent_content = "parent comment" + + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + emotions = parent_comment.emotions |> Map.from_struct() |> Map.delete(:id) + assert @default_emotions == emotions + end + + test "can make emotion to comment", ~m(repo user user2)a do + parent_content = "parent comment" + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(ArticleComment, parent_comment.id) + + assert emotions.downvote_count == 2 + assert user_exist_in?(user, emotions.latest_downvote_users) + assert user_exist_in?(user2, emotions.latest_downvote_users) + end + + test "can undo emotion to comment", ~m(repo user user2)a do + parent_content = "parent comment" + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(ArticleComment, parent_comment.id) + + assert emotions.downvote_count == 2 + assert user_exist_in?(user, emotions.latest_downvote_users) + assert user_exist_in?(user2, emotions.latest_downvote_users) + + {:ok, _} = CMS.undo_emotion_to_comment(parent_comment.id, :downvote, user) + {:ok, _} = CMS.undo_emotion_to_comment(parent_comment.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(ArticleComment, parent_comment.id) + assert emotions.downvote_count == 0 + assert not user_exist_in?(user, emotions.latest_downvote_users) + assert not user_exist_in?(user2, emotions.latest_downvote_users) + end + + test "same user make same emotion to same comment.", ~m(repo user)a do + parent_content = "parent comment" + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user) + + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + assert parent_comment.emotions.downvote_count == 1 + assert user_exist_in?(user, parent_comment.emotions.latest_downvote_users) + end + + test "same user same emotion to same comment only have one user_emotion record", + ~m(repo user)a do + parent_content = "parent comment" + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :heart, user) + + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + {:ok, records} = ORM.find_all(ArticleCommentUserEmotion, %{page: 1, size: 10}) + assert records.total_count == 1 + + {:ok, record} = + ORM.find_by(ArticleCommentUserEmotion, %{ + article_comment_id: parent_comment.id, + user_id: user.id + }) + + assert record.downvote + assert record.heart + end + + test "different user can make same emotions on same comment", ~m(repo user user2 user3)a do + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent comment", user) + + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :beer, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :beer, user2) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :beer, user3) + + {:ok, %{emotions: emotions}} = ORM.find(ArticleComment, parent_comment.id) + # IO.inspect(emotions, label: "the parent_comment") + + assert emotions.beer_count == 3 + assert user_exist_in?(user, emotions.latest_beer_users) + assert user_exist_in?(user2, emotions.latest_beer_users) + assert user_exist_in?(user3, emotions.latest_beer_users) + end + + test "same user can make differcent emotions on same comment", ~m(repo user)a do + parent_content = "parent comment" + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :downvote, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :beer, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :heart, user) + {:ok, _} = CMS.emotion_to_comment(parent_comment.id, :orz, user) + + {:ok, %{emotions: emotions}} = ORM.find(ArticleComment, parent_comment.id) + + assert emotions.downvote_count == 1 + assert user_exist_in?(user, emotions.latest_downvote_users) + + assert emotions.beer_count == 1 + assert user_exist_in?(user, emotions.latest_beer_users) + + assert emotions.heart_count == 1 + assert user_exist_in?(user, emotions.latest_heart_users) + + assert emotions.orz_count == 1 + assert user_exist_in?(user, emotions.latest_orz_users) + + assert emotions.pill_count == 0 + assert not user_exist_in?(user, emotions.latest_pill_users) + + assert emotions.biceps_count == 0 + assert not user_exist_in?(user, emotions.latest_biceps_users) + + assert emotions.confused_count == 0 + assert not user_exist_in?(user, emotions.latest_confused_users) + end + end +end diff --git a/test/groupher_server/cms/comments/repo_comment_replies_test.exs b/test/groupher_server/cms/comments/repo_comment_replies_test.exs new file mode 100644 index 000000000..6be589753 --- /dev/null +++ b/test/groupher_server/cms/comments/repo_comment_replies_test.exs @@ -0,0 +1,213 @@ +defmodule GroupherServer.Test.CMS.Comments.RepoCommentReplies do + @moduledoc false + + use GroupherServer.TestTools + + alias Helper.ORM + alias GroupherServer.CMS + + alias CMS.{ArticleComment, Repo} + + @max_parent_replies_count CMS.ArticleComment.max_parent_replies_count() + + setup do + {:ok, user} = db_insert(:user) + {:ok, user2} = db_insert(:user) + {:ok, repo} = db_insert(:repo) + + {:ok, ~m(user user2 repo)a} + end + + describe "[basic article comment replies]" do + test "exsit comment can be reply", ~m(repo user user2)a do + parent_content = "parent comment" + reply_content = "reply comment" + + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + {:ok, replyed_comment} = CMS.reply_article_comment(parent_comment.id, reply_content, user2) + assert replyed_comment.reply_to.id == parent_comment.id + + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + assert exist_in?(replyed_comment, parent_comment.replies) + end + + test "deleted comment can not be reply", ~m(repo user user2)a do + parent_content = "parent comment" + reply_content = "reply comment" + + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + {:ok, _} = CMS.delete_article_comment(parent_comment) + + {:error, _} = CMS.reply_article_comment(parent_comment.id, reply_content, user2) + end + + test "multi reply should belong to one parent comment", ~m(repo user user2)a do + parent_content = "parent comment" + reply_content_1 = "reply comment 1" + reply_content_2 = "reply comment 2" + + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, parent_content, user) + + {:ok, replyed_comment_1} = + CMS.reply_article_comment(parent_comment.id, reply_content_1, user2) + + {:ok, replyed_comment_2} = + CMS.reply_article_comment(parent_comment.id, reply_content_2, user2) + + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + assert exist_in?(replyed_comment_1, parent_comment.replies) + assert exist_in?(replyed_comment_2, parent_comment.replies) + end + + test "reply to reply inside a comment should belong same parent comment", + ~m(repo user user2)a do + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent comment", user) + + {:ok, replyed_comment_1} = CMS.reply_article_comment(parent_comment.id, "reply 1", user2) + {:ok, replyed_comment_2} = CMS.reply_article_comment(replyed_comment_1.id, "reply 2", user2) + {:ok, replyed_comment_3} = CMS.reply_article_comment(replyed_comment_2.id, "reply 3", user) + + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + # IO.inspect(parent_comment.replies, label: "parent_comment.replies") + + assert exist_in?(replyed_comment_1, parent_comment.replies) + assert exist_in?(replyed_comment_2, parent_comment.replies) + assert exist_in?(replyed_comment_3, parent_comment.replies) + + {:ok, replyed_comment_1} = ORM.find(ArticleComment, replyed_comment_1.id) + {:ok, replyed_comment_2} = ORM.find(ArticleComment, replyed_comment_2.id) + {:ok, replyed_comment_3} = ORM.find(ArticleComment, replyed_comment_3.id) + + assert replyed_comment_1.reply_to_id == parent_comment.id + assert replyed_comment_2.reply_to_id == replyed_comment_1.id + assert replyed_comment_3.reply_to_id == replyed_comment_2.id + end + + test "reply to reply inside a comment should have is_reply_to_others flag in meta", + ~m(repo user user2)a do + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent comment", user) + + {:ok, replyed_comment_1} = CMS.reply_article_comment(parent_comment.id, "reply 1", user2) + {:ok, replyed_comment_2} = CMS.reply_article_comment(replyed_comment_1.id, "reply 2", user2) + {:ok, replyed_comment_3} = CMS.reply_article_comment(replyed_comment_2.id, "reply 3", user) + + {:ok, _parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + {:ok, replyed_comment_1} = ORM.find(ArticleComment, replyed_comment_1.id) + {:ok, replyed_comment_2} = ORM.find(ArticleComment, replyed_comment_2.id) + {:ok, replyed_comment_3} = ORM.find(ArticleComment, replyed_comment_3.id) + + assert not replyed_comment_1.meta.is_reply_to_others + assert replyed_comment_2.meta.is_reply_to_others + assert replyed_comment_3.meta.is_reply_to_others + end + + test "comment replies only contains @max_parent_replies_count replies", ~m(repo user)a do + total_reply_count = @max_parent_replies_count + 1 + + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent_conent", user) + + reply_comment_list = + Enum.reduce(1..total_reply_count, [], fn n, acc -> + {:ok, replyed_comment} = + CMS.reply_article_comment(parent_comment.id, "reply_content_#{n}", user) + + acc ++ [replyed_comment] + end) + + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + + assert length(parent_comment.replies) == @max_parent_replies_count + assert exist_in?(Enum.at(reply_comment_list, 0), parent_comment.replies) + assert exist_in?(Enum.at(reply_comment_list, 1), parent_comment.replies) + assert exist_in?(Enum.at(reply_comment_list, 2), parent_comment.replies) + assert not exist_in?(List.last(reply_comment_list), parent_comment.replies) + end + + test "replyed user should appear in article comment participators", ~m(repo user user2)a do + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent_conent", user) + {:ok, _} = CMS.reply_article_comment(parent_comment.id, "reply_content", user2) + + {:ok, article} = ORM.find(Repo, repo.id) + + assert exist_in?(user, article.article_comments_participators) + assert exist_in?(user2, article.article_comments_participators) + end + + test "replies count should inc by 1 after got replyed", ~m(repo user user2)a do + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent_conent", user) + assert parent_comment.replies_count === 0 + + {:ok, _} = CMS.reply_article_comment(parent_comment.id, "reply_content", user2) + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + assert parent_comment.replies_count === 1 + + {:ok, _} = CMS.reply_article_comment(parent_comment.id, "reply_content", user2) + {:ok, parent_comment} = ORM.find(ArticleComment, parent_comment.id) + assert parent_comment.replies_count === 2 + end + end + + describe "[paged article comment replies]" do + test "can get paged replies of a parent comment", ~m(repo user)a do + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent_conent", user) + {:ok, paged_replies} = CMS.paged_comment_replies(parent_comment.id, %{page: 1, size: 20}) + assert is_valid_pagination?(paged_replies, :raw, :empty) + + total_reply_count = 30 + + reply_comment_list = + Enum.reduce(1..total_reply_count, [], fn n, acc -> + {:ok, replyed_comment} = + CMS.reply_article_comment(parent_comment.id, "reply_content_#{n}", user) + + acc ++ [replyed_comment] + end) + + {:ok, paged_replies} = CMS.paged_comment_replies(parent_comment.id, %{page: 1, size: 20}) + + assert total_reply_count == paged_replies.total_count + assert is_valid_pagination?(paged_replies, :raw) + + assert exist_in?(Enum.at(reply_comment_list, 0), paged_replies.entries) + assert exist_in?(Enum.at(reply_comment_list, 1), paged_replies.entries) + assert exist_in?(Enum.at(reply_comment_list, 2), paged_replies.entries) + assert exist_in?(Enum.at(reply_comment_list, 3), paged_replies.entries) + end + + test "can get reply_to info of a parent comment", ~m(repo user)a do + page_number = 1 + page_size = 10 + + {:ok, parent_comment} = CMS.create_article_comment(:repo, repo.id, "parent_conent", user) + + {:ok, reply_comment} = CMS.reply_article_comment(parent_comment.id, "reply_content_1", user) + + {:ok, reply_comment2} = + CMS.reply_article_comment(parent_comment.id, "reply_content_2", user) + + {:ok, paged_comments} = + CMS.paged_article_comments( + :repo, + repo.id, + %{page: page_number, size: page_size}, + :timeline + ) + + reply_comment = Enum.find(paged_comments.entries, &(&1.id == reply_comment.id)) + + assert reply_comment.reply_to.id == parent_comment.id + assert reply_comment.reply_to.body_html == parent_comment.body_html + assert reply_comment.reply_to.author.id == parent_comment.author_id + + reply_comment2 = Enum.find(paged_comments.entries, &(&1.id == reply_comment2.id)) + + assert reply_comment2.reply_to.id == parent_comment.id + assert reply_comment2.reply_to.body_html == parent_comment.body_html + assert reply_comment2.reply_to.author.id == parent_comment.author_id + end + end +end diff --git a/test/groupher_server/cms/comments/repo_comment_test.exs b/test/groupher_server/cms/comments/repo_comment_test.exs new file mode 100644 index 000000000..6f7c15e2f --- /dev/null +++ b/test/groupher_server/cms/comments/repo_comment_test.exs @@ -0,0 +1,566 @@ +defmodule GroupherServer.Test.CMS.Comments.JobComment do + @moduledoc false + + use GroupherServer.TestTools + + alias Helper.ORM + alias GroupherServer.{Accounts, CMS} + + alias CMS.{ArticleComment, ArticlePinnedComment, Embeds, Job} + + @delete_hint CMS.ArticleComment.delete_hint() + @report_threshold_for_fold ArticleComment.report_threshold_for_fold() + @default_comment_meta Embeds.ArticleCommentMeta.default_meta() + @pinned_comment_limit ArticleComment.pinned_comment_limit() + + setup do + {:ok, user} = db_insert(:user) + {:ok, user2} = db_insert(:user) + {:ok, job} = db_insert(:job) + + {:ok, ~m(user user2 job)a} + end + + describe "[basic article comment]" do + test "job are supported by article comment.", ~m(user job)a do + {:ok, job_comment_1} = CMS.create_article_comment(:job, job.id, "job_comment 1", user) + {:ok, job_comment_2} = CMS.create_article_comment(:job, job.id, "job_comment 2", user) + + {:ok, job} = ORM.find(Job, job.id, preload: :article_comments) + + assert exist_in?(job_comment_1, job.article_comments) + assert exist_in?(job_comment_2, job.article_comments) + end + + test "comment should have default meta after create", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "job comment", user) + assert comment.meta |> Map.from_struct() |> Map.delete(:id) == @default_comment_meta + end + + test "comment can be updated", ~m(job user)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "job comment", user) + + {:ok, updated_comment} = CMS.update_article_comment(comment, "updated content") + + assert updated_comment.body_html == "updated content" + end + end + + describe "[article comment floor]" do + test "comment will have a floor number after created", ~m(user job)a do + {:ok, job_comment} = CMS.create_article_comment(:job, job.id, "comment", user) + {:ok, job_comment2} = CMS.create_article_comment(:job, job.id, "comment2", user) + + {:ok, job_comment} = ORM.find(ArticleComment, job_comment.id) + {:ok, job_comment2} = ORM.find(ArticleComment, job_comment2.id) + + assert job_comment.floor == 1 + assert job_comment2.floor == 2 + end + end + + describe "[article comment participator for job]" do + test "job will have participator after comment created", ~m(user job)a do + job_comment_1 = "job_comment 1" + + {:ok, _} = CMS.create_article_comment(:job, job.id, job_comment_1, user) + + {:ok, job} = ORM.find(Job, job.id) + + participator = List.first(job.article_comments_participators) + assert participator.id == user.id + end + + test "psot participator will not contains same user", ~m(user job)a do + job_comment_1 = "job_comment 1" + + {:ok, _} = CMS.create_article_comment(:job, job.id, job_comment_1, user) + {:ok, _} = CMS.create_article_comment(:job, job.id, job_comment_1, user) + + {:ok, job} = ORM.find(Job, job.id) + + assert 1 == length(job.article_comments_participators) + end + + test "recent comment user should appear at first of the psot participators", + ~m(user user2 job)a do + job_comment_1 = "job_comment 1" + + {:ok, _} = CMS.create_article_comment(:job, job.id, job_comment_1, user) + {:ok, _} = CMS.create_article_comment(:job, job.id, job_comment_1, user2) + + {:ok, job} = ORM.find(Job, job.id) + + participator = List.first(job.article_comments_participators) + + assert participator.id == user2.id + end + end + + describe "[article comment upvotes]" do + test "user can upvote a job comment", ~m(user job)a do + comment = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, comment, user) + + CMS.upvote_article_comment(comment.id, user) + + {:ok, comment} = ORM.find(ArticleComment, comment.id, preload: :upvotes) + + assert 1 == length(comment.upvotes) + assert List.first(comment.upvotes).user_id == user.id + end + + test "article author upvote job comment will have flag", ~m(job user)a do + comment = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, comment, user) + {:ok, author_user} = ORM.find(Accounts.User, job.author.user.id) + + CMS.upvote_article_comment(comment.id, author_user) + + {:ok, comment} = ORM.find(ArticleComment, comment.id, preload: :upvotes) + assert comment.meta.is_article_author_upvoted + end + + test "user upvote job comment will add id to upvoted_user_ids", ~m(job user)a do + comment = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, comment, user) + {:ok, comment} = CMS.upvote_article_comment(comment.id, user) + + assert user.id in comment.meta.upvoted_user_ids + end + + test "user undo upvote job comment will remove id from upvoted_user_ids", + ~m(job user user2)a do + comment = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, comment, user) + {:ok, _comment} = CMS.upvote_article_comment(comment.id, user) + {:ok, comment} = CMS.upvote_article_comment(comment.id, user2) + + assert user2.id in comment.meta.upvoted_user_ids + assert user.id in comment.meta.upvoted_user_ids + + {:ok, comment} = CMS.undo_upvote_article_comment(comment.id, user2) + + assert user.id in comment.meta.upvoted_user_ids + assert user2.id not in comment.meta.upvoted_user_ids + end + + test "user upvote a already-upvoted comment fails", ~m(user job)a do + comment = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, comment, user) + + CMS.upvote_article_comment(comment.id, user) + {:error, _} = CMS.upvote_article_comment(comment.id, user) + end + + test "upvote comment should inc the comment's upvotes_count", ~m(user user2 job)a do + comment = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, comment, user) + {:ok, comment} = ORM.find(ArticleComment, comment.id) + assert comment.upvotes_count == 0 + + {:ok, _} = CMS.upvote_article_comment(comment.id, user) + {:ok, _} = CMS.upvote_article_comment(comment.id, user2) + + {:ok, comment} = ORM.find(ArticleComment, comment.id) + assert comment.upvotes_count == 2 + end + + test "user can undo upvote a job comment", ~m(user job)a do + content = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, content, user) + CMS.upvote_article_comment(comment.id, user) + + {:ok, comment} = ORM.find(ArticleComment, comment.id, preload: :upvotes) + assert 1 == length(comment.upvotes) + + {:ok, comment} = CMS.undo_upvote_article_comment(comment.id, user) + assert 0 == comment.upvotes_count + end + + test "user can undo upvote a job comment with no upvote", ~m(user job)a do + content = "job_comment" + {:ok, comment} = CMS.create_article_comment(:job, job.id, content, user) + {:ok, comment} = CMS.undo_upvote_article_comment(comment.id, user) + assert 0 == comment.upvotes_count + + {:ok, comment} = CMS.undo_upvote_article_comment(comment.id, user) + assert 0 == comment.upvotes_count + end + end + + describe "[article comment fold/unfold]" do + test "user can fold a comment", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, comment} = ORM.find(ArticleComment, comment.id) + + assert not comment.is_folded + + {:ok, comment} = CMS.fold_article_comment(comment.id, user) + {:ok, comment} = ORM.find(ArticleComment, comment.id) + assert comment.is_folded + end + + test "user can unfold a comment", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, _comment} = CMS.fold_article_comment(comment.id, user) + {:ok, comment} = ORM.find(ArticleComment, comment.id) + + assert comment.is_folded + + {:ok, _comment} = CMS.unfold_article_comment(comment.id, user) + {:ok, comment} = ORM.find(ArticleComment, comment.id) + assert not comment.is_folded + end + end + + describe "[article comment pin/unpin]" do + test "user can pin a comment", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, comment} = ORM.find(ArticleComment, comment.id) + + assert not comment.is_pinned + + {:ok, comment} = CMS.pin_article_comment(comment.id) + {:ok, comment} = ORM.find(ArticleComment, comment.id) + + assert comment.is_pinned + + {:ok, pined_record} = ArticlePinnedComment |> ORM.find_by(%{job_id: job.id}) + assert pined_record.job_id == job.id + end + + test "user can unpin a comment", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + {:ok, _comment} = CMS.pin_article_comment(comment.id) + {:ok, comment} = CMS.undo_pin_article_comment(comment.id) + + assert not comment.is_pinned + assert {:error, _} = ArticlePinnedComment |> ORM.find_by(%{article_comment_id: comment.id}) + end + + test "pinned comments has a limit for each article", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + Enum.reduce(0..(@pinned_comment_limit - 1), [], fn _, _acc -> + {:ok, _comment} = CMS.pin_article_comment(comment.id) + end) + + assert {:error, _} = CMS.pin_article_comment(comment.id) + end + end + + describe "[article comment report/unreport]" do + # + # test "user can report a comment", ~m(user job)a do + # {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + # {:ok, comment} = ORM.find(ArticleComment, comment.id) + + # {:ok, comment} = CMS.report_article_comment(comment.id, "reason", "attr", user) + # {:ok, comment} = ORM.find(ArticleComment, comment.id) + # end + + # + # test "user can unreport a comment", ~m(user job)a do + # {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + # {:ok, _comment} = CMS.report_article_comment(comment.id, "reason", "attr", user) + # {:ok, comment} = ORM.find(ArticleComment, comment.id) + + # {:ok, _comment} = CMS.undo_report_article_comment(comment.id, user) + # {:ok, comment} = ORM.find(ArticleComment, comment.id) + # end + + test "can undo a report with other user report it too", + ~m(user user2 job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + {:ok, _comment} = CMS.report_article_comment(comment.id, "reason", "attr", user) + {:ok, _comment} = CMS.report_article_comment(comment.id, "reason", "attr", user2) + + filter = %{content_type: :article_comment, content_id: comment.id, page: 1, size: 20} + {:ok, all_reports} = CMS.paged_reports(filter) + assert all_reports.total_count == 1 + + report = all_reports.entries |> List.first() + assert report.report_cases |> length == 2 + assert Enum.any?(report.report_cases, &(&1.user.login == user.login)) + assert Enum.any?(report.report_cases, &(&1.user.login == user2.login)) + + {:ok, _report} = CMS.undo_report_article(:article_comment, comment.id, user) + + filter = %{content_type: :article_comment, content_id: comment.id, page: 1, size: 20} + {:ok, all_reports} = CMS.paged_reports(filter) + assert all_reports.total_count == 1 + + report = all_reports.entries |> List.first() + assert report.report_cases |> length == 1 + assert Enum.any?(report.report_cases, &(&1.user.login == user2.login)) + end + + test "report user < @report_threshold_for_fold will not fold comment", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + assert not comment.is_folded + + Enum.reduce(1..(@report_threshold_for_fold - 1), [], fn _, _acc -> + {:ok, user} = db_insert(:user) + {:ok, _comment} = CMS.report_article_comment(comment.id, "reason", "attr", user) + end) + + {:ok, comment} = ORM.find(ArticleComment, comment.id) + assert not comment.is_folded + end + + test "report user > @report_threshold_for_fold will cause comment fold", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + assert not comment.is_folded + + Enum.reduce(1..(@report_threshold_for_fold + 1), [], fn _, _acc -> + {:ok, user} = db_insert(:user) + {:ok, _comment} = CMS.report_article_comment(comment.id, "reason", "attr", user) + end) + + {:ok, comment} = ORM.find(ArticleComment, comment.id) + assert comment.is_folded + end + end + + describe "paged article comments" do + test "can load paged comments participators of a article", ~m(user job)a do + total_count = 30 + page_size = 10 + thread = :job + + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, new_user} = db_insert(:user) + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", new_user) + + acc ++ [comment] + end) + + {:ok, _comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, _comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + {:ok, results} = + CMS.paged_article_comments_participators(thread, job.id, %{page: 1, size: page_size}) + + assert results |> is_valid_pagination?(:raw) + assert results.total_count == total_count + 1 + end + + test "paged article comments folded flag should be false", ~m(user job)a do + total_count = 30 + page_number = 1 + page_size = 10 + + all_comments = + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + acc ++ [comment] + end) + + {:ok, paged_comments} = + CMS.paged_article_comments(:job, job.id, %{page: page_number, size: page_size}, :replies) + + random_comment = all_comments |> Enum.at(Enum.random(0..total_count)) + + assert not random_comment.is_folded + + assert page_number == paged_comments.page_number + assert page_size == paged_comments.page_size + assert total_count == paged_comments.total_count + end + + test "paged article comments should contains pinned comments at top position", + ~m(user job)a do + total_count = 20 + page_number = 1 + page_size = 5 + + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + acc ++ [comment] + end) + + {:ok, random_comment_1} = CMS.create_article_comment(:job, job.id, "pin commment", user) + {:ok, random_comment_2} = CMS.create_article_comment(:job, job.id, "pin commment2", user) + + {:ok, pined_comment_1} = CMS.pin_article_comment(random_comment_1.id) + {:ok, pined_comment_2} = CMS.pin_article_comment(random_comment_2.id) + + {:ok, paged_comments} = + CMS.paged_article_comments(:job, job.id, %{page: page_number, size: page_size}, :replies) + + assert pined_comment_1.id == List.first(paged_comments.entries) |> Map.get(:id) + assert pined_comment_2.id == Enum.at(paged_comments.entries, 1) |> Map.get(:id) + + assert paged_comments.total_count == total_count + 2 + end + + test "only page 1 have pinned coments", + ~m(user job)a do + total_count = 20 + page_number = 2 + page_size = 5 + + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + acc ++ [comment] + end) + + {:ok, random_comment_1} = CMS.create_article_comment(:job, job.id, "pin commment", user) + {:ok, random_comment_2} = CMS.create_article_comment(:job, job.id, "pin commment2", user) + + {:ok, pined_comment_1} = CMS.pin_article_comment(random_comment_1.id) + {:ok, pined_comment_2} = CMS.pin_article_comment(random_comment_2.id) + + {:ok, paged_comments} = + CMS.paged_article_comments(:job, job.id, %{page: page_number, size: page_size}, :replies) + + assert not exist_in?(pined_comment_1, paged_comments.entries) + assert not exist_in?(pined_comment_2, paged_comments.entries) + + assert paged_comments.total_count == total_count + end + + test "paged article comments should not contains folded and repoted comments", + ~m(user job)a do + total_count = 15 + page_number = 1 + page_size = 20 + + all_comments = + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + acc ++ [comment] + end) + + random_comment_1 = all_comments |> Enum.at(0) + random_comment_2 = all_comments |> Enum.at(1) + random_comment_3 = all_comments |> Enum.at(3) + + {:ok, _comment} = CMS.fold_article_comment(random_comment_1.id, user) + {:ok, _comment} = CMS.fold_article_comment(random_comment_2.id, user) + {:ok, _comment} = CMS.fold_article_comment(random_comment_3.id, user) + + {:ok, paged_comments} = + CMS.paged_article_comments(:job, job.id, %{page: page_number, size: page_size}, :replies) + + assert not exist_in?(random_comment_1, paged_comments.entries) + assert not exist_in?(random_comment_2, paged_comments.entries) + assert not exist_in?(random_comment_3, paged_comments.entries) + + assert page_number == paged_comments.page_number + assert page_size == paged_comments.page_size + assert total_count - 3 == paged_comments.total_count + end + + test "can loaded paged folded comment", ~m(user job)a do + total_count = 10 + page_number = 1 + page_size = 20 + + all_folded_comments = + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + CMS.fold_article_comment(comment.id, user) + + acc ++ [comment] + end) + + random_comment_1 = all_folded_comments |> Enum.at(1) + random_comment_2 = all_folded_comments |> Enum.at(3) + random_comment_3 = all_folded_comments |> Enum.at(5) + + {:ok, paged_comments} = + CMS.paged_folded_article_comments(:job, job.id, %{page: page_number, size: page_size}) + + assert exist_in?(random_comment_1, paged_comments.entries) + assert exist_in?(random_comment_2, paged_comments.entries) + assert exist_in?(random_comment_3, paged_comments.entries) + + assert page_number == paged_comments.page_number + assert page_size == paged_comments.page_size + assert total_count == paged_comments.total_count + end + end + + describe "[article comment delete]" do + test "delete comment still exsit in paged list and content is gone", ~m(user job)a do + total_count = 10 + page_number = 1 + page_size = 20 + + all_comments = + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + acc ++ [comment] + end) + + random_comment = all_comments |> Enum.at(1) + + {:ok, deleted_comment} = CMS.delete_article_comment(random_comment) + + {:ok, paged_comments} = + CMS.paged_article_comments(:job, job.id, %{page: page_number, size: page_size}, :replies) + + assert exist_in?(deleted_comment, paged_comments.entries) + assert deleted_comment.is_deleted + assert deleted_comment.body_html == @delete_hint + end + + test "delete comment still update article's comments_count field", ~m(user job)a do + {:ok, _comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, _comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, _comment} = CMS.create_article_comment(:job, job.id, "commment", user) + {:ok, _comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + {:ok, job} = ORM.find(Job, job.id) + + assert job.article_comments_count == 5 + + {:ok, _} = CMS.delete_article_comment(comment) + + {:ok, job} = ORM.find(Job, job.id) + assert job.article_comments_count == 4 + end + + test "delete comment still delete pinned record if needed", ~m(user job)a do + total_count = 10 + + all_comments = + Enum.reduce(1..total_count, [], fn _, acc -> + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + + acc ++ [comment] + end) + + random_comment = all_comments |> Enum.at(1) + + {:ok, _comment} = CMS.pin_article_comment(random_comment.id) + {:ok, _comment} = ORM.find(ArticleComment, random_comment.id) + + {:ok, _} = CMS.delete_article_comment(random_comment) + assert {:error, _comment} = ORM.find(ArticlePinnedComment, random_comment.id) + end + end + + describe "[article comment info]" do + test "author of the article comment a comment should have flag", ~m(user job)a do + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", user) + assert not comment.is_article_author + + author_user = job.author.user + {:ok, comment} = CMS.create_article_comment(:job, job.id, "commment", author_user) + assert comment.is_article_author + end + end +end diff --git a/test/groupher_server/cms/emotions/repo_emotions_test.exs b/test/groupher_server/cms/emotions/repo_emotions_test.exs new file mode 100644 index 000000000..9c619e609 --- /dev/null +++ b/test/groupher_server/cms/emotions/repo_emotions_test.exs @@ -0,0 +1,177 @@ +defmodule GroupherServer.Test.CMS.Emotions.RepoEmotions do + @moduledoc false + + use GroupherServer.TestTools + + alias Helper.ORM + alias GroupherServer.CMS + + alias CMS.{Embeds, ArticleUserEmotion} + + @default_emotions Embeds.ArticleEmotion.default_emotions() + + setup do + {:ok, user} = db_insert(:user) + {:ok, community} = db_insert(:community) + {:ok, user2} = db_insert(:user) + {:ok, user3} = db_insert(:user) + + repo_attrs = mock_attrs(:repo, %{community_id: community.id}) + + {:ok, ~m(user user2 user3 community repo_attrs)a} + end + + describe "[emotion in paged repos]" do + test "login user should got viewer has emotioned status", + ~m(community repo_attrs user)a do + total_count = 10 + page_number = 10 + page_size = 20 + + all_repos = + Enum.reduce(0..total_count, [], fn _, acc -> + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + acc ++ [repo] + end) + + random_repo = all_repos |> Enum.at(3) + + {:ok, _} = CMS.emotion_to_article(:repo, random_repo.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:repo, random_repo.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:repo, random_repo.id, :popcorn, user) + + {:ok, paged_articles} = + CMS.paged_articles(:repo, %{page: page_number, size: page_size}, user) + + target = Enum.find(paged_articles.entries, &(&1.id == random_repo.id)) + + assert target.emotions.downvote_count == 1 + assert user_exist_in?(user, target.emotions.latest_downvote_users) + assert target.emotions.viewer_has_downvoteed + + assert target.emotions.beer_count == 1 + assert user_exist_in?(user, target.emotions.latest_beer_users) + assert target.emotions.viewer_has_beered + + assert target.emotions.popcorn_count == 1 + assert user_exist_in?(user, target.emotions.latest_popcorn_users) + assert target.emotions.viewer_has_popcorned + end + end + + describe "[basic article emotion]" do + test "repo has default emotions after created", ~m(community repo_attrs user)a do + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + + emotions = repo.emotions |> Map.from_struct() |> Map.delete(:id) + assert @default_emotions == emotions + end + + test "can make emotion to repo", ~m(community repo_attrs user user2)a do + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Repo, repo.id) + + assert emotions.downvote_count == 2 + assert user_exist_in?(user, emotions.latest_downvote_users) + assert user_exist_in?(user2, emotions.latest_downvote_users) + end + + test "can undo emotion to repo", ~m(community repo_attrs user user2)a do + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user2) + + {:ok, _} = CMS.undo_emotion_to_article(:repo, repo.id, :downvote, user) + {:ok, _} = CMS.undo_emotion_to_article(:repo, repo.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Repo, repo.id) + + assert emotions.downvote_count == 0 + assert not user_exist_in?(user, emotions.latest_downvote_users) + assert not user_exist_in?(user2, emotions.latest_downvote_users) + end + + test "same user make same emotion to same repo.", ~m(community repo_attrs user)a do + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user) + + {:ok, repo} = ORM.find(CMS.Repo, repo.id) + + assert repo.emotions.downvote_count == 1 + assert user_exist_in?(user, repo.emotions.latest_downvote_users) + end + + test "same user same emotion to same repo only have one user_emotion record", + ~m(community repo_attrs user)a do + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :heart, user) + + {:ok, repo} = ORM.find(CMS.Repo, repo.id) + + {:ok, records} = ORM.find_all(ArticleUserEmotion, %{page: 1, size: 10}) + assert records.total_count == 1 + + {:ok, record} = ORM.find_by(ArticleUserEmotion, %{repo_id: repo.id, user_id: user.id}) + assert record.downvote + assert record.heart + end + + test "different user can make same emotions on same repo", + ~m(community repo_attrs user user2 user3)a do + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :beer, user2) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :beer, user3) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Repo, repo.id) + + assert emotions.beer_count == 3 + assert user_exist_in?(user, emotions.latest_beer_users) + assert user_exist_in?(user2, emotions.latest_beer_users) + assert user_exist_in?(user3, emotions.latest_beer_users) + end + + test "same user can make differcent emotions on same repo", ~m(community repo_attrs user)a do + {:ok, repo} = CMS.create_article(community, :repo, repo_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :heart, user) + {:ok, _} = CMS.emotion_to_article(:repo, repo.id, :orz, user) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Repo, repo.id) + + assert emotions.downvote_count == 1 + assert user_exist_in?(user, emotions.latest_downvote_users) + + assert emotions.beer_count == 1 + assert user_exist_in?(user, emotions.latest_beer_users) + + assert emotions.heart_count == 1 + assert user_exist_in?(user, emotions.latest_heart_users) + + assert emotions.orz_count == 1 + assert user_exist_in?(user, emotions.latest_orz_users) + + assert emotions.pill_count == 0 + assert not user_exist_in?(user, emotions.latest_pill_users) + + assert emotions.biceps_count == 0 + assert not user_exist_in?(user, emotions.latest_biceps_users) + + assert emotions.confused_count == 0 + assert not user_exist_in?(user, emotions.latest_confused_users) + end + end +end From f6e7d5943022874a95941011beafef4d676a6334 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 15:28:01 +0800 Subject: [PATCH 14/18] refactor: post_communities macro --- lib/groupher_server/cms/helper/macros.ex | 19 +++++++++++++++++++ lib/groupher_server/cms/post.ex | 8 +------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 0a0ebed2e..2285f624d 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -188,4 +188,23 @@ defmodule GroupherServer.CMS.Helper.Macros do timestamps() end end + + @doc """ + + # TABLE: "communities_[article]s" + add(:community_id, references(:communities, on_delete: :delete_all), null: false) + add(:[article]_id, references(:cms_[article]s, on_delete: :delete_all), null: false) + + create(unique_index(:communities_[article]s, [:community_id, :[article]_id])) + """ + defmacro article_community_field(thread) do + quote do + many_to_many( + :communities, + Community, + join_through: unquote("communities_#{to_string(thread)}s"), + on_replace: :delete + ) + end + end end diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index 10d802673..931328583 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -44,13 +44,7 @@ defmodule GroupherServer.CMS.Post do on_replace: :delete ) - many_to_many( - :communities, - Community, - join_through: "communities_posts", - on_replace: :delete - ) - + article_community_field(:post) general_article_fields() end From 3dc30ae4723e014d14185fa924c8cbd2b16ece08 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 15:40:12 +0800 Subject: [PATCH 15/18] refactor: community_article macro --- lib/groupher_server/cms/community.ex | 29 ++---------------------- lib/groupher_server/cms/helper/macros.ex | 14 ++++++++++++ 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/lib/groupher_server/cms/community.ex b/lib/groupher_server/cms/community.ex index 10c1358a6..85b13825e 100644 --- a/lib/groupher_server/cms/community.ex +++ b/lib/groupher_server/cms/community.ex @@ -4,14 +4,12 @@ defmodule GroupherServer.CMS.Community do use Ecto.Schema import Ecto.Changeset + import GroupherServer.CMS.Helper.Macros alias GroupherServer.{Accounts, CMS} alias CMS.{ Category, - Post, - Repo, - Job, CommunityThread, CommunitySubscriber, CommunityEditor, @@ -59,30 +57,7 @@ defmodule GroupherServer.CMS.Community do # on_replace: :delete ) - many_to_many( - :posts, - Post, - join_through: "communities_posts", - join_keys: [community_id: :id, post_id: :id] - ) - - many_to_many( - :repos, - Repo, - join_through: "communities_repos", - join_keys: [community_id: :id, repo_id: :id] - ) - - many_to_many( - :jobs, - Job, - join_through: "communities_jobs", - join_keys: [community_id: :id, job_id: :id] - ) - - # posts_managers - # jobs_managers - # tuts_managers + community_article_fields() # # posts_block_list ... timestamps(type: :utc_datetime) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 2285f624d..fbe6df1db 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -189,6 +189,20 @@ defmodule GroupherServer.CMS.Helper.Macros do end end + defmacro community_article_fields() do + @article_threads + |> Enum.map(fn thread -> + quote do + many_to_many( + unquote(:"#{thread}s"), + Module.concat(CMS, unquote(thread) |> to_string |> Recase.to_pascal()), + join_through: unquote("communities_#{to_string(thread)}s"), + join_keys: [community_id: :id] ++ Keyword.new([{unquote(:"#{thread}_id"), :id}]) + ) + end + end) + end + @doc """ # TABLE: "communities_[article]s" From ab32c920a48aad25c81fe164fc5a52fa80bc131e Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 15:44:08 +0800 Subject: [PATCH 16/18] refactor: add some doc --- lib/groupher_server/cms/helper/macros.ex | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index fbe6df1db..138c13ced 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -39,6 +39,7 @@ defmodule GroupherServer.CMS.Helper.Macros do end @doc """ + for GroupherServer.CMS.[Article] article_comments related fields MIGRATION: @@ -66,6 +67,7 @@ defmodule GroupherServer.CMS.Helper.Macros do end @doc """ + for GroupherServer.CMS.[Article] viewer has xxx fields for each article those fields is virtual, do not need DB migration @@ -80,6 +82,7 @@ defmodule GroupherServer.CMS.Helper.Macros do end @doc """ + for GroupherServer.CMS.[Article] aritlce's upvote and collect feature MIGRATION: @@ -106,6 +109,8 @@ defmodule GroupherServer.CMS.Helper.Macros do end @doc """ + for GroupherServer.CMS.[Article] + common casting fields for general_article_fields """ def general_article_fields(:cast) do @@ -120,6 +125,7 @@ defmodule GroupherServer.CMS.Helper.Macros do end @doc """ + for GroupherServer.CMS.[Article] MIGRATION: @@ -189,6 +195,15 @@ defmodule GroupherServer.CMS.Helper.Macros do end end + @doc """ + for GroupherServer.CMS.Community + + # TABLE: "communities_[article]s" + add(:community_id, references(:communities, on_delete: :delete_all), null: false) + add(:[article]_id, references(:cms_[article]s, on_delete: :delete_all), null: false) + + create(unique_index(:communities_[article]s, [:community_id, :[article]_id])) + """ defmacro community_article_fields() do @article_threads |> Enum.map(fn thread -> @@ -204,6 +219,7 @@ defmodule GroupherServer.CMS.Helper.Macros do end @doc """ + for GroupherServer.CMS.[Article] # TABLE: "communities_[article]s" add(:community_id, references(:communities, on_delete: :delete_all), null: false) From 149e845684aebb1fab06569ae7810087e57f196a Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 16:01:11 +0800 Subject: [PATCH 17/18] refactor: move article_thread config to config.ex --- config/config.exs | 2 ++ lib/groupher_server/cms/abuse_report.ex | 4 +++- lib/groupher_server/cms/article_collect.ex | 4 +++- lib/groupher_server/cms/article_comment.ex | 3 ++- lib/groupher_server/cms/article_pinned_comment.ex | 3 ++- lib/groupher_server/cms/article_upvote.ex | 4 +++- lib/groupher_server/cms/article_user_emotion.ex | 2 +- lib/groupher_server/cms/community.ex | 2 -- lib/groupher_server/cms/delegates/abuse_report.ex | 4 ++-- .../cms/delegates/article_comment_action.ex | 5 +++-- lib/groupher_server/cms/helper/macros.ex | 3 ++- lib/groupher_server/cms/helper/matcher2.ex | 3 ++- lib/groupher_server/cms/helper/utils.ex | 3 ++- lib/groupher_server/cms/job.ex | 10 ++-------- lib/groupher_server/cms/pinned_article.ex | 4 +++- lib/groupher_server/cms/post.ex | 2 +- lib/groupher_server/cms/repo.ex | 13 +++---------- lib/groupher_server_web/resolvers/cms_resolver.ex | 1 - 18 files changed, 36 insertions(+), 36 deletions(-) diff --git a/config/config.exs b/config/config.exs index fcd5f1437..1a8e4ef58 100644 --- a/config/config.exs +++ b/config/config.exs @@ -61,6 +61,8 @@ config :groupher_server, :customization, sidebar_communities_index: %{} config :groupher_server, :article, + # NOTE: do not change unless you know what you are doing + article_threads: [:post, :job, :repo], # NOTE: if you want to add/remove emotion, just edit the list below # and migrate the field to table "articles_users_emotions" supported_emotions: [ diff --git a/lib/groupher_server/cms/abuse_report.ex b/lib/groupher_server/cms/abuse_report.ex index 3cfa93f7b..85146601a 100644 --- a/lib/groupher_server/cms/abuse_report.ex +++ b/lib/groupher_server/cms/abuse_report.ex @@ -4,14 +4,16 @@ defmodule GroupherServer.CMS.AbuseReport do use Ecto.Schema use Accessible + import Ecto.Changeset + import Helper.Utils, only: [get_config: 2] import GroupherServer.CMS.Helper.Macros import GroupherServer.CMS.Helper.Utils, only: [articles_foreign_key_constraint: 1] alias GroupherServer.{Accounts, CMS} alias CMS.{ArticleComment, Embeds} - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) # @required_fields ~w(article_comment_id user_id recived_user_id)a @optional_fields ~w(article_comment_id account_id operate_user_id deal_with report_cases_count)a diff --git a/lib/groupher_server/cms/article_collect.ex b/lib/groupher_server/cms/article_collect.ex index 8b04079f6..723dcd232 100644 --- a/lib/groupher_server/cms/article_collect.ex +++ b/lib/groupher_server/cms/article_collect.ex @@ -3,14 +3,16 @@ defmodule GroupherServer.CMS.ArticleCollect do alias __MODULE__ use Ecto.Schema + import Ecto.Changeset + import Helper.Utils, only: [get_config: 2] import GroupherServer.CMS.Helper.Macros import GroupherServer.CMS.Helper.Utils, only: [articles_foreign_key_constraint: 1] alias GroupherServer.{Accounts, CMS} alias Accounts.{User, CollectFolder} - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) @required_fields ~w(user_id)a @optional_fields ~w(thread)a diff --git a/lib/groupher_server/cms/article_comment.ex b/lib/groupher_server/cms/article_comment.ex index 8069b0102..c8055d239 100644 --- a/lib/groupher_server/cms/article_comment.ex +++ b/lib/groupher_server/cms/article_comment.ex @@ -6,6 +6,7 @@ defmodule GroupherServer.CMS.ArticleComment do use Accessible import Ecto.Changeset + import Helper.Utils, only: [get_config: 2] import GroupherServer.CMS.Helper.Macros import GroupherServer.CMS.Helper.Utils, only: [articles_foreign_key_constraint: 1] @@ -13,7 +14,7 @@ defmodule GroupherServer.CMS.ArticleComment do alias CMS.{Embeds, ArticleCommentUpvote} # alias Helper.HTML - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) @required_fields ~w(body_html author_id)a @optional_fields ~w(reply_to_id replies_count is_folded is_deleted floor is_article_author)a diff --git a/lib/groupher_server/cms/article_pinned_comment.ex b/lib/groupher_server/cms/article_pinned_comment.ex index 7cbd585bf..fd470ea29 100644 --- a/lib/groupher_server/cms/article_pinned_comment.ex +++ b/lib/groupher_server/cms/article_pinned_comment.ex @@ -6,6 +6,7 @@ defmodule GroupherServer.CMS.ArticlePinnedComment do use Accessible import Ecto.Changeset + import Helper.Utils, only: [get_config: 2] import GroupherServer.CMS.Helper.Macros import GroupherServer.CMS.Helper.Utils, only: [articles_foreign_key_constraint: 1] @@ -13,7 +14,7 @@ defmodule GroupherServer.CMS.ArticlePinnedComment do alias CMS.ArticleComment # alias Helper.HTML - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) @required_fields ~w(article_comment_id)a # @optional_fields ~w(post_id job_id repo_id)a diff --git a/lib/groupher_server/cms/article_upvote.ex b/lib/groupher_server/cms/article_upvote.ex index a09ea50bb..bc67482a3 100644 --- a/lib/groupher_server/cms/article_upvote.ex +++ b/lib/groupher_server/cms/article_upvote.ex @@ -3,14 +3,16 @@ defmodule GroupherServer.CMS.ArticleUpvote do alias __MODULE__ use Ecto.Schema + import Ecto.Changeset + import Helper.Utils, only: [get_config: 2] import GroupherServer.CMS.Helper.Macros import GroupherServer.CMS.Helper.Utils, only: [articles_foreign_key_constraint: 1] alias GroupherServer.{Accounts, CMS} alias Accounts.User - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) @required_fields ~w(user_id)a @optional_fields ~w(thread)a diff --git a/lib/groupher_server/cms/article_user_emotion.ex b/lib/groupher_server/cms/article_user_emotion.ex index f620c5091..621fd5cd3 100644 --- a/lib/groupher_server/cms/article_user_emotion.ex +++ b/lib/groupher_server/cms/article_user_emotion.ex @@ -29,7 +29,7 @@ defmodule GroupherServer.CMS.ArticleUserEmotion do alias GroupherServer.{Accounts, CMS} @supported_emotions get_config(:article, :supported_emotions) - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) @required_fields ~w(user_id recived_user_id)a @optional_fields Enum.map(@article_threads, &:"#{&1}_id") ++ diff --git a/lib/groupher_server/cms/community.ex b/lib/groupher_server/cms/community.ex index 85b13825e..1c3da40bf 100644 --- a/lib/groupher_server/cms/community.ex +++ b/lib/groupher_server/cms/community.ex @@ -17,14 +17,12 @@ defmodule GroupherServer.CMS.Community do CommunityCheatsheet } - @article_threads [:post, :job, :repo] @max_pinned_article_count_per_thread 2 @required_fields ~w(title desc user_id logo raw)a # @required_fields ~w(title desc user_id)a @optional_fields ~w(label geo_info index aka)a - def article_threads, do: @article_threads def max_pinned_article_count_per_thread, do: @max_pinned_article_count_per_thread schema "communities" do diff --git a/lib/groupher_server/cms/delegates/abuse_report.ex b/lib/groupher_server/cms/delegates/abuse_report.ex index 18d004cc2..116e9cde3 100644 --- a/lib/groupher_server/cms/delegates/abuse_report.ex +++ b/lib/groupher_server/cms/delegates/abuse_report.ex @@ -3,7 +3,7 @@ defmodule GroupherServer.CMS.Delegate.AbuseReport do CURD and operations for article comments """ import Ecto.Query, warn: false - import Helper.Utils, only: [done: 1, strip_struct: 1] + import Helper.Utils, only: [done: 1, strip_struct: 1, get_config: 2] import GroupherServer.CMS.Helper.Matcher2 import ShortMaps @@ -17,9 +17,9 @@ defmodule GroupherServer.CMS.Delegate.AbuseReport do alias Ecto.Multi + @article_threads get_config(:article, :article_threads) @report_threshold_for_fold ArticleComment.report_threshold_for_fold() - @article_threads Community.article_threads() @export_author_keys [:id, :login, :nickname, :avatar] @export_article_keys [:id, :title, :digest, :upvotes_count, :views] @export_report_keys [ diff --git a/lib/groupher_server/cms/delegates/article_comment_action.ex b/lib/groupher_server/cms/delegates/article_comment_action.ex index 0041d07cb..6345627ba 100644 --- a/lib/groupher_server/cms/delegates/article_comment_action.ex +++ b/lib/groupher_server/cms/delegates/article_comment_action.ex @@ -3,7 +3,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do CURD and operations for article comments """ import Ecto.Query, warn: false - import Helper.Utils, only: [done: 1, strip_struct: 1] + import Helper.Utils, only: [done: 1, strip_struct: 1, get_config: 2] import Helper.ErrorCode import GroupherServer.CMS.Delegate.ArticleComment, @@ -30,7 +30,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do alias Ecto.Multi - @article_threads Community.article_threads() + @article_threads get_config(:article, :article_threads) + @max_parent_replies_count ArticleComment.max_parent_replies_count() @pinned_comment_limit ArticleComment.pinned_comment_limit() diff --git a/lib/groupher_server/cms/helper/macros.ex b/lib/groupher_server/cms/helper/macros.ex index 138c13ced..ae69b809e 100644 --- a/lib/groupher_server/cms/helper/macros.ex +++ b/lib/groupher_server/cms/helper/macros.ex @@ -2,13 +2,14 @@ defmodule GroupherServer.CMS.Helper.Macros do @moduledoc """ macros for define article related fields in CMS models """ + import Helper.Utils, only: [get_config: 2] alias GroupherServer.{CMS, Accounts} alias Accounts.User alias CMS.{Author, Community, ArticleComment, ArticleUpvote, ArticleCollect} - @article_threads Community.article_threads() + @article_threads get_config(:article, :article_threads) @doc """ generate belongs to fields for given thread diff --git a/lib/groupher_server/cms/helper/matcher2.ex b/lib/groupher_server/cms/helper/matcher2.ex index d9a9805c4..a25b72b19 100644 --- a/lib/groupher_server/cms/helper/matcher2.ex +++ b/lib/groupher_server/cms/helper/matcher2.ex @@ -2,11 +2,12 @@ defmodule GroupherServer.CMS.Helper.Matcher2.Macros do @moduledoc """ generate match functions """ + import Helper.Utils, only: [get_config: 2] alias GroupherServer.CMS alias CMS.{ArticleComment, Community, Embeds} - @article_threads Community.article_threads() + @article_threads get_config(:article, :article_threads) @doc """ match basic threads diff --git a/lib/groupher_server/cms/helper/utils.ex b/lib/groupher_server/cms/helper/utils.ex index 7d2acfca3..e2b797840 100644 --- a/lib/groupher_server/cms/helper/utils.ex +++ b/lib/groupher_server/cms/helper/utils.ex @@ -3,11 +3,12 @@ defmodule GroupherServer.CMS.Helper.Utils do utils for CMS helper """ import Ecto.Changeset + import Helper.Utils, only: [get_config: 2] alias GroupherServer.CMS alias CMS.Community - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) @article_fields @article_threads |> Enum.map(&:"#{&1}_id") @doc """ diff --git a/lib/groupher_server/cms/job.ex b/lib/groupher_server/cms/job.ex index fcb53dc8a..2b1da26cc 100644 --- a/lib/groupher_server/cms/job.ex +++ b/lib/groupher_server/cms/job.ex @@ -9,7 +9,7 @@ defmodule GroupherServer.CMS.Job do import GroupherServer.CMS.Helper.Macros alias GroupherServer.{CMS, Accounts} - alias CMS.{Author, Embeds, ArticleComment, Community, Tag, ArticleUpvote, ArticleCollect} + alias CMS.{Embeds, Tag} alias Helper.HTML @timestamps_opts [type: :utc_datetime_usec] @@ -50,13 +50,7 @@ defmodule GroupherServer.CMS.Job do on_replace: :delete ) - many_to_many( - :communities, - Community, - join_through: "communities_jobs", - on_replace: :delete - ) - + article_community_field(:job) general_article_fields() end diff --git a/lib/groupher_server/cms/pinned_article.ex b/lib/groupher_server/cms/pinned_article.ex index 4cfcdbf66..e5eb13491 100644 --- a/lib/groupher_server/cms/pinned_article.ex +++ b/lib/groupher_server/cms/pinned_article.ex @@ -3,14 +3,16 @@ defmodule GroupherServer.CMS.PinnedArticle do alias __MODULE__ use Ecto.Schema + import Ecto.Changeset + import Helper.Utils, only: [get_config: 2] import GroupherServer.CMS.Helper.Macros import GroupherServer.CMS.Helper.Utils, only: [articles_foreign_key_constraint: 1] alias GroupherServer.CMS alias CMS.Community - @article_threads CMS.Community.article_threads() + @article_threads get_config(:article, :article_threads) @required_fields ~w(community_id thread)a # @optional_fields ~w(post_id job_id repo_id)a diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index 931328583..2942a443c 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -9,7 +9,7 @@ defmodule GroupherServer.CMS.Post do import GroupherServer.CMS.Helper.Macros alias GroupherServer.CMS - alias CMS.{Embeds, Community, PostComment, Tag} + alias CMS.{Embeds, PostComment, Tag} alias Helper.HTML diff --git a/lib/groupher_server/cms/repo.ex b/lib/groupher_server/cms/repo.ex index 141f40cc3..3ecefa91c 100644 --- a/lib/groupher_server/cms/repo.ex +++ b/lib/groupher_server/cms/repo.ex @@ -8,9 +8,8 @@ defmodule GroupherServer.CMS.Repo do import Ecto.Changeset import GroupherServer.CMS.Helper.Macros - alias GroupherServer.{CMS, Accounts} - - alias CMS.{Embeds, Community, RepoContributor, RepoLang, Tag} + alias GroupherServer.CMS + alias CMS.{Embeds, RepoContributor, RepoLang, Tag} alias Helper.HTML @@ -51,13 +50,7 @@ defmodule GroupherServer.CMS.Repo do on_replace: :delete ) - many_to_many( - :communities, - Community, - join_through: "communities_repos", - on_replace: :delete - ) - + article_community_field(:repo) general_article_fields() end diff --git a/lib/groupher_server_web/resolvers/cms_resolver.ex b/lib/groupher_server_web/resolvers/cms_resolver.ex index 9c6fcdbee..14a06b29c 100644 --- a/lib/groupher_server_web/resolvers/cms_resolver.ex +++ b/lib/groupher_server_web/resolvers/cms_resolver.ex @@ -1,7 +1,6 @@ defmodule GroupherServerWeb.Resolvers.CMS do @moduledoc false - import GroupherServer.CMS.Helper.Matcher import ShortMaps import Ecto.Query, warn: false From 04896d02cfab535d96c7b3c44f56db88e26a37ff Mon Sep 17 00:00:00 2001 From: mydearxym Date: Mon, 17 May 2021 16:02:14 +0800 Subject: [PATCH 18/18] refactor: rm unused warning --- lib/groupher_server_web/resolvers/cms_resolver.ex | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/groupher_server_web/resolvers/cms_resolver.ex b/lib/groupher_server_web/resolvers/cms_resolver.ex index 14a06b29c..e7c437d27 100644 --- a/lib/groupher_server_web/resolvers/cms_resolver.ex +++ b/lib/groupher_server_web/resolvers/cms_resolver.ex @@ -214,10 +214,6 @@ defmodule GroupherServerWeb.Resolvers.CMS do CMS.set_tag(thread, %Tag{id: tag_id}, id) end - def set_refined_tag(_root, ~m(community_id thread id)a, _info) do - CMS.set_refined_tag(%Community{id: community_id}, thread, id) - end - def unset_tag(_root, ~m(id thread tag_id)a, _info) do CMS.unset_tag(thread, %Tag{id: tag_id}, id) end