Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit a6128c5

Browse files
authored
refactor(editor-workflow): re-org workflow with article & comment CURD & test (#395)
* refactor(editor-workflow): editor parse wip * refactor(editor-workflow): editor parse test fix * refactor(editor-workflow): editor parse test list case * refactor(editor-workflow): add body_html to all articles * refactor(editor-workflow): adjust body fields to article_comments * refactor(editor-workflow): fix body field when create comment * refactor(editor-workflow): fix body field when create comment wip * refactor(editor-workflow): wip * refactor(editor-workflow): post digest workflow * refactor(editor-workflow): article create workflow * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): rich test for comment test wip * refactor(editor-workflow): fix comment test * refactor(editor-workflow): fix comment test * refactor(editor-workflow): fix comment test * refactor(editor-workflow): fix comment test * refactor(editor-workflow): fix comment test wip * refactor(editor-workflow): fix comment test wip * chore: clean up * test(comment): body refactor wip * test(article): body parse & test adjust * test(article): body parse & test adjust * test(article): body parse & test adjust * test(article): fix test * test(article): fix test
1 parent c45bc80 commit a6128c5

File tree

75 files changed

+1424
-1127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+1424
-1127
lines changed

Diff for: config/config.exs

+2-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ config :groupher_server, :article,
9696
:confused,
9797
:pill,
9898
:popcorn
99-
]
99+
],
100+
digest_length: 120
100101

101102
config :groupher_server, GroupherServerWeb.Gettext, default_locale: "zh_CN", locales: ~w(en zh_CN)
102103

Diff for: lib/groupher_server/cms/delegates/article_comment.ex

+42-36
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
1111
import ShortMaps
1212

1313
alias Helper.Types, as: T
14-
alias Helper.{ORM, QueryBuilder}
14+
alias Helper.{ORM, QueryBuilder, Converter}
1515
alias GroupherServer.{Accounts, CMS, Repo}
1616
alias CMS.Model.Post
1717

@@ -92,13 +92,13 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
9292
@doc """
9393
creates a comment for article like psot, job ...
9494
"""
95-
def create_article_comment(thread, article_id, content, %User{} = user) do
95+
def create_article_comment(thread, article_id, body, %User{} = user) do
9696
with {:ok, info} <- match(thread),
9797
{:ok, article} <- ORM.find(info.model, article_id, preload: [author: :user]),
9898
true <- can_comment?(article, user) do
9999
Multi.new()
100100
|> Multi.run(:create_article_comment, fn _, _ ->
101-
do_create_comment(content, info.foreign_key, article, user)
101+
do_create_comment(body, info.foreign_key, article, user)
102102
end)
103103
|> Multi.run(:update_article_comments_count, fn _, %{create_article_comment: comment} ->
104104
update_article_comments_count(comment, :inc)
@@ -133,15 +133,20 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
133133
update a comment for article like psot, job ...
134134
"""
135135
# 如果是 solution, 那么要更新对应的 post 的 solution_digest
136-
def update_article_comment(%ArticleComment{is_solution: true} = article_comment, content) do
137-
with {:ok, post} <- ORM.find(Post, article_comment.post_id) do
138-
post |> ORM.update(%{solution_digest: content})
139-
article_comment |> ORM.update(%{body_html: content})
136+
def update_article_comment(%ArticleComment{is_solution: true} = article_comment, body) do
137+
with {:ok, post} <- ORM.find(Post, article_comment.post_id),
138+
{:ok, parsed} <- Converter.Article.parse_body(body),
139+
{:ok, digest} <- Converter.Article.parse_digest(parsed.body_map) do
140+
%{body: body, body_html: body_html} = parsed
141+
post |> ORM.update(%{solution_digest: digest})
142+
article_comment |> ORM.update(%{body: body, body_html: body_html})
140143
end
141144
end
142145

143-
def update_article_comment(%ArticleComment{} = article_comment, content) do
144-
article_comment |> ORM.update(%{body_html: content})
146+
def update_article_comment(%ArticleComment{} = article_comment, body) do
147+
with {:ok, %{body: body, body_html: body_html}} <- Converter.Article.parse_body(body) do
148+
article_comment |> ORM.update(%{body: body, body_html: body_html})
149+
end
145150
end
146151

147152
@doc """
@@ -216,7 +221,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
216221
|> result()
217222
end
218223

219-
# add participator to article-like content (Post, Job ...) and update count
224+
# add participator to article-like(Post, Job ...) and update count
220225
def add_participator_to_article(
221226
%{article_comments_participators: article_comments_participators} = article,
222227
%User{} = user
@@ -255,32 +260,27 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
255260
end
256261
end
257262

258-
# creat article comment for parent or reply
259-
# set floor
260-
# TODO: parse editor-json
261-
# set default emotions
262-
def do_create_comment(content, foreign_key, article, %User{id: user_id}) do
263-
thread = foreign_key |> to_string |> String.split("_id") |> List.first() |> String.upcase()
264-
265-
count_query = from(c in ArticleComment, where: field(c, ^foreign_key) == ^article.id)
266-
floor = Repo.aggregate(count_query, :count) + 1
267-
268-
ArticleComment
269-
|> ORM.create(
270-
Map.put(
271-
%{
272-
author_id: user_id,
273-
body_html: content,
274-
emotions: @default_emotions,
275-
floor: floor,
276-
is_article_author: user_id == article.author.user.id,
277-
thread: thread,
278-
meta: @default_comment_meta
279-
},
280-
foreign_key,
281-
article.id
282-
)
283-
)
263+
@doc """
264+
create article comment for parent or reply
265+
"""
266+
def do_create_comment(body, foreign_key, article, %User{id: user_id}) do
267+
with {:ok, %{body: body, body_html: body_html}} <- Converter.Article.parse_body(body) do
268+
# e.g: :post_id -> "POST", :job_id -> "JOB"
269+
thread = foreign_key |> to_string |> String.slice(0..-4) |> String.upcase()
270+
271+
attrs = %{
272+
author_id: user_id,
273+
body: body,
274+
body_html: body_html,
275+
emotions: @default_emotions,
276+
floor: get_comment_floor(article, foreign_key),
277+
is_article_author: user_id == article.author.user.id,
278+
thread: thread,
279+
meta: @default_comment_meta
280+
}
281+
282+
ArticleComment |> ORM.create(Map.put(attrs, foreign_key, article.id))
283+
end
284284
end
285285

286286
defp do_paged_article_comment(thread, article_id, filters, where_query, user) do
@@ -398,6 +398,12 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
398398
{:ok, :pass}
399399
end
400400

401+
# get next floor under an article's comments list
402+
defp get_comment_floor(article, foreign_key) do
403+
count_query = from(c in ArticleComment, where: field(c, ^foreign_key) == ^article.id)
404+
Repo.aggregate(count_query, :count) + 1
405+
end
406+
401407
defp result({:ok, %{set_question_flag_ifneed: result}}), do: {:ok, result}
402408
defp result({:ok, %{delete_article_comment: result}}), do: {:ok, result}
403409
defp result({:ok, %{mark_solution: result}}), do: {:ok, result}

Diff for: lib/groupher_server/cms/delegates/article_curd.ex

+49-23
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,13 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
66

77
import GroupherServer.CMS.Helper.Matcher
88

9-
import Helper.Utils,
10-
only: [
11-
done: 1,
12-
pick_by: 2,
13-
integerfy: 1,
14-
strip_struct: 1,
15-
module_to_atom: 1,
16-
get_config: 2,
17-
ensure: 2
18-
]
9+
import Helper.Utils, only: [done: 1, pick_by: 2, module_to_atom: 1, get_config: 2, ensure: 2]
1910

2011
import GroupherServer.CMS.Delegate.Helper, only: [mark_viewer_emotion_states: 2]
2112
import Helper.ErrorCode
2213
import ShortMaps
2314

24-
alias Helper.{Later, ORM, QueryBuilder}
15+
alias Helper.{Later, ORM, QueryBuilder, Converter}
2516
alias GroupherServer.{Accounts, CMS, Delivery, Email, Repo, Statistics}
2617

2718
alias Accounts.Model.User
@@ -172,7 +163,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
172163
|> Multi.run(:update_user_published_meta, fn _, _ ->
173164
Accounts.update_published_states(uid, thread)
174165
end)
166+
# TODO: run mini tasks
175167
|> Multi.run(:mention_users, fn _, %{create_article: article} ->
168+
# article.body |> Jason.decode!() |> 各种小 task
176169
Delivery.mention_from_content(community.raw, thread, article, attrs, %User{id: uid})
177170
{:ok, :pass}
178171
end)
@@ -213,7 +206,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
213206
"""
214207
def update_article(article, args) do
215208
Multi.new()
216-
|> Multi.run(:update_article, fn _, _ -> ORM.update(article, args) end)
209+
|> Multi.run(:update_article, fn _, _ ->
210+
do_update_article(article, args)
211+
end)
217212
|> Multi.run(:update_comment_question_flag_if_need, fn _, %{update_article: update_article} ->
218213
# 如果帖子的类型变了,那么 update 所有的 flag
219214
case Map.has_key?(args, :is_question) do
@@ -386,17 +381,43 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
386381
end
387382

388383
# for create artilce step in Multi.new
389-
defp do_create_article(target, attrs, %Author{id: aid}, %Community{id: cid}) do
390-
target
391-
|> struct()
392-
|> target.changeset(attrs)
393-
|> Ecto.Changeset.put_change(:emotions, @default_emotions)
394-
|> Ecto.Changeset.put_change(:author_id, aid)
395-
|> Ecto.Changeset.put_change(:original_community_id, integerfy(cid))
396-
|> Ecto.Changeset.put_embed(:meta, @default_article_meta)
397-
|> Repo.insert()
384+
defp do_create_article(model, attrs, %Author{id: author_id}, %Community{id: community_id}) do
385+
# special article like Repo do not have :body, assign it with default-empty rich text
386+
body = Map.get(attrs, :body, Converter.Article.default_rich_text())
387+
attrs = attrs |> Map.merge(%{body: body})
388+
389+
with {:ok, attrs} <- add_rich_text_attrs(attrs) do
390+
model.__struct__
391+
|> model.changeset(attrs)
392+
|> Ecto.Changeset.put_change(:emotions, @default_emotions)
393+
|> Ecto.Changeset.put_change(:author_id, author_id)
394+
|> Ecto.Changeset.put_change(:original_community_id, community_id)
395+
|> Ecto.Changeset.put_embed(:meta, @default_article_meta)
396+
|> Repo.insert()
397+
end
398398
end
399399

400+
defp do_update_article(article, %{body: _} = attrs) do
401+
with {:ok, attrs} <- add_rich_text_attrs(attrs) do
402+
ORM.update(article, attrs)
403+
end
404+
end
405+
406+
defp do_update_article(article, attrs), do: ORM.update(article, attrs)
407+
408+
# is update or create article with body field, parsed and extand it into attrs
409+
defp add_rich_text_attrs(%{body: body} = attrs) when not is_nil(body) do
410+
with {:ok, parsed} <- Converter.Article.parse_body(body),
411+
{:ok, digest} <- Converter.Article.parse_digest(parsed.body_map) do
412+
attrs
413+
|> Map.merge(Map.take(parsed, [:body, :body_html]))
414+
|> Map.merge(%{digest: digest})
415+
|> done
416+
end
417+
end
418+
419+
defp add_rich_text_attrs(attrs), do: attrs
420+
400421
# except Job, other article will just pass, should use set_article_tags function instead
401422
# defp exec_update_tags(_, _tags_ids), do: {:ok, :pass}
402423

@@ -413,7 +434,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
413434
case Enum.empty?(meta.viewed_user_ids) or user_not_viewed do
414435
true ->
415436
new_ids = Enum.uniq([user_id] ++ meta.viewed_user_ids)
416-
meta = meta |> Map.merge(%{viewed_user_ids: new_ids}) |> strip_struct
437+
meta = meta |> Map.merge(%{viewed_user_ids: new_ids})
417438
ORM.update_meta(article, meta)
418439

419440
false ->
@@ -429,11 +450,16 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
429450

430451
defp result({:ok, %{update_edit_status: result}}), do: {:ok, result}
431452
defp result({:ok, %{update_article: result}}), do: {:ok, result}
453+
# NOTE: for read article, order is import
432454
defp result({:ok, %{set_viewer_has_states: result}}), do: result |> done()
433455
defp result({:ok, %{update_article_meta: result}}), do: {:ok, result}
434456

435457
defp result({:error, :create_article, _result, _steps}) do
436-
{:error, [message: "create cms article author", code: ecode(:create_fails)]}
458+
{:error, [message: "create article", code: ecode(:create_fails)]}
459+
end
460+
461+
defp result({:error, :update_article, _result, _steps}) do
462+
{:error, [message: "update article", code: ecode(:update_fails)]}
437463
end
438464

439465
defp result({:error, :mirror_article, _result, _steps}) do

Diff for: lib/groupher_server/cms/helper/macros.ex

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ defmodule GroupherServer.CMS.Helper.Macros do
125125
def general_article_fields(:cast) do
126126
[
127127
:body,
128+
:body_html,
128129
:digest,
129130
:original_community_id,
130131
:article_comments_count,
@@ -187,6 +188,7 @@ defmodule GroupherServer.CMS.Helper.Macros do
187188
quote do
188189
field(:title, :string)
189190
field(:body, :string)
191+
field(:body_html, :string)
190192
field(:digest, :string)
191193

192194
belongs_to(:author, Author)

Diff for: lib/groupher_server/cms/models/article_comment.ex

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ defmodule GroupherServer.CMS.Model.ArticleComment do
1717
# alias Helper.HTML
1818
@article_threads get_config(:article, :threads)
1919

20-
@required_fields ~w(body_html author_id)a
21-
@optional_fields ~w(reply_to_id replies_count is_folded is_deleted floor is_article_author thread is_for_question is_solution)a
22-
@updatable_fields ~w(is_folded is_deleted floor upvotes_count is_pinned is_for_question is_solution)a
20+
@required_fields ~w(body author_id)a
21+
@optional_fields ~w(body_html reply_to_id replies_count is_folded is_deleted floor is_article_author thread is_for_question is_solution)a
22+
@updatable_fields ~w(body_html is_folded is_deleted floor upvotes_count is_pinned is_for_question is_solution)a
2323

2424
@article_fields @article_threads |> Enum.map(&:"#{&1}_id")
2525

@@ -52,6 +52,7 @@ defmodule GroupherServer.CMS.Model.ArticleComment do
5252
belongs_to(:author, User, foreign_key: :author_id)
5353

5454
field(:thread, :string)
55+
field(:body, :string)
5556
field(:body_html, :string)
5657
# 是否被折叠
5758
field(:is_folded, :boolean, default: false)

Diff for: lib/groupher_server_web/resolvers/cms_resolver.ex

+8-8
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ defmodule GroupherServerWeb.Resolvers.CMS do
6969
CMS.create_article(%Community{id: community_id}, thread, args, user)
7070
end
7171

72-
def update_article(_root, %{passport_source: content} = args, _info) do
73-
CMS.update_article(content, args)
72+
def update_article(_root, %{passport_source: article} = args, _info) do
73+
CMS.update_article(article, args)
7474
end
7575

7676
def delete_article(_root, %{passport_source: content}, _info), do: ORM.delete(content)
@@ -294,22 +294,22 @@ defmodule GroupherServerWeb.Resolvers.CMS do
294294
CMS.paged_article_comments_participators(thread, id, filter)
295295
end
296296

297-
def create_article_comment(_root, ~m(thread id content)a, %{context: %{cur_user: user}}) do
298-
CMS.create_article_comment(thread, id, content, user)
297+
def create_article_comment(_root, ~m(thread id body)a, %{context: %{cur_user: user}}) do
298+
CMS.create_article_comment(thread, id, body, user)
299299
end
300300

301-
def update_article_comment(_root, ~m(content passport_source)a, _info) do
301+
def update_article_comment(_root, ~m(body passport_source)a, _info) do
302302
comment = passport_source
303-
CMS.update_article_comment(comment, content)
303+
CMS.update_article_comment(comment, body)
304304
end
305305

306306
def delete_article_comment(_root, ~m(passport_source)a, _info) do
307307
comment = passport_source
308308
CMS.delete_article_comment(comment)
309309
end
310310

311-
def reply_article_comment(_root, ~m(id content)a, %{context: %{cur_user: user}}) do
312-
CMS.reply_article_comment(id, content, user)
311+
def reply_article_comment(_root, ~m(id body)a, %{context: %{cur_user: user}}) do
312+
CMS.reply_article_comment(id, body, user)
313313
end
314314

315315
def upvote_article_comment(_root, ~m(id)a, %{context: %{cur_user: user}}) do

Diff for: lib/groupher_server_web/schema/Helper/fields.ex

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do
1919
field(:id, :id)
2020
field(:title, :string)
2121
field(:body, :string)
22+
field(:body_html, :string)
2223
field(:digest, :string)
2324
field(:views, :integer)
2425
field(:is_pinned, :boolean)

Diff for: lib/groupher_server_web/schema/cms/cms_types.ex

+1-3
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
6161
field(:length, :integer)
6262
field(:link_addr, :string)
6363
field(:copy_right, :string)
64-
field(:body, :string)
6564

6665
timestamp_fields(:article)
6766
end
@@ -78,7 +77,6 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
7877
field(:length, :integer)
7978
field(:link_addr, :string)
8079
field(:copy_right, :string)
81-
field(:body, :string)
8280

8381
timestamp_fields(:article)
8482
end
@@ -91,7 +89,6 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
9189

9290
field(:length, :integer)
9391
field(:link_addr, :string)
94-
# field(:body, :string)
9592

9693
timestamp_fields(:article)
9794
end
@@ -259,6 +256,7 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
259256

260257
object :article_comment_reply do
261258
field(:id, :id)
259+
field(:body, :string)
262260
field(:body_html, :string)
263261
field(:author, :user, resolve: dataloader(CMS, :author))
264262
field(:floor, :integer)

0 commit comments

Comments
 (0)