summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre de Lacroix <pierre@pdelacroix.com>2020-12-09 12:10:39 +0000
committerPierre de Lacroix <pierre@pdelacroix.com>2020-12-09 12:10:39 +0000
commitd189c923eb7e63fb7cb8c6dbd8816f7ca3b9384f (patch)
treedb6fede8164782facfae767d970bdf5838ce92e6
parentupdate description (diff)
parentfix tests in CI (diff)
Merge branch 'repo_setup' into 'master'
Repo setup See merge request kazarma/matrix_app_service.ex!13
-rw-r--r--.gitlab-ci.yml10
-rw-r--r--config/config.exs3
-rw-r--r--config/test.exs13
-rw-r--r--lib/matrix_app_service/application.ex23
-rw-r--r--lib/matrix_app_service/bridge.ex3
-rw-r--r--lib/matrix_app_service/bridge/room.ex21
-rw-r--r--lib/matrix_app_service/bridge/user.ex21
-rw-r--r--lib/matrix_app_service/bridge_config.ex227
-rw-r--r--lib/matrix_app_service/migrations.ex27
-rw-r--r--lib/matrix_app_service/repo.ex5
-rw-r--r--mix.exs5
-rw-r--r--mix.lock41
-rw-r--r--priv/repo/migrations/20201209095612_migrate_itself.exs7
-rw-r--r--test/matrix_app_service/bridge_test.exs141
-rw-r--r--test/support/conn_case.ex6
-rw-r--r--test/support/data_case.ex55
-rw-r--r--test/test_helper.exs1
17 files changed, 585 insertions, 24 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1dfcee7..9d6c6d8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -11,8 +11,18 @@ before_script:
test:
stage: static_analysis
+ services:
+ - postgres:latest
+ variables:
+ POSTGRES_DB: matrix_app_service_test
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: postgres
+ POSTGRES_HOST: postgres
+ POSTGRES_HOST_AUTH_METHOD: trust
script:
- MIX_ENV=test mix compile
+ - MIX_ENV=test mix ecto.create
+ - MIX_ENV=test mix ecto.migrate
- mix test --cover
artifacts:
when: always
diff --git a/config/config.exs b/config/config.exs
index 8d782dc..692048a 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -7,6 +7,9 @@
# General application configuration
use Mix.Config
+config :matrix_app_service,
+ ecto_repos: [MatrixAppService.Repo]
+
# Configures the endpoint
config :matrix_app_service, MatrixAppServiceWeb.Endpoint,
url: [host: "localhost"],
diff --git a/config/test.exs b/config/test.exs
index ed14857..905574a 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -1,5 +1,17 @@
use Mix.Config
+# Configure your database
+#
+# The MIX_TEST_PARTITION environment variable can be used
+# to provide built-in test partitioning in CI environment.
+# Run `mix help test` for more information.
+config :matrix_app_service, MatrixAppService.Repo,
+ username: System.get_env("POSTGRES_USER") || "postgres",
+ password: System.get_env("POSTGRES_PASSWORD") || "postgres",
+ database: "matrix_app_service_test#{System.get_env("MIX_TEST_PARTITION")}",
+ hostname: System.get_env("POSTGRES_HOST") || "localhost",
+ pool: Ecto.Adapters.SQL.Sandbox
+
# We don't run a server during test. If one is required,
# you can enable the server option below.
config :matrix_app_service, MatrixAppServiceWeb.Endpoint,
@@ -11,6 +23,7 @@ config :logger, level: :warn
config :matrix_app_service,
internal_supervisor: true,
+ internal_repo: true,
transaction_adapter: MatrixAppService.TestTransactionAdapter,
room_adapter: MatrixAppService.TestRoomAdapter,
user_adapter: MatrixAppService.TestUserAdapter,
diff --git a/lib/matrix_app_service/application.ex b/lib/matrix_app_service/application.ex
index 383c0f9..408d5ab 100644
--- a/lib/matrix_app_service/application.ex
+++ b/lib/matrix_app_service/application.ex
@@ -18,15 +18,20 @@ defmodule MatrixAppService.Application do
]
children =
- if start_endpoint?() do
- [
- # MatrixAppServiceWeb.Endpoint
+ if start_endpoint?(),
+ do: [
{MatrixAppServiceWeb.Endpoint, endpoint_config()}
| children
- ]
- else
- children
- end
+ ],
+ else: children
+
+ children =
+ if start_repo?(),
+ do: [
+ MatrixAppService.Repo
+ | children
+ ],
+ else: children
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
@@ -48,6 +53,10 @@ defmodule MatrixAppService.Application do
Application.get_env(:matrix_app_service, :internal_supervisor, false)
end
+ def start_repo?() do
+ Application.get_env(:matrix_app_service, :internal_repo, false)
+ end
+
def endpoint_config() do
[
transaction_adapter: Application.fetch_env!(:matrix_app_service, :transaction_adapter),
diff --git a/lib/matrix_app_service/bridge.ex b/lib/matrix_app_service/bridge.ex
new file mode 100644
index 0000000..e0e0fee
--- /dev/null
+++ b/lib/matrix_app_service/bridge.ex
@@ -0,0 +1,3 @@
+defmodule MatrixAppService.Bridge do
+ use MatrixAppService.BridgeConfig, repo: MatrixAppService.Repo
+end
diff --git a/lib/matrix_app_service/bridge/room.ex b/lib/matrix_app_service/bridge/room.ex
new file mode 100644
index 0000000..73ef1ea
--- /dev/null
+++ b/lib/matrix_app_service/bridge/room.ex
@@ -0,0 +1,21 @@
+defmodule MatrixAppService.Bridge.Room do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ schema "rooms" do
+ field(:data, :map)
+ field(:local_id, :string)
+ field(:remote_id, :string)
+
+ timestamps()
+ end
+
+ @doc false
+ def changeset(room, attrs) do
+ room
+ |> cast(attrs, [:local_id, :remote_id, :data])
+ # |> validate_required([:local_id, :remote_id, :data])
+ |> unique_constraint(:local_id)
+ |> unique_constraint(:remote_id)
+ end
+end
diff --git a/lib/matrix_app_service/bridge/user.ex b/lib/matrix_app_service/bridge/user.ex
new file mode 100644
index 0000000..7bf604a
--- /dev/null
+++ b/lib/matrix_app_service/bridge/user.ex
@@ -0,0 +1,21 @@
+defmodule MatrixAppService.Bridge.User do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ schema "users" do
+ field(:data, :map)
+ field(:local_id, :string)
+ field(:remote_id, :string)
+
+ timestamps()
+ end
+
+ @doc false
+ def changeset(user, attrs) do
+ user
+ |> cast(attrs, [:local_id, :remote_id, :data])
+ # |> validate_required([:local_id, :remote_id, :data])
+ |> unique_constraint(:local_id)
+ |> unique_constraint(:remote_id)
+ end
+end
diff --git a/lib/matrix_app_service/bridge_config.ex b/lib/matrix_app_service/bridge_config.ex
new file mode 100644
index 0000000..68723c6
--- /dev/null
+++ b/lib/matrix_app_service/bridge_config.ex
@@ -0,0 +1,227 @@
+defmodule MatrixAppService.BridgeConfig do
+ @moduledoc """
+ The Bridge config.
+ """
+
+ defmacro __using__(repo: repo) do
+ quote bind_quoted: [repo: repo] do
+ @repo repo
+
+ import Ecto.Query, warn: false
+ # alias MatrixAppService.Repo
+
+ alias MatrixAppService.Bridge.User
+
+ @doc """
+ Returns the list of users.
+
+ ## Examples
+
+ iex> list_users()
+ [%User{}, ...]
+
+ """
+ def list_users do
+ @repo.all(User)
+ end
+
+ @doc """
+ Gets a single user.
+
+ Raises `Ecto.NoResultsError` if the User does not exist.
+
+ ## Examples
+
+ iex> get_user!(123)
+ %User{}
+
+ iex> get_user!(456)
+ ** (Ecto.NoResultsError)
+
+ """
+ def get_user!(id), do: @repo.get!(User, id)
+
+ def get_user_by_local_id(local_id),
+ do: @repo.get_by(User, local_id: local_id) || %User{local_id: local_id}
+
+ def get_user_by_remote_id(remote_id),
+ do: @repo.get_by(User, remote_id: remote_id) || %User{remote_id: remote_id}
+
+ @doc """
+ Creates a user.
+
+ ## Examples
+
+ iex> create_user(%{field: value})
+ {:ok, %User{}}
+
+ iex> create_user(%{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def create_user(attrs \\ %{}) do
+ %User{}
+ |> User.changeset(attrs)
+ |> @repo.insert()
+ end
+
+ def upsert_user(attrs, selectors) do
+ with %User{} = user <- @repo.get_by(User, selectors) do
+ update_user(user, attrs)
+ else
+ _ ->
+ create_user(Enum.into(selectors, attrs, fn {k, v} -> {to_string(k), v} end))
+ end
+ end
+
+ @doc """
+ Updates a user.
+
+ ## Examples
+
+ iex> update_user(user, %{field: new_value})
+ {:ok, %User{}}
+
+ iex> update_user(user, %{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def update_user(%User{} = user, attrs) do
+ user
+ |> User.changeset(attrs)
+ |> @repo.update()
+ end
+
+ @doc """
+ Deletes a user.
+
+ ## Examples
+
+ iex> delete_user(user)
+ {:ok, %User{}}
+
+ iex> delete_user(user)
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def delete_user(%User{} = user) do
+ @repo.delete(user)
+ end
+
+ @doc """
+ Returns an `%Ecto.Changeset{}` for tracking user changes.
+
+ ## Examples
+
+ iex> change_user(user)
+ %Ecto.Changeset{data: %User{}}
+
+ """
+ def change_user(%User{} = user, attrs \\ %{}) do
+ User.changeset(user, attrs)
+ end
+
+ alias MatrixAppService.Bridge.Room
+
+ @doc """
+ Returns the list of rooms.
+
+ ## Examples
+
+ iex> list_rooms()
+ [%Room{}, ...]
+
+ """
+ def list_rooms do
+ @repo.all(Room)
+ end
+
+ @doc """
+ Gets a single room.
+
+ Raises `Ecto.NoResultsError` if the Room does not exist.
+
+ ## Examples
+
+ iex> get_room!(123)
+ %Room{}
+
+ iex> get_room!(456)
+ ** (Ecto.NoResultsError)
+
+ """
+ def get_room!(id), do: @repo.get!(Room, id)
+
+ def get_room_by_local_id(local_id),
+ do: @repo.get_by(Room, local_id: local_id) || %Room{local_id: local_id}
+
+ def get_room_by_remote_id(remote_id),
+ do: @repo.get_by(Room, remote_id: remote_id) || %Room{remote_id: remote_id}
+
+ @doc """
+ Creates a room.
+
+ ## Examples
+
+ iex> create_room(%{field: value})
+ {:ok, %Room{}}
+
+ iex> create_room(%{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def create_room(attrs \\ %{}) do
+ %Room{}
+ |> Room.changeset(attrs)
+ |> @repo.insert()
+ end
+
+ @doc """
+ Updates a room.
+
+ ## Examples
+
+ iex> update_room(room, %{field: new_value})
+ {:ok, %Room{}}
+
+ iex> update_room(room, %{field: bad_value})
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def update_room(%Room{} = room, attrs) do
+ room
+ |> Room.changeset(attrs)
+ |> @repo.update()
+ end
+
+ @doc """
+ Deletes a room.
+
+ ## Examples
+
+ iex> delete_room(room)
+ {:ok, %Room{}}
+
+ iex> delete_room(room)
+ {:error, %Ecto.Changeset{}}
+
+ """
+ def delete_room(%Room{} = room) do
+ @repo.delete(room)
+ end
+
+ @doc """
+ Returns an `%Ecto.Changeset{}` for tracking room changes.
+
+ ## Examples
+
+ iex> change_room(room)
+ %Ecto.Changeset{data: %Room{}}
+
+ """
+ def change_room(%Room{} = room, attrs \\ %{}) do
+ Room.changeset(room, attrs)
+ end
+ end
+ end
+end
diff --git a/lib/matrix_app_service/migrations.ex b/lib/matrix_app_service/migrations.ex
new file mode 100644
index 0000000..6ae5344
--- /dev/null
+++ b/lib/matrix_app_service/migrations.ex
@@ -0,0 +1,27 @@
+defmodule MatrixAppService.Migrations do
+ use Ecto.Migration
+
+ def change do
+ create table(:users) do
+ add(:local_id, :string)
+ add(:remote_id, :string)
+ add(:data, :map)
+
+ timestamps()
+ end
+
+ create(unique_index(:users, [:local_id]))
+ create(unique_index(:users, [:remote_id]))
+
+ create table(:rooms) do
+ add(:local_id, :string)
+ add(:remote_id, :string)
+ add(:data, :map)
+
+ timestamps()
+ end
+
+ create(unique_index(:rooms, [:local_id]))
+ create(unique_index(:rooms, [:remote_id]))
+ end
+end
diff --git a/lib/matrix_app_service/repo.ex b/lib/matrix_app_service/repo.ex
new file mode 100644
index 0000000..c52348a
--- /dev/null
+++ b/lib/matrix_app_service/repo.ex
@@ -0,0 +1,5 @@
+defmodule MatrixAppService.Repo do
+ use Ecto.Repo,
+ otp_app: :matrix_app_service,
+ adapter: Ecto.Adapters.Postgres
+end
diff --git a/mix.exs b/mix.exs
index a8e84fb..e0cffe4 100644
--- a/mix.exs
+++ b/mix.exs
@@ -59,10 +59,13 @@ defmodule MatrixAppService.MixProject do
{:telemetry_poller, "~> 0.4"},
{:jason, "~> 1.0"},
{:plug_cowboy, "~> 2.0"},
+ {:phoenix_ecto, "~> 4.1"},
+ {:ecto_sql, "~> 3.4"},
{:polyjuice_client, "~> 0.3.1"},
{:ex_doc, "~> 0.22", only: :dev, runtime: false},
{:junit_formatter, "~> 3.1", only: :test},
- {:cobertura_cover, "~> 0.9.0", only: :test}
+ {:cobertura_cover, "~> 0.9.0", only: :test},
+ {:postgrex, ">= 0.0.0", only: :test}
]
end
diff --git a/mix.lock b/mix.lock
index 399628f..9782076 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,34 +1,43 @@
%{
"certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
"cobertura_cover": {:hex, :cobertura_cover, "0.9.0", "01b9c5d2688d68240c1394c931383f8b29105b894ae499ef48aefd082a8a42b3", [:mix], [], "hexpm", "870bc4658cacc5c80d13f1206b688925234d2dc4e00278e8a3e72fbbd6bea0b1"},
- "cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "04fd8c6a39edc6aaa9c26123009200fc61f92a3a94f3178c527b70b767c6e605"},
- "cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm", "79f954a7021b302186a950a32869dbc185523d99d3e44ce430cd1f3289f41ed4"},
- "earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"},
- "ex_doc": {:hex, :ex_doc, "0.22.6", "0fb1e09a3e8b69af0ae94c8b4e4df36995d8c88d5ec7dbd35617929144b62c00", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "1e0aceda15faf71f1b0983165e6e7313be628a460e22a031e32913b98edbd638"},
+ "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
+ "cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
+ "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
+ "cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
+ "db_connection": {:hex, :db_connection, "2.3.1", "4c9f3ed1ef37471cbdd2762d6655be11e38193904d9c5c1c9389f1b891a3088e", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "abaab61780dde30301d840417890bd9f74131041afd02174cf4e10635b3a63f5"},
+ "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
+ "earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
+ "ecto": {:hex, :ecto, "3.5.5", "48219a991bb86daba6e38a1e64f8cea540cded58950ff38fbc8163e062281a07", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "98dd0e5e1de7f45beca6130d13116eae675db59adfa055fb79612406acf6f6f1"},
+ "ecto_sql": {:hex, :ecto_sql, "3.5.3", "1964df0305538364b97cc4661a2bd2b6c89d803e66e5655e4e55ff1571943efd", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.5.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d2f53592432ce17d3978feb8f43e8dc0705e288b0890caf06d449785f018061c"},
+ "ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
- "jason": {:hex, :jason, "1.2.0", "10043418c42d2493d0ee212d3fddd25d7ffe484380afad769a0a38795938e448", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "116747dbe057794c3a3e4e143b7c8390b29f634e16c78a7f59ba75bfa6852e7f"},
+ "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
"junit_formatter": {:hex, :junit_formatter, "3.1.0", "3f69c61c5413750f9c45e367d77aabbeac9b395acf478d8e70b4ee9d1989c709", [:mix], [], "hexpm", "da52401a93f711fc4f77ffabdda68f9a16fcad5d96f5fce4ae606ab1d73b72f4"},
- "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"},
- "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
+ "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
+ "makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
- "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
+ "mime": {:hex, :mime, "1.5.0", "203ef35ef3389aae6d361918bf3f952fa17a09e8e43b5aa592b93eba05d0fb8d", [:mix], [], "hexpm", "55a94c0f552249fc1a3dd9cd2d3ab9de9d3c89b559c2bd01121f824834f24746"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mutex": {:hex, :mutex, "1.1.3", "d7e19f96fe19d6d97583bf12ca1ec182bbf14619b7568592cc461135de1c3b81", [:mix], [], "hexpm", "2b83b92784add2611c23dd527073b5e8dfe3c9c6c94c5bf9e3081b5c41c3ff3e"},
- "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"},
+ "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
- "phoenix": {:hex, :phoenix, "1.5.1", "95156589879dc69201d5fc0ebdbfdfc7901a09a3616ea611ec297f81340275a2", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc272b38e79d2881790fccae6f67a9fbe9b790103d6878175ea03d23003152eb"},
+ "phoenix": {:hex, :phoenix, "1.5.7", "2923bb3af924f184459fe4fa4b100bd25fa6468e69b2803dfae82698269aa5e0", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "774cd64417c5a3788414fdbb2be2eb9bcd0c048d9e6ad11a0c1fd67b7c0d0978"},
+ "phoenix_ecto": {:hex, :phoenix_ecto, "4.2.1", "13f124cf0a3ce0f1948cf24654c7b9f2347169ff75c1123f44674afee6af3b03", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "478a1bae899cac0a6e02be1deec7e2944b7754c04e7d4107fc5a517f877743c0"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
- "plug": {:hex, :plug, "1.10.0", "6508295cbeb4c654860845fb95260737e4a8838d34d115ad76cd487584e2fc4d", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "422a9727e667be1bf5ab1de03be6fa0ad67b775b2d84ed908f3264415ef29d4a"},
- "plug_cowboy": {:hex, :plug_cowboy, "2.2.1", "fcf58aa33227a4322a050e4783ee99c63c031a2e7f9a2eb7340d55505e17f30f", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3b43de24460d87c0971887286e7a20d40462e48eb7235954681a20cee25ddeb6"},
- "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"},
+ "plug": {:hex, :plug, "1.11.0", "f17217525597628298998bc3baed9f8ea1fa3f1160aa9871aee6df47a6e4d38e", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2d9c633f0499f9dc5c2fd069161af4e2e7756890b81adcbb2ceaa074e8308876"},
+ "plug_cowboy": {:hex, :plug_cowboy, "2.4.1", "779ba386c0915027f22e14a48919a9545714f849505fa15af2631a0d298abf0f", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d72113b6dff7b37a7d9b2a5b68892808e3a9a752f2bf7e503240945385b70507"},
+ "plug_crypto": {:hex, :plug_crypto, "1.2.0", "1cb20793aa63a6c619dd18bb33d7a3aa94818e5fd39ad357051a67f26dfa2df6", [:mix], [], "hexpm", "a48b538ae8bf381ffac344520755f3007cc10bd8e90b240af98ea29b69683fc2"},
"poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm", "ba8836feea4b394bb718a161fc59a288fe0109b5006d6bdf97b6badfcf6f0f25"},
"polyjuice_client": {:hex, :polyjuice_client, "0.3.1", "cc312602a8da0d4d61b0a890bb72d9c6662f17cd0fc5782d8f7358274e3e6e4b", [:mix], [{:hackney, "~> 1.12", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:mutex, "~> 1.1.3", [hex: :mutex, repo: "hexpm", optional: false]}, {:polyjuice_util, "~> 0.1.0", [hex: :polyjuice_util, repo: "hexpm", optional: false]}], "hexpm", "e9585faab7562cac3e91a64d328905cefabc74219fafa9e77e09f4e5e4e82957"},
"polyjuice_util": {:hex, :polyjuice_util, "0.1.0", "69901959c143245b47829c8302d0605dff6c0e1c3b116730c162982e0f512ee0", [:mix], [], "hexpm", "af5d1f614f52ce1da59a1f5a7c49249a2dbfda279d99d52d1b4e83e84c19a8d5"},
+ "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
+ "postgrex": {:hex, :postgrex, "0.15.7", "724410acd48abac529d0faa6c2a379fb8ae2088e31247687b16cacc0e0883372", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "88310c010ff047cecd73d5ceca1d99205e4b1ab1b9abfdab7e00f5c9d20ef8f9"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
- "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"},
- "telemetry_metrics": {:hex, :telemetry_metrics, "0.4.2", "1de986fad9aa6bf81f8a33ddfd16e5d8ab0dec6272e624eb517c1a92a44d41a9", [:mix], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e56ffed2dbe293ab6cf7c94980faeb368cb360662c1927f54fc634a4ca55362e"},
- "telemetry_poller": {:hex, :telemetry_poller, "0.5.0", "4770888ef85599ead39c7f51d6b4b62306e602d96c69b2625d54dea3d9a5204b", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69e4e8e65b0ae077c9e14cd5f42c7cc486de0e07ac6e3409e6f0e52699a7872c"},
+ "telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
+ "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.0", "da9d49ee7e6bb1c259d36ce6539cd45ae14d81247a2b0c90edf55e2b50507f7b", [:mix], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5cfe67ad464b243835512aa44321cee91faed6ea868d7fb761d7016e02915c3d"},
+ "telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"},
}
diff --git a/priv/repo/migrations/20201209095612_migrate_itself.exs b/priv/repo/migrations/20201209095612_migrate_itself.exs
new file mode 100644
index 0000000..04df688
--- /dev/null
+++ b/priv/repo/migrations/20201209095612_migrate_itself.exs
@@ -0,0 +1,7 @@
+defmodule MatrixAppService.Repo.Migrations.MigrateItself do
+ use Ecto.Migration
+
+ def change do
+ MatrixAppService.Migrations.change()
+ end
+end
diff --git a/test/matrix_app_service/bridge_test.exs b/test/matrix_app_service/bridge_test.exs
new file mode 100644
index 0000000..0644f39
--- /dev/null
+++ b/test/matrix_app_service/bridge_test.exs
@@ -0,0 +1,141 @@
+defmodule MatrixAppService.BridgeTest do
+ use MatrixAppService.DataCase
+
+ alias MatrixAppService.Bridge
+
+ describe "users" do
+ alias MatrixAppService.Bridge.User
+
+ @valid_attrs %{data: %{}, local_id: "some local_id", remote_id: "some remote_id"}
+ @update_attrs %{
+ data: %{},
+ local_id: "some updated local_id",
+ remote_id: "some updated remote_id"
+ }
+
+ # @invalid_attrs %{data: nil, local_id: nil, remote_id: nil}
+
+ def user_fixture(attrs \\ %{}) do
+ {:ok, user} =
+ attrs
+ |> Enum.into(@valid_attrs)
+ |> Bridge.create_user()
+
+ user
+ end
+
+ test "list_users/0 returns all users" do
+ user = user_fixture()
+ assert Bridge.list_users() == [user]
+ end
+
+ test "get_user!/1 returns the user with given id" do
+ user = user_fixture()
+ assert Bridge.get_user!(user.id) == user
+ end
+
+ test "create_user/1 with valid data creates a user" do
+ assert {:ok, %User{} = user} = Bridge.create_user(@valid_attrs)
+ assert user.data == %{}
+ assert user.local_id == "some local_id"
+ assert user.remote_id == "some remote_id"
+ end
+
+ # test "create_user/1 with invalid data returns error changeset" do
+ # assert {:error, %Ecto.Changeset{}} = Bridge.create_user(@invalid_attrs)
+ # end
+
+ test "update_user/2 with valid data updates the user" do
+ user = user_fixture()
+ assert {:ok, %User{} = user} = Bridge.update_user(user, @update_attrs)
+ assert user.data == %{}
+ assert user.local_id == "some updated local_id"
+ assert user.remote_id == "some updated remote_id"
+ end
+
+ # test "update_user/2 with invalid data returns error changeset" do
+ # user = user_fixture()
+ # assert {:error, %Ecto.Changeset{}} = Bridge.update_user(user, @invalid_attrs)
+ # assert user == Bridge.get_user!(user.id)
+ # end
+
+ test "delete_user/1 deletes the user" do
+ user = user_fixture()
+ assert {:ok, %User{}} = Bridge.delete_user(user)
+ assert_raise Ecto.NoResultsError, fn -> Bridge.get_user!(user.id) end
+ end
+
+ test "change_user/1 returns a user changeset" do
+ user = user_fixture()
+ assert %Ecto.Changeset{} = Bridge.change_user(user)
+ end
+ end
+
+ describe "rooms" do
+ alias MatrixAppService.Bridge.Room
+
+ @valid_attrs %{data: %{}, local_id: "some local_id", remote_id: "some remote_id"}
+ @update_attrs %{
+ data: %{},
+ local_id: "some updated local_id",
+ remote_id: "some updated remote_id"
+ }
+
+ # @invalid_attrs %{data: nil, local_id: nil, remote_id: nil}
+
+ def room_fixture(attrs \\ %{}) do
+ {:ok, room} =
+ attrs
+ |> Enum.into(@valid_attrs)
+ |> Bridge.create_room()
+
+ room
+ end
+
+ test "list_rooms/0 returns all rooms" do
+ room = room_fixture()
+ assert Bridge.list_rooms() == [room]
+ end
+
+ test "get_room!/1 returns the room with given id" do
+ room = room_fixture()
+ assert Bridge.get_room!(room.id) == room
+ end
+
+ test "create_room/1 with valid data creates a room" do
+ assert {:ok, %Room{} = room} = Bridge.create_room(@valid_attrs)
+ assert room.data == %{}
+ assert room.local_id == "some local_id"
+ assert room.remote_id == "some remote_id"
+ end
+
+ # test "create_room/1 with invalid data returns error changeset" do
+ # assert {:error, %Ecto.Changeset{}} = Bridge.create_room(@invalid_attrs)
+ # end
+
+ test "update_room/2 with valid data updates the room" do
+ room = room_fixture()
+ assert {:ok, %Room{} = room} = Bridge.update_room(room, @update_attrs)
+ assert room.data == %{}
+ assert room.local_id == "some updated local_id"
+ assert room.remote_id == "some updated remote_id"
+ end
+
+ # test "update_room/2 with invalid data returns error changeset" do
+ # room = room_fixture()
+ # assert {:error, %Ecto.Changeset{}} = Bridge.update_room(room, @invalid_attrs)
+ # assert room == Bridge.get_room!(room.id)
+ # end
+
+ test "delete_room/1 deletes the room" do
+ room = room_fixture()
+ assert {:ok, %Room{}} = Bridge.delete_room(room)
+ assert_raise Ecto.NoResultsError, fn -> Bridge.get_room!(room.id) end
+ end
+
+ test "change_room/1 returns a room changeset" do
+ room = room_fixture()
+ assert %Ecto.Changeset{} = Bridge.change_room(room)
+ end
+ end
+end
diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex
index e1ce056..582801d 100644
--- a/test/support/conn_case.ex
+++ b/test/support/conn_case.ex
@@ -32,6 +32,12 @@ defmodule MatrixAppServiceWeb.ConnCase do
end
setup tags do
+ :ok = Ecto.Adapters.SQL.Sandbox.checkout(MatrixAppService.Repo)
+
+ unless tags[:async] do
+ Ecto.Adapters.SQL.Sandbox.mode(MatrixAppService.Repo, {:shared, self()})
+ end
+
conn =
if tags[:authenticated] do
Phoenix.ConnTest.build_conn(:get, "/", %{
diff --git a/test/support/data_case.ex b/test/support/data_case.ex
new file mode 100644
index 0000000..76994a7
--- /dev/null
+++ b/test/support/data_case.ex
@@ -0,0 +1,55 @@
+defmodule MatrixAppService.DataCase do
+ @moduledoc """
+ This module defines the setup for tests requiring
+ access to the application's data layer.
+
+ You may define functions here to be used as helpers in
+ your tests.
+
+ Finally, if the test case interacts with the database,
+ we enable the SQL sandbox, so changes done to the database
+ are reverted at the end of every test. If you are using
+ PostgreSQL, you can even run database tests asynchronously
+ by setting `use MatrixAppService.DataCase, async: true`, although
+ this option is not recommended for other databases.
+ """
+
+ use ExUnit.CaseTemplate
+
+ using do
+ quote do
+ alias MatrixAppService.Repo
+
+ import Ecto
+ import Ecto.Changeset
+ import Ecto.Query
+ import MatrixAppService.DataCase
+ end
+ end
+
+ setup tags do
+ :ok = Ecto.Adapters.SQL.Sandbox.checkout(MatrixAppService.Repo)
+
+ unless tags[:async] do
+ Ecto.Adapters.SQL.Sandbox.mode(MatrixAppService.Repo, {:shared, self()})
+ end
+
+ :ok
+ end
+
+ @doc """
+ A helper that transforms changeset errors into a map of messages.
+
+ assert {:error, changeset} = Accounts.create_user(%{password: "short"})
+ assert "password is too short" in errors_on(changeset).password
+ assert %{password: ["password is too short"]} = errors_on(changeset)
+
+ """
+ def errors_on(changeset) do
+ Ecto.Changeset.traverse_errors(changeset, fn {message, opts} ->
+ Regex.replace(~r"%{(\w+)}", message, fn _, key ->
+ opts |> Keyword.get(String.to_existing_atom(key), key) |> to_string()
+ end)
+ end)
+ end
+end
diff --git a/test/test_helper.exs b/test/test_helper.exs
index 3140500..baf9e64 100644
--- a/test/test_helper.exs
+++ b/test/test_helper.exs
@@ -1,2 +1,3 @@
+Ecto.Adapters.SQL.Sandbox.mode(MatrixAppService.Repo, :manual)
ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter])
ExUnit.start()