Merge branch 'bug/fix-issue-when-updating-event' into 'master'

Fix issue when updating event and introduce background jobs

See merge request framasoft/mobilizon!300
This commit is contained in:
Thomas Citharel 2019-11-04 17:05:32 +01:00
commit 92d694acf4
17 changed files with 193 additions and 39 deletions

View file

@ -137,6 +137,11 @@ config :mobilizon, Mobilizon.Service.Geospatial.GoogleMaps,
config :mobilizon, Mobilizon.Service.Geospatial.MapQuest, config :mobilizon, Mobilizon.Service.Geospatial.MapQuest,
api_key: System.get_env("GEOSPATIAL_MAP_QUEST_API_KEY") || nil api_key: System.get_env("GEOSPATIAL_MAP_QUEST_API_KEY") || nil
config :mobilizon, Oban,
repo: Mobilizon.Storage.Repo,
prune: {:maxlen, 10_000},
queues: [default: 10, search: 20]
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs" import_config "#{Mix.env()}.exs"

View file

@ -40,3 +40,5 @@ config :exvcr,
vcr_cassette_library_dir: "test/fixtures/vcr_cassettes" vcr_cassette_library_dir: "test/fixtures/vcr_cassettes"
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Mock config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Mock
config :mobilizon, Oban, queues: false, prune: :disabled

View file

@ -7,7 +7,7 @@ defmodule Mix.Tasks.Mobilizon.SetupSearch do
use Mix.Task use Mix.Task
alias Mobilizon.Service.Search alias Mobilizon.Service.Workers.BuildSearchWorker
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
alias Mobilizon.Events.Event alias Mobilizon.Events.Event
import Ecto.Query import Ecto.Query
@ -30,7 +30,7 @@ defmodule Mix.Tasks.Mobilizon.SetupSearch do
end end
defp insert_search_event([%Event{url: url} = event | events], nb_events) do defp insert_search_event([%Event{url: url} = event | events], nb_events) do
case Search.insert_search_event(event) do case BuildSearchWorker.insert_search_event(event) do
{:ok, _} -> {:ok, _} ->
Logger.debug("Added event #{url} to the search") Logger.debug("Added event #{url} to the search")

View file

@ -37,6 +37,7 @@ defmodule Mobilizon do
# supervisors # supervisors
Mobilizon.Storage.Repo, Mobilizon.Storage.Repo,
MobilizonWeb.Endpoint, MobilizonWeb.Endpoint,
{Oban, Application.get_env(:mobilizon, Oban)},
# workers # workers
Guardian.DB.Token.SweeperServer, Guardian.DB.Token.SweeperServer,
Mobilizon.Service.Federator, Mobilizon.Service.Federator,
@ -46,9 +47,7 @@ defmodule Mobilizon do
cachex_spec(:activity_pub, 2500, 3, 15) cachex_spec(:activity_pub, 2500, 3, 15)
] ]
opts = [strategy: :one_for_one, name: Mobilizon.Supervisor] Supervisor.start_link(children, strategy: :one_for_one, name: Mobilizon.Supervisor)
Supervisor.start_link(children, opts)
end end
@spec config_change(keyword, keyword, [atom]) :: :ok @spec config_change(keyword, keyword, [atom]) :: :ok

View file

@ -179,6 +179,8 @@ defmodule Mobilizon.Events.Event do
defp put_tags(%Changeset{} = changeset, _), do: changeset defp put_tags(%Changeset{} = changeset, _), do: changeset
# We need a changeset instead of a raw struct because of slug which is generated in changeset # We need a changeset instead of a raw struct because of slug which is generated in changeset
defp process_tag(%{id: _id} = tag), do: tag
defp process_tag(tag) do defp process_tag(tag) do
Tag.changeset(%Tag{}, tag) Tag.changeset(%Tag{}, tag)
end end

View file

@ -13,7 +13,7 @@ defmodule Mobilizon.Events do
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Addresses.Address alias Mobilizon.Addresses.Address
alias Mobilizon.Service.Search alias Mobilizon.Service.Workers.BuildSearchWorker
alias Mobilizon.Events.{ alias Mobilizon.Events.{
Comment, Comment,
@ -253,7 +253,9 @@ defmodule Mobilizon.Events do
def create_event(attrs \\ %{}) do def create_event(attrs \\ %{}) do
with {:ok, %{insert: %Event{} = event}} <- do_create_event(attrs), with {:ok, %{insert: %Event{} = event}} <- do_create_event(attrs),
%Event{} = event <- Repo.preload(event, @event_preloads) do %Event{} = event <- Repo.preload(event, @event_preloads) do
Task.start(fn -> Search.insert_search_event(event) end) unless event.draft,
do: BuildSearchWorker.enqueue(:insert_search_event, %{"event_id" => event.id})
{:ok, event} {:ok, event}
else else
err -> err err -> err
@ -291,7 +293,7 @@ defmodule Mobilizon.Events do
We start by updating the event and then insert a first participant if the event is not a draft anymore We start by updating the event and then insert a first participant if the event is not a draft anymore
""" """
@spec update_event(Event.t(), map) :: {:ok, Event.t()} | {:error, Changeset.t()} @spec update_event(Event.t(), map) :: {:ok, Event.t()} | {:error, Changeset.t()}
def update_event(%Event{} = old_event, attrs) do def update_event(%Event{draft: old_draft} = old_event, attrs) do
with %Changeset{changes: changes} = changeset <- with %Changeset{changes: changes} = changeset <-
Event.update_changeset(Repo.preload(old_event, :tags), attrs), Event.update_changeset(Repo.preload(old_event, :tags), attrs),
{:ok, %{update: %Event{} = new_event}} <- {:ok, %{update: %Event{} = new_event}} <-
@ -301,7 +303,7 @@ defmodule Mobilizon.Events do
changeset changeset
) )
|> Multi.run(:write, fn _repo, %{update: %Event{draft: draft} = event} -> |> Multi.run(:write, fn _repo, %{update: %Event{draft: draft} = event} ->
with {:is_draft, false} <- {:is_draft, draft}, with {:was_draft, true} <- {:was_draft, old_draft == true && draft == false},
{:ok, %Participant{} = participant} <- {:ok, %Participant{} = participant} <-
create_participant( create_participant(
%{ %{
@ -313,7 +315,7 @@ defmodule Mobilizon.Events do
) do ) do
{:ok, participant} {:ok, participant}
else else
{:is_draft, true} -> {:ok, nil} {:was_draft, false} -> {:ok, nil}
err -> err err -> err
end end
end) end)
@ -326,7 +328,8 @@ defmodule Mobilizon.Events do
changes changes
) )
Task.start(fn -> Search.update_search_event(new_event) end) unless new_event.draft,
do: BuildSearchWorker.enqueue(:update_search_event, %{"event_id" => new_event.id})
{:ok, Repo.preload(new_event, @event_preloads)} {:ok, Repo.preload(new_event, @event_preloads)}
end end
@ -473,6 +476,16 @@ defmodule Mobilizon.Events do
|> Repo.one() |> Repo.one()
end end
@doc """
Gets a tag by its title.
"""
@spec get_tag_by_title(String.t()) :: Tag.t() | nil
def get_tag_by_title(slug) do
slug
|> tag_by_title_query()
|> Repo.one()
end
@doc """ @doc """
Gets an existing tag or creates the new one. Gets an existing tag or creates the new one.
""" """
@ -1351,6 +1364,11 @@ defmodule Mobilizon.Events do
from(t in Tag, where: t.slug == ^slug) from(t in Tag, where: t.slug == ^slug)
end end
@spec tag_by_title_query(String.t()) :: Ecto.Query.t()
defp tag_by_title_query(title) do
from(t in Tag, where: t.title == ^title, limit: 1)
end
@spec tags_for_event_query(integer) :: Ecto.Query.t() @spec tags_for_event_query(integer) :: Ecto.Query.t()
defp tags_for_event_query(event_id) do defp tags_for_event_query(event_id) do
from( from(

View file

@ -4,6 +4,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Utils do
""" """
alias Mobilizon.Actors.Actor alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.Tag alias Mobilizon.Events.Tag
alias Mobilizon.Mention alias Mobilizon.Mention
alias Mobilizon.Service.ActivityPub alias Mobilizon.Service.ActivityPub
@ -66,7 +67,7 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Utils do
defp fetch_tag(tag, acc) when is_map(tag) do defp fetch_tag(tag, acc) when is_map(tag) do
case tag["type"] do case tag["type"] do
"Hashtag" -> "Hashtag" ->
acc ++ [%{title: tag}] acc ++ [existing_tag_or_data(tag["name"])]
_err -> _err ->
acc acc
@ -74,7 +75,18 @@ defmodule Mobilizon.Service.ActivityPub.Converter.Utils do
end end
defp fetch_tag(tag, acc) when is_bitstring(tag) do defp fetch_tag(tag, acc) when is_bitstring(tag) do
acc ++ [%{title: tag}] acc ++ [existing_tag_or_data(tag)]
end
defp existing_tag_or_data("#" <> tag_title) do
existing_tag_or_data(tag_title)
end
defp existing_tag_or_data(tag_title) do
case Events.get_tag_by_title(tag_title) do
%Tag{} = tag -> %{title: tag.title, id: tag.id}
nil -> %{title: tag_title}
end
end end
@spec create_mention(map(), list()) :: list() @spec create_mention(map(), list()) :: list()

View file

@ -1,12 +1,28 @@
defmodule Mobilizon.Service.Search do defmodule Mobilizon.Service.Workers.BuildSearchWorker do
@moduledoc """ @moduledoc """
Module to handle search service Worker to build search results
""" """
alias Mobilizon.Events
alias Mobilizon.Events.Event alias Mobilizon.Events.Event
alias Mobilizon.Storage.Repo alias Mobilizon.Storage.Repo
alias Ecto.Adapters.SQL alias Ecto.Adapters.SQL
use Mobilizon.Service.Workers.WorkerHelper, queue: "search"
@impl Oban.Worker
def perform(%{"op" => "insert_search_event", "event_id" => event_id}, _job) do
with {:ok, %Event{} = event} <- Events.get_event_with_preload(event_id) do
insert_search_event(event)
end
end
def perform(%{"op" => "update_search_event", "event_id" => event_id}, _job) do
with {:ok, %Event{} = event} <- Events.get_event_with_preload(event_id) do
update_search_event(event)
end
end
def insert_search_event(%Event{} = event) do def insert_search_event(%Event{} = event) do
SQL.query( SQL.query(
Repo, Repo,

View file

@ -0,0 +1,50 @@
# Portions of this file are derived from Pleroma:
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social>
# SPDX-License-Identifier: AGPL-3.0-only
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/lib/pleroma/workers/worker_helper.ex
defmodule Mobilizon.Service.Workers.WorkerHelper do
@moduledoc """
Tools to ease dealing with workers
"""
alias Mobilizon.Config
alias Mobilizon.Service.Workers.WorkerHelper
def worker_args(queue) do
case Config.get([:workers, :retries, queue]) do
nil -> []
max_attempts -> [max_attempts: max_attempts]
end
end
def sidekiq_backoff(attempt, pow \\ 4, base_backoff \\ 15) do
backoff =
:math.pow(attempt, pow) +
base_backoff +
:rand.uniform(2 * base_backoff) * attempt
trunc(backoff)
end
defmacro __using__(opts) do
caller_module = __CALLER__.module
queue = Keyword.fetch!(opts, :queue)
quote do
# Note: `max_attempts` is intended to be overridden in `new/2` call
use Oban.Worker,
queue: unquote(queue),
max_attempts: 1
def enqueue(operation, params, worker_args \\ []) do
params = Map.merge(%{"op" => operation}, params)
queue_atom = String.to_existing_atom(unquote(queue))
worker_args = worker_args ++ WorkerHelper.worker_args(queue_atom)
unquote(caller_module)
|> apply(:new, [params, worker_args])
|> Mobilizon.Storage.Repo.insert()
end
end
end
end

View file

@ -100,6 +100,7 @@ defmodule Mobilizon.Mixfile do
{:ex_cldr_dates_times, "~> 2.0"}, {:ex_cldr_dates_times, "~> 2.0"},
{:ex_optimizer, "~> 0.1"}, {:ex_optimizer, "~> 0.1"},
{:progress_bar, "~> 2.0"}, {:progress_bar, "~> 2.0"},
{:oban, "~> 0.10"},
# Dev and test dependencies # Dev and test dependencies
{:phoenix_live_reload, "~> 1.2", only: [:dev, :e2e]}, {:phoenix_live_reload, "~> 1.2", only: [:dev, :e2e]},
{:ex_machina, "~> 2.3", only: [:dev, :test]}, {:ex_machina, "~> 2.3", only: [:dev, :test]},

View file

@ -85,6 +85,7 @@
"mock": {:hex, :mock, "0.3.3", "42a433794b1291a9cf1525c6d26b38e039e0d3a360732b5e467bfc77ef26c914", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, "mock": {:hex, :mock, "0.3.3", "42a433794b1291a9cf1525c6d26b38e039e0d3a360732b5e467bfc77ef26c914", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"mogrify": {:hex, :mogrify, "0.7.3", "1494ee739f6e90de158dec4d4edee2d854d2f2d06a522e943f996ae176bca53d", [:mix], [], "hexpm"}, "mogrify": {:hex, :mogrify, "0.7.3", "1494ee739f6e90de158dec4d4edee2d854d2f2d06a522e943f996ae176bca53d", [:mix], [], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"},
"oban": {:hex, :oban, "0.10.1", "c2ca0a413fb66b21dd58c7cb67fd80b01e9d79a0fbb28573f110057e7fdc3807", [:mix], [{:ecto_sql, "~> 3.1", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.4.10", "619e4a545505f562cd294df52294372d012823f4fd9d34a6657a8b242898c255", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix": {:hex, :phoenix, "1.4.10", "619e4a545505f562cd294df52294372d012823f4fd9d34a6657a8b242898c255", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},

View file

@ -0,0 +1,7 @@
defmodule Mobilizon.Storage.Repo.Migrations.AddUniqueIndexOnActorAndEventForParticipant do
use Ecto.Migration
def change do
create(unique_index(:participants, [:event_id, :actor_id]))
end
end

View file

@ -0,0 +1,13 @@
defmodule Mobilizon.Storage.Repo.Migrations.AddObanJobsTable do
use Ecto.Migration
def up do
Oban.Migrations.up()
end
# We specify `version: 1` in `down`, ensuring that we'll roll all the way back down if
# necessary, regardless of which version we've migrated `up` to.
def down do
Oban.Migrations.down(version: 1)
end
end

View file

@ -7,7 +7,7 @@ defmodule Mobilizon.EventsTest do
alias Mobilizon.Events alias Mobilizon.Events
alias Mobilizon.Events.{Comment, Event, Participant, Session, Tag, TagRelation, Track} alias Mobilizon.Events.{Comment, Event, Participant, Session, Tag, TagRelation, Track}
alias Mobilizon.Storage.Page alias Mobilizon.Storage.Page
alias Mobilizon.Service.Search alias Mobilizon.Service.Workers.BuildSearchWorker
@event_valid_attrs %{ @event_valid_attrs %{
begins_on: "2010-04-17 14:00:00Z", begins_on: "2010-04-17 14:00:00Z",
@ -23,7 +23,7 @@ defmodule Mobilizon.EventsTest do
setup do setup do
actor = insert(:actor) actor = insert(:actor)
event = insert(:event, organizer_actor: actor, visibility: :public) event = insert(:event, organizer_actor: actor, visibility: :public)
Search.insert_search_event(event) BuildSearchWorker.insert_search_event(event)
{:ok, actor: actor, event: event} {:ok, actor: actor, event: event}
end end
@ -63,7 +63,7 @@ defmodule Mobilizon.EventsTest do
assert title == hd(Events.build_events_for_search(event.title).elements).title assert title == hd(Events.build_events_for_search(event.title).elements).title
%Event{} = event2 = insert(:event, title: "Special event") %Event{} = event2 = insert(:event, title: "Special event")
Search.insert_search_event(event2) BuildSearchWorker.insert_search_event(event2)
assert event2.title == assert event2.title ==
Events.build_events_for_search("Special").elements |> hd() |> Map.get(:title) Events.build_events_for_search("Special").elements |> hd() |> Map.get(:title)
@ -76,7 +76,7 @@ defmodule Mobilizon.EventsTest do
tag1 = insert(:tag, title: "coucou") tag1 = insert(:tag, title: "coucou")
tag2 = insert(:tag, title: "hola") tag2 = insert(:tag, title: "hola")
%Event{} = event3 = insert(:event, title: "Nothing like it", tags: [tag1, tag2]) %Event{} = event3 = insert(:event, title: "Nothing like it", tags: [tag1, tag2])
Search.insert_search_event(event3) BuildSearchWorker.insert_search_event(event3)
assert event3.title == assert event3.title ==
Events.build_events_for_search("hola").elements |> hd() |> Map.get(:title) Events.build_events_for_search("hola").elements |> hd() |> Map.get(:title)

View file

@ -1,8 +1,10 @@
defmodule MobilizonWeb.Resolvers.EventResolverTest do defmodule MobilizonWeb.Resolvers.EventResolverTest do
use MobilizonWeb.ConnCase use MobilizonWeb.ConnCase
use Bamboo.Test use Bamboo.Test
use Oban.Testing, repo: Mobilizon.Storage.Repo
alias Mobilizon.Events alias Mobilizon.Events
alias MobilizonWeb.{AbsintheHelpers, Email} alias MobilizonWeb.{AbsintheHelpers, Email}
alias Mobilizon.Service.Workers.BuildSearchWorker
import Mobilizon.Factory import Mobilizon.Factory
@event %{ @event %{
@ -105,6 +107,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
organizer_actor_id: "#{actor.id}", organizer_actor_id: "#{actor.id}",
category: "birthday" category: "birthday"
) { ) {
id,
title, title,
uuid uuid
} }
@ -117,6 +120,8 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event" assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
{id, ""} = json_response(res, 200)["data"]["createEvent"]["id"] |> Integer.parse()
assert_enqueued(worker: BuildSearchWorker, args: %{event_id: id, op: :insert_search_event})
end end
test "create_event/3 creates an event and escapes title and description", %{ test "create_event/3 creates an event and escapes title and description", %{
@ -132,6 +137,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
begins_on: $begins_on, begins_on: $begins_on,
organizer_actor_id: $organizer_actor_id organizer_actor_id: $organizer_actor_id
) { ) {
id,
title, title,
description, description,
uuid uuid
@ -159,6 +165,9 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
assert res["data"]["createEvent"]["description"] == assert res["data"]["createEvent"]["description"] ==
"<b>My description</b> <img src=\"http://placekitten.com/g/200/300\" />" "<b>My description</b> <img src=\"http://placekitten.com/g/200/300\" />"
{id, ""} = res["data"]["createEvent"]["id"] |> Integer.parse()
assert_enqueued(worker: BuildSearchWorker, args: %{event_id: id, op: :insert_search_event})
end end
test "create_event/3 creates an event as a draft", %{conn: conn, actor: actor, user: user} do test "create_event/3 creates an event as a draft", %{conn: conn, actor: actor, user: user} do
@ -192,6 +201,12 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
event_uuid = json_response(res, 200)["data"]["createEvent"]["uuid"] event_uuid = json_response(res, 200)["data"]["createEvent"]["uuid"]
event_id = json_response(res, 200)["data"]["createEvent"]["id"] event_id = json_response(res, 200)["data"]["createEvent"]["id"]
{event_id_int, ""} = Integer.parse(event_id)
refute_enqueued(
worker: BuildSearchWorker,
args: %{event_id: event_id_int, op: :insert_search_event}
)
query = """ query = """
{ {
@ -275,6 +290,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
showEndTime: false showEndTime: false
} }
) { ) {
id,
title, title,
description, description,
begins_on, begins_on,
@ -318,6 +334,12 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
assert event["options"]["maximumAttendeeCapacity"] == 30 assert event["options"]["maximumAttendeeCapacity"] == 30
assert event["options"]["showRemainingAttendeeCapacity"] == true assert event["options"]["showRemainingAttendeeCapacity"] == true
assert event["options"]["showEndTime"] == false assert event["options"]["showEndTime"] == false
{event_id_int, ""} = Integer.parse(event["id"])
assert_enqueued(
worker: BuildSearchWorker,
args: %{event_id: event_id_int, op: :insert_search_event}
)
end end
test "create_event/3 creates an event with tags", %{conn: conn, actor: actor, user: user} do test "create_event/3 creates an event with tags", %{conn: conn, actor: actor, user: user} do
@ -675,6 +697,7 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
locality: "#{address.locality}" locality: "#{address.locality}"
} }
) { ) {
id,
uuid, uuid,
url, url,
title, title,
@ -734,6 +757,13 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
%{"slug" => "tag2-updated", "title" => "tag2_updated"} %{"slug" => "tag2-updated", "title" => "tag2_updated"}
] ]
{event_id_int, ""} = Integer.parse(event_res["id"])
assert_enqueued(
worker: BuildSearchWorker,
args: %{event_id: event_id_int, op: :update_search_event}
)
{:ok, new_event} = Mobilizon.Events.get_event(event.id) {:ok, new_event} = Mobilizon.Events.get_event(event.id)
assert_delivered_email( assert_delivered_email(

View file

@ -474,7 +474,7 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
query = """ query = """
{ {
event(uuid: "#{event.uuid}") { event(uuid: "#{event.uuid}") {
participants(page: 1, limit: 1, roles: "participant,moderator,administrator,creator", actorId: "#{ participants(page: 2, limit: 1, roles: "participant,moderator,administrator,creator", actorId: "#{
actor.id actor.id
}") { }") {
role, role,
@ -493,11 +493,7 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
sorted_participants = sorted_participants =
json_response(res, 200)["data"]["event"]["participants"] json_response(res, 200)["data"]["event"]["participants"]
|> Enum.sort_by( |> Enum.filter(&(&1["role"] == "PARTICIPANT"))
&(&1
|> Map.get("actor")
|> Map.get("preferredUsername"))
)
assert sorted_participants == [ assert sorted_participants == [
%{ %{
@ -511,7 +507,7 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
query = """ query = """
{ {
event(uuid: "#{event.uuid}") { event(uuid: "#{event.uuid}") {
participants(page: 2, limit: 1, roles: "participant,moderator,administrator,creator", actorId: "#{ participants(page: 1, limit: 1, roles: "participant,moderator,administrator,creator", actorId: "#{
actor.id actor.id
}") { }") {
role, role,
@ -594,10 +590,12 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
actor_id: not_approved.id actor_id: not_approved.id
}) })
rejected = insert(:actor)
Events.create_participant(%{ Events.create_participant(%{
role: :rejected, role: :rejected,
event_id: event.id, event_id: event.id,
actor_id: not_approved.id actor_id: rejected.id
}) })
query = """ query = """

View file

@ -2,7 +2,7 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
use MobilizonWeb.ConnCase use MobilizonWeb.ConnCase
alias MobilizonWeb.AbsintheHelpers alias MobilizonWeb.AbsintheHelpers
import Mobilizon.Factory import Mobilizon.Factory
alias Mobilizon.Service.Search alias Mobilizon.Service.Workers.BuildSearchWorker
setup %{conn: conn} do setup %{conn: conn} do
user = insert(:user) user = insert(:user)
@ -17,7 +17,7 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
insert(:actor, user: user, preferred_username: "test_person") insert(:actor, user: user, preferred_username: "test_person")
insert(:actor, type: :Group, preferred_username: "test_group") insert(:actor, type: :Group, preferred_username: "test_group")
event = insert(:event, title: "test_event") event = insert(:event, title: "test_event")
Search.insert_search_event(event) BuildSearchWorker.insert_search_event(event)
query = """ query = """
{ {
@ -51,7 +51,7 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
actor = insert(:actor, user: user, preferred_username: "test_person") actor = insert(:actor, user: user, preferred_username: "test_person")
insert(:actor, type: :Group, preferred_username: "test_group") insert(:actor, type: :Group, preferred_username: "test_group")
event = insert(:event, title: "test_event") event = insert(:event, title: "test_event")
Search.insert_search_event(event) BuildSearchWorker.insert_search_event(event)
query = """ query = """
{ {
@ -84,7 +84,7 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
insert(:actor, user: user, preferred_username: "test_person") insert(:actor, user: user, preferred_username: "test_person")
group = insert(:actor, type: :Group, preferred_username: "test_group") group = insert(:actor, type: :Group, preferred_username: "test_group")
event = insert(:event, title: "test_event") event = insert(:event, title: "test_event")
Search.insert_search_event(event) BuildSearchWorker.insert_search_event(event)
query = """ query = """
{ {
@ -118,9 +118,9 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
event1 = insert(:event, title: "Pineapple fashion week") event1 = insert(:event, title: "Pineapple fashion week")
event2 = insert(:event, title: "I love pineAPPLE") event2 = insert(:event, title: "I love pineAPPLE")
event3 = insert(:event, title: "Hello") event3 = insert(:event, title: "Hello")
Search.insert_search_event(event1) BuildSearchWorker.insert_search_event(event1)
Search.insert_search_event(event2) BuildSearchWorker.insert_search_event(event2)
Search.insert_search_event(event3) BuildSearchWorker.insert_search_event(event3)
query = """ query = """
{ {
@ -161,9 +161,9 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
event1 = insert(:event, title: "Pineapple fashion week") event1 = insert(:event, title: "Pineapple fashion week")
event2 = insert(:event, title: "I love pineAPPLE") event2 = insert(:event, title: "I love pineAPPLE")
event3 = insert(:event, title: "Hello") event3 = insert(:event, title: "Hello")
Search.insert_search_event(event1) BuildSearchWorker.insert_search_event(event1)
Search.insert_search_event(event2) BuildSearchWorker.insert_search_event(event2)
Search.insert_search_event(event3) BuildSearchWorker.insert_search_event(event3)
query = """ query = """
{ {
@ -198,7 +198,7 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
insert(:actor, user: user, preferred_username: "person", name: "Torréfaction du Kafé") insert(:actor, user: user, preferred_username: "person", name: "Torréfaction du Kafé")
insert(:actor, type: :Group, preferred_username: "group", name: "Kafé group") insert(:actor, type: :Group, preferred_username: "group", name: "Kafé group")
event = insert(:event, title: "Tour du monde des Kafés") event = insert(:event, title: "Tour du monde des Kafés")
Search.insert_search_event(event) BuildSearchWorker.insert_search_event(event)
# Elaborate query # Elaborate query
query = """ query = """
@ -230,7 +230,7 @@ defmodule MobilizonWeb.Resolvers.SearchResolverTest do
insert(:actor, user: user, preferred_username: "person", name: "Torréfaction du Kafé") insert(:actor, user: user, preferred_username: "person", name: "Torréfaction du Kafé")
group = insert(:actor, type: :Group, preferred_username: "group", name: "Kafé group") group = insert(:actor, type: :Group, preferred_username: "group", name: "Kafé group")
event = insert(:event, title: "Tour du monde des Kafés") event = insert(:event, title: "Tour du monde des Kafés")
Search.insert_search_event(event) BuildSearchWorker.insert_search_event(event)
# Elaborate query # Elaborate query
query = """ query = """