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

Commit 01dc257

Browse files
committed
refactor(pinned-article): max_pinned_article_count_per_thread
1 parent da89cec commit 01dc257

File tree

6 files changed

+91
-33
lines changed

6 files changed

+91
-33
lines changed

lib/groupher_server/cms/community.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ defmodule GroupherServer.CMS.Community do
1919
CommunityCheatsheet
2020
}
2121

22+
@max_pinned_article_count_per_thread 2
23+
2224
@required_fields ~w(title desc user_id logo raw)a
2325
# @required_fields ~w(title desc user_id)a
2426
@optional_fields ~w(label geo_info index aka)a
2527

28+
def max_pinned_article_count_per_thread, do: @max_pinned_article_count_per_thread
29+
2630
schema "communities" do
2731
field(:title, :string)
2832
field(:aka, :string)

lib/groupher_server/cms/delegates/article_operation.ex

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleOperation do
44
"""
55
import GroupherServer.CMS.Utils.Matcher
66
import Ecto.Query, warn: false
7-
# import Helper.ErrorCode
7+
8+
import Helper.ErrorCode
89
import ShortMaps
910
import GroupherServer.CMS.Utils.Matcher2
1011

@@ -20,7 +21,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleOperation do
2021
JobCommunityFlag,
2122
RepoCommunityFlag,
2223
Tag,
23-
PinedArticle,
24+
PinnedArticle,
2425
PinedPost,
2526
PinedJob,
2627
PinedRepo
@@ -29,12 +30,34 @@ defmodule GroupherServer.CMS.Delegate.ArticleOperation do
2930
alias GroupherServer.CMS.Repo, as: CMSRepo
3031
alias GroupherServer.Repo
3132

32-
@spec pin_article(T.article_thread(), Integer.t(), Integer.t()) :: {:ok, PinedArticle.t()}
33+
alias Ecto.Multi
34+
35+
@max_pinned_article_count_per_thread Community.max_pinned_article_count_per_thread()
36+
37+
@spec pin_article(T.article_thread(), Integer.t(), Integer.t()) :: {:ok, PinnedArticle.t()}
3338
def pin_article(thread, article_id, community_id) do
3439
with {:ok, info} <- match(thread),
35-
{:ok, community} <- ORM.find(Community, community_id) do
36-
args = Map.put(%{community_id: community.id}, info.foreign_key, article_id)
37-
PinedArticle |> ORM.create(args)
40+
{:ok, community} <- ORM.find(Community, community_id),
41+
{:ok, _} <- check_pinned_article_count(community_id, thread) do
42+
Multi.new()
43+
|> Multi.run(:update_article_pinned_flag, fn _, _ ->
44+
# ORM.update(comment, %{is_pined: true})
45+
{:ok, :pass}
46+
end)
47+
|> Multi.run(:create_pinned_article, fn _, _ ->
48+
thread_upcase = thread |> to_string |> String.upcase()
49+
50+
args =
51+
Map.put(
52+
%{community_id: community.id, thread: thread_upcase},
53+
info.foreign_key,
54+
article_id
55+
)
56+
57+
PinnedArticle |> ORM.create(args)
58+
end)
59+
|> Repo.transaction()
60+
|> create_pinned_article_result()
3861
end
3962
end
4063

@@ -267,18 +290,26 @@ defmodule GroupherServer.CMS.Delegate.ArticleOperation do
267290
|> Repo.update()
268291
end
269292

270-
# make sure the reuest tag is in the current community thread
271-
# example: you can't set a other thread tag to this thread's article
293+
# check if the thread has aready enough pined articles
294+
defp check_pinned_article_count(community_id, thread) do
295+
thread_upcase = thread |> to_string |> String.upcase()
296+
297+
query =
298+
from(p in PinnedArticle,
299+
where: p.community_id == ^community_id and p.thread == ^thread_upcase
300+
)
272301

273-
# defp tag_in_community_thread?(%Community{id: communityId}, thread, tag) do
274-
# with {:ok, community} <- ORM.find(Community, communityId) do
275-
# matched_tags =
276-
# Tag
277-
# |> where([t], t.community_id == ^community.id)
278-
# |> where([t], t.thread == ^to_string(thread))
279-
# |> Repo.all()
302+
pinned_articles = query |> Repo.all()
280303

281-
# tag in matched_tags
282-
# end
283-
# end
304+
case length(pinned_articles) >= @max_pinned_article_count_per_thread do
305+
true -> raise_error(:too_much_pinned_article, "too much pinned article")
306+
_ -> {:ok, :pass}
307+
end
308+
end
309+
310+
defp create_pinned_article_result({:ok, %{create_pinned_article: result}}), do: {:ok, result}
311+
312+
defp create_pinned_article_result({:error, _, result, _steps}) do
313+
{:error, result}
314+
end
284315
end

lib/groupher_server/cms/pined_article.ex renamed to lib/groupher_server/cms/pinned_article.ex

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule GroupherServer.CMS.PinedArticle do
1+
defmodule GroupherServer.CMS.PinnedArticle do
22
@moduledoc false
33
alias __MODULE__
44

@@ -8,21 +8,23 @@ defmodule GroupherServer.CMS.PinedArticle do
88
alias GroupherServer.CMS
99
alias CMS.{Community, Post, Job}
1010

11-
@required_fields ~w(community_id)a
11+
@required_fields ~w(community_id thread)a
1212
@optional_fields ~w(post_id job_id)a
1313

14-
@type t :: %PinedArticle{}
15-
schema "pined_articles" do
14+
@type t :: %PinnedArticle{}
15+
schema "pinned_articles" do
1616
belongs_to(:post, Post, foreign_key: :post_id)
1717
belongs_to(:job, Job, foreign_key: :job_id)
1818
belongs_to(:community, Community, foreign_key: :community_id)
1919

20+
field(:thread, :string)
21+
2022
timestamps(type: :utc_datetime)
2123
end
2224

2325
@doc false
24-
def changeset(%PinedArticle{} = pined_article, attrs) do
25-
pined_article
26+
def changeset(%PinnedArticle{} = pinned_article, attrs) do
27+
pinned_article
2628
|> cast(attrs, @optional_fields ++ @required_fields)
2729
|> validate_required(@required_fields)
2830
|> foreign_key_constraint(:post_id)

lib/helper/error_code.ex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ defmodule Helper.ErrorCode do
77
@throttle_base 4200
88
@account_base 4300
99
@comment_base 4400
10+
@article_base 4500
1011

1112
@spec raise_error(Atom.t(), String.t()) :: {:error, [message: String.t(), code: Integer.t()]}
1213
def raise_error(code_atom, msg) do
@@ -38,8 +39,10 @@ defmodule Helper.ErrorCode do
3839
def ecode(:throttle_inverval), do: @throttle_base + 1
3940
def ecode(:throttle_hour), do: @throttle_base + 2
4041
def ecode(:throttle_day), do: @throttle_base + 3
41-
#
42+
# comment
4243
def ecode(:create_comment), do: @comment_base + 1
44+
# article
45+
def ecode(:too_much_pinned_article), do: @article_base + 1
4346

4447
def ecode, do: @default_base
4548
# def ecode(_), do: @default_base

priv/repo/migrations/20210429014800_create_pined_article.exs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ defmodule GroupherServer.Repo.Migrations.CreatePinedArticle do
22
use Ecto.Migration
33

44
def change do
5-
create table(:pined_articles) do
5+
create table(:pinned_articles) do
66
add(:post_id, references(:cms_posts, on_delete: :delete_all))
77
add(:job_id, references(:cms_jobs, on_delete: :delete_all))
88
add(:community_id, references(:communities, on_delete: :delete_all), null: false)
9+
add(:thread, :string)
910

1011
timestamps()
1112
end
1213

13-
create(index(:pined_articles, [:post_id]))
14-
create(index(:pined_articles, [:job_id]))
15-
create(index(:pined_articles, [:community_id]))
16-
create(unique_index(:pined_articles, [:post_id, :job_id, :community_id]))
14+
create(index(:pinned_articles, [:post_id]))
15+
create(index(:pinned_articles, [:job_id]))
16+
create(index(:pinned_articles, [:community_id]))
17+
create(unique_index(:pinned_articles, [:post_id, :job_id, :community_id]))
1718
end
1819
end

test/groupher_server/cms/article_pin_test.exs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@ defmodule GroupherServer.Test.CMS.ArticlePin do
55
alias GroupherServer.CMS
66

77
alias CMS.{
8-
PinedArticle,
8+
Community,
9+
PinnedArticle,
910
Post,
1011
Job
1112
}
1213

14+
@max_pinned_article_count_per_thread Community.max_pinned_article_count_per_thread()
15+
1316
setup do
1417
{:ok, user} = db_insert(:user)
1518
{:ok, community} = db_insert(:community)
@@ -22,15 +25,29 @@ defmodule GroupherServer.Test.CMS.ArticlePin do
2225
end
2326

2427
describe "[cms post pin]" do
25-
@tag :wip2
28+
@tag :wip
2629
test "can pin a post", ~m(community post)a do
2730
{:ok, _} = CMS.pin_article(:post, post.id, community.id)
28-
{:ok, pind_article} = ORM.find_by(PinedArticle, %{post_id: post.id})
31+
{:ok, pind_article} = ORM.find_by(PinnedArticle, %{post_id: post.id})
2932

3033
assert pind_article.post_id == post.id
3134
end
3235

3336
@tag :wip2
37+
test "one community & thread can only pin certern count of post", ~m(community post user)a do
38+
{:ok, post2} = CMS.create_content(community, :post, mock_attrs(:post), user)
39+
{:ok, post3} = CMS.create_content(community, :post, mock_attrs(:post), user)
40+
41+
Enum.reduce(1..@max_pinned_article_count_per_thread, [], fn _, acc ->
42+
{:ok, _} = CMS.pin_article(:post, post.id, community.id)
43+
acc
44+
end)
45+
46+
{:error, reason} = CMS.pin_article(:post, post3.id, community.id)
47+
assert reason |> Keyword.get(:code) == ecode(:too_much_pinned_article)
48+
end
49+
50+
@tag :wip
3451
test "can not pin a non-exsit post", ~m(community post)a do
3552
assert {:error, _} = CMS.pin_article(:post, 8848, community.id)
3653
end

0 commit comments

Comments
 (0)