From da0b045771a4703bc3ca0f7b0fdfa5e47d0564e0 Mon Sep 17 00:00:00 2001 From: Moritz Date: Sat, 24 Jan 2026 08:38:33 +0100 Subject: [PATCH] Fix missing actor parameters and restore AshAuthentication bypass tests --- .../member_cycle_calculations_test.exs | 30 +++++++------ .../member_type_change_integration_test.exs | 8 ++-- .../membership_fee_cycle_test.exs | 12 ++--- test/mv/accounts/user_policies_test.exs | 45 +++++++++---------- test/mv_web/member_live/index_test.exs | 3 +- 5 files changed, 50 insertions(+), 48 deletions(-) diff --git a/test/membership/member_cycle_calculations_test.exs b/test/membership/member_cycle_calculations_test.exs index 030aa8b..ea7f378 100644 --- a/test/membership/member_cycle_calculations_test.exs +++ b/test/membership/member_cycle_calculations_test.exs @@ -81,7 +81,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :current_cycle_status) + member = Ash.load!(member, :current_cycle_status, actor: actor) assert member.current_cycle_status == :paid end @@ -100,7 +100,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :current_cycle_status) + member = Ash.load!(member, :current_cycle_status, actor: actor) assert member.current_cycle_status == nil end @@ -108,7 +108,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do fee_type = create_fee_type(%{interval: :yearly}, actor) member = create_member(%{membership_fee_type_id: fee_type.id}, actor) - member = Ash.load!(member, :current_cycle_status) + member = Ash.load!(member, :current_cycle_status, actor: actor) assert member.current_cycle_status == nil end @@ -130,7 +130,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :current_cycle_status) + member = Ash.load!(member, :current_cycle_status, actor: actor) assert member.current_cycle_status == :unpaid end end @@ -176,7 +176,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :last_cycle_status) + member = Ash.load!(member, :last_cycle_status, actor: actor) # Should return status of 2023 (last completed) assert member.last_cycle_status == :unpaid end @@ -199,7 +199,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :last_cycle_status) + member = Ash.load!(member, :last_cycle_status, actor: actor) assert member.last_cycle_status == nil end @@ -207,7 +207,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do fee_type = create_fee_type(%{interval: :yearly}, actor) member = create_member(%{membership_fee_type_id: fee_type.id}, actor) - member = Ash.load!(member, :last_cycle_status) + member = Ash.load!(member, :last_cycle_status, actor: actor) assert member.last_cycle_status == nil end @@ -240,7 +240,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :last_cycle_status) + member = Ash.load!(member, :last_cycle_status, actor: actor) # Should return status of last month (last completed) assert member.last_cycle_status == :paid end @@ -309,7 +309,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do ) end - member = Ash.load!(member, :overdue_count) + member = Ash.load!(member, :overdue_count, actor: actor) # Should only count 2022 (unpaid and ended) assert member.overdue_count == 1 end @@ -329,7 +329,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :overdue_count) + member = Ash.load!(member, :overdue_count, actor: actor) assert member.overdue_count == 0 end @@ -337,7 +337,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do fee_type = create_fee_type(%{interval: :yearly}, actor) member = create_member(%{membership_fee_type_id: fee_type.id}, actor) - member = Ash.load!(member, :overdue_count) + member = Ash.load!(member, :overdue_count, actor: actor) assert member.overdue_count == 0 end @@ -384,7 +384,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :overdue_count) + member = Ash.load!(member, :overdue_count, actor: actor) # Should only count two_months_ago (unpaid and ended) assert member.overdue_count == 1 end @@ -424,7 +424,7 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do actor ) - member = Ash.load!(member, :overdue_count) + member = Ash.load!(member, :overdue_count, actor: actor) assert member.overdue_count == 3 end end @@ -470,7 +470,9 @@ defmodule Mv.Membership.MemberCycleCalculationsTest do ) member = - Ash.load!(member, [:current_cycle_status, :last_cycle_status, :overdue_count]) + Ash.load!(member, [:current_cycle_status, :last_cycle_status, :overdue_count], + actor: actor + ) assert member.current_cycle_status == :unpaid assert member.last_cycle_status == :paid diff --git a/test/membership/member_type_change_integration_test.exs b/test/membership/member_type_change_integration_test.exs index 24d4355..cb289be 100644 --- a/test/membership/member_type_change_integration_test.exs +++ b/test/membership/member_type_change_integration_test.exs @@ -120,7 +120,7 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do |> Ash.Query.filter(member_id == ^member.id and cycle_start == ^current_cycle_start) |> Ash.read_one(actor: actor) do {:ok, existing_cycle} when not is_nil(existing_cycle) -> - Ash.destroy!(existing_cycle) + Ash.destroy!(existing_cycle, actor: actor) _ -> :ok @@ -313,7 +313,7 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do |> Ash.Query.filter(member_id == ^member.id and cycle_start == ^past_cycle_start) |> Ash.read_one(actor: actor) do {:ok, existing_cycle} when not is_nil(existing_cycle) -> - Ash.destroy!(existing_cycle) + Ash.destroy!(existing_cycle, actor: actor) _ -> :ok @@ -337,7 +337,7 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do |> Ash.Query.filter(member_id == ^member.id and cycle_start == ^current_cycle_start) |> Ash.read_one(actor: actor) do {:ok, existing_cycle} when not is_nil(existing_cycle) -> - Ash.destroy!(existing_cycle) + Ash.destroy!(existing_cycle, actor: actor) _ -> :ok @@ -426,7 +426,7 @@ defmodule Mv.Membership.MemberTypeChangeIntegrationTest do Enum.each(existing_cycles, fn cycle -> if cycle.cycle_start != current_cycle_start do - Ash.destroy!(cycle) + Ash.destroy!(cycle, actor: actor) end end) diff --git a/test/membership_fees/membership_fee_cycle_test.exs b/test/membership_fees/membership_fee_cycle_test.exs index 4f78d1b..46d6216 100644 --- a/test/membership_fees/membership_fee_cycle_test.exs +++ b/test/membership_fees/membership_fee_cycle_test.exs @@ -190,27 +190,27 @@ defmodule Mv.MembershipFees.MembershipFeeCycleTest do # unpaid -> paid cycle1 = create_cycle(member, fee_type, %{status: :unpaid}, actor) - assert {:ok, c1} = Ash.update(cycle1, %{}, action: :mark_as_paid) + assert {:ok, c1} = Ash.update(cycle1, %{}, actor: actor, action: :mark_as_paid) assert c1.status == :paid # paid -> suspended - assert {:ok, c2} = Ash.update(c1, %{}, action: :mark_as_suspended) + assert {:ok, c2} = Ash.update(c1, %{}, actor: actor, action: :mark_as_suspended) assert c2.status == :suspended # suspended -> unpaid - assert {:ok, c3} = Ash.update(c2, %{}, action: :mark_as_unpaid) + assert {:ok, c3} = Ash.update(c2, %{}, actor: actor, action: :mark_as_unpaid) assert c3.status == :unpaid # unpaid -> suspended - assert {:ok, c4} = Ash.update(c3, %{}, action: :mark_as_suspended) + assert {:ok, c4} = Ash.update(c3, %{}, actor: actor, action: :mark_as_suspended) assert c4.status == :suspended # suspended -> paid - assert {:ok, c5} = Ash.update(c4, %{}, action: :mark_as_paid) + assert {:ok, c5} = Ash.update(c4, %{}, actor: actor, action: :mark_as_paid) assert c5.status == :paid # paid -> unpaid - assert {:ok, c6} = Ash.update(c5, %{}, action: :mark_as_unpaid) + assert {:ok, c6} = Ash.update(c5, %{}, actor: actor, action: :mark_as_unpaid) assert c6.status == :unpaid end end diff --git a/test/mv/accounts/user_policies_test.exs b/test/mv/accounts/user_policies_test.exs index b7a0910..e04213a 100644 --- a/test/mv/accounts/user_policies_test.exs +++ b/test/mv/accounts/user_policies_test.exs @@ -343,29 +343,24 @@ defmodule Mv.Accounts.UserPoliciesTest do end describe "AshAuthentication bypass" do - test "register_with_password works with system actor" do - # Registration should work (AshAuthentication bypass in production) - # Note: When directly calling Ash actions in tests, the AshAuthentication bypass - # may not be active, so we use system_actor to test the functionality - system_actor = Mv.Helpers.SystemActor.get_system_actor() - - {:ok, user} = + test "register_with_password works without actor via AshAuthentication bypass" do + # Test that AshAuthentication bypass allows registration without actor + # This tests the actual bypass mechanism, not admin permissions + changeset = Accounts.User |> Ash.Changeset.for_create(:register_with_password, %{ email: "register#{System.unique_integer([:positive])}@example.com", password: "testpassword123" }) - |> Ash.create(actor: system_actor) + |> Ash.Changeset.set_context(%{private: %{ash_authentication?: true}}) + + {:ok, user} = Ash.create(changeset) assert user.email end - test "register_with_rauthy works with OIDC user_info" do - # OIDC registration should work (AshAuthentication bypass in production) - # Note: When directly calling Ash actions in tests, the AshAuthentication bypass - # may not be active, so we use system_actor to test the functionality - system_actor = Mv.Helpers.SystemActor.get_system_actor() - + test "register_with_rauthy works without actor via AshAuthentication bypass" do + # Test that AshAuthentication bypass allows OIDC registration without actor user_info = %{ "sub" => "oidc_sub_#{System.unique_integer([:positive])}", "email" => "oidc#{System.unique_integer([:positive])}@example.com" @@ -373,20 +368,24 @@ defmodule Mv.Accounts.UserPoliciesTest do oauth_tokens = %{access_token: "token", refresh_token: "refresh"} - {:ok, user} = + changeset = Accounts.User |> Ash.Changeset.for_create(:register_with_rauthy, %{ user_info: user_info, oauth_tokens: oauth_tokens }) - |> Ash.create(actor: system_actor) + |> Ash.Changeset.set_context(%{private: %{ash_authentication?: true}}) + + {:ok, user} = Ash.create(changeset) assert user.email assert user.oidc_id == user_info["sub"] end - test "sign_in_with_rauthy works with OIDC user_info" do - # First create a user with OIDC ID + test "sign_in_with_rauthy works without actor via AshAuthentication bypass" do + # First create a user with OIDC ID (using system_actor for setup) + system_actor = Mv.Helpers.SystemActor.get_system_actor() + user_info_create = %{ "sub" => "oidc_sub_#{System.unique_integer([:positive])}", "email" => "oidc#{System.unique_integer([:positive])}@example.com" @@ -394,8 +393,6 @@ defmodule Mv.Accounts.UserPoliciesTest do oauth_tokens = %{access_token: "token", refresh_token: "refresh"} - system_actor = Mv.Helpers.SystemActor.get_system_actor() - {:ok, user} = Accounts.User |> Ash.Changeset.for_create(:register_with_rauthy, %{ @@ -404,14 +401,16 @@ defmodule Mv.Accounts.UserPoliciesTest do }) |> Ash.create(actor: system_actor) - # Now test sign_in_with_rauthy (should work via AshAuthentication bypass) - {:ok, signed_in_user} = + # Now test sign_in_with_rauthy without actor (should work via AshAuthentication bypass) + query = Accounts.User |> Ash.Query.for_read(:sign_in_with_rauthy, %{ user_info: user_info_create, oauth_tokens: oauth_tokens }) - |> Ash.read_one(actor: system_actor) + |> Ash.Query.set_context(%{private: %{ash_authentication?: true}}) + + {:ok, signed_in_user} = Ash.read_one(query) assert signed_in_user.id == user.id end diff --git a/test/mv_web/member_live/index_test.exs b/test/mv_web/member_live/index_test.exs index 0f3d03b..0624c77 100644 --- a/test/mv_web/member_live/index_test.exs +++ b/test/mv_web/member_live/index_test.exs @@ -1323,7 +1323,8 @@ defmodule MvWeb.MemberLive.IndexTest do }) |> Ash.create(actor: system_actor) - member_without_value = member_without_value |> Ash.load!(:custom_field_values) + member_without_value = + member_without_value |> Ash.load!(:custom_field_values, actor: system_actor) members = [member_with_true, member_with_false, member_without_value] filters = %{to_string(boolean_field.id) => true}