Skip to content

Commit 3ce5ce3

Browse files
authored
Merge pull request #274 from steelstyle/feature/show-pending-moderation
Adds a method to retrieve actions pending moderation which are actionable by the logged in user.
2 parents d7ce773 + dc9bd0a commit 3ce5ce3

File tree

4 files changed

+114
-7
lines changed

4 files changed

+114
-7
lines changed

apps/cf/lib/moderation/moderation.ex

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defmodule CF.Moderation do
1111
1212
-------------
1313
14-
Some usefull commands for testing:
14+
Some useful commands for testing:
1515
# Insert 5 comments with 10 flags on each
1616
DB.Factory.insert_list(5, :comment) |> Enum.map(&DB.Factory.with_action/1) |> CF.TestUtils.flag_comments(10)
1717
# Update flags
@@ -53,11 +53,7 @@ defmodule CF.Moderation do
5353
UserPermissions.check!(user, :collective_moderation)
5454

5555
UserAction
56-
|> where([a], a.user_id != ^user.id)
57-
|> without_user_feedback(user)
58-
|> join(:inner, [a, _], f in Flag, f.action_id == a.id)
59-
|> group_by([a, _, _], a.id)
60-
|> being_reported()
56+
|> requiring_moderation(user)
6157
|> preload([a, _, _], [:user])
6258
|> order_by(fragment("RANDOM()"))
6359
|> select([a, _, _], a)
@@ -66,6 +62,21 @@ defmodule CF.Moderation do
6662
|> moderation_entry()
6763
end
6864

65+
@doc """
66+
Get the count of actions for which number of flags is above the limit and for which
67+
user hasn't voted yet. Will raise if `user` doesn't have permission to moderate.
68+
"""
69+
@spec unread_count!(DB.Schema.User.t()) :: any
70+
def unread_count!(user) do
71+
UserPermissions.check!(user, :collective_moderation)
72+
73+
UserAction
74+
|> requiring_moderation(user)
75+
|> select([a, _, _], a)
76+
|> subquery
77+
|> Repo.aggregate(:count, :id)
78+
end
79+
6980
@doc """
7081
Record user feedback for a flagged action
7182
Will raise if `user` doesn't have permission to moderate
@@ -132,6 +143,15 @@ defmodule CF.Moderation do
132143
end)
133144
end
134145

146+
defp requiring_moderation(query, user) do
147+
query
148+
|> where([a], a.user_id != ^user.id)
149+
|> without_user_feedback(user)
150+
|> join(:inner, [a, _], f in Flag, f.action_id == a.id)
151+
|> group_by([a, _, _], a.id)
152+
|> being_reported()
153+
end
154+
135155
defp moderation_entry(action = %UserAction{}) do
136156
%ModerationEntry{
137157
action: action,
Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,80 @@
11
defmodule CF.ModerationTest do
22
use CF.DataCase
3-
# import CF.TestUtils, only: [flag_comments: 2]
3+
4+
import CF.TestUtils, only: [flag_comments: 2]
5+
6+
alias CF.Moderation
7+
alias DB.Schema.UserAction
8+
49
doctest CF.Moderation
510

611
# TODO can only give one feedback
712
# TODO cannot give feedback on an action which is not reported
813
# TODO Make sure user doesn't get and cannot give feedback on its own actions or actions he's targeted by
14+
15+
describe "unread_count" do
16+
test "no moderation entries if all open actions belong to users" do
17+
user = insert(:user, reputation: 1000)
18+
limit = max(Moderation.nb_flags_to_report(:create, :comment), 0)
19+
20+
Enum.each(1..5, fn x ->
21+
comment =
22+
insert(:comment, %{user: user, text: "Own comment" <> to_string(x)})
23+
|> with_action()
24+
25+
flag_comments([comment], limit)
26+
end)
27+
28+
count = Moderation.unread_count!(user)
29+
assert count == 0
30+
end
31+
32+
test "count pending actions from other users" do
33+
user = insert(:user, reputation: 1000)
34+
limit = Moderation.nb_flags_to_report(:create, :comment)
35+
36+
comment =
37+
insert(:comment, %{user: user, text: "Own comment"})
38+
|> with_action()
39+
40+
flag_comments([comment], limit)
41+
42+
Enum.each(1..8, fn x ->
43+
comment = insert(:comment, %{text: "User comment " <> to_string(x)}) |> with_action()
44+
flag_comments([comment], limit)
45+
Repo
46+
end)
47+
48+
count = Moderation.unread_count!(user)
49+
assert count == 8
50+
end
51+
52+
test "count pending actions from other users, unless already moderated" do
53+
user = insert(:user, reputation: 1000)
54+
limit = Moderation.nb_flags_to_report(:create, :comment)
55+
comment = insert(:comment, %{user: user, text: "Own comment"}) |> with_action()
56+
flag_comments([comment], limit)
57+
58+
Enum.each(1..8, fn x ->
59+
comment = insert(:comment, %{text: "User comment" <> to_string(x)}) |> with_action()
60+
flag_comments([comment], limit)
61+
62+
# Produce feedback for two of the actions.
63+
if rem(x, 3) == 0 do
64+
action =
65+
Repo.get_by!(
66+
UserAction,
67+
entity: :comment,
68+
type: :create,
69+
comment_id: comment.id
70+
)
71+
72+
Moderation.feedback!(user, action.id, 1, 1)
73+
end
74+
end)
75+
76+
count = Moderation.unread_count!(user)
77+
assert count == 6
78+
end
79+
end
980
end

apps/cf_graphql/lib/resolvers/users.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ defmodule CF.Graphql.Resolvers.Users do
55

66
import Ecto.Query
77

8+
alias CF.Moderation
9+
810
alias Kaur.Result
911

1012
alias DB.Repo
@@ -78,6 +80,14 @@ defmodule CF.Graphql.Resolvers.Users do
7880
|> Result.ok()
7981
end
8082

83+
@doc """
84+
Resolve user actions history
85+
"""
86+
def pending_moderations(user, _, _) do
87+
Moderation.unread_count!(user)
88+
|> Result.ok()
89+
end
90+
8191
@doc """
8292
Get videos added by this user
8393
"""

apps/cf_graphql/lib/schema/types/user.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ defmodule CF.Graphql.Schema.Types.User do
5959
resolve(&Resolvers.Notifications.for_user/3)
6060
end
6161

62+
@desc "Actions pending moderation"
63+
field :actions_pending_moderation, :integer do
64+
middleware(Middleware.RequireAuthentication)
65+
resolve(&Resolvers.Users.pending_moderations/3)
66+
end
67+
6268
@desc "User subscriptions"
6369
field :subscriptions, list_of(:notifications_subscription) do
6470
middleware(Middleware.RequireAuthentication)

0 commit comments

Comments
 (0)