defmodule Mv.Membership.JoinRequestApprovalPolicyTest do @moduledoc """ Policy tests for JoinRequest approval UI (Step 2). Asserts that approve/reject and list are allowed for normal_user and admin, and forbidden for read_only, own_data, and actor: nil. No UI; domain and resource policies only. """ use Mv.DataCase, async: true alias Mv.Fixtures alias Mv.Membership describe "list_join_requests/1" do test "normal_user can list join requests" do user = Fixtures.user_with_role_fixture("normal_user") assert {:ok, _list} = Membership.list_join_requests(actor: user) end test "admin can list join requests" do user = Fixtures.user_with_role_fixture("admin") assert {:ok, _list} = Membership.list_join_requests(actor: user) end test "read_only cannot list join requests" do user = Fixtures.user_with_role_fixture("read_only") assert {:error, %Ash.Error.Forbidden{}} = Membership.list_join_requests(actor: user) end test "own_data cannot list join requests" do user = Fixtures.user_with_role_fixture("own_data") assert {:error, %Ash.Error.Forbidden{}} = Membership.list_join_requests(actor: user) end test "actor nil cannot list join requests" do assert {:error, %Ash.Error.Forbidden{}} = Membership.list_join_requests(actor: nil) end end describe "approve_join_request/2" do setup do request = Fixtures.submitted_join_request_fixture() %{request: request} end test "normal_user can approve a submitted join request", %{request: request} do user = Fixtures.user_with_role_fixture("normal_user") assert {:ok, approved} = Membership.approve_join_request(request.id, actor: user) assert approved.status == :approved assert approved.approved_at != nil assert approved.reviewed_by_user_id == user.id assert approved.reviewed_by_display == to_string(user.email) end test "admin can approve a submitted join request", %{request: request} do user = Fixtures.user_with_role_fixture("admin") assert {:ok, approved} = Membership.approve_join_request(request.id, actor: user) assert approved.status == :approved end test "read_only cannot approve", %{request: request} do user = Fixtures.user_with_role_fixture("read_only") assert {:error, %Ash.Error.Forbidden{}} = Membership.approve_join_request(request.id, actor: user) end test "own_data cannot approve", %{request: request} do user = Fixtures.user_with_role_fixture("own_data") assert {:error, %Ash.Error.Forbidden{}} = Membership.approve_join_request(request.id, actor: user) end test "actor nil cannot approve", %{request: request} do assert {:error, %Ash.Error.Forbidden{}} = Membership.approve_join_request(request.id, actor: nil) end end describe "reject_join_request/2" do setup do request = Fixtures.submitted_join_request_fixture() %{request: request} end test "normal_user can reject a submitted join request", %{request: request} do user = Fixtures.user_with_role_fixture("normal_user") assert {:ok, rejected} = Membership.reject_join_request(request.id, actor: user) assert rejected.status == :rejected assert rejected.rejected_at != nil assert rejected.reviewed_by_user_id == user.id assert rejected.reviewed_by_display == to_string(user.email) end test "admin can reject a submitted join request", %{request: request} do user = Fixtures.user_with_role_fixture("admin") assert {:ok, rejected} = Membership.reject_join_request(request.id, actor: user) assert rejected.status == :rejected end test "read_only cannot reject", %{request: request} do user = Fixtures.user_with_role_fixture("read_only") assert {:error, %Ash.Error.Forbidden{}} = Membership.reject_join_request(request.id, actor: user) end test "own_data cannot reject", %{request: request} do user = Fixtures.user_with_role_fixture("own_data") assert {:error, %Ash.Error.Forbidden{}} = Membership.reject_join_request(request.id, actor: user) end test "actor nil cannot reject", %{request: request} do assert {:error, %Ash.Error.Forbidden{}} = Membership.reject_join_request(request.id, actor: nil) end end end