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

refactor(blog): GQ endpoint #433

Merged
merged 3 commits into from
Oct 3, 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
42 changes: 23 additions & 19 deletions lib/groupher_server/cms/delegates/blog_curd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@ defmodule GroupherServer.CMS.Delegate.BlogCURD do
CURD operation on post/job ...
"""
import Ecto.Query, warn: false
import Helper.Utils, only: [strip_struct: 1]
import Helper.Utils, only: [strip_struct: 1, done: 1]
import GroupherServer.Support.Factory, only: [mock_rich_text: 1]
import Helper.ErrorCode

import GroupherServer.CMS.Delegate.ArticleCURD, only: [create_article: 4]
# import Helper.Utils, only: [done: 1]

# import Helper.ErrorCode
# import ShortMaps

# alias Helper.{ORM}
alias GroupherServer.{Accounts, CMS, Repo}
alias CMS.Model.{BlogRSS, Community}
alias Accounts.Model.User
Expand Down Expand Up @@ -46,22 +42,14 @@ defmodule GroupherServer.CMS.Delegate.BlogCURD do
blog_author = if is_nil(feed.author), do: nil, else: Map.from_struct(feed.author)
selected_feed = Enum.find(feed.history_feed, &(&1.title == attrs.title))

# TODO: feed_digest, feed_content
attrs =
attrs
|> Map.merge(%{
link_addr: selected_feed.link_addr,
published: selected_feed.published,
blog_author: blog_author
})
|> Enum.reject(fn {_, v} -> is_nil(v) end)
|> Map.new()

create_article(community, :blog, attrs, user)
with {:ok, attrs} <- build_blog_attrs(attrs, blog_author, selected_feed) do
# TODO: feed_digest, feed_content
create_article(community, :blog, attrs, user)
end
end

# rss 记录不存在, 先创建 rss, 再创建 blog
defp do_create_blog(%Community{} = community, attrs, %User{} = user, feed) do
defp do_create_blog(%Community{} = community, attrs, %User{} = user, _feed) do
with {:ok, feed} <- CMS.blog_rss_info(attrs.rss),
{:ok, feed} <- create_blog_rss(feed) do
do_create_blog(community, attrs, user, feed)
Expand Down Expand Up @@ -111,4 +99,20 @@ defmodule GroupherServer.CMS.Delegate.BlogCURD do
{:error, _} -> {:error, [message: "blog rss is invalid", code: ecode(:invalid_blog_rss)]}
end
end

defp build_blog_attrs(_attrs, _blog_author, nil),
do: {:error, [message: "blog title not in rss", code: ecode(:invalid_blog_title)]}

defp build_blog_attrs(attrs, blog_author, selected_feed) do
attrs
|> Map.merge(%{
link_addr: selected_feed.link_addr,
published: selected_feed.published,
blog_author: blog_author,
body: mock_rich_text("pleace use content field instead")
})
|> Enum.reject(fn {_, v} -> is_nil(v) end)
|> Map.new()
|> done
end
end
4 changes: 4 additions & 0 deletions lib/groupher_server_web/resolvers/cms_resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ defmodule GroupherServerWeb.Resolvers.CMS do
def wiki(_root, ~m(community)a, _info), do: CMS.get_wiki(%Community{raw: community})
def cheatsheet(_root, ~m(community)a, _info), do: CMS.get_cheatsheet(%Community{raw: community})

def create_blog(_root, ~m(community_id)a = args, %{context: %{cur_user: user}}) do
CMS.create_blog(%Community{id: community_id}, args, user)
end

def create_works(_root, args, %{context: %{cur_user: user}}) do
CMS.create_works(args, user)
end
Expand Down
31 changes: 13 additions & 18 deletions lib/groupher_server_web/schema/cms/mutations/blog.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,31 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Blog do
@desc "create a blog"
field :create_blog, :blog do
arg(:title, non_null(:string))
arg(:body, non_null(:string))
arg(:rss, non_null(:string))
arg(:community_id, non_null(:id))
arg(:link_addr, :string)
arg(:thread, :thread, default_value: :blog)
arg(:article_tags, list_of(:id))

middleware(M.Authorize, :login)
middleware(M.PublishThrottle)
resolve(&R.CMS.create_article/3)
resolve(&R.CMS.create_blog/3)
middleware(M.Statistics.MakeContribute, for: [:user, :community])
end

@desc "update a cms/blog"
field :update_blog, :blog do
arg(:id, non_null(:id))
arg(:title, :string)
arg(:body, :string)
arg(:digest, :string)
arg(:link_addr, :string)
# @desc "update a cms/blog"
# field :update_blog, :blog do
# arg(:id, non_null(:id))
# arg(:title, :string)

arg(:article_tags, list_of(:id))

# ...
# arg(:article_tags, list_of(:id))
# # ...

middleware(M.Authorize, :login)
middleware(M.PassportLoader, source: :blog)
middleware(M.Passport, claim: "owner;cms->c?->blog.edit")
# middleware(M.Authorize, :login)
# middleware(M.PassportLoader, source: :blog)
# middleware(M.Passport, claim: "owner;cms->c?->blog.edit")

resolve(&R.CMS.update_article/3)
end
# resolve(&R.CMS.update_article/3)
# end

article_react_mutations(:blog, [
:upvote,
Expand Down
1 change: 1 addition & 0 deletions lib/helper/error_code.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ defmodule Helper.ErrorCode do
def ecode(:cite_artilce), do: @article_base + 10
def ecode(:archived), do: @article_base + 11
def ecode(:invalid_blog_rss), do: @article_base + 12
def ecode(:invalid_blog_title), do: @article_base + 13
# def ecode(:already_solved), do: @article_base + 10

def ecode, do: @default_base
Expand Down
132 changes: 36 additions & 96 deletions test/groupher_server_web/mutation/cms/articles/blog_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ defmodule GroupherServer.Test.Mutation.Articles.Blog do

alias CMS.Model.Blog

@rss mock_rss_addr()

setup do
{:ok, user} = db_insert(:user)
{:ok, community} = db_insert(:community)
Expand All @@ -24,18 +26,19 @@ defmodule GroupherServer.Test.Mutation.Articles.Blog do
@create_blog_query """
mutation (
$title: String!,
$body: String,
$rss: String!,
$communityId: ID!,
$articleTags: [Id]
) {
createBlog(
title: $title,
body: $body,
rss: $rss,
communityId: $communityId,
articleTags: $articleTags
) {
id
title
digest
document {
bodyHtml
}
Expand All @@ -49,13 +52,14 @@ defmodule GroupherServer.Test.Mutation.Articles.Blog do
}
}
"""
@tag :wip
test "create blog with valid attrs and make sure author exsit" do
{:ok, user} = db_insert(:user)
user_conn = simu_conn(:user, user)

{:ok, community} = db_insert(:community)
blog_attr = mock_attrs(:blog)

blog_attr = mock_attrs(:blog) |> Map.merge(%{rss: @rss})
# IO.inspect(blog_attr, label: "# blog_attr -> ")
variables = blog_attr |> Map.merge(%{communityId: community.id}) |> camelize_map_key

created = user_conn |> mutation_result(@create_blog_query, variables, "createBlog")
Expand All @@ -64,10 +68,26 @@ defmodule GroupherServer.Test.Mutation.Articles.Blog do

assert created["id"] == to_string(found.id)
assert created["originalCommunity"]["id"] == to_string(community.id)

assert created["id"] == to_string(found.id)
end

@tag :wip
test "create blog with non-exsit title fails" do
{:ok, user} = db_insert(:user)
user_conn = simu_conn(:user, user)

{:ok, community} = db_insert(:community)
blog_attr = mock_attrs(:blog) |> Map.merge(%{rss: @rss})

variables =
blog_attr
|> Map.merge(%{communityId: community.id, title: "non-exsit"})
|> camelize_map_key

assert user_conn
|> mutation_get_error?(@create_blog_query, variables, ecode(:invalid_blog_title))
end

test "create blog with valid tags id list", ~m(user_conn user community)a do
article_tag_attrs = mock_attrs(:article_tag)
{:ok, article_tag} = CMS.create_article_tag(community, :blog, article_tag_attrs, user)
Expand Down Expand Up @@ -99,100 +119,20 @@ defmodule GroupherServer.Test.Mutation.Articles.Blog do
assert not String.contains?(body_html, "script")
end

test "create blog should excape xss attracts 2" do
{:ok, user} = db_insert(:user)
user_conn = simu_conn(:user, user)

{:ok, community} = db_insert(:community)

blog_attr = mock_attrs(:blog, %{body: mock_xss_string(:safe)})
variables = blog_attr |> Map.merge(%{communityId: community.id}) |> camelize_map_key
result = user_conn |> mutation_result(@create_blog_query, variables, "createBlog")
{:ok, blog} = ORM.find(Blog, result["id"], preload: :document)
body_html = blog |> get_in([:document, :body_html])

assert String.contains?(body_html, "&lt;script&gt;blackmail&lt;/script&gt;")
end

@query """
mutation($id: ID!, $title: String, $body: String, $articleTags: [Ids]){
updateBlog(id: $id, title: $title, body: $body, articleTags: $articleTags) {
id
title
document {
bodyHtml
}
articleTags {
id
}
}
}
"""
test "update a blog without login user fails", ~m(guest_conn blog)a do
unique_num = System.unique_integer([:positive, :monotonic])

variables = %{
id: blog.id,
title: "updated title #{unique_num}",
body: mock_rich_text("updated body #{unique_num}")
}

assert guest_conn |> mutation_get_error?(@query, variables, ecode(:account_login))
end

test "blog can be update by owner", ~m(owner_conn blog)a do
unique_num = System.unique_integer([:positive, :monotonic])

variables = %{
id: blog.id,
title: "updated title #{unique_num}",
body: mock_rich_text("updated body #{unique_num}")
}
# test "create blog should excape xss attracts" do
# {:ok, user} = db_insert(:user)
# user_conn = simu_conn(:user, user)

result = owner_conn |> mutation_result(@query, variables, "updateBlog")
# {:ok, community} = db_insert(:community)

assert result["title"] == variables.title
# blog_attr = mock_attrs(:blog, %{body: mock_xss_string(:safe)})
# variables = blog_attr |> Map.merge(%{communityId: community.id}) |> camelize_map_key
# result = user_conn |> mutation_result(@create_blog_query, variables, "createBlog")
# {:ok, blog} = ORM.find(Blog, result["id"], preload: :document)
# body_html = blog |> get_in([:document, :body_html])

assert result
|> get_in(["document", "bodyHtml"])
|> String.contains?(~s(updated body #{unique_num}))
end

test "login user with auth passport update a blog", ~m(blog)a do
blog = blog |> Repo.preload(:communities)

blog_communities_0 = blog.communities |> List.first() |> Map.get(:title)
passport_rules = %{blog_communities_0 => %{"blog.edit" => true}}
rule_conn = simu_conn(:user, cms: passport_rules)

unique_num = System.unique_integer([:positive, :monotonic])

variables = %{
id: blog.id,
title: "updated title #{unique_num}",
body: mock_rich_text("updated body #{unique_num}")
}

updated = rule_conn |> mutation_result(@query, variables, "updateBlog")

assert updated["id"] == to_string(blog.id)
end

test "unauth user update blog fails", ~m(user_conn guest_conn blog)a do
unique_num = System.unique_integer([:positive, :monotonic])

variables = %{
id: blog.id,
title: "updated title #{unique_num}",
body: mock_rich_text("updated body #{unique_num}")
}

rule_conn = simu_conn(:user, cms: %{"what.ever" => true})

assert user_conn |> mutation_get_error?(@query, variables, ecode(:passport))
assert guest_conn |> mutation_get_error?(@query, variables, ecode(:account_login))
assert rule_conn |> mutation_get_error?(@query, variables, ecode(:passport))
end
# assert String.contains?(body_html, "&lt;script&gt;blackmail&lt;/script&gt;")
# end

@query """
mutation($id: ID!){
Expand Down
2 changes: 0 additions & 2 deletions test/groupher_server_web/mutation/cms/articles/works_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
}
}
"""
@tag :wip
test "create works with valid attrs and make sure author exsit", ~m(community)a do
{:ok, user} = db_insert(:user)
user_conn = simu_conn(:user, user)
Expand Down Expand Up @@ -232,7 +231,6 @@ defmodule GroupherServer.Test.Mutation.Articles.Works do
}
}
"""
@tag :wip
test "works can be update by owner", ~m(owner_conn works)a do
unique_num = System.unique_integer([:positive, :monotonic])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ defmodule GroupherServer.Test.Mutation.Statistics do
@create_blog_query """
mutation (
$title: String!,
$body: String!,
$rss: String!
$communityId: ID!,
$articleTags: [Ids]
) {
createBlog(
title: $title,
body: $body,
rss: $rss,
communityId: $communityId,
articleTags: $articleTags
) {
Expand Down
9 changes: 3 additions & 6 deletions test/helper/rss_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ defmodule GroupherServer.Test.Helper.RSSTest do
# blog_attrs = mock_attrs(:blog, %{community_id: community.id})
blog_attrs = %{
rss: @rss,
title: title,
body: mock_rich_text("pleace use content field instead")
title: title
}

{:ok, blog} = CMS.create_blog(community, blog_attrs, user)
Expand All @@ -44,8 +43,7 @@ defmodule GroupherServer.Test.Helper.RSSTest do
# blog_attrs = mock_attrs(:blog, %{community_id: community.id})
blog_attrs = %{
rss: @rss,
title: title,
body: mock_rich_text("pleace use content field instead")
title: title
}

{:ok, blog} = CMS.create_blog(community, blog_attrs, user)
Expand Down Expand Up @@ -75,8 +73,7 @@ defmodule GroupherServer.Test.Helper.RSSTest do
# blog_attrs = mock_attrs(:blog, %{community_id: community.id})
blog_attrs = %{
rss: @rss,
title: title,
body: mock_rich_text("pleace use content field instead")
title: title
}

{:ok, blog} = CMS.create_blog(community, blog_attrs, user)
Expand Down
5 changes: 3 additions & 2 deletions test/support/factory.ex
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,10 @@ defmodule GroupherServer.Support.Factory do

%{
meta: @default_article_meta |> Map.merge(%{thread: "BLOG"}),
title: "blog-#{String.slice(text, 1, 49)}",
title: "HTML slot 插槽元素深入",
rss: mock_rss_addr(),
body: mock_rich_text(text),
digest: String.slice(text, 1, 150),
# digest: String.slice(text, 1, 150),
length: String.length(text),
author: mock(:author),
views: Enum.random(0..2000),
Expand Down