Multi tenancy for tests + federation WIP

This commit is contained in:
Mayel de Borniol 2022-10-25 10:27:43 +13:00
parent 19820b7fbc
commit c1fc1cf0de
13 changed files with 96 additions and 165 deletions

View file

@ -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

View file

@ -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",

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()) <>
"""
<script defer phx-track-static crossorigin='anonymous' src='#{js}'></script>
"""
"""
#{PhoenixGon.View.render_gon_script(conn) |> Phoenix.HTML.safe_to_string()}
<script defer phx-track-static crossorigin='anonymous' src='#{js}'></script>
"""
end
def reload!(), do: Phoenix.CodeReloader.reload!(__MODULE__)

View file

@ -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

View file

@ -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

View file

@ -1,8 +1,25 @@
defmodule Iconify.HeroiconsOutline.ArrowRight do
use Phoenix.Component
def render(assigns) do
~H"""
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" class={@class} viewBox="0 0 24 24" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m14 5l7 7m0 0l-7 7m7-7H3"/></svg>
<svg
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
role="img"
class={@class}
viewBox="0 0 24 24"
aria-hidden="true"
>
<path
fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m14 5l7 7m0 0l-7 7m7-7H3"
/>
</svg>
"""
end
end

View file

@ -18,8 +18,6 @@ defmodule Bonfire.DataCase do
using do
quote do
alias Bonfire.Common.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query

View file

@ -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)