defmodule MyPlugin.ContractTest do @moduledoc """ Contract compliance tests. These verify that the plugin conforms to the Tribes plugin contract. When Tribes.Plugin.ContractTest is available (host dep loaded), replace this file with: defmodule MyPlugin.ContractTest do use Tribes.Plugin.ContractTest, plugin: MyPlugin.Plugin, otp_app: :my_plugin end Until then, this file provides a standalone equivalent. """ use ExUnit.Case, async: true @plugin MyPlugin.Plugin @manifest_path Path.join(__DIR__, "../manifest.json") |> Path.expand() setup_all do manifest = @manifest_path |> File.read!() |> Jason.decode!() spec = @plugin.register(%{pubsub: nil, repo: nil}) %{manifest: manifest, spec: spec} end test "runtime provides matches manifest provides", %{manifest: manifest, spec: spec} do normalise = fn cap -> if String.contains?(cap, "@"), do: cap, else: "#{cap}@1" end manifest_caps = manifest["provides"] |> Enum.map(normalise) |> Enum.sort() runtime_caps = spec.provides |> Enum.map(normalise) |> Enum.sort() assert manifest_caps == runtime_caps, "manifest provides #{inspect(manifest_caps)} != runtime provides #{inspect(runtime_caps)}" end test "runtime requires matches manifest requires", %{manifest: manifest, spec: spec} do normalise = fn cap -> if String.contains?(cap, "@"), do: cap, else: "#{cap}@1" end manifest_caps = manifest["requires"] |> Enum.map(normalise) |> Enum.sort() runtime_caps = spec.requires |> Enum.map(normalise) |> Enum.sort() assert manifest_caps == runtime_caps, "manifest requires #{inspect(manifest_caps)} != runtime requires #{inspect(runtime_caps)}" end test "spec has all required keys", %{spec: spec} do required_keys = [ :name, :version, :provides, :requires, :nav_items, :pages, :children, :global_js, :global_css, :migrations_path, :hooks ] for key <- required_keys do assert Map.has_key?(spec, key), "spec must contain #{inspect(key)}" end end test "name in spec matches manifest", %{manifest: manifest, spec: spec} do assert spec.name == manifest["name"] end test "migrations_path exists if manifest declares migrations", %{manifest: manifest, spec: spec} do if manifest["migrations"] do assert is_binary(spec.migrations_path), "migrations_path must be set when manifest declares migrations: true" assert File.dir?(spec.migrations_path), "migrations_path #{inspect(spec.migrations_path)} must be an existing directory" end end end