From c1fc1cf0de1d751491d61376d194bf04f39712c1 Mon Sep 17 00:00:00 2001 From: Mayel de Borniol Date: Tue, 25 Oct 2022 10:27:43 +1300 Subject: [PATCH] Multi tenancy for tests + federation WIP --- docs/CHANGELOG-autogenerated.md | 2 +- flavours/cooperation/config/activity_pub.exs | 30 +++-- flavours/cooperation/config/runtime.exs | 25 +++-- flavours/cooperation/config/test.exs | 11 +- justfile | 12 ++ lib/application.ex | 10 +- lib/error_reporting.ex | 23 ---- lib/web/endpoint.ex | 11 +- lib/web/endpoint_template.ex | 104 ------------------ lib/web/fake_remote_endpoint.ex | 2 +- .../icons/heroicons-outline/arrow-right.ex | 19 +++- test/support/data_case.ex | 2 - test/test_helper.exs | 10 +- 13 files changed, 96 insertions(+), 165 deletions(-) delete mode 100644 lib/error_reporting.ex delete mode 100644 lib/web/endpoint_template.ex diff --git a/docs/CHANGELOG-autogenerated.md b/docs/CHANGELOG-autogenerated.md index 8ea10e8061..1ef9fdf129 100644 --- a/docs/CHANGELOG-autogenerated.md +++ b/docs/CHANGELOG-autogenerated.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) -## [Unreleased (2022-10-21)] +## [Unreleased (2022-10-24)] ### Added - Enable/disable extensions [#448](https://github.com/bonfire-networks/bonfire-app/issues/448) - Coordination MVP [#445](https://github.com/bonfire-networks/bonfire-app/issues/445) by mayel & ivanminutillo diff --git a/flavours/cooperation/config/activity_pub.exs b/flavours/cooperation/config/activity_pub.exs index d24d4ca12f..8ede0034fc 100644 --- a/flavours/cooperation/config/activity_pub.exs +++ b/flavours/cooperation/config/activity_pub.exs @@ -5,14 +5,6 @@ config :activity_pub, :repo, Bonfire.Common.Repo config :nodeinfo, :adapter, Bonfire.Federate.ActivityPub.NodeinfoAdapter -config :activity_pub, :mrf_simple, - media_removal: [], - media_nsfw: [], - report_removal: [], - accept: [], - avatar_removal: [], - banner_removal: [] - config :activity_pub, :instance, hostname: "localhost", federation_publisher_modules: [ActivityPubWeb.Publisher], @@ -21,6 +13,22 @@ config :activity_pub, :instance, rewrite_policy: [Bonfire.Federate.ActivityPub.BoundariesMRF], handle_unknown_activities: true +config :activity_pub, :boundaries, + block: [], + silence_them: [], + ghost_them: [] + +config :activity_pub, :mrf_simple, + reject: [], + accept: [], + media_removal: [], + media_nsfw: [], + report_removal: [], + avatar_removal: [], + banner_removal: [] + +config :http_signatures, adapter: ActivityPub.Signature + config :activity_pub, :http, proxy_url: nil, send_user_agent: true, @@ -34,7 +42,11 @@ config :activity_pub, :http, ] config :activity_pub, ActivityPubWeb.Endpoint, - render_errors: [view: ActivityPubWeb.ErrorView, accepts: ~w(json), layout: false] + render_errors: [ + view: ActivityPubWeb.ErrorView, + accepts: ~w(json), + layout: false + ] config :activity_pub, :json_contexts, %{ "Hashtag" => "as:Hashtag", diff --git a/flavours/cooperation/config/runtime.exs b/flavours/cooperation/config/runtime.exs index 51d31dbfce..7296f1e856 100644 --- a/flavours/cooperation/config/runtime.exs +++ b/flavours/cooperation/config/runtime.exs @@ -8,6 +8,13 @@ host = System.get_env("HOSTNAME", "localhost") server_port = String.to_integer(System.get_env("SERVER_PORT", "4000")) public_port = String.to_integer(System.get_env("PUBLIC_PORT", "4000")) +repos = + if System.get_env("TEST_INSTANCE") == "yes", + do: [Bonfire.Common.Repo, Bonfire.Common.TestInstanceRepo], + else: [Bonfire.Common.Repo] + +# [Bonfire.Common.Repo, Beacon.Repo] + ## load runtime configs directly via extension-provided modules Bonfire.Common.Config.LoadExtensionsConfig.load_configs() ## @@ -60,7 +67,9 @@ config :bonfire, signing_salt: signing_salt config :bonfire, Bonfire.Web.Endpoint, - server: config_env() == :test and System.get_env("TEST_INSTANCE") == "yes" or System.get_env("START_SERVER") == "yes", + server: + config_env() != :test or System.get_env("TEST_INSTANCE") == "yes" or + System.get_env("START_SERVER") == "yes", url: [ host: host, port: public_port @@ -84,12 +93,6 @@ end pool_size = String.to_integer(System.get_env("POOL_SIZE", "10")) -config :bonfire, :ecto_repos, [Bonfire.Common.Repo] -# config :bonfire, :ecto_repos, [Bonfire.Common.Repo, Beacon.Repo] -config :bonfire, Bonfire.Common.Repo, repo_connection_config -config :beacon, Beacon.Repo, repo_connection_config -config :beacon, Beacon.Repo, pool_size: pool_size - database = case config_env() do :test -> "bonfire_test#{System.get_env("MIX_TEST_PARTITION")}" @@ -97,9 +100,17 @@ database = _ -> System.get_env("POSTGRES_DB", "bonfire") end +config :bonfire, :ecto_repos, repos +config :paginator, ecto_repos: repos +config :bonfire, Bonfire.Common.Repo, repo_connection_config +config :bonfire, Bonfire.Common.TestInstanceRepo, repo_connection_config +config :beacon, Beacon.Repo, repo_connection_config config :bonfire, Bonfire.Common.Repo, database: database +config :bonfire, Bonfire.Common.TestInstanceRepo, database: "bonfire_test_instance" config :beacon, Beacon.Repo, database: database config :paginator, Paginator.Repo, database: database +config :beacon, Beacon.Repo, pool_size: pool_size +config :bonfire, Bonfire.Common.TestInstanceRepo, priv: "priv/repo" # start prod-only config if config_env() == :prod do diff --git a/flavours/cooperation/config/test.exs b/flavours/cooperation/config/test.exs index 3817f946a5..f4f3dad70b 100644 --- a/flavours/cooperation/config/test.exs +++ b/flavours/cooperation/config/test.exs @@ -42,19 +42,20 @@ config :bonfire, Bonfire.Web.FakeRemoteEndpoint, live_view: [signing_salt: System.get_env("SIGNING_SALT")], render_errors: [view: Bonfire.UI.Common.ErrorView, accepts: ~w(html json), layout: false] -config :bonfire, Oban, testing: :manual +config :tesla, + adapter: + if(System.get_env("TEST_INSTANCE") == "yes", do: Tesla.Adapter.Hackney, else: Tesla.Mock) + +config :bonfire, Oban, + testing: if(System.get_env("TEST_INSTANCE") == "yes", do: :inline, else: :manual) config :pbkdf2_elixir, :rounds, 1 config :mix_test_interactive, clear: true -config :paginator, ecto_repos: [Bonfire.Common.Repo] - config :paginator, Paginator.Repo, pool: Ecto.Adapters.SQL.Sandbox, username: System.get_env("POSTGRES_USER", "postgres"), password: System.get_env("POSTGRES_PASSWORD", "postgres"), hostname: System.get_env("POSTGRES_HOST", "localhost") - -# database: db diff --git a/justfile b/justfile index ce211b4cf3..3770c1a635 100644 --- a/justfile +++ b/justfile @@ -403,6 +403,18 @@ test-watch *args='': test-interactive *args='': @MIX_ENV=test just mix test.interactive --stale $@ +test-federation-lib *args='forks/activity_pub': + @MIX_ENV=test just test-watch $@ + +test-federation-integration *args='forks/bonfire_federate_activitypub/test/activity_pub_integration': + @MIX_ENV=test just test-watch $@ + +test-federation-extensions *args='forks/*/test/*federat* forks/*/test/*/*federat* forks/*/test/*/*/*federat*': + @MIX_ENV=test just test-watch $@ + +test-federation-two *args='forks/bonfire_federate_activitypub/test/two_instances': + @MIX_ENV=test TEST_INSTANCE=yes just test-watch $@ + # dev-test-watch: init ## Run tests # docker-compose run --service-ports -e MIX_ENV=test web iex -S mix phx.server diff --git a/lib/application.ex b/lib/application.ex index 272c206c83..96e03ef1ba 100755 --- a/lib/application.ex +++ b/lib/application.ex @@ -106,18 +106,18 @@ defmodule Bonfire.Application do def applications(:test, true = _test_instance?, _any) do @apps_before ++ - [@endpoint_module, Bonfire.Web.FakeRemoteEndpoint] ++ - @apps_after + [Bonfire.Common.TestInstanceRepo] ++ + [@endpoint_module, Bonfire.Web.FakeRemoteEndpoint] ++ + @apps_after end # default apps def applications(_env, _test_instance?, _any) do @apps_before ++ - [@endpoint_module] ++ - @apps_after + [@endpoint_module] ++ + @apps_after end - # Tell Phoenix to update the endpoint configuration # whenever the application is updated. def config_change(changed, _new, removed) do diff --git a/lib/error_reporting.ex b/lib/error_reporting.ex deleted file mode 100644 index 0c2f379a78..0000000000 --- a/lib/error_reporting.ex +++ /dev/null @@ -1,23 +0,0 @@ -defmodule Bonfire.ErrorReporting do - @behaviour Plug - import Untangle - - defmacro __using__(_) do - quote do - require Bonfire.Common.Extend - Bonfire.Common.Extend.use_if_enabled(Sentry.PlugCapture) - end - end - - @impl true - def init(_opts) do - [] - end - - @impl true - def call(conn, opts) do - if Bonfire.Common.Extend.module_enabled?(Sentry), - do: Sentry.PlugContext.call(conn, opts), - else: conn - end -end diff --git a/lib/web/endpoint.ex b/lib/web/endpoint.ex index 7307722592..13951e8f78 100755 --- a/lib/web/endpoint.ex +++ b/lib/web/endpoint.ex @@ -1,6 +1,6 @@ defmodule Bonfire.Web.Endpoint do use Phoenix.Endpoint, otp_app: :bonfire - use Bonfire.Web.EndpointTemplate + use Bonfire.UI.Common.EndpointTemplate alias Bonfire.Common.Utils alias Bonfire.Common.Config @@ -10,6 +10,7 @@ defmodule Bonfire.Web.Endpoint do socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket) plug(Phoenix.LiveReloader) plug(Phoenix.CodeReloader) + plug(Phoenix.Ecto.CheckRepoStatus, otp_app: :bonfire) # plug(PhoenixProfiler) @@ -62,10 +63,10 @@ defmodule Bonfire.Web.Endpoint do static_path("/assets/bonfire_basic.js") end - (PhoenixGon.View.render_gon_script(conn) |> Phoenix.HTML.safe_to_string()) <> - """ - - """ + """ + #{PhoenixGon.View.render_gon_script(conn) |> Phoenix.HTML.safe_to_string()} + + """ end def reload!(), do: Phoenix.CodeReloader.reload!(__MODULE__) diff --git a/lib/web/endpoint_template.ex b/lib/web/endpoint_template.ex deleted file mode 100644 index 4206e4422b..0000000000 --- a/lib/web/endpoint_template.ex +++ /dev/null @@ -1,104 +0,0 @@ -defmodule Bonfire.Web.EndpointTemplate do - alias Bonfire.Common.Config - - defmacro __using__(_) do - quote do - # make sure this comes before the Phoenix endpoint - use Bonfire.ErrorReporting - import Bonfire.Common.Extend - alias Bonfire.Web.EndpointTemplate - - use_if_enabled(Absinthe.Phoenix.Endpoint) - - if Application.compile_env(:bonfire, :sql_sandbox) do - plug(Phoenix.Ecto.SQL.Sandbox) - end - - socket("/live", Phoenix.LiveView.Socket, - websocket: [ - connect_info: [ - :user_agent, - session: EndpointTemplate.session_options() - ] - ] - ) - - if module_enabled?(Bonfire.API.GraphQL.UserSocket) do - socket("/api/socket", Bonfire.API.GraphQL.UserSocket, - websocket: true, - longpoll: false - ) - end - - # Serve at "/" the static files from "priv/static" directory. - # - # You should set gzip to true if you are running phx.digest - # when deploying your static files in production. - - plug(Plug.Static, - at: "/", - from: :bonfire, - gzip: true, - only: - ~w(public assets css fonts images js favicon.ico pwa pwabuilder-sw.js robots.txt cache_manifest.json source.tar.gz index.html) - ) - - plug(Plug.Static, - at: "/data/uploads/", - from: "data/uploads", - gzip: true - ) - - plug(Plug.Static, - at: "/", - from: :livebook, - gzip: true, - only: ~w(images js) - ) - - plug(Plug.Static, - at: "/livebook/", - from: :livebook, - gzip: true, - only: ~w(css images js favicon.ico robots.txt cache_manifest.json) - ) - - # TODO: serve priv/static from any extensions that have one as well? - - plug(Phoenix.LiveDashboard.RequestLogger, - param_key: "request_logger", - cookie_key: "request_logger" - ) - - plug(Plug.RequestId) - plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint]) - - plug(Plug.Parsers, - parsers: [:urlencoded, :multipart, :json], - pass: ["*/*"], - json_decoder: Phoenix.json_library() - ) - - plug(Bonfire.ErrorReporting) - - plug(Plug.MethodOverride) - plug(Plug.Head) - plug(Plug.Session, EndpointTemplate.session_options()) - end - end - - def session_options do - # TODO: check that this is changeable at runtime - # The session will be stored in the cookie and signed, - # this means its contents can be read but not tampered with. - # Set :encryption_salt if you would also like to encrypt it. - [ - store: :cookie, - key: "_bonfire_key", - signing_salt: Config.get!(:signing_salt), - encryption_salt: Config.get!(:encryption_salt), - # 60 days by default - max_age: Config.get(:session_time_to_remember, 60 * 60 * 24 * 60) - ] - end -end diff --git a/lib/web/fake_remote_endpoint.ex b/lib/web/fake_remote_endpoint.ex index 980f2cad8d..09be31fcef 100644 --- a/lib/web/fake_remote_endpoint.ex +++ b/lib/web/fake_remote_endpoint.ex @@ -1,6 +1,6 @@ defmodule Bonfire.Web.FakeRemoteEndpoint do use Phoenix.Endpoint, otp_app: :bonfire - use Bonfire.Web.EndpointTemplate + use Bonfire.UI.Common.EndpointTemplate plug(Bonfire.Web.Router) end diff --git a/lib/web/icons/heroicons-outline/arrow-right.ex b/lib/web/icons/heroicons-outline/arrow-right.ex index be720ca8dc..0e6793f147 100644 --- a/lib/web/icons/heroicons-outline/arrow-right.ex +++ b/lib/web/icons/heroicons-outline/arrow-right.ex @@ -1,8 +1,25 @@ defmodule Iconify.HeroiconsOutline.ArrowRight do use Phoenix.Component + def render(assigns) do ~H""" - + """ end end diff --git a/test/support/data_case.ex b/test/support/data_case.ex index 61528b0565..9baf3af62c 100755 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -18,8 +18,6 @@ defmodule Bonfire.DataCase do using do quote do - alias Bonfire.Common.Repo - import Ecto import Ecto.Changeset import Ecto.Query diff --git a/test/test_helper.exs b/test/test_helper.exs index 2be1a1c1c5..3e8780fa35 100755 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,3 +1,5 @@ +import Bonfire.Common.Config, only: [repo: 0] + ExUnit.configure( formatters: [ExUnit.CLIFormatter, ExUnitNotifier] ++ @@ -17,10 +19,10 @@ ExUnit.start( # Mix.Task.run("ecto.create") # Mix.Task.run("ecto.migrate") -# Ecto.Adapters.SQL.Sandbox.mode(Bonfire.Common.Repo, :manual) +# Ecto.Adapters.SQL.Sandbox.mode(repo(), :manual) # if System.get_env("START_SERVER") !="yes" do -Ecto.Adapters.SQL.Sandbox.mode(Bonfire.Common.Repo, :auto) +Ecto.Adapters.SQL.Sandbox.mode(repo(), :auto) # end # ExUnit.after_suite(fn results -> @@ -42,3 +44,7 @@ IO.puts(""" Testing shows the presence, not the absence of bugs. - Edsger W. Dijkstra """) + +# insert fixtures on startup (because running them as part of migrations inserts in primary repo) +if System.get_env("TEST_INSTANCE") == "yes", + do: Bonfire.Common.TestInstanceRepo.apply(&Bonfire.Boundaries.Fixtures.insert/0)