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

fix(user): improve common article extract #375

Merged
merged 4 commits into from
May 31, 2021
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
4 changes: 0 additions & 4 deletions lib/groupher_server/accounts/collect_folder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ defmodule GroupherServer.Accounts.CollectFolder do
@required_fields ~w(user_id title)a
@optional_fields ~w(index total_count private desc last_updated)a

@supported_threads [:post, :job, :repo]

def supported_threads, do: @supported_threads

@type t :: %CollectFolder{}
schema "collect_folders" do
belongs_to(:user, User, foreign_key: :user_id)
Expand Down
14 changes: 10 additions & 4 deletions lib/groupher_server/accounts/delegates/collect_folder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule GroupherServer.Accounts.Delegate.CollectFolder do
alias Helper.QueryBuilder

import Helper.ErrorCode
import Helper.Utils, only: [done: 1]
import Helper.Utils, only: [done: 1, get_config: 2]

import ShortMaps

Expand All @@ -24,7 +24,7 @@ defmodule GroupherServer.Accounts.Delegate.CollectFolder do
# @max_article_count_per_collect_folder 300

@default_meta Embeds.CollectFolderMeta.default_meta()
@supported_collect_threads [:post, :job]
@article_threads get_config(:article, :article_threads)

@doc """
list a user's not-private collect folders
Expand Down Expand Up @@ -75,9 +75,15 @@ defmodule GroupherServer.Accounts.Delegate.CollectFolder do
end

defp do_paged_collect_folder_articles(folder, filter) do
Repo.preload(folder.collects, @supported_collect_threads)
article_preload =
@article_threads
|> Enum.reduce([], fn thread, acc ->
acc ++ Keyword.new([{thread, [author: :user]}])
end)

Repo.preload(folder.collects, article_preload)
|> ORM.embeds_paginater(filter)
|> ORM.extract_articles(@supported_collect_threads)
|> ORM.extract_articles()
|> done()
end

Expand Down
5 changes: 2 additions & 3 deletions lib/groupher_server/accounts/delegates/publish.ex
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,8 @@ defmodule GroupherServer.Accounts.Delegate.Publish do
thread = thread |> to_string |> String.upcase()
thread_atom = thread |> String.downcase() |> String.to_atom()

# article_preload = Keyword.new([{thread_atom, :author}])
# query = from(comment in ArticleComment, preload: ^article_preload)
query = from(comment in ArticleComment, preload: ^thread_atom)
article_preload = Keyword.new([{thread_atom, [author: :user]}])
query = from(comment in ArticleComment, preload: ^article_preload)

query
|> join(:inner, [comment], author in assoc(comment, :author))
Expand Down
15 changes: 10 additions & 5 deletions lib/groupher_server/accounts/delegates/upvoted_articles.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ defmodule GroupherServer.Accounts.Delegate.UpvotedArticles do
get contents(posts, jobs ...) that user upvotes
"""
import Ecto.Query, warn: false
import Helper.Utils, only: [done: 1]
import Helper.Utils, only: [done: 1, get_config: 2]
import ShortMaps

alias Helper.{ORM, QueryBuilder}

alias GroupherServer.CMS
alias CMS.{ArticleUpvote}

# TODO: move to Model
@supported_uovoted_threads [:post, :job]
@article_threads get_config(:article, :article_threads)

@doc """
get paged upvoted articles
Expand All @@ -31,13 +30,19 @@ defmodule GroupherServer.Accounts.Delegate.UpvotedArticles do
end

defp load_upvoted_articles(where_query, %{page: page, size: size} = filter) do
query = from(a in ArticleUpvote, preload: ^@supported_uovoted_threads)
article_preload =
@article_threads
|> Enum.reduce([], fn thread, acc ->
acc ++ Keyword.new([{thread, [author: :user]}])
end)

query = from(a in ArticleUpvote, preload: ^article_preload)

query
|> where(^where_query)
|> QueryBuilder.filter_pack(filter)
|> ORM.paginater(~m(page size)a)
|> ORM.extract_articles(@supported_uovoted_threads)
|> ORM.extract_articles()
|> done()
end
end
19 changes: 9 additions & 10 deletions lib/groupher_server/accounts/embeds/collect_folder_meta.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ defmodule GroupherServer.Accounts.Embeds.CollectFolderMeta.Macros do
field(:has_repo, :boolean, default: false)
field(:repo_count, :integer, default: 0)
"""
alias GroupherServer.Accounts.CollectFolder
import Helper.Utils, only: [get_config: 2]

@supported_threads CollectFolder.supported_threads()
@article_threads get_config(:article, :article_threads)

defmacro threads_fields() do
@supported_threads
@article_threads
|> Enum.map(fn thread ->
quote do
field(unquote(:"has_#{thread}"), :boolean, default: false)
Expand All @@ -27,21 +27,20 @@ end

defmodule GroupherServer.Accounts.Embeds.CollectFolderMeta do
@moduledoc """
general article meta info for article-like content, like @supported_threads
general article meta info for articles
"""
use Ecto.Schema
import Ecto.Changeset
import GroupherServer.Accounts.Embeds.CollectFolderMeta.Macros
import Helper.Utils, only: [get_config: 2]

alias GroupherServer.Accounts.CollectFolder
@article_threads get_config(:article, :article_threads)

@supported_threads CollectFolder.supported_threads()

@optional_fields Enum.map(@supported_threads, &:"#{&1}_count") ++
Enum.map(@supported_threads, &:"has_#{&1}")
@optional_fields Enum.map(@article_threads, &:"#{&1}_count") ++
Enum.map(@article_threads, &:"has_#{&1}")

def default_meta() do
@supported_threads
@article_threads
|> Enum.reduce([], fn thread, acc -> acc ++ ["#{thread}_count": 0, "has_#{thread}": false] end)
|> Enum.into(%{})
end
Expand Down
3 changes: 1 addition & 2 deletions lib/groupher_server_web/schema/Helper/fields.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do
@page_size get_config(:general, :page_size)
@supported_emotions get_config(:article, :supported_emotions)
@supported_comment_emotions get_config(:article, :comment_supported_emotions)
@supported_collect_folder_threads Accounts.CollectFolder.supported_threads()

@article_threads get_config(:article, :article_threads)

Expand Down Expand Up @@ -242,7 +241,7 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do
general collect folder meta info
"""
defmacro collect_folder_meta_fields() do
@supported_collect_folder_threads
@article_threads
|> Enum.map(fn thread ->
quote do
field(unquote(:"has_#{thread}"), :boolean)
Expand Down
2 changes: 1 addition & 1 deletion lib/groupher_server_web/schema/cms/cms_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
field(:id, :id)
# field(:body_html, :string)
field(:title, :string)
field(:author, :user, resolve: dataloader(CMS, :author))
field(:author, :common_user)
end

object :common_article_comment do
Expand Down
16 changes: 11 additions & 5 deletions lib/helper/orm.ex
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ defmodule Helper.ORM do
|> Repo.update()
end

@doc """
extract common article info and assign it to 'article' field
"""
def extract_and_assign_article(%{entries: entries} = paged_articles) do
entries =
Enum.map(entries, fn item ->
Expand All @@ -307,24 +310,27 @@ defmodule Helper.ORM do

@doc "extract common articles info"
@spec extract_articles(T.paged_data(), [Atom.t()]) :: T.paged_article_common()
def extract_articles(%{entries: entries} = paged_articles, supported_threads) do
def extract_articles(%{entries: entries} = paged_articles, threads \\ @article_threads) do
paged_articles
|> Map.put(:entries, Enum.map(entries, &extract_article_info(&1, supported_threads)))
|> Map.put(:entries, Enum.map(entries, &extract_article_info(&1, threads)))
end

defp extract_article_info(reaction, supported_threads) do
thread = Enum.find(supported_threads, &(not is_nil(Map.get(reaction, &1))))
defp extract_article_info(reaction, threads) do
thread = Enum.find(threads, &(not is_nil(Map.get(reaction, &1))))
article = Map.get(reaction, thread)

export_article_info(thread, article)
end

defp export_article_info(thread, article) do
author = article.author.user

%{
thread: thread,
id: article.id,
title: article.title,
upvotes_count: Map.get(article, :upvotes_count)
upvotes_count: Map.get(article, :upvotes_count),
author: author
}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ defmodule GroupherServer.Test.Accounts.Published.Job do
end

describe "[publised job comments]" do
@tag :wip2
test "can get published article comments", ~m(job user)a do
total_count = 10

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ defmodule GroupherServer.Test.Accounts.Published.Post do
end

describe "[publised post comments]" do
@tag :wip2
test "can get published article comments", ~m(post user)a do
total_count = 10

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ defmodule GroupherServer.Test.Accounts.Published.Repo do
end

describe "[publised repo comments]" do
@tag :wip2
test "can get published article comments", ~m(repo user)a do
total_count = 10

Expand Down
5 changes: 3 additions & 2 deletions test/groupher_server/accounts/reacted_articles_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ defmodule GroupherServer.Test.Accounts.ReactedContents do
end

describe "[user upvoted articles]" do
@tag :wip2
test "user can get paged upvoted common articles", ~m(user post job)a do
{:ok, _} = CMS.upvote_article(:post, post.id, user)
{:ok, _} = CMS.upvote_article(:job, job.id, user)
Expand All @@ -28,8 +29,8 @@ defmodule GroupherServer.Test.Accounts.ReactedContents do
assert job.id == article_job |> Map.get(:id)
assert post.id == article_post |> Map.get(:id)

assert [:id, :thread, :title, :upvotes_count] == article_post |> Map.keys()
assert [:id, :thread, :title, :upvotes_count] == article_job |> Map.keys()
assert [:author, :id, :thread, :title, :upvotes_count] == article_post |> Map.keys()
assert [:author, :id, :thread, :title, :upvotes_count] == article_job |> Map.keys()
end

test "user can get paged upvoted posts by thread filter", ~m(user post job)a do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Jobs do
}
}
"""
@tag :wip2

test "can get published jobs", ~m(guest_conn community user)a do
job_attrs = mock_attrs(:job, %{community_id: community.id})

Expand Down Expand Up @@ -62,6 +62,10 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Jobs do
article {
id
title
author {
nickname
login
}
}
}
totalPages
Expand All @@ -71,7 +75,7 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Jobs do
}
}
"""
@tag :wip2

test "user can get paged published comments on job", ~m(guest_conn user job)a do
pub_comments =
Enum.reduce(1..@publish_count, [], fn _, acc ->
Expand All @@ -82,14 +86,18 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Jobs do
random_comment_id = pub_comments |> Enum.random() |> Map.get(:id) |> to_string

variables = %{login: user.login, thread: "JOB", filter: %{page: 1, size: 20}}

results = guest_conn |> query_result(@query, variables, "pagedPublishedArticleComments")

entries = results["entries"]
assert results |> is_valid_pagination?
assert results["totalCount"] == @publish_count

assert results["entries"] |> Enum.all?(&(&1["article"]["id"] == to_string(job.id)))
assert results["entries"] |> Enum.all?(&(&1["author"]["id"] == to_string(user.id)))
assert results["entries"] |> Enum.any?(&(&1["id"] == random_comment_id))
assert entries |> Enum.all?(&(not is_nil(&1["article"]["author"])))

assert entries |> Enum.all?(&(&1["article"]["id"] == to_string(job.id)))
assert entries |> Enum.all?(&(&1["author"]["id"] == to_string(user.id)))
assert entries |> Enum.any?(&(&1["id"] == random_comment_id))
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Posts do
}
}
"""
@tag :wip2

test "can get published posts", ~m(guest_conn community user)a do
post_attrs = mock_attrs(:post, %{community_id: community.id})

Expand Down Expand Up @@ -62,6 +62,10 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Posts do
article {
id
title
author {
nickname
login
}
}
}
totalPages
Expand All @@ -71,7 +75,7 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Posts do
}
}
"""
@tag :wip2

test "user can get paged published comments on post", ~m(guest_conn user post)a do
pub_comments =
Enum.reduce(1..@publish_count, [], fn _, acc ->
Expand All @@ -82,14 +86,18 @@ defmodule GroupherServer.Test.Query.Accounts.Published.Posts do
random_comment_id = pub_comments |> Enum.random() |> Map.get(:id) |> to_string

variables = %{login: user.login, thread: "POST", filter: %{page: 1, size: 20}}

results = guest_conn |> query_result(@query, variables, "pagedPublishedArticleComments")

entries = results["entries"]
assert results |> is_valid_pagination?
assert results["totalCount"] == @publish_count

assert results["entries"] |> Enum.all?(&(&1["article"]["id"] == to_string(post.id)))
assert results["entries"] |> Enum.all?(&(&1["author"]["id"] == to_string(user.id)))
assert results["entries"] |> Enum.any?(&(&1["id"] == random_comment_id))
assert entries |> Enum.all?(&(not is_nil(&1["article"]["author"])))

assert entries |> Enum.all?(&(&1["article"]["id"] == to_string(post.id)))
assert entries |> Enum.all?(&(&1["author"]["id"] == to_string(user.id)))
assert entries |> Enum.any?(&(&1["id"] == random_comment_id))
end
end
end
Loading