Skip to content

Instantly share code, notes, and snippets.

@sb8244
Created August 10, 2023 18:39
Show Gist options
  • Save sb8244/6fdf7e9cafd9b0dbdc6d824a25f727b6 to your computer and use it in GitHub Desktop.
Save sb8244/6fdf7e9cafd9b0dbdc6d824a25f727b6 to your computer and use it in GitHub Desktop.
defmodule Super.RepoTest do
use Super.DataCase, async: true
require Logger
@skipped_schemas [UserService.User]
defp tenant_schemas do
{:ok, mods} = :application.get_key(:super, :modules)
Enum.map(mods, fn mod ->
Code.ensure_loaded!(mod)
if function_exported?(mod, :__schema__, 1) do
fields = mod.__schema__(:fields)
if :team_id in fields and mod not in @skipped_schemas do
mod
end
end
end)
|> Enum.reject(&is_nil/1)
end
describe "enforced_schemas" do
test "all application schemas are enforced" do
schemas = Super.Repo.enforced_schemas()
Enum.each(tenant_schemas(), fn mod ->
enforced_fields =
Enum.filter(schemas, fn {schema, _id} ->
schema == mod
end)
team_id = Enum.filter(enforced_fields, fn {_, type} -> type == :team_id end)
assert length(team_id) == 1, "#{mod} missing enforcement: team_id"
end)
end
test "all application schemas with team_id are indexed on it" do
# This test prints out all failures manually rather than failing the test immediately
{:ok, %{rows: rows}} = Repo.query("SELECT tablename FROM pg_indexes WHERE indexdef LIKE '%(team_id)%'")
indexed_tables = Enum.map(rows, fn [t] -> t end)
passes =
tenant_schemas()
|> Enum.map(fn mod -> mod.__schema__(:source) end)
|> Enum.sort()
|> Enum.map(fn table_name ->
indexed? = table_name in indexed_tables
if indexed? do
true
else
# See 20210504180331_add_missing_tenant_indices.exs for example of how to use
IO.puts("create index(\"#{table_name}\", [:team_id], concurrently: true)")
false
end
end)
assert Enum.uniq(passes) == [true]
end
end
describe "query_limit" do
test "process attribute limits the number of queries" do
Process.put(:query_limit, 3)
assert Repo.all(UserService.User) == []
assert Repo.all(UserService.User) == []
assert Repo.all(UserService.User) == []
assert_raise(RuntimeError, fn ->
Repo.all(UserService.User)
end)
Process.delete(:query_limit)
assert Repo.all(UserService.User) == []
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment