Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions lib/groupher_server/cms/delegates/article_curd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
|> Multi.run(:set_community, fn _, %{create_content: content} ->
ArticleOperation.set_community(community, thread, content.id)
end)
|> Multi.run(:set_meta, fn _, %{create_content: content} ->
ArticleOperation.set_meta(thread, content.id)
end)
|> Multi.run(:set_topic, fn _, %{create_content: content} ->
exec_set_topic(thread, content.id, attrs)
end)
Expand Down Expand Up @@ -127,8 +130,12 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
|> Multi.run(:update_content, fn _, _ ->
ORM.update(content, args)
end)
|> Multi.run(:update_meta, fn _, %{update_content: update_content} ->
ArticleOperation.update_meta(update_content, :is_edited)
end)
|> Multi.run(:update_tag, fn _, _ ->
exec_update_tags(content, args.tags)
# TODO: move it to ArticleOperation moudel
exec_update_tags(content, args)
end)
|> Repo.transaction()
|> update_content_result()
Expand Down Expand Up @@ -407,6 +414,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
{:error, [message: "set community", code: ecode(:create_fails)]}
end

defp create_content_result({:error, :set_meta, _result, _steps}) do
{:error, [message: "set meta info", code: ecode(:create_fails)]}
end

defp create_content_result({:error, :set_community_flag, _result, _steps}) do
{:error, [message: "set community flag", code: ecode(:create_fails)]}
end
Expand All @@ -423,10 +434,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
{:error, [message: "log action", code: ecode(:create_fails)]}
end

# except Job, other content will just pass, should use set_tag function instead
# defp exec_update_tags(_, _tags_ids), do: {:ok, :pass}

defp update_content_result({:ok, %{update_content: result}}), do: {:ok, result}
defp update_content_result({:ok, %{update_meta: result}}), do: {:ok, result}
defp update_content_result({:error, :update_content, result, _steps}), do: {:error, result}
defp update_content_result({:error, :update_tag, result, _steps}), do: {:error, result}

Expand Down Expand Up @@ -479,9 +487,12 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
{:ok, :pass}
end

defp exec_update_tags(_content, tags_ids) when length(tags_ids) == 0, do: {:ok, :pass}
# except Job, other content will just pass, should use set_tag function instead
# defp exec_update_tags(_, _tags_ids), do: {:ok, :pass}

defp exec_update_tags(content, tags_ids) do
defp exec_update_tags(_content, %{tags: tags_ids}) when tags_ids == [], do: {:ok, :pass}

defp exec_update_tags(content, %{tags: tags_ids}) do
with {:ok, content} <- ORM.find(content.__struct__, content.id, preload: :tags) do
tags =
Enum.reduce(tags_ids, [], fn t, acc ->
Expand All @@ -502,4 +513,6 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
|> Repo.update()
end
end

defp exec_update_tags(_content, _), do: {:ok, :pass}
end
34 changes: 34 additions & 0 deletions lib/groupher_server/cms/delegates/article_operation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ defmodule GroupherServer.CMS.Delegate.ArticleOperation do
alias GroupherServer.CMS.Repo, as: CMSRepo
alias GroupherServer.Repo

@default_article_meta %{
isEdited: false,
forbidComment: false,
isReported: false
# linkedPostsCount: 0,
# linkedJobsCount: 0,
# linkedWorksCount: 0,
# reaction: %{
# rocketCount: 0,
# heartCount: 0,
# }
}

@doc "for test usage"
def default_article_meta(), do: @default_article_meta

def pin_content(%Post{id: post_id}, %Community{id: community_id}, topic) do
with {:ok, %{id: topic_id}} <- ORM.find_by(Topic, %{raw: topic}),
{:ok, pined} <-
Expand Down Expand Up @@ -277,6 +293,24 @@ defmodule GroupherServer.CMS.Delegate.ArticleOperation do

def set_topic(_topic, _thread, _content_id), do: {:ok, :pass}

@doc "set meta info"
def set_meta(:post, content_id) do
ORM.update_by(Post, [id: content_id], %{meta: @default_article_meta})
end

def set_meta(_, _), do: {:ok, :pass}

@doc "update isEdited meta label if needed"
def update_meta(%Post{meta: %{"isEdited" => false} = meta} = content, :is_edited) do
ORM.update(content, %{meta: Map.merge(meta, %{"isEdited" => true})})
end

def update_meta(%Post{meta: nil} = content, :is_edited) do
ORM.update(content, %{meta: Map.merge(@default_article_meta, %{"isEdited" => true})})
end

def update_meta(content, _), do: {:ok, content}

# make sure the reuest tag is in the current community thread
# example: you can't set a other thread tag to this thread's article

Expand Down
4 changes: 3 additions & 1 deletion lib/groupher_server/cms/post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ defmodule GroupherServer.CMS.Post do

@timestamps_opts [type: :utc_datetime_usec]
@required_fields ~w(title body digest length)a
@optional_fields ~w(origial_community_id link_addr copy_right link_addr link_icon)a
@optional_fields ~w(origial_community_id link_addr copy_right link_addr link_icon meta)a

@type t :: %Post{}
schema "cms_posts" do
Expand All @@ -36,6 +36,8 @@ defmodule GroupherServer.CMS.Post do
field(:length, :integer)
field(:views, :integer, default: 0)

field(:meta, :map)

has_many(:community_flags, {"posts_communities_flags", PostCommunityFlag})

# NOTE: this one is tricky, pin is dynamic changed when return by func: add_pin_contents_ifneed
Expand Down
26 changes: 21 additions & 5 deletions lib/groupher_server_web/resolvers/cms_resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ defmodule GroupherServerWeb.Resolvers.CMS do
alias CMS.{Post, Video, Repo, Job, Community, Category, Tag, Thread}

alias Helper.ORM
alias Helper.Utils

@default_article_meta CMS.Delegate.ArticleOperation.default_article_meta()

# #######################
# community ..
Expand Down Expand Up @@ -102,12 +105,8 @@ defmodule GroupherServerWeb.Resolvers.CMS do
CMS.create_content(%Community{id: community_id}, thread, args, user)
end

def update_content(_root, %{passport_source: content, tags: _tags} = args, _info) do
CMS.update_content(content, args)
end

def update_content(_root, %{passport_source: content} = args, _info) do
ORM.update(content, args)
CMS.update_content(content, args)
end

def delete_content(_root, %{passport_source: content}, _info), do: ORM.delete(content)
Expand Down Expand Up @@ -445,4 +444,21 @@ defmodule GroupherServerWeb.Resolvers.CMS do
def tags_count(root, _, _) do
CMS.count(%Community{id: root.id}, :tags)
end

@doc """
covert normal map to absinthe fmt
e.g:
%{"exampleKey" => false } -> %{example_key: false }
"""
def get_article_meta(root, _, _) do
# if meta is nil , means exsit article or test env (like: db_insert)
meta = if is_nil(root.meta), do: @default_article_meta, else: root.meta

fmt_meta =
meta
|> Utils.snake_map_key()
|> Utils.keys_to_atoms()

{:ok, fmt_meta}
end
end
25 changes: 25 additions & 0 deletions lib/groupher_server_web/schema/cms/cms_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
field(:communities, list_of(:community), resolve: dataloader(CMS, :communities))
# field(:topic)

# article meta info
field(:meta, :article_meta) do
# NOTE: absinthe has issue with :map resolving, do it mannulay
resolve(&R.CMS.get_article_meta/3)
end

# field :meta, :article_meta do
# resolve(&R.CMS.get_meta/3)
# end

field :comments, list_of(:comment) do
arg(:filter, :members_filter)

Expand Down Expand Up @@ -448,4 +458,19 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
field(:entries, list_of(:thread))
pagination_fields()
end

@desc "article meta info"
object :article_meta do
field(:is_edited, :boolean)
field(:forbid_comment, :boolean)
# field(:isReported, :boolean)
# field(:linked_posts_count, :integer)
# field(:linked_jobs_count, :integer)
# field(:linked_works_count, :integer)

# reaction: %{
# rocketCount: 0,
# heartCount: 0,
# }
end
end
29 changes: 26 additions & 3 deletions lib/helper/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,13 @@ defmodule Helper.Utils do
def keys_to_atoms(string) when is_binary(string), do: string

def reduce_keys_to_atoms({key, val}) when is_map(val),
do: {String.to_existing_atom(key), keys_to_atoms(val)}
# do: {String.to_existing_atom(key), keys_to_atoms(val)}
do: {String.to_atom(key), keys_to_atoms(val)}

def reduce_keys_to_atoms({key, val}) when is_list(val),
do: {String.to_existing_atom(key), Enum.map(val, &keys_to_atoms(&1))}
do: {String.to_atom(key), Enum.map(val, &keys_to_atoms(&1))}

def reduce_keys_to_atoms({key, val}), do: {String.to_existing_atom(key), val}
def reduce_keys_to_atoms({key, val}), do: {String.to_atom(key), val}

@doc """
see https://stackoverflow.com/a/61559842/4050784
Expand Down Expand Up @@ -168,6 +169,28 @@ defmodule Helper.Utils do

defp map_to_camel({k, v}), do: {Recase.to_camel(to_string(k)), v}

@spec snake_map_key(map) :: map
def snake_map_key(map) do
map_list =
Enum.map(map, fn {k, v} ->
v =
cond do
is_datetime?(v) ->
DateTime.to_iso8601(v)

is_map(v) ->
snake_map_key(safe_map(v))

true ->
v
end

{Recase.to_snake(to_string(k)), v}
end)

Enum.into(map_list, %{})
end

def is_datetime?(%DateTime{}), do: true
def is_datetime?(_), do: false

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ defmodule GroupherServer.Mixfile do
{:plug_cowboy, "~> 2.4.1"},
{:plug, "~> 1.11.0"},
# GraphQl tool
{:absinthe, "~> 1.6.1"},
{:absinthe, "~> 1.6.2"},
# Plug support for Absinthe
{:absinthe_plug, "~> 1.5.4"},
# Password hashing lib
Expand Down
9 changes: 9 additions & 0 deletions priv/repo/migrations/20210324064013_add_meta_to_posts.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule GroupherServer.Repo.Migrations.AddMetaToPosts do
use Ecto.Migration

def change do
alter table(:cms_posts) do
add(:meta, :map)
end
end
end
52 changes: 52 additions & 0 deletions test/groupher_server/cms/post_meta_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule GroupherServer.Test.CMS.PostMeta do
use GroupherServer.TestTools

alias Helper.ORM
alias GroupherServer.CMS
alias Helper.Utils

@default_article_meta CMS.Delegate.ArticleOperation.default_article_meta()

setup do
{:ok, user} = db_insert(:user)
# {:ok, post} = db_insert(:post)
{:ok, community} = db_insert(:community)

post_attrs = mock_attrs(:post, %{community_id: community.id})

{:ok, ~m(user community post_attrs)a}
end

describe "[cms post meta info]" do
alias CMS.{Author, Post}

@tag :wip
test "can get default meta info", ~m(user community post_attrs)a do
assert {:error, _} = ORM.find_by(Author, user_id: user.id)

{:ok, post} = CMS.create_content(community, :post, post_attrs, user)
{:ok, post} = ORM.find_by(Post, id: post.id)

assert @default_article_meta == Utils.keys_to_atoms(post.meta)
end

@tag :wip
test "isEdited flag should set to true after post updated", ~m(user community post_attrs)a do
{:ok, post} = CMS.create_content(community, :post, post_attrs, user)
{:ok, post} = ORM.find_by(Post, id: post.id)

assert post.meta["isEdited"] == false

{:ok, _} = CMS.update_content(post, %{"title" => "new title"})
{:ok, post} = ORM.find_by(Post, id: post.id)

assert post.meta["isEdited"] == true
end

# test "post with image should have imageCount in meta" do
# end

# test "post with video should have imageCount in meta" do
# end
end
end
2 changes: 1 addition & 1 deletion test/groupher_server/cms/post_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ defmodule GroupherServer.Test.CMS.Post do
assert author.user_id == user.id
end

test "create post with an exsit community fails", ~m(user)a do
test "create post with an non-exsit community fails", ~m(user)a do
invalid_attrs = mock_attrs(:post, %{community_id: non_exsit_id()})
ivalid_community = %Community{id: non_exsit_id()}

Expand Down
18 changes: 18 additions & 0 deletions test/groupher_server_web/mutation/cms/post_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ defmodule GroupherServer.Test.Mutation.Post do
title
body
copyRight
meta {
isEdited
}
}
}
"""
Expand Down Expand Up @@ -265,6 +268,21 @@ defmodule GroupherServer.Test.Mutation.Post do
assert updated_post["copyRight"] == variables.copyRight
end

test "update post with valid attrs should have isEdited meta info update",
~m(owner_conn post)a do
unique_num = System.unique_integer([:positive, :monotonic])

variables = %{
id: post.id,
title: "updated title #{unique_num}",
body: "updated body #{unique_num}"
}

updated_post = owner_conn |> mutation_result(@query, variables, "updatePost")

assert true == updated_post["meta"]["isEdited"]
end

test "login user with auth passport update a post", ~m(post)a do
belongs_community_title = post.communities |> List.first() |> Map.get(:title)

Expand Down
Loading