diff --git a/config/config.exs b/config/config.exs index 607196a39..7a25dd0db 100644 --- a/config/config.exs +++ b/config/config.exs @@ -60,6 +60,34 @@ config :groupher_server, :customization, display_density: "20", sidebar_communities_index: %{} +config :groupher_server, :article, + emotionable_threads: [:post, :job], + # NOTE: if you want to add/remove emotion, just edit the list below + # and migrate the field to table "articles_users_emotions" + supported_emotions: [ + :upvote, + :downvote, + :beer, + :heart, + :biceps, + :orz, + :confused, + :pill, + :popcorn + ], + # NOTE: if you want to add/remove emotion, just edit the list below + # and migrate the field to table "articles_comments_users_emotions" + comment_supported_emotions: [ + :downvote, + :beer, + :heart, + :biceps, + :orz, + :confused, + :pill, + :popcorn + ] + config :groupher_server, GroupherServerWeb.Gettext, default_locale: "zh_CN", locales: ~w(en zh_CN) config :groupher_server, :cloud_assets, diff --git a/lib/groupher_server/cms/article_comment.ex b/lib/groupher_server/cms/article_comment.ex index 73e3191b0..ea8177991 100644 --- a/lib/groupher_server/cms/article_comment.ex +++ b/lib/groupher_server/cms/article_comment.ex @@ -25,9 +25,6 @@ defmodule GroupherServer.CMS.ArticleComment do @max_participator_count 5 @max_parent_replies_count 3 - # NOTE: if you want to add/remove emotion, just edit the list below - # and migrate the field to table "articles_comments_users_emotions" - @supported_emotions [:downvote, :beer, :heart, :biceps, :orz, :confused, :pill, :popcorn] @max_latest_emotion_users_count 5 @delete_hint "this comment is deleted" diff --git a/lib/groupher_server/cms/article_comment_user_emotion.ex b/lib/groupher_server/cms/article_comment_user_emotion.ex index 8bc30a8f1..82deccf8a 100644 --- a/lib/groupher_server/cms/article_comment_user_emotion.ex +++ b/lib/groupher_server/cms/article_comment_user_emotion.ex @@ -1,8 +1,7 @@ defmodule GroupherServer.CMS.ArticleCommentUserEmotion.Macros do - alias GroupherServer.CMS - alias CMS.ArticleComment + import Helper.Utils, only: [get_config: 2] - @supported_emotions ArticleComment.supported_emotions() + @supported_emotions get_config(:article, :comment_supported_emotions) defmacro emotion_fields() do @supported_emotions @@ -21,14 +20,14 @@ defmodule GroupherServer.CMS.ArticleCommentUserEmotion do use Ecto.Schema import Ecto.Changeset import GroupherServer.CMS.ArticleCommentUserEmotion.Macros + import Helper.Utils, only: [get_config: 2] alias GroupherServer.{Accounts, CMS} alias CMS.ArticleComment - @supported_emotions ArticleComment.supported_emotions() + @supported_emotions get_config(:article, :comment_supported_emotions) @required_fields ~w(article_comment_id user_id recived_user_id)a - # @optional_fields ~w(downvote beer heart biceps orz confused pill)a @optional_fields Enum.map(@supported_emotions, &:"#{&1}") @type t :: %ArticleCommentUserEmotion{} diff --git a/lib/groupher_server/cms/article_user_emotion.ex b/lib/groupher_server/cms/article_user_emotion.ex new file mode 100644 index 000000000..23a387940 --- /dev/null +++ b/lib/groupher_server/cms/article_user_emotion.ex @@ -0,0 +1,68 @@ +defmodule GroupherServer.CMS.ArticleUserEmotion.Macros do + import Helper.Utils, only: [get_config: 2] + + alias GroupherServer.CMS + + @supported_emotions get_config(:article, :supported_emotions) + + defmacro emotion_fields() do + @supported_emotions + |> Enum.map(fn emotion -> + quote do + field(unquote(:"#{emotion}"), :boolean, default: false) + end + end) + end +end + +defmodule GroupherServer.CMS.ArticleUserEmotion do + @moduledoc false + alias __MODULE__ + + use Ecto.Schema + import Ecto.Changeset + import GroupherServer.CMS.ArticleUserEmotion.Macros + import Helper.Utils, only: [get_config: 2] + + alias GroupherServer.{Accounts, CMS} + alias CMS.{Post, Job} + + @supported_emotions get_config(:article, :supported_emotions) + @supported_threads get_config(:article, :emotionable_threads) + + @required_fields ~w(user_id recived_user_id)a + @optional_fields Enum.map(@supported_threads, &:"#{&1}_id") ++ + Enum.map(@supported_emotions, &:"#{&1}") + + @type t :: %ArticleUserEmotion{} + schema "articles_users_emotions" do + belongs_to(:post, Post, foreign_key: :post_id) + belongs_to(:job, Job, foreign_key: :job_id) + belongs_to(:recived_user, Accounts.User, foreign_key: :recived_user_id) + belongs_to(:user, Accounts.User, foreign_key: :user_id) + + emotion_fields() + timestamps(type: :utc_datetime) + end + + @doc false + def changeset(%ArticleUserEmotion{} = struct, attrs) do + struct + |> cast(attrs, @required_fields ++ @optional_fields) + |> validate_required(@required_fields) + |> foreign_key_constraint(:post_id) + |> foreign_key_constraint(:job_id) + |> foreign_key_constraint(:user_id) + |> foreign_key_constraint(:recived_user_id) + end + + def update_changeset(%ArticleUserEmotion{} = struct, attrs) do + struct + |> cast(attrs, @required_fields ++ @optional_fields) + |> validate_required(@required_fields) + |> foreign_key_constraint(:post_id) + |> foreign_key_constraint(:job_id) + |> foreign_key_constraint(:user_id) + |> foreign_key_constraint(:recived_user_id) + end +end diff --git a/lib/groupher_server/cms/author.ex b/lib/groupher_server/cms/author.ex index 5dcbdaaf9..7947db553 100644 --- a/lib/groupher_server/cms/author.ex +++ b/lib/groupher_server/cms/author.ex @@ -7,15 +7,15 @@ defmodule GroupherServer.CMS.Author do import Ecto.Changeset - alias GroupherServer.{Accounts, CMS} - alias CMS.Post + alias GroupherServer.Accounts + # alias CMS.Post @type t :: %Author{} schema "cms_authors" do field(:role, :string) # field(:user_id, :id) - has_many(:posts, Post) + # has_many(:posts, Post) # user_id filed in own-table belongs_to(:user, Accounts.User) diff --git a/lib/groupher_server/cms/cms.ex b/lib/groupher_server/cms/cms.ex index c3e8b2562..0c0577280 100644 --- a/lib/groupher_server/cms/cms.ex +++ b/lib/groupher_server/cms/cms.ex @@ -11,6 +11,7 @@ defmodule GroupherServer.CMS do AbuseReport, ArticleCURD, ArticleOperation, + ArticleEmotion, ArticleReaction, ArticleComment, ArticleCommentAction, @@ -111,6 +112,9 @@ defmodule GroupherServer.CMS do defdelegate set_community(community, thread, content_id), to: ArticleOperation defdelegate unset_community(community, thread, content_id), to: ArticleOperation + defdelegate emotion_to_article(thread, article_id, args, user), to: ArticleEmotion + defdelegate undo_emotion_to_article(thread, article_id, args, user), to: ArticleEmotion + # Comment CURD defdelegate list_article_comments(thread, article_id, filters, mode), to: ArticleComment defdelegate list_article_comments(thread, article_id, filters, mode, user), to: ArticleComment diff --git a/lib/groupher_server/cms/delegates/article_comment.ex b/lib/groupher_server/cms/delegates/article_comment.ex index cc6d49345..dbd72b160 100644 --- a/lib/groupher_server/cms/delegates/article_comment.ex +++ b/lib/groupher_server/cms/delegates/article_comment.ex @@ -3,9 +3,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do CURD and operations for article comments """ import Ecto.Query, warn: false - import Helper.Utils, only: [done: 1] + import Helper.Utils, only: [done: 1, get_config: 2] import Helper.ErrorCode + import GroupherServer.CMS.Delegate.Helper, only: [mark_viewer_emotion_states: 3] import GroupherServer.CMS.Helper.Matcher2 import ShortMaps @@ -17,9 +18,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do alias CMS.{ArticleComment, ArticlePinedComment, Embeds} alias Ecto.Multi + @supported_emotions get_config(:article, :comment_supported_emotions) @max_participator_count ArticleComment.max_participator_count() @default_emotions Embeds.ArticleCommentEmotion.default_emotions() - @supported_emotions ArticleComment.supported_emotions() @delete_hint ArticleComment.delete_hint() @default_comment_meta Embeds.ArticleCommentMeta.default_meta() @@ -215,8 +216,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do # |> QueryBuilder.filter_pack(Map.merge(filters, %{sort: :asc_inserted})) |> QueryBuilder.filter_pack(Map.merge(filters, %{sort: sort})) |> ORM.paginater(~m(page size)a) - |> set_viewer_emotion_ifneed(user) |> add_pined_comments_ifneed(thread, article_id, filters) + |> mark_viewer_emotion_states(user, :comment) |> mark_viewer_has_upvoted(user) |> done() end @@ -233,7 +234,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do |> where(^where_query) |> QueryBuilder.filter_pack(filters) |> ORM.paginater(~m(page size)a) - |> set_viewer_emotion_ifneed(user) + |> mark_viewer_emotion_states(user, :comment) |> mark_viewer_has_upvoted(user) |> done() end @@ -273,30 +274,6 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do defp add_pined_comments_ifneed(paged_comments, _thread, _article_id, _), do: paged_comments - defp user_in_logins?([], _), do: false - defp user_in_logins?(ids_list, %User{login: login}), do: Enum.member?(ids_list, login) - - defp set_viewer_emotion_ifneed(paged_comments, nil), do: paged_comments - defp set_viewer_emotion_ifneed(%{entries: []} = paged_comments, _), do: paged_comments - - defp set_viewer_emotion_ifneed(%{entries: entries} = paged_comments, %User{} = user) do - new_entries = - Enum.map(entries, fn comment -> - update_viewed_status = - @supported_emotions - |> Enum.reduce([], fn emotion, acc -> - already_emotioned = user_in_logins?(comment.emotions[:"#{emotion}_user_logins"], user) - acc ++ ["viewer_has_#{emotion}ed": already_emotioned] - end) - |> Enum.into(%{}) - - updated_emotions = Map.merge(comment.emotions, update_viewed_status) - Map.put(comment, :emotions, updated_emotions) - end) - - %{paged_comments | entries: new_entries} - end - defp mark_viewer_has_upvoted(paged_comments, nil), do: paged_comments defp mark_viewer_has_upvoted(%{entries: entries} = paged_comments, %User{} = user) do diff --git a/lib/groupher_server/cms/delegates/article_comment_emotion.ex b/lib/groupher_server/cms/delegates/article_comment_emotion.ex index ce33c799b..113f6c31a 100644 --- a/lib/groupher_server/cms/delegates/article_comment_emotion.ex +++ b/lib/groupher_server/cms/delegates/article_comment_emotion.ex @@ -4,6 +4,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do """ import Ecto.Query, warn: false + import GroupherServer.CMS.Delegate.Helper, only: [update_emotions_field: 4] + alias Helper.ORM alias GroupherServer.{Accounts, CMS, Repo} @@ -15,8 +17,6 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do @type t_user_list :: [%{login: String.t()}] @type t_mention_status :: %{user_list: t_user_list, user_count: Integer.t()} - @max_latest_emotion_users_count ArticleComment.max_latest_emotion_users_count() - @doc "make emotion to a comment" def emotion_to_comment(comment_id, emotion, %User{} = user) do with {:ok, comment} <- ORM.find(ArticleComment, comment_id, preload: :author) do @@ -31,18 +31,18 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do args = Map.put(target, :"#{emotion}", true) case ORM.find_by(ArticleCommentUserEmotion, target) do - {:ok, article_comment_user_emotion} -> article_comment_user_emotion |> ORM.update(args) - {:error, _} -> ArticleCommentUserEmotion |> ORM.create(args) + {:ok, article_comment_user_emotion} -> ORM.update(article_comment_user_emotion, args) + {:error, _} -> ORM.create(ArticleCommentUserEmotion, args) end end) - |> Multi.run(:query_emotion_status, fn _, _ -> - query_emotion_status(comment, emotion) + |> Multi.run(:query_emotion_states, fn _, _ -> + query_emotion_states(comment, emotion) end) - |> Multi.run(:update_comment_emotion, fn _, %{query_emotion_status: status} -> - update_comment_emotion(comment, emotion, status, user) + |> Multi.run(:update_emotions_field, fn _, %{query_emotion_states: status} -> + update_emotions_field(comment, emotion, status, user) end) |> Repo.transaction() - |> update_emotion_result + |> update_emotions_field_result end end @@ -56,23 +56,28 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do user_id: user.id } - {:ok, article_comment_user_emotion} = ORM.find_by(ArticleCommentUserEmotion, target) - args = Map.put(target, :"#{emotion}", false) - article_comment_user_emotion |> ORM.update(args) + case ORM.find_by(ArticleCommentUserEmotion, target) do + {:ok, article_comment_user_emotion} -> + args = Map.put(target, :"#{emotion}", false) + article_comment_user_emotion |> ORM.update(args) + + {:error, _} -> + ORM.create(ArticleCommentUserEmotion, target) + end end) - |> Multi.run(:query_emotion_status, fn _, _ -> - query_emotion_status(comment, emotion) + |> Multi.run(:query_emotion_states, fn _, _ -> + query_emotion_states(comment, emotion) end) - |> Multi.run(:update_comment_emotion, fn _, %{query_emotion_status: status} -> - update_comment_emotion(comment, emotion, status, user) + |> Multi.run(:update_emotions_field, fn _, %{query_emotion_states: status} -> + update_emotions_field(comment, emotion, status, user) end) |> Repo.transaction() - |> update_emotion_result + |> update_emotions_field_result end end - @spec query_emotion_status(ArticleComment.t(), Atom.t()) :: {:ok, t_mention_status} - defp query_emotion_status(comment, emotion) do + @spec query_emotion_states(ArticleComment.t(), Atom.t()) :: {:ok, t_mention_status} + defp query_emotion_states(comment, emotion) do # 每次被 emotion 动作触发后重新查询,主要原因 # 1.并发下保证数据准确,类似 views 阅读数的统计 # 2. 前端使用 nickname 而非 login 展示,如果用户改了 nickname, 可以"自动纠正" @@ -91,41 +96,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do {:ok, %{user_list: emotioned_user_info_list, user_count: emotioned_user_count}} end - @spec update_comment_emotion(ArticleComment.t(), Atom.t(), t_mention_status, User.t()) :: - {:ok, ArticleComment.t()} | {:error, any} - defp update_comment_emotion(comment, emotion, status, user) do - %{user_count: user_count, user_list: user_list} = status - - emotions = - %{} - |> Map.put(:"#{emotion}_count", user_count) - |> Map.put(:"#{emotion}_user_logins", user_list |> Enum.map(& &1.login)) - |> Map.put( - :"latest_#{emotion}_users", - Enum.slice(user_list, 0, @max_latest_emotion_users_count) - ) - - viewer_has_emotioned = user.login in Map.get(emotions, :"#{emotion}_user_logins") - emotions = emotions |> Map.put(:"viewer_has_#{emotion}ed", viewer_has_emotioned) - - comment - |> Ecto.Changeset.change() - |> Ecto.Changeset.put_embed(:emotions, emotions) - |> Repo.update() - # virtual field can not be updated - |> add_viewer_emotioned_ifneed(emotions) - end - - defp add_viewer_emotioned_ifneed({:error, error}, _), do: {:error, error} - - defp add_viewer_emotioned_ifneed({:ok, comment}, emotions) do - # Map.merge(comment, %{emotion: emotions}) - {:ok, Map.merge(comment, %{emotion: emotions})} - end - - defp update_emotion_result({:ok, %{update_comment_emotion: result}}), do: {:ok, result} + defp update_emotions_field_result({:ok, %{update_emotions_field: result}}), do: {:ok, result} - defp update_emotion_result({:error, _, result, _steps}) do + defp update_emotions_field_result({:error, _, result, _steps}) do {:error, result} end end diff --git a/lib/groupher_server/cms/delegates/article_curd.ex b/lib/groupher_server/cms/delegates/article_curd.ex index fcf0aa81a..ceea9d7ca 100644 --- a/lib/groupher_server/cms/delegates/article_curd.ex +++ b/lib/groupher_server/cms/delegates/article_curd.ex @@ -8,9 +8,11 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do import GroupherServer.CMS.Helper.Matcher, only: [match_action: 2] import Helper.Utils, only: [done: 1, pick_by: 2, integerfy: 1, strip_struct: 1] + import GroupherServer.CMS.Delegate.Helper, only: [mark_viewer_emotion_states: 2] import Helper.ErrorCode + import ShortMaps - alias Helper.{Later, ORM} + alias Helper.{Later, ORM, QueryBuilder} alias GroupherServer.{Accounts, CMS, Delivery, Email, Repo, Statistics} alias Accounts.User @@ -20,6 +22,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do alias Ecto.Multi + @default_emotions Embeds.ArticleEmotion.default_emotions() @default_article_meta Embeds.ArticleMeta.default_meta() @doc """ @@ -49,31 +52,40 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do end def paged_articles(thread, filter) do + %{page: page, size: size} = filter + with {:ok, info} <- match(thread) do info.model |> domain_filter_query(filter) |> community_with_flag_query(filter) - |> ORM.find_all(filter) + |> QueryBuilder.filter_pack(filter) + |> ORM.paginater(~m(page size)a) |> add_pin_contents_ifneed(info.model, filter) + |> done() end end def paged_articles(thread, filter, %User{} = user) do + %{page: page, size: size} = filter + with {:ok, info} <- match(thread) do info.model |> domain_filter_query(filter) |> community_with_flag_query(filter) - |> ORM.find_all(filter) + |> QueryBuilder.filter_pack(filter) + |> ORM.paginater(~m(page size)a) |> add_pin_contents_ifneed(info.model, filter) + |> mark_viewer_emotion_states(user) |> mark_viewer_has_states(user) + |> done() end end - defp mark_viewer_has_states({:ok, %{entries: []} = contents}, _), do: {:ok, contents} + defp mark_viewer_has_states(%{entries: []} = contents, _), do: contents - defp mark_viewer_has_states({:ok, %{entries: entries} = contents}, user) do + defp mark_viewer_has_states(%{entries: entries} = contents, user) do entries = Enum.map(entries, &Map.merge(&1, do_mark_viewer_has_states(&1.meta, user))) - {:ok, Map.merge(contents, %{entries: entries})} + Map.merge(contents, %{entries: entries}) end defp mark_viewer_has_states({:error, reason}, _), do: {:error, reason} @@ -288,26 +300,23 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do defp domain_filter_query(queryable, _filter), do: queryable - defp add_pin_contents_ifneed(contents, querable, %{community: _community} = filter) do + defp add_pin_contents_ifneed(contents, querable, %{community: community} = filter) do with {:ok, _} <- should_add_pin?(filter), {:ok, info} <- match(querable), - {:ok, normal_contents} <- contents, - true <- Map.has_key?(filter, :community), - true <- 1 == Map.get(normal_contents, :page_number) do - {:ok, pined_content} = + true <- 1 == Map.get(contents, :page_number) do + {:ok, pinned_articles} = PinnedArticle |> join(:inner, [p], c in assoc(p, :community)) - |> join(:inner, [p], content in assoc(p, ^info.thread)) - |> where([p, c, content], c.raw == ^filter.community) - |> select([p, c, content], content) + # |> join(:inner, [p], article in assoc(p, ^filter.thread)) + |> join(:inner, [p], article in assoc(p, ^info.thread)) + |> where([p, c, article], c.raw == ^community) + |> select([p, c, article], article) # 10 pined contents per community/thread, at most - |> ORM.paginater(%{page: 1, size: 10}) - |> done() + |> ORM.find_all(%{page: 1, size: 10}) - concat_contents(pined_content, normal_contents) + concat_contents(pinned_articles, contents) else - _error -> - contents + _error -> contents end end @@ -315,22 +324,16 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do # if filter contains like: tags, sort.., then don't add pin content defp should_add_pin?(%{page: 1, tag: :all, sort: :desc_inserted} = filter) do - filter - |> Map.keys() - |> Enum.reject(fn x -> x in [:community, :tag, :sort, :page, :size] end) - |> case do - [] -> {:ok, :pass} - _ -> {:error, :pass} - end + {:ok, :pass} end defp should_add_pin?(_filter), do: {:error, :pass} - defp concat_contents(%{total_count: 0}, normal_contents), do: {:ok, normal_contents} + defp concat_contents(%{total_count: 0}, normal_contents), do: normal_contents - defp concat_contents(pined_content, normal_contents) do + defp concat_contents(pinned_articles, normal_contents) do pind_entries = - pined_content + pinned_articles |> Map.get(:entries) |> Enum.map(&struct(&1, %{is_pinned: true})) @@ -348,7 +351,6 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do # those two are equals # |> Map.put(:total_count, pind_count + normal_count - pind_count) |> Map.put(:total_count, normal_count) - |> done end defp create_content_result({:ok, %{create_content: result}}) do @@ -389,6 +391,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do target |> struct() |> target.changeset(attrs) + |> Ecto.Changeset.put_change(:emotions, @default_emotions) |> Ecto.Changeset.put_change(:author_id, aid) |> Ecto.Changeset.put_change(:origial_community_id, integerfy(cid)) |> Ecto.Changeset.put_embed(:meta, @default_article_meta) diff --git a/lib/groupher_server/cms/delegates/article_emotion.ex b/lib/groupher_server/cms/delegates/article_emotion.ex new file mode 100644 index 000000000..599c3a2af --- /dev/null +++ b/lib/groupher_server/cms/delegates/article_emotion.ex @@ -0,0 +1,107 @@ +defmodule GroupherServer.CMS.Delegate.ArticleEmotion do + @moduledoc """ + CURD and operations for article comments + """ + import Ecto.Query, warn: false + import GroupherServer.CMS.Helper.Matcher2 + + import GroupherServer.CMS.Delegate.Helper, only: [update_emotions_field: 4] + + alias Helper.ORM + alias GroupherServer.{Accounts, CMS, Repo} + + alias Accounts.User + alias CMS.{ArticleUserEmotion} + + alias Ecto.Multi + + @type t_user_list :: [%{login: String.t()}] + @type t_mention_status :: %{user_list: t_user_list, user_count: Integer.t()} + + @doc "make emotion to a comment" + def emotion_to_article(thread, article_id, emotion, %User{} = user) do + with {:ok, info} <- match(thread), + {:ok, article} <- ORM.find(info.model, article_id, preload: :author) do + Multi.new() + |> Multi.run(:create_user_emotion, fn _, _ -> + target = + %{recived_user_id: article.author.user_id, user_id: user.id} + |> Map.put(info.foreign_key, article_id) + + args = Map.put(target, :"#{emotion}", true) + + case ORM.find_by(ArticleUserEmotion, target) do + {:ok, article_user_emotion} -> ORM.update(article_user_emotion, args) + {:error, _} -> ORM.create(ArticleUserEmotion, args) + end + end) + |> Multi.run(:query_emotion_status, fn _, _ -> + query_emotion_status(thread, article.id, emotion) + end) + |> Multi.run(:update_emotions_field, fn _, %{query_emotion_status: status} -> + update_emotions_field(article, emotion, status, user) + end) + |> Repo.transaction() + |> update_emotions_field_result + end + end + + def undo_emotion_to_article(thread, article_id, emotion, %User{} = user) do + with {:ok, info} <- match(thread), + {:ok, article} <- ORM.find(info.model, article_id, preload: :author) do + Multi.new() + |> Multi.run(:update_user_emotion, fn _, _ -> + target = + %{recived_user_id: article.author.user_id, user_id: user.id} + |> Map.put(info.foreign_key, article_id) + + case ORM.find_by(ArticleUserEmotion, target) do + {:ok, article_user_emotion} -> + args = Map.put(target, :"#{emotion}", false) + article_user_emotion |> ORM.update(args) + + {:error, _} -> + # args = Map.put(target, :"#{emotion}", false) + args = target + ORM.create(ArticleUserEmotion, args) + end + end) + |> Multi.run(:query_emotion_status, fn _, _ -> + query_emotion_status(thread, article.id, emotion) + end) + |> Multi.run(:update_emotions_field, fn _, %{query_emotion_status: status} -> + update_emotions_field(article, emotion, status, user) + end) + |> Repo.transaction() + |> update_emotions_field_result + end + end + + # @spec query_emotion_status(ArticleComment.t(), Atom.t()) :: {:ok, t_mention_status} + defp query_emotion_status(thread, article_id, emotion) do + with {:ok, info} <- match(thread) do + # 每次被 emotion 动作触发后重新查询,主要原因 + # 1.并发下保证数据准确,类似 views 阅读数的统计 + # 2. 前端使用 nickname 而非 login 展示,如果用户改了 nickname, 可以"自动纠正" + query = + from(a in ArticleUserEmotion, + join: user in User, + on: a.user_id == user.id, + where: field(a, ^info.foreign_key) == ^article_id, + where: field(a, ^emotion) == true, + select: %{login: user.login, nickname: user.nickname} + ) + + emotioned_user_info_list = Repo.all(query) |> Enum.uniq() + emotioned_user_count = length(emotioned_user_info_list) + + {:ok, %{user_list: emotioned_user_info_list, user_count: emotioned_user_count}} + end + end + + defp update_emotions_field_result({:ok, %{update_emotions_field: result}}), do: {:ok, result} + + defp update_emotions_field_result({:error, _, result, _steps}) do + {:error, result} + end +end diff --git a/lib/groupher_server/cms/delegates/helper.ex b/lib/groupher_server/cms/delegates/helper.ex new file mode 100644 index 000000000..aa677c3bd --- /dev/null +++ b/lib/groupher_server/cms/delegates/helper.ex @@ -0,0 +1,86 @@ +defmodule GroupherServer.CMS.Delegate.Helper do + @moduledoc """ + helpers for GroupherServer.CMS.Delegate + """ + import Helper.Utils, only: [get_config: 2, done: 1] + + alias GroupherServer.{Accounts, Repo} + alias Accounts.User + + # TODO: + # @max_latest_emotion_users_count ArticleComment.max_latest_emotion_users_count() + @max_latest_emotion_users_count 4 + @supported_emotions get_config(:article, :supported_emotions) + @supported_comment_emotions get_config(:article, :comment_supported_emotions) + + defp get_supported_mentions(:comment), do: @supported_comment_emotions + defp get_supported_mentions(_), do: @supported_emotions + + def mark_viewer_emotion_states(paged_contents, nil), do: paged_contents + def mark_viewer_emotion_states(paged_contents, nil, :comment), do: paged_contents + def mark_viewer_emotion_states(%{entries: []} = paged_contents, _), do: paged_contents + + @doc """ + mark viewer emotions status for article or comment + """ + def mark_viewer_emotion_states( + %{entries: entries} = paged_contents, + %User{} = user, + type \\ :article + ) do + IO.inspect("hello?") + supported_emotions = get_supported_mentions(type) + + new_entries = + Enum.map(entries, fn article -> + update_viewed_status = + supported_emotions + |> Enum.reduce([], fn emotion, acc -> + already_emotioned = user_in_logins?(article.emotions[:"#{emotion}_user_logins"], user) + acc ++ ["viewer_has_#{emotion}ed": already_emotioned] + end) + |> Enum.into(%{}) + + updated_emotions = Map.merge(article.emotions, update_viewed_status) + Map.put(article, :emotions, updated_emotions) + end) + + %{paged_contents | entries: new_entries} + end + + @doc """ + update emotions field for boty article and comment + """ + def update_emotions_field(content, emotion, status, user) do + %{user_count: user_count, user_list: user_list} = status + + emotions = + %{} + |> Map.put(:"#{emotion}_count", user_count) + |> Map.put(:"#{emotion}_user_logins", user_list |> Enum.map(& &1.login)) + |> Map.put( + :"latest_#{emotion}_users", + Enum.slice(user_list, 0, @max_latest_emotion_users_count) + ) + + viewer_has_emotioned = user.login in Map.get(emotions, :"#{emotion}_user_logins") + emotions = emotions |> Map.put(:"viewer_has_#{emotion}ed", viewer_has_emotioned) + + content + |> Ecto.Changeset.change() + |> Ecto.Changeset.put_embed(:emotions, emotions) + |> Repo.update() + # virtual field can not be updated + |> add_viewer_emotioned_ifneed(emotions) + |> done + end + + defp add_viewer_emotioned_ifneed({:error, error}, _), do: {:error, error} + + defp add_viewer_emotioned_ifneed({:ok, comment}, emotions) do + Map.merge(comment, %{emotion: emotions}) + end + + defp user_in_logins?([], _), do: false + defp user_in_logins?(ids_list, %User{login: login}), do: Enum.member?(ids_list, login) +end diff --git a/lib/groupher_server/cms/embeds/article_comment_emotion.ex b/lib/groupher_server/cms/embeds/article_comment_emotion.ex index 3eda03378..35bf3e888 100644 --- a/lib/groupher_server/cms/embeds/article_comment_emotion.ex +++ b/lib/groupher_server/cms/embeds/article_comment_emotion.ex @@ -8,10 +8,12 @@ defmodule GroupherServer.CMS.Embeds.ArticleCommentEmotion.Macros do field(:viewer_has_beered, :boolean, default: false, virtual: true) embeds_many(:latest_beer_users, Embeds.User, on_replace: :delete) """ + import Helper.Utils, only: [get_config: 2] + alias GroupherServer.CMS - alias CMS.{ArticleComment, Embeds} + alias CMS.Embeds - @supported_emotions ArticleComment.supported_emotions() + @supported_emotions get_config(:article, :comment_supported_emotions) defmacro emotion_fields() do @supported_emotions @@ -35,11 +37,9 @@ defmodule GroupherServer.CMS.Embeds.ArticleCommentEmotion do import Ecto.Changeset import GroupherServer.CMS.Embeds.ArticleCommentEmotion.Macros + import Helper.Utils, only: [get_config: 2] - alias GroupherServer.CMS.ArticleComment - - @supported_emotions ArticleComment.supported_emotions() - + @supported_emotions get_config(:article, :comment_supported_emotions) @optional_fields Enum.map(@supported_emotions, &:"#{&1}_count") ++ Enum.map(@supported_emotions, &:"#{&1}_user_logins") diff --git a/lib/groupher_server/cms/embeds/article_emotion.ex b/lib/groupher_server/cms/embeds/article_emotion.ex new file mode 100644 index 000000000..694c11718 --- /dev/null +++ b/lib/groupher_server/cms/embeds/article_emotion.ex @@ -0,0 +1,74 @@ +defmodule GroupherServer.CMS.Embeds.ArticleEmotion.Macros do + @moduledoc """ + general fields for each emotion + + e.g: + field(:beer_count, :integer, default: 0) + field(:beer_user_logins, :string) + field(:viewer_has_beered, :boolean, default: false, virtual: true) + embeds_many(:latest_beer_users, Embeds.User, on_replace: :delete) + """ + import Helper.Utils, only: [get_config: 2] + + alias GroupherServer.CMS + alias CMS.Embeds + + @supported_emotions get_config(:article, :supported_emotions) + + defmacro emotion_fields() do + @supported_emotions + |> Enum.map(fn emotion -> + quote do + field(unquote(:"#{emotion}_count"), :integer, default: 0) + field(unquote(:"#{emotion}_user_logins"), {:array, :string}, default: []) + field(unquote(:"viewer_has_#{emotion}ed"), :boolean, default: false, virtual: true) + embeds_many(unquote(:"latest_#{emotion}_users"), Embeds.User, on_replace: :delete) + end + end) + end +end + +defmodule GroupherServer.CMS.Embeds.ArticleEmotion do + @moduledoc """ + general article meta info for article-like content, like post, job, works ... + """ + use Ecto.Schema + use Accessible + + import Ecto.Changeset + import GroupherServer.CMS.Embeds.ArticleEmotion.Macros + import Helper.Utils, only: [get_config: 2] + + @supported_emotions get_config(:article, :supported_emotions) + + @optional_fields Enum.map(@supported_emotions, &:"#{&1}_count") ++ + Enum.map(@supported_emotions, &:"#{&1}_user_logins") + + @doc "default emotion status for article comment" + # for create comment and test usage + def default_emotions() do + @supported_emotions + |> Enum.reduce([], fn emotion, acc -> + acc ++ + [ + "#{emotion}_count": 0, + "latest_#{emotion}_users": [], + "#{emotion}_user_logins": [], + "viewer_has_#{emotion}ed": false + ] + end) + |> Enum.into(%{}) + end + + embedded_schema do + emotion_fields() + end + + def changeset(struct, params) do + struct + |> cast(params, @optional_fields) + + # |> cast_embed(:latest_downvote_users, required: false, with: &Embeds.User.changeset/2) + # |> ... + end +end diff --git a/lib/groupher_server/cms/job.ex b/lib/groupher_server/cms/job.ex index 0cfbeaaf3..51f62046a 100644 --- a/lib/groupher_server/cms/job.ex +++ b/lib/groupher_server/cms/job.ex @@ -70,6 +70,8 @@ defmodule GroupherServer.CMS.Job do # 评论参与者,只保留最近 5 个 embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete) + embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) + many_to_many( :tags, Tag, @@ -114,6 +116,7 @@ defmodule GroupherServer.CMS.Job do content |> validate_length(:title, min: 3, max: 50) |> validate_length(:body, min: 3, max: 10_000) + # |> cast_embed(:emotions, with: &Embeds.ArticleEmotion.changeset/2) |> HTML.safe_string(:body) end end diff --git a/lib/groupher_server/cms/post.ex b/lib/groupher_server/cms/post.ex index fcd20c3d3..336d15fbf 100644 --- a/lib/groupher_server/cms/post.ex +++ b/lib/groupher_server/cms/post.ex @@ -72,6 +72,8 @@ defmodule GroupherServer.CMS.Post do # 评论参与者,只保留最近 5 个 embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete) + embeds_one(:emotions, Embeds.ArticleEmotion, on_replace: :update) + # The keys are inflected from the schema names! # see https://hexdocs.pm/ecto/Ecto.Schema.html many_to_many( @@ -118,6 +120,7 @@ defmodule GroupherServer.CMS.Post do defp generl_changeset(content) do content |> 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) diff --git a/lib/groupher_server/cms/repo.ex b/lib/groupher_server/cms/repo.ex index 6ccd4408c..c24c879c6 100644 --- a/lib/groupher_server/cms/repo.ex +++ b/lib/groupher_server/cms/repo.ex @@ -53,6 +53,7 @@ defmodule GroupherServer.CMS.Repo do 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) has_many(:community_flags, {"repos_communities_flags", RepoCommunityFlag}) diff --git a/lib/groupher_server_web/middleware/pagesize_proof.ex b/lib/groupher_server_web/middleware/pagesize_proof.ex index ad9431eb5..a990486c1 100644 --- a/lib/groupher_server_web/middleware/pagesize_proof.ex +++ b/lib/groupher_server_web/middleware/pagesize_proof.ex @@ -45,11 +45,8 @@ defmodule GroupherServerWeb.Middleware.PageSizeProof do def call(resolution, _) do case valid_size(resolution.arguments) do - {:error, msg} -> - resolution |> handle_absinthe_error(msg, ecode(:pagination)) - - arguments -> - %{resolution | arguments: sort_desc_by_default(arguments)} + {:error, msg} -> resolution |> handle_absinthe_error(msg, ecode(:pagination)) + arguments -> %{resolution | arguments: sort_desc_by_default(arguments)} end end diff --git a/lib/groupher_server_web/resolvers/cms_resolver.ex b/lib/groupher_server_web/resolvers/cms_resolver.ex index 0e534db87..d3937feca 100644 --- a/lib/groupher_server_web/resolvers/cms_resolver.ex +++ b/lib/groupher_server_web/resolvers/cms_resolver.ex @@ -55,6 +55,7 @@ defmodule GroupherServerWeb.Resolvers.CMS do end def paged_articles(_root, ~m(thread filter)a, %{context: %{cur_user: user}}) do + IO.inspect(filter, label: "the filter") CMS.paged_articles(thread, filter, user) end @@ -128,6 +129,14 @@ defmodule GroupherServerWeb.Resolvers.CMS do CMS.collected_users(thread, id, filter) end + def emotion_to_article(_root, ~m(id thread emotion)a, %{context: %{cur_user: user}}) do + CMS.emotion_to_article(thread, id, emotion, user) + end + + def undo_emotion_to_article(_root, ~m(id thread emotion)a, %{context: %{cur_user: user}}) do + CMS.undo_emotion_to_article(thread, id, emotion, user) + end + # ####################### # category .. # ####################### diff --git a/lib/groupher_server_web/schema/Helper/fields.ex b/lib/groupher_server_web/schema/Helper/fields.ex index 4fbae7e5c..4959c24ee 100644 --- a/lib/groupher_server_web/schema/Helper/fields.ex +++ b/lib/groupher_server_web/schema/Helper/fields.ex @@ -5,10 +5,10 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do import Helper.Utils, only: [get_config: 2] alias GroupherServer.{Accounts, CMS} - alias CMS.{ArticleComment} @page_size get_config(:general, :page_size) - @supported_emotions ArticleComment.supported_emotions() + @supported_emotions get_config(:article, :supported_emotions) + @supported_comment_emotions get_config(:article, :comment_supported_emotions) @supported_collect_folder_threads Accounts.CollectFolder.supported_threads() defmacro timestamp_fields do @@ -193,7 +193,7 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do end @doc """ - general emotion enum for comments + general emotion enum for articles #NOTE: xxx_user_logins field is not support for gq-endpoint """ defmacro emotion_enum() do @@ -206,7 +206,20 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do end @doc """ - general emotions for comments + general emotion enum for comments + #NOTE: xxx_user_logins field is not support for gq-endpoint + """ + defmacro comment_emotion_enum() do + @supported_comment_emotions + |> Enum.map(fn emotion -> + quote do + value(unquote(:"#{emotion}")) + end + end) + end + + @doc """ + general emotions for articles #NOTE: xxx_user_logins field is not support for gq-endpoint """ defmacro emotion_fields() do @@ -220,6 +233,21 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do end) end + @doc """ + general emotions for comments + #NOTE: xxx_user_logins field is not support for gq-endpoint + """ + defmacro comment_emotion_fields() do + @supported_comment_emotions + |> Enum.map(fn emotion -> + quote do + field(unquote(:"#{emotion}_count"), :integer) + field(unquote(:"viewer_has_#{emotion}ed"), :boolean) + field(unquote(:"latest_#{emotion}_users"), list_of(:simple_user)) + end + end) + end + @doc """ general collect folder meta info """ diff --git a/lib/groupher_server_web/schema/Helper/mutations.ex b/lib/groupher_server_web/schema/Helper/mutations.ex index e4cc7034f..4efeebfd0 100644 --- a/lib/groupher_server_web/schema/Helper/mutations.ex +++ b/lib/groupher_server_web/schema/Helper/mutations.ex @@ -100,4 +100,28 @@ defmodule GroupherServerWeb.Schema.Helper.Mutations do end end end + + defmacro article_emotion_mutation(thread) do + quote do + @desc unquote("emotion to #{thread}") + field unquote(:"emotion_to_#{thread}"), unquote(thread) do + arg(:id, non_null(:id)) + arg(:emotion, non_null(:article_emotion)) + arg(:thread, unquote(:"#{thread}_thread"), default_value: unquote(thread)) + + middleware(M.Authorize, :login) + resolve(&R.CMS.emotion_to_article/3) + end + + @desc unquote("undo emotion to #{thread}") + field unquote(:"undo_emotion_to_#{thread}"), unquote(thread) do + arg(:id, non_null(:id)) + arg(:emotion, non_null(:article_emotion)) + arg(:thread, unquote(:"#{thread}_thread"), default_value: unquote(thread)) + + middleware(M.Authorize, :login) + resolve(&R.CMS.undo_emotion_to_article/3) + end + end + end end diff --git a/lib/groupher_server_web/schema/cms/cms_misc.ex b/lib/groupher_server_web/schema/cms/cms_misc.ex index 986342a6e..3e8c92f8b 100644 --- a/lib/groupher_server_web/schema/cms/cms_misc.ex +++ b/lib/groupher_server_web/schema/cms/cms_misc.ex @@ -153,10 +153,11 @@ defmodule GroupherServerWeb.Schema.CMS.Misc do value(:grey) end + @desc "emotion options of article" + enum(:article_emotion, do: emotion_enum()) + @desc "emotion options of comment" - enum :article_comment_emotion do - emotion_enum() - end + enum(:article_comment_emotion, do: comment_emotion_enum()) @desc "the filter mode for list comments" enum :article_comments_mode do diff --git a/lib/groupher_server_web/schema/cms/cms_queries.ex b/lib/groupher_server_web/schema/cms/cms_queries.ex index e5b71a932..838b9a733 100644 --- a/lib/groupher_server_web/schema/cms/cms_queries.ex +++ b/lib/groupher_server_web/schema/cms/cms_queries.ex @@ -79,10 +79,6 @@ defmodule GroupherServerWeb.Schema.CMS.Queries do resolve(&R.CMS.cheatsheet/3) end - article_queries(:post) - article_queries(:job) - article_queries(:repo) - article_reacted_users_query(:upvot, &R.CMS.upvoted_users/3) article_reacted_users_query(:collect, &R.CMS.collected_users/3) @@ -207,5 +203,9 @@ defmodule GroupherServerWeb.Schema.CMS.Queries do resolve(&R.CMS.search_items/3) end + + article_queries(:post) + article_queries(:job) + article_queries(:repo) end end diff --git a/lib/groupher_server_web/schema/cms/cms_types.ex b/lib/groupher_server_web/schema/cms/cms_types.ex index a60a3c751..e865c9167 100644 --- a/lib/groupher_server_web/schema/cms/cms_types.ex +++ b/lib/groupher_server_web/schema/cms/cms_types.ex @@ -44,6 +44,7 @@ defmodule GroupherServerWeb.Schema.CMS.Types do field(:communities, list_of(:community), resolve: dataloader(CMS, :communities)) field(:meta, :article_meta) + field(:emotions, :article_emotions) field :comments, list_of(:comment) do arg(:filter, :members_filter) @@ -99,6 +100,7 @@ defmodule GroupherServerWeb.Schema.CMS.Types do field(:communities, list_of(:community), resolve: dataloader(CMS, :communities)) field(:meta, :article_meta) + field(:emotions, :article_emotions) field(:salary, :string) field(:exp, :string) @@ -316,6 +318,10 @@ defmodule GroupherServerWeb.Schema.CMS.Types do end object :article_comment_emotions do + comment_emotion_fields() + end + + object :article_emotions do emotion_fields() end diff --git a/lib/groupher_server_web/schema/cms/mutations/job.ex b/lib/groupher_server_web/schema/cms/mutations/job.ex index 942baf6bb..69eb489c7 100644 --- a/lib/groupher_server_web/schema/cms/mutations/job.ex +++ b/lib/groupher_server_web/schema/cms/mutations/job.ex @@ -75,6 +75,7 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Job do article_pin_mutation(:job) article_trash_mutation(:job) article_delete_mutation(:job) + article_emotion_mutation(:job) ############# end end diff --git a/lib/groupher_server_web/schema/cms/mutations/post.ex b/lib/groupher_server_web/schema/cms/mutations/post.ex index e4b6b0ff2..a662556fc 100644 --- a/lib/groupher_server_web/schema/cms/mutations/post.ex +++ b/lib/groupher_server_web/schema/cms/mutations/post.ex @@ -49,6 +49,7 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Post do article_pin_mutation(:post) article_trash_mutation(:post) article_delete_mutation(:post) + article_emotion_mutation(:post) ############# end end diff --git a/priv/repo/migrations/20210510005623_add_emotions_to_post.exs b/priv/repo/migrations/20210510005623_add_emotions_to_post.exs new file mode 100644 index 000000000..6e10dc11b --- /dev/null +++ b/priv/repo/migrations/20210510005623_add_emotions_to_post.exs @@ -0,0 +1,9 @@ +defmodule GroupherServer.Repo.Migrations.AddEmotionsToPost do + use Ecto.Migration + + def change do + alter table(:cms_posts) do + add(:emotions, :map) + end + end +end diff --git a/priv/repo/migrations/20210510020858_create_article_user_emotion.exs b/priv/repo/migrations/20210510020858_create_article_user_emotion.exs new file mode 100644 index 000000000..ad247cada --- /dev/null +++ b/priv/repo/migrations/20210510020858_create_article_user_emotion.exs @@ -0,0 +1,25 @@ +defmodule GroupherServer.Repo.Migrations.CreateArticleUserEmotion do + use Ecto.Migration + + def change do + create table(:articles_users_emotions) do + add(:post_id, references(:cms_posts, on_delete: :delete_all)) + add(:job_id, references(:cms_jobs, on_delete: :delete_all)) + + add(:user_id, references(:users, on_delete: :delete_all), null: false) + add(:recived_user_id, references(:users, on_delete: :delete_all), null: false) + + add(:upvote, :boolean, default: false) + add(:downvote, :boolean, default: false) + add(:beer, :boolean, default: false) + add(:heart, :boolean, default: false) + add(:biceps, :boolean, default: false) + add(:orz, :boolean, default: false) + add(:confused, :boolean, default: false) + add(:pill, :boolean, default: false) + add(:popcorn, :boolean, default: false) + + timestamps() + end + end +end diff --git a/priv/repo/migrations/20210510060205_add_emotions_to_cms_jobs.exs b/priv/repo/migrations/20210510060205_add_emotions_to_cms_jobs.exs new file mode 100644 index 000000000..c41c98e58 --- /dev/null +++ b/priv/repo/migrations/20210510060205_add_emotions_to_cms_jobs.exs @@ -0,0 +1,9 @@ +defmodule GroupherServer.Repo.Migrations.AddEmotionsToCmsJobs do + use Ecto.Migration + + def change do + alter table(:cms_jobs) do + add(:emotions, :map) + end + end +end diff --git a/priv/repo/migrations/20210510090556_add_emotions_to_repo.exs b/priv/repo/migrations/20210510090556_add_emotions_to_repo.exs new file mode 100644 index 000000000..db441b534 --- /dev/null +++ b/priv/repo/migrations/20210510090556_add_emotions_to_repo.exs @@ -0,0 +1,9 @@ +defmodule GroupherServer.Repo.Migrations.AddEmotionsToRepo do + use Ecto.Migration + + def change do + alter table(:cms_repos) do + add(:emotions, :map) + end + end +end diff --git a/test/groupher_server/cms/comments/post_comment_replies_test.exs b/test/groupher_server/cms/comments/post_comment_replies_test.exs index ab96e2ddc..d7508fa62 100644 --- a/test/groupher_server/cms/comments/post_comment_replies_test.exs +++ b/test/groupher_server/cms/comments/post_comment_replies_test.exs @@ -160,7 +160,7 @@ defmodule GroupherServer.Test.CMS.Comments.PostCommentReplies do end describe "[paged article comment replies]" do - @tag :wip + @tag :wip3 test "can get paged replies of a parent comment", ~m(post user)a do {:ok, parent_comment} = CMS.create_article_comment(:post, post.id, "parent_conent", user) {:ok, paged_replies} = CMS.list_comment_replies(parent_comment.id, %{page: 1, size: 20}) diff --git a/test/groupher_server/cms/comments/post_comment_test.exs b/test/groupher_server/cms/comments/post_comment_test.exs index a635353da..66fed7c8d 100644 --- a/test/groupher_server/cms/comments/post_comment_test.exs +++ b/test/groupher_server/cms/comments/post_comment_test.exs @@ -435,7 +435,7 @@ defmodule GroupherServer.Test.CMS.Comments.PostComment do assert paged_comments.total_count == total_count end - @tag :wip + @tag :wip3 test "paged article comments should not contains folded and repoted comments", ~m(user post)a do total_count = 15 diff --git a/test/groupher_server/cms/emotions/job_emotions_test.exs b/test/groupher_server/cms/emotions/job_emotions_test.exs new file mode 100644 index 000000000..699214674 --- /dev/null +++ b/test/groupher_server/cms/emotions/job_emotions_test.exs @@ -0,0 +1,185 @@ +defmodule GroupherServer.Test.CMS.Emotions.JobEmotions 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) + + job_attrs = mock_attrs(:job, %{community_id: community.id}) + + {:ok, ~m(user user2 user3 community job_attrs)a} + end + + describe "[emotion in paged jobs]" do + @tag :wip3 + test "login user should got viewer has emotioned status", + ~m(community job_attrs user)a do + total_count = 10 + page_number = 10 + page_size = 20 + + all_jobs = + Enum.reduce(0..total_count, [], fn _, acc -> + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + acc ++ [job] + end) + + random_job = all_jobs |> Enum.at(3) + + {:ok, _} = CMS.emotion_to_article(:job, random_job.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:job, random_job.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:job, random_job.id, :popcorn, user) + + {:ok, paged_articles} = + CMS.paged_articles(:job, %{page: page_number, size: page_size}, user) + + target = Enum.find(paged_articles.entries, &(&1.id == random_job.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 + @tag :wip3 + test "job has default emotions after created", ~m(community job_attrs user)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + emotions = job.emotions |> Map.from_struct() |> Map.delete(:id) + assert @default_emotions == emotions + end + + @tag :wip3 + test "can make emotion to job", ~m(community job_attrs user user2)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Job, job.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 + + @tag :wip3 + test "can undo emotion to job", ~m(community job_attrs user user2)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user2) + + {:ok, _} = CMS.undo_emotion_to_article(:job, job.id, :downvote, user) + {:ok, _} = CMS.undo_emotion_to_article(:job, job.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Job, job.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 + + @tag :wip3 + test "same user make same emotion to same job.", ~m(community job_attrs user)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user) + + {:ok, job} = ORM.find(CMS.Job, job.id) + + assert job.emotions.downvote_count == 1 + assert user_exist_in?(user, job.emotions.latest_downvote_users) + end + + @tag :wip3 + test "same user same emotion to same job only have one user_emotion record", + ~m(community job_attrs user)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :heart, user) + + {:ok, job} = ORM.find(CMS.Job, job.id) + + {:ok, records} = ORM.find_all(ArticleUserEmotion, %{page: 1, size: 10}) + assert records.total_count == 1 + + {:ok, record} = ORM.find_by(ArticleUserEmotion, %{job_id: job.id, user_id: user.id}) + assert record.downvote + assert record.heart + end + + @tag :wip3 + test "different user can make same emotions on same job", + ~m(community job_attrs user user2 user3)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:job, job.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :beer, user2) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :beer, user3) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Job, job.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 + + @tag :wip3 + test "same user can make differcent emotions on same job", ~m(community job_attrs user)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :heart, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :orz, user) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Job, job.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/emotions/post_emotions_test.exs b/test/groupher_server/cms/emotions/post_emotions_test.exs new file mode 100644 index 000000000..24a10fce8 --- /dev/null +++ b/test/groupher_server/cms/emotions/post_emotions_test.exs @@ -0,0 +1,185 @@ +defmodule GroupherServer.Test.CMS.Emotions.PostEmotions 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) + + post_attrs = mock_attrs(:post, %{community_id: community.id}) + + {:ok, ~m(user user2 user3 community post_attrs)a} + end + + describe "[emotion in paged posts]" do + @tag :wip3 + test "login user should got viewer has emotioned status", + ~m(community post_attrs user)a do + total_count = 10 + page_number = 10 + page_size = 20 + + all_posts = + Enum.reduce(0..total_count, [], fn _, acc -> + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + acc ++ [post] + end) + + random_post = all_posts |> Enum.at(3) + + {:ok, _} = CMS.emotion_to_article(:post, random_post.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:post, random_post.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:post, random_post.id, :popcorn, user) + + {:ok, paged_articles} = + CMS.paged_articles(:post, %{page: page_number, size: page_size}, user) + + target = Enum.find(paged_articles.entries, &(&1.id == random_post.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 + @tag :wip3 + test "post has default emotions after created", ~m(community post_attrs user)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + emotions = post.emotions |> Map.from_struct() |> Map.delete(:id) + assert @default_emotions == emotions + end + + @tag :wip3 + test "can make emotion to post", ~m(community post_attrs user user2)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Post, post.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 + + @tag :wip3 + test "can undo emotion to post", ~m(community post_attrs user user2)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user2) + + {:ok, _} = CMS.undo_emotion_to_article(:post, post.id, :downvote, user) + {:ok, _} = CMS.undo_emotion_to_article(:post, post.id, :downvote, user2) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Post, post.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 + + @tag :wip3 + test "same user make same emotion to same post.", ~m(community post_attrs user)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user) + + {:ok, post} = ORM.find(CMS.Post, post.id) + + assert post.emotions.downvote_count == 1 + assert user_exist_in?(user, post.emotions.latest_downvote_users) + end + + @tag :wip3 + test "same user same emotion to same post only have one user_emotion record", + ~m(community post_attrs user)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :heart, user) + + {:ok, post} = ORM.find(CMS.Post, post.id) + + {:ok, records} = ORM.find_all(ArticleUserEmotion, %{page: 1, size: 10}) + assert records.total_count == 1 + + {:ok, record} = ORM.find_by(ArticleUserEmotion, %{post_id: post.id, user_id: user.id}) + assert record.downvote + assert record.heart + end + + @tag :wip3 + test "different user can make same emotions on same post", + ~m(community post_attrs user user2 user3)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:post, post.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :beer, user2) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :beer, user3) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Post, post.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 + + @tag :wip3 + test "same user can make differcent emotions on same post", ~m(community post_attrs user)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :downvote, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :beer, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :heart, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :orz, user) + + {:ok, %{emotions: emotions}} = ORM.find(CMS.Post, post.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/post_test.exs b/test/groupher_server/cms/post_test.exs index 4f4743e80..eae07914a 100644 --- a/test/groupher_server/cms/post_test.exs +++ b/test/groupher_server/cms/post_test.exs @@ -18,6 +18,7 @@ defmodule GroupherServer.Test.CMS.Post do describe "[cms post curd]" do alias CMS.{Author, Community} + @tag :wip3 test "can create post with valid attrs", ~m(user community post_attrs)a do assert {:error, _} = ORM.find_by(Author, user_id: user.id) diff --git a/test/groupher_server/cms/repo_test.exs b/test/groupher_server/cms/repo_test.exs index f818ecea0..0446b00c5 100644 --- a/test/groupher_server/cms/repo_test.exs +++ b/test/groupher_server/cms/repo_test.exs @@ -17,7 +17,7 @@ defmodule GroupherServer.Test.Repo do describe "[cms repo curd]" do alias CMS.{Author, Community} - + @tag :wip3 test "can create repo with valid attrs", ~m(user community repo_attrs)a do assert {:error, _} = ORM.find_by(Author, user_id: user.id) diff --git a/test/groupher_server_web/mutation/accounts/customization_test.exs b/test/groupher_server_web/mutation/accounts/customization_test.exs index 8f42ad231..de3de03cd 100644 --- a/test/groupher_server_web/mutation/accounts/customization_test.exs +++ b/test/groupher_server_web/mutation/accounts/customization_test.exs @@ -72,7 +72,7 @@ defmodule GroupherServer.Test.Mutation.Account.Customization do } } """ - @tag :wip3 + @tag :wip2 test "PageSizeProof middleware should lint c11n displayDensity size", ~m(user)a do user_conn = simu_conn(:user, user) db_insert_multi(:post, 50) diff --git a/test/groupher_server_web/mutation/cms/articles/job_emotion_test.exs b/test/groupher_server_web/mutation/cms/articles/job_emotion_test.exs new file mode 100644 index 000000000..b822aff94 --- /dev/null +++ b/test/groupher_server_web/mutation/cms/articles/job_emotion_test.exs @@ -0,0 +1,73 @@ +defmodule GroupherServer.Test.Mutation.Articles.JobEmotion do + use GroupherServer.TestTools + + alias GroupherServer.CMS + + setup do + {:ok, user} = db_insert(:user) + {:ok, community} = db_insert(:community) + + job_attrs = mock_attrs(:job, %{community_id: community.id}) + + guest_conn = simu_conn(:guest) + user_conn = simu_conn(:user) + owner_conn = simu_conn(:user, user) + + {:ok, ~m(user_conn user guest_conn owner_conn community job_attrs)a} + end + + describe "[job emotion]" do + @emotion_query """ + mutation($id: ID!, $emotion: ArticleEmotion!) { + emotionToJob(id: $id, emotion: $emotion) { + id + emotions { + beerCount + viewerHasBeered + latestBeerUsers { + login + nickname + } + } + } + } + """ + @tag :wip3 + test "login user can emotion to a pjob", ~m(community job_attrs user user_conn)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + + variables = %{id: job.id, emotion: "BEER"} + article = user_conn |> mutation_result(@emotion_query, variables, "emotionToJob") + + assert article |> get_in(["emotions", "beerCount"]) == 1 + assert get_in(article, ["emotions", "viewerHasBeered"]) + end + + @emotion_query """ + mutation($id: ID!, $emotion: ArticleEmotion!) { + undoEmotionToJob(id: $id, emotion: $emotion) { + id + emotions { + beerCount + viewerHasBeered + latestBeerUsers { + login + nickname + } + } + } + } + """ + @tag :wip3 + test "login user can undo emotion to a job", ~m(community job_attrs user owner_conn)a do + {:ok, job} = CMS.create_content(community, :job, job_attrs, user) + {:ok, _} = CMS.emotion_to_article(:job, job.id, :beer, user) + + variables = %{id: job.id, emotion: "BEER"} + article = owner_conn |> mutation_result(@emotion_query, variables, "undoEmotionToJob") + + assert article |> get_in(["emotions", "beerCount"]) == 0 + assert not get_in(article, ["emotions", "viewerHasBeered"]) + end + end +end diff --git a/test/groupher_server_web/mutation/cms/job_test.exs b/test/groupher_server_web/mutation/cms/articles/job_test.exs similarity index 99% rename from test/groupher_server_web/mutation/cms/job_test.exs rename to test/groupher_server_web/mutation/cms/articles/job_test.exs index 2993ebdd1..058835bc0 100644 --- a/test/groupher_server_web/mutation/cms/job_test.exs +++ b/test/groupher_server_web/mutation/cms/articles/job_test.exs @@ -1,4 +1,4 @@ -defmodule GroupherServer.Test.Mutation.Job do +defmodule GroupherServer.Test.Mutation.Articles.Job do use GroupherServer.TestTools alias Helper.ORM diff --git a/test/groupher_server_web/mutation/cms/articles/post_emotion_test.exs b/test/groupher_server_web/mutation/cms/articles/post_emotion_test.exs new file mode 100644 index 000000000..30c37a5e4 --- /dev/null +++ b/test/groupher_server_web/mutation/cms/articles/post_emotion_test.exs @@ -0,0 +1,73 @@ +defmodule GroupherServer.Test.Mutation.Articles.PostEmotion do + use GroupherServer.TestTools + + alias GroupherServer.CMS + + setup do + {:ok, user} = db_insert(:user) + {:ok, community} = db_insert(:community) + + post_attrs = mock_attrs(:post, %{community_id: community.id}) + + guest_conn = simu_conn(:guest) + user_conn = simu_conn(:user) + owner_conn = simu_conn(:user, user) + + {:ok, ~m(user_conn user guest_conn owner_conn community post_attrs)a} + end + + describe "[post emotion]" do + @emotion_query """ + mutation($id: ID!, $emotion: ArticleEmotion!) { + emotionToPost(id: $id, emotion: $emotion) { + id + emotions { + beerCount + viewerHasBeered + latestBeerUsers { + login + nickname + } + } + } + } + """ + @tag :wip3 + test "login user can emotion to a ppost", ~m(community post_attrs user user_conn)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + + variables = %{id: post.id, emotion: "BEER"} + article = user_conn |> mutation_result(@emotion_query, variables, "emotionToPost") + + assert article |> get_in(["emotions", "beerCount"]) == 1 + assert get_in(article, ["emotions", "viewerHasBeered"]) + end + + @emotion_query """ + mutation($id: ID!, $emotion: ArticleEmotion!) { + undoEmotionToPost(id: $id, emotion: $emotion) { + id + emotions { + beerCount + viewerHasBeered + latestBeerUsers { + login + nickname + } + } + } + } + """ + @tag :wip3 + test "login user can undo emotion to a post", ~m(community post_attrs user owner_conn)a do + {:ok, post} = CMS.create_content(community, :post, post_attrs, user) + {:ok, _} = CMS.emotion_to_article(:post, post.id, :beer, user) + + variables = %{id: post.id, emotion: "BEER"} + article = owner_conn |> mutation_result(@emotion_query, variables, "undoEmotionToPost") + + assert article |> get_in(["emotions", "beerCount"]) == 0 + assert not get_in(article, ["emotions", "viewerHasBeered"]) + end + end +end diff --git a/test/groupher_server_web/mutation/cms/post_test.exs b/test/groupher_server_web/mutation/cms/articles/post_test.exs similarity index 99% rename from test/groupher_server_web/mutation/cms/post_test.exs rename to test/groupher_server_web/mutation/cms/articles/post_test.exs index 917477f8b..b632559c1 100644 --- a/test/groupher_server_web/mutation/cms/post_test.exs +++ b/test/groupher_server_web/mutation/cms/articles/post_test.exs @@ -1,4 +1,4 @@ -defmodule GroupherServer.Test.Mutation.Post do +defmodule GroupherServer.Test.Mutation.Articles.Post do use GroupherServer.TestTools alias Helper.{ORM, Utils} diff --git a/test/groupher_server_web/mutation/cms/repo_test.exs b/test/groupher_server_web/mutation/cms/articles/repo_test.exs similarity index 99% rename from test/groupher_server_web/mutation/cms/repo_test.exs rename to test/groupher_server_web/mutation/cms/articles/repo_test.exs index 0ae79a6e4..afedc0217 100644 --- a/test/groupher_server_web/mutation/cms/repo_test.exs +++ b/test/groupher_server_web/mutation/cms/articles/repo_test.exs @@ -1,4 +1,4 @@ -defmodule GroupherServer.Test.Mutation.Repo do +defmodule GroupherServer.Test.Mutation.Articles.Repo do use GroupherServer.TestTools alias Helper.ORM diff --git a/test/groupher_server_web/query/cms/comments/job_comment_test.exs b/test/groupher_server_web/query/cms/comments/job_comment_test.exs index c1697a533..891d0e773 100644 --- a/test/groupher_server_web/query/cms/comments/job_comment_test.exs +++ b/test/groupher_server_web/query/cms/comments/job_comment_test.exs @@ -551,7 +551,7 @@ defmodule GroupherServer.Test.Query.Comments.JobComment do } } """ - @tag :wip2 + @tag :wip3 test "guest user can get paged participators", ~m(guest_conn job user)a do total_count = 30 page_size = 10 diff --git a/test/groupher_server_web/query/cms/jobs_flags_test.exs b/test/groupher_server_web/query/cms/jobs_flags_test.exs index b992b3343..e977f1a87 100644 --- a/test/groupher_server_web/query/cms/jobs_flags_test.exs +++ b/test/groupher_server_web/query/cms/jobs_flags_test.exs @@ -51,7 +51,7 @@ defmodule GroupherServer.Test.Query.JobsFlags do } } """ - @tag :wip + @tag :wip3 test "if have pined jobs, the pined jobs should at the top of entries", ~m(guest_conn community job_m)a do variables = %{filter: %{community: community.raw}} diff --git a/test/groupher_server_web/query/cms/repos_flags_test.exs b/test/groupher_server_web/query/cms/repos_flags_test.exs index 021056e0c..c0cf8707a 100644 --- a/test/groupher_server_web/query/cms/repos_flags_test.exs +++ b/test/groupher_server_web/query/cms/repos_flags_test.exs @@ -50,6 +50,7 @@ defmodule GroupherServer.Test.Query.ReposFlags do } } """ + @tag :wip3 test "if have pined repos, the pined repos should at the top of entries", ~m(guest_conn community repo_m)a do variables = %{filter: %{community: community.raw}} diff --git a/test/support/factory.ex b/test/support/factory.ex index c1165dcd3..59e6726c0 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -10,6 +10,8 @@ defmodule GroupherServer.Support.Factory do alias GroupherServer.Repo alias GroupherServer.{Accounts, CMS, Delivery} + @default_emotions CMS.Embeds.ArticleCommentEmotion.default_emotions() + defp mock_meta(:post) do body = Faker.Lorem.sentence(%Range{first: 80, last: 120}) @@ -23,7 +25,8 @@ defmodule GroupherServer.Support.Factory do communities: [ mock(:community), mock(:community) - ] + ], + emotions: @default_emotions } end @@ -58,7 +61,8 @@ defmodule GroupherServer.Support.Factory do communities: [ mock(:community), mock(:community) - ] + ], + emotions: @default_emotions } end @@ -121,7 +125,8 @@ defmodule GroupherServer.Support.Factory do scale: scale_enum |> Enum.at(Enum.random(0..(length(scale_enum) - 1))), communities: [ mock(:community) - ] + ], + emotions: @default_emotions } end