From 38a33eb850fcb75e0a634a63ff552e8991a6fd47 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 3 Oct 2021 13:30:34 +0800 Subject: [PATCH 1/3] refactor(blog): GQ endpoint --- .../cms/delegates/blog_curd.ex | 42 ++++++++++--------- .../resolvers/cms_resolver.ex | 4 ++ .../schema/cms/mutations/blog.ex | 9 +--- lib/helper/error_code.ex | 1 + .../mutation/cms/articles/blog_test.exs | 30 ++++++++++--- .../mutation/cms/articles/works_test.exs | 2 - test/helper/rss_test.exs | 9 ++-- test/support/factory.ex | 5 ++- 8 files changed, 61 insertions(+), 41 deletions(-) diff --git a/lib/groupher_server/cms/delegates/blog_curd.ex b/lib/groupher_server/cms/delegates/blog_curd.ex index c8752668d..e87773542 100644 --- a/lib/groupher_server/cms/delegates/blog_curd.ex +++ b/lib/groupher_server/cms/delegates/blog_curd.ex @@ -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 @@ -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) @@ -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 diff --git a/lib/groupher_server_web/resolvers/cms_resolver.ex b/lib/groupher_server_web/resolvers/cms_resolver.ex index 8d35d0d6b..dd7bf49f2 100644 --- a/lib/groupher_server_web/resolvers/cms_resolver.ex +++ b/lib/groupher_server_web/resolvers/cms_resolver.ex @@ -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 diff --git a/lib/groupher_server_web/schema/cms/mutations/blog.ex b/lib/groupher_server_web/schema/cms/mutations/blog.ex index 1f2b2971e..8d939cb8f 100644 --- a/lib/groupher_server_web/schema/cms/mutations/blog.ex +++ b/lib/groupher_server_web/schema/cms/mutations/blog.ex @@ -9,15 +9,14 @@ 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 @@ -25,12 +24,8 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Blog do field :update_blog, :blog do arg(:id, non_null(:id)) arg(:title, :string) - arg(:body, :string) - arg(:digest, :string) - arg(:link_addr, :string) arg(:article_tags, list_of(:id)) - # ... middleware(M.Authorize, :login) diff --git a/lib/helper/error_code.ex b/lib/helper/error_code.ex index e947c7c16..d6a892aa2 100644 --- a/lib/helper/error_code.ex +++ b/lib/helper/error_code.ex @@ -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 diff --git a/test/groupher_server_web/mutation/cms/articles/blog_test.exs b/test/groupher_server_web/mutation/cms/articles/blog_test.exs index 644e3757a..e5cb6aaf9 100644 --- a/test/groupher_server_web/mutation/cms/articles/blog_test.exs +++ b/test/groupher_server_web/mutation/cms/articles/blog_test.exs @@ -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) @@ -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 } @@ -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") @@ -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) diff --git a/test/groupher_server_web/mutation/cms/articles/works_test.exs b/test/groupher_server_web/mutation/cms/articles/works_test.exs index d406042d8..442a01389 100644 --- a/test/groupher_server_web/mutation/cms/articles/works_test.exs +++ b/test/groupher_server_web/mutation/cms/articles/works_test.exs @@ -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) @@ -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]) diff --git a/test/helper/rss_test.exs b/test/helper/rss_test.exs index 6d630311d..8fc0c5223 100644 --- a/test/helper/rss_test.exs +++ b/test/helper/rss_test.exs @@ -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) @@ -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) @@ -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) diff --git a/test/support/factory.ex b/test/support/factory.ex index c6ed4f426..eb100ed2b 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -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), From 766cc24f34a352e7a192ec136aa7ed9363a089e9 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 3 Oct 2021 13:53:34 +0800 Subject: [PATCH 2/3] refactor(blog): hide update & fix test --- .../schema/cms/mutations/blog.ex | 22 ++--- .../mutation/cms/articles/blog_test.exs | 80 ------------------- .../mutation/statistics/statistics_test.exs | 4 +- 3 files changed, 13 insertions(+), 93 deletions(-) diff --git a/lib/groupher_server_web/schema/cms/mutations/blog.ex b/lib/groupher_server_web/schema/cms/mutations/blog.ex index 8d939cb8f..3a136586d 100644 --- a/lib/groupher_server_web/schema/cms/mutations/blog.ex +++ b/lib/groupher_server_web/schema/cms/mutations/blog.ex @@ -20,20 +20,20 @@ defmodule GroupherServerWeb.Schema.CMS.Mutations.Blog do 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) + # @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, diff --git a/test/groupher_server_web/mutation/cms/articles/blog_test.exs b/test/groupher_server_web/mutation/cms/articles/blog_test.exs index e5cb6aaf9..fc7572305 100644 --- a/test/groupher_server_web/mutation/cms/articles/blog_test.exs +++ b/test/groupher_server_web/mutation/cms/articles/blog_test.exs @@ -134,86 +134,6 @@ defmodule GroupherServer.Test.Mutation.Articles.Blog do assert String.contains?(body_html, "<script>blackmail</script>") 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}") - } - - result = owner_conn |> mutation_result(@query, variables, "updateBlog") - - assert result["title"] == variables.title - - 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 - @query """ mutation($id: ID!){ deleteBlog(id: $id) { diff --git a/test/groupher_server_web/mutation/statistics/statistics_test.exs b/test/groupher_server_web/mutation/statistics/statistics_test.exs index efb69be7e..14f8c68ca 100644 --- a/test/groupher_server_web/mutation/statistics/statistics_test.exs +++ b/test/groupher_server_web/mutation/statistics/statistics_test.exs @@ -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 ) { From faf530819af86a77ca8c0b7d08214a1952002be0 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 3 Oct 2021 14:08:22 +0800 Subject: [PATCH 3/3] refactor(blog): skip xss test --- .../mutation/cms/articles/blog_test.exs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/groupher_server_web/mutation/cms/articles/blog_test.exs b/test/groupher_server_web/mutation/cms/articles/blog_test.exs index fc7572305..5da6a2ce4 100644 --- a/test/groupher_server_web/mutation/cms/articles/blog_test.exs +++ b/test/groupher_server_web/mutation/cms/articles/blog_test.exs @@ -119,20 +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) + # test "create blog should excape xss attracts" do + # {:ok, user} = db_insert(:user) + # user_conn = simu_conn(:user, user) - {:ok, community} = db_insert(:community) + # {: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]) + # 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, "<script>blackmail</script>") - end + # assert String.contains?(body_html, "<script>blackmail</script>") + # end @query """ mutation($id: ID!){