add test for search_controller/ 100% coverage

This commit is contained in:
Maksim 2019-07-10 08:28:03 +00:00 committed by kaniini
parent 9822f3a05e
commit 008c55e4e9
3 changed files with 176 additions and 102 deletions

View File

@ -4,29 +4,27 @@
defmodule Pleroma.Web.MastodonAPI.SearchController do defmodule Pleroma.Web.MastodonAPI.SearchController do
use Pleroma.Web, :controller use Pleroma.Web, :controller
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Plugs.RateLimiter
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.ControllerHelper
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.ControllerHelper
require Logger require Logger
plug(RateLimiter, :search when action in [:search, :search2, :account_search])
plug(Pleroma.Plugs.RateLimiter, :search when action in [:search, :search2, :account_search])
def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end, []) accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end, [])
statuses = with_fallback(fn -> Activity.search(user, query) end, []) statuses = with_fallback(fn -> Activity.search(user, query) end, [])
tags_path = Web.base_url() <> "/tag/" tags_path = Web.base_url() <> "/tag/"
tags = tags =
query query
|> String.split() |> prepare_tags
|> Enum.uniq()
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|> Enum.map(fn tag -> %{name: tag, url: tags_path <> tag} end) |> Enum.map(fn tag -> %{name: tag, url: tags_path <> tag} end)
res = %{ res = %{
@ -40,15 +38,10 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
end end
def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end, []) accounts = with_fallback(fn -> User.search(query, search_options(params, user)) end)
statuses = with_fallback(fn -> Activity.search(user, query) end, []) statuses = with_fallback(fn -> Activity.search(user, query) end)
tags = tags = prepare_tags(query)
query
|> String.split()
|> Enum.uniq()
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
res = %{ res = %{
"accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user), "accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
@ -67,6 +60,14 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
json(conn, res) json(conn, res)
end end
defp prepare_tags(query) do
query
|> String.split()
|> Enum.uniq()
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
end
defp search_options(params, user) do defp search_options(params, user) do
[ [
resolve: params["resolve"] == "true", resolve: params["resolve"] == "true",
@ -77,7 +78,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
] ]
end end
defp with_fallback(f, fallback) do defp with_fallback(f, fallback \\ []) do
try do try do
f.() f.()
rescue rescue

View File

@ -19,6 +19,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1] import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1]
# TODO: Add cached version. # TODO: Add cached version.
defp get_replied_to_activities([]), do: %{}
defp get_replied_to_activities(activities) do defp get_replied_to_activities(activities) do
activities activities
|> Enum.map(fn |> Enum.map(fn

View File

@ -6,123 +6,194 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Web
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
import Pleroma.Factory import Pleroma.Factory
import ExUnit.CaptureLog import ExUnit.CaptureLog
import Tesla.Mock import Tesla.Mock
import Mock
setup do setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end) mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok :ok
end end
test "account search", %{conn: conn} do describe ".search2" do
user = insert(:user) test "it returns empty result if user or status search return undefined error", %{conn: conn} do
user_two = insert(:user, %{nickname: "shp@shitposter.club"}) with_mocks [
user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]},
{Pleroma.Activity, [], [search: fn _u, _q -> raise "Oops" end]}
] do
conn = get(conn, "/api/v2/search", %{"q" => "2hu"})
results = assert results = json_response(conn, 200)
conn
|> assign(:user, user)
|> get("/api/v1/accounts/search", %{"q" => "shp"})
|> json_response(200)
result_ids = for result <- results, do: result["acct"] assert results["accounts"] == []
assert results["statuses"] == []
end
end
assert user_two.nickname in result_ids test "search", %{conn: conn} do
assert user_three.nickname in result_ids user = insert(:user)
user_two = insert(:user, %{nickname: "shp@shitposter.club"})
user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
results = {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu private"})
conn
|> assign(:user, user)
|> get("/api/v1/accounts/search", %{"q" => "2hu"})
|> json_response(200)
result_ids = for result <- results, do: result["acct"] {:ok, _activity} =
CommonAPI.post(user, %{
"status" => "This is about 2hu, but private",
"visibility" => "private"
})
assert user_three.nickname in result_ids {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
end
test "search", %{conn: conn} do conn = get(conn, "/api/v2/search", %{"q" => "2hu #private"})
user = insert(:user)
user_two = insert(:user, %{nickname: "shp@shitposter.club"})
user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
{:ok, _activity} =
CommonAPI.post(user, %{
"status" => "This is about 2hu, but private",
"visibility" => "private"
})
{:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
conn =
conn
|> get("/api/v1/search", %{"q" => "2hu"})
assert results = json_response(conn, 200)
[account | _] = results["accounts"]
assert account["id"] == to_string(user_three.id)
assert results["hashtags"] == []
[status] = results["statuses"]
assert status["id"] == to_string(activity.id)
end
test "search fetches remote statuses", %{conn: conn} do
capture_log(fn ->
conn =
conn
|> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"})
assert results = json_response(conn, 200) assert results = json_response(conn, 200)
# IO.inspect results
[account | _] = results["accounts"]
assert account["id"] == to_string(user_three.id)
assert results["hashtags"] == [
%{"name" => "private", "url" => "#{Web.base_url()}/tag/private"}
]
[status] = results["statuses"] [status] = results["statuses"]
assert status["uri"] == "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment" assert status["id"] == to_string(activity.id)
end) end
end end
test "search doesn't show statuses that it shouldn't", %{conn: conn} do describe ".account_search" do
{:ok, activity} = test "account search", %{conn: conn} do
CommonAPI.post(insert(:user), %{ user = insert(:user)
"status" => "This is about 2hu, but private", user_two = insert(:user, %{nickname: "shp@shitposter.club"})
"visibility" => "private" user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
})
results =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/search", %{"q" => "shp"})
|> json_response(200)
result_ids = for result <- results, do: result["acct"]
assert user_two.nickname in result_ids
assert user_three.nickname in result_ids
results =
conn
|> assign(:user, user)
|> get("/api/v1/accounts/search", %{"q" => "2hu"})
|> json_response(200)
result_ids = for result <- results, do: result["acct"]
assert user_three.nickname in result_ids
end
end
describe ".search" do
test "it returns empty result if user or status search return undefined error", %{conn: conn} do
with_mocks [
{Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]},
{Pleroma.Activity, [], [search: fn _u, _q -> raise "Oops" end]}
] do
conn =
conn
|> get("/api/v1/search", %{"q" => "2hu"})
assert results = json_response(conn, 200)
assert results["accounts"] == []
assert results["statuses"] == []
end
end
test "search", %{conn: conn} do
user = insert(:user)
user_two = insert(:user, %{nickname: "shp@shitposter.club"})
user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
{:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"})
{:ok, _activity} =
CommonAPI.post(user, %{
"status" => "This is about 2hu, but private",
"visibility" => "private"
})
{:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"})
capture_log(fn ->
conn = conn =
conn conn
|> get("/api/v1/search", %{"q" => Object.normalize(activity).data["id"]}) |> get("/api/v1/search", %{"q" => "2hu"})
assert results = json_response(conn, 200) assert results = json_response(conn, 200)
[] = results["statuses"] [account | _] = results["accounts"]
end) assert account["id"] == to_string(user_three.id)
end
test "search fetches remote accounts", %{conn: conn} do assert results["hashtags"] == []
user = insert(:user)
conn = [status] = results["statuses"]
conn assert status["id"] == to_string(activity.id)
|> assign(:user, user) end
|> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "true"})
assert results = json_response(conn, 200) test "search fetches remote statuses", %{conn: conn} do
[account] = results["accounts"] capture_log(fn ->
assert account["acct"] == "shp@social.heldscal.la" conn =
end conn
|> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"})
test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do assert results = json_response(conn, 200)
conn =
conn
|> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "false"})
assert results = json_response(conn, 200) [status] = results["statuses"]
assert [] == results["accounts"]
assert status["uri"] ==
"tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
end)
end
test "search doesn't show statuses that it shouldn't", %{conn: conn} do
{:ok, activity} =
CommonAPI.post(insert(:user), %{
"status" => "This is about 2hu, but private",
"visibility" => "private"
})
capture_log(fn ->
conn =
conn
|> get("/api/v1/search", %{"q" => Object.normalize(activity).data["id"]})
assert results = json_response(conn, 200)
[] = results["statuses"]
end)
end
test "search fetches remote accounts", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "true"})
assert results = json_response(conn, 200)
[account] = results["accounts"]
assert account["acct"] == "shp@social.heldscal.la"
end
test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do
conn =
conn
|> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "false"})
assert results = json_response(conn, 200)
assert [] == results["accounts"]
end
end end
end end