diff --git a/app/controllers/organizations/activations_controller.rb b/app/controllers/organizations/activations_controller.rb new file mode 100644 index 000000000..1efb80557 --- /dev/null +++ b/app/controllers/organizations/activations_controller.rb @@ -0,0 +1,23 @@ +module Organizations + class ActivationsController < Organizations::BaseController + def update + @user = User.find(params[:user_id]) + + authorize! @user, with: ActivationsPolicy + + if @user.deactivated_at + @user.activate + else + @user.deactivate + end + + respond_to do |format| + success = @user.deactivated_at.nil? ? + t(".activated", staff: @user.full_name) : + t(".deactivated", staff: @user.full_name) + format.html { redirect_to staff_staff_index_path, notice: success } + format.turbo_stream { flash.now[:notice] = success } + end + end + end +end diff --git a/app/controllers/organizations/staff/staff_controller.rb b/app/controllers/organizations/staff/staff_controller.rb index f9e80915c..548b8ce0f 100644 --- a/app/controllers/organizations/staff/staff_controller.rb +++ b/app/controllers/organizations/staff/staff_controller.rb @@ -1,5 +1,4 @@ class Organizations::Staff::StaffController < Organizations::BaseController - before_action :set_staff, only: [:update_activation] include ::Pagy::Backend layout "dashboard" @@ -12,28 +11,4 @@ def index limit: 10 ) end - - def update_activation - if @staff.deactivated_at - @staff.activate - else - @staff.deactivate - end - - respond_to do |format| - success = @staff.deactivated_at.nil? ? - t(".activated", staff: @staff.full_name) : - t(".deactivated", staff: @staff.full_name) - format.html { redirect_to staff_staff_index_path, notice: success } - format.turbo_stream { flash.now[:notice] = success } - end - end - - private - - def set_staff - @staff = User.find(params[:staff_id]) - - authorize! @staff - end end diff --git a/app/models/concerns/authorizable.rb b/app/models/concerns/authorizable.rb index bcd63185c..cd7e437bc 100644 --- a/app/models/concerns/authorizable.rb +++ b/app/models/concerns/authorizable.rb @@ -57,6 +57,8 @@ def staff?(organization) view_people view_form_submissions manage_faqs + activate_adopter + activate_foster ] ).freeze diff --git a/app/policies/organizations/activations_policy.rb b/app/policies/organizations/activations_policy.rb new file mode 100644 index 000000000..a90f5db52 --- /dev/null +++ b/app/policies/organizations/activations_policy.rb @@ -0,0 +1,18 @@ +module Organizations + class ActivationsPolicy < ApplicationPolicy + pre_check :verify_organization! + pre_check :verify_active_staff! + + def update? + return false if record.id == user.id + + record_role = record.roles.first.name + + if %w[super_admin admin].include?(record_role) + permission?(:activate_staff) + else + permission?(:activate_foster) && permission?(:activate_adopter) + end + end + end +end diff --git a/app/policies/organizations/user_policy.rb b/app/policies/organizations/user_policy.rb index 872d6497b..d1cc3f52b 100644 --- a/app/policies/organizations/user_policy.rb +++ b/app/policies/organizations/user_policy.rb @@ -5,8 +5,4 @@ class Organizations::UserPolicy < ApplicationPolicy def index? permission?(:manage_staff) end - - def update_activation? - permission?(:activate_staff) && record.id != user.id - end end diff --git a/app/views/layouts/shared/_footer.html.erb b/app/views/layouts/shared/_footer.html.erb index 6bf49aabe..8d1f6ad7e 100644 --- a/app/views/layouts/shared/_footer.html.erb +++ b/app/views/layouts/shared/_footer.html.erb @@ -5,11 +5,11 @@
-

<%= t('.title') %>

+

<%= t('.organization_name', name: Current.tenant.name) %>

<%= t('.call') %> - <%= link_to t('.action'), new_organization_account_request_path %> + <%= link_to t('.action'), Rails.env.production? ? "https://www.homewardtails.org/organization_account_request/new" : "http://localhost:3000/organization_account_request/new" %>

diff --git a/app/views/organizations/activations/update.turbo_stream.erb b/app/views/organizations/activations/update.turbo_stream.erb new file mode 100644 index 000000000..6708d44fd --- /dev/null +++ b/app/views/organizations/activations/update.turbo_stream.erb @@ -0,0 +1 @@ +<%= turbo_stream.replace "flash", partial: "layouts/shared/flash_messages" %> diff --git a/app/views/organizations/staff/adopters/_adopter_cards.html.erb b/app/views/organizations/staff/adopters/_adopter_cards.html.erb index 11ac6e80c..80e427091 100644 --- a/app/views/organizations/staff/adopters/_adopter_cards.html.erb +++ b/app/views/organizations/staff/adopters/_adopter_cards.html.erb @@ -16,6 +16,10 @@ <%= t(:joined) %> <%= adopter.created_at.strftime("%d %B, %Y") %>
+
+ <%= t(:deactivate) %> + <%= render "organizations/staff/shared/deactivate_toggle", user: adopter.user %> +
diff --git a/app/views/organizations/staff/adopters/_adopter_table.html.erb b/app/views/organizations/staff/adopters/_adopter_table.html.erb index 01297de62..94b7fbaf7 100644 --- a/app/views/organizations/staff/adopters/_adopter_table.html.erb +++ b/app/views/organizations/staff/adopters/_adopter_table.html.erb @@ -6,6 +6,7 @@ <%= t(:name) %> <%= t(:joined_at) %> + <%= t(:deactivate) %> @@ -25,6 +26,9 @@ <%= adopter.created_at.strftime("%d %B, %Y") %> + + <%= render "organizations/staff/shared/deactivate_toggle", user: adopter.user %> + <% end %> diff --git a/app/views/organizations/staff/custom_pages/_form.html.erb b/app/views/organizations/staff/custom_pages/_form.html.erb index 43ab86765..47540f0b5 100644 --- a/app/views/organizations/staff/custom_pages/_form.html.erb +++ b/app/views/organizations/staff/custom_pages/_form.html.erb @@ -21,7 +21,7 @@ label: "Hero Image", class: 'form-control'%> - Images must be .png or .jpeg under 2MB + Image must be .png or .jpeg under 2MB
<%= form.text_area :about, label: "About Us", placeholder: "About Us text", class: 'form-control' %>
diff --git a/app/views/organizations/staff/fosterers/_fosterer_cards.html.erb b/app/views/organizations/staff/fosterers/_fosterer_cards.html.erb index eccd6d089..3a9a6987a 100644 --- a/app/views/organizations/staff/fosterers/_fosterer_cards.html.erb +++ b/app/views/organizations/staff/fosterers/_fosterer_cards.html.erb @@ -16,6 +16,10 @@ <%= t(:joined) %> <%= fosterer.created_at.strftime("%d %B, %Y") %> +
+ <%= t(:deactivate) %> + <%= render "organizations/staff/shared/deactivate_toggle", user: fosterer.user %> +
diff --git a/app/views/organizations/staff/fosterers/_fosterer_table.html.erb b/app/views/organizations/staff/fosterers/_fosterer_table.html.erb index 5f87889fd..0d395e77d 100644 --- a/app/views/organizations/staff/fosterers/_fosterer_table.html.erb +++ b/app/views/organizations/staff/fosterers/_fosterer_table.html.erb @@ -8,6 +8,7 @@ <%= t(:name) %> <%= t(:email) %> + <%= t(:deactivate) %> <%= t(:phone) %> <% if can_edit_person %> <%= t(:action) %> @@ -31,6 +32,9 @@ <%= fosterer.email %> + + <%= render "organizations/staff/shared/deactivate_toggle", user: fosterer.user %> + <%= fosterer.phone_number %> diff --git a/app/views/organizations/staff/shared/_attachment_form.html.erb b/app/views/organizations/staff/shared/_attachment_form.html.erb index d592f8e9c..afc990301 100644 --- a/app/views/organizations/staff/shared/_attachment_form.html.erb +++ b/app/views/organizations/staff/shared/_attachment_form.html.erb @@ -16,6 +16,13 @@ direct_upload: true, class: "custom-attachments", hide_label: true %> + + <% if attachment_type == 'files' %> + Files must be .pdf, .png, or .jpeg under 2MB. + <% elsif attachment_type == 'images' %> + Images must be .jpg or .png under 1MB. + <%end%> +
<%= form.submit t("general.attach"), class: "btn btn-outline-success" %> diff --git a/app/views/organizations/staff/staff/_deactivate_toggle.html.erb b/app/views/organizations/staff/shared/_deactivate_toggle.html.erb similarity index 68% rename from app/views/organizations/staff/staff/_deactivate_toggle.html.erb rename to app/views/organizations/staff/shared/_deactivate_toggle.html.erb index bc8dc6a58..28f5961d7 100644 --- a/app/views/organizations/staff/staff/_deactivate_toggle.html.erb +++ b/app/views/organizations/staff/shared/_deactivate_toggle.html.erb @@ -1,12 +1,12 @@ -
> - <%= form_with model: staff, url: staff_staff_update_activation_path(staff) do |form| %> +
> + <%= form_with model: user, url: activations_path(user_id: user.id) do |form| %>
<%= form.check_box :deactivated?, { class: "form-check-input", role: "switch", - disabled: staff == current_user, + disabled: user == current_user, id: "flexSwitchCheckChecked", onchange: "this.form.requestSubmit()" }, diff --git a/app/views/organizations/staff/staff/_staff_cards.html.erb b/app/views/organizations/staff/staff/_staff_cards.html.erb index 8cc621bb6..e497352f6 100644 --- a/app/views/organizations/staff/staff/_staff_cards.html.erb +++ b/app/views/organizations/staff/staff/_staff_cards.html.erb @@ -22,7 +22,7 @@
<%= t(:deactivate) %> - <%= render "deactivate_toggle", staff: staff %> + <%= render "organizations/staff/shared/deactivate_toggle", user: staff %>
diff --git a/app/views/organizations/staff/staff/_staff_table.html.erb b/app/views/organizations/staff/staff/_staff_table.html.erb index 645a75c92..4a70c9cc0 100644 --- a/app/views/organizations/staff/staff/_staff_table.html.erb +++ b/app/views/organizations/staff/staff/_staff_table.html.erb @@ -31,7 +31,7 @@ <%= staff.created_at.strftime("%d %B, %Y") %> - <%= render "deactivate_toggle", staff: staff %> + <%= render "organizations/staff/shared/deactivate_toggle", user: staff %> <% end %> diff --git a/app/views/organizations/staff/staff/update_activation.turbo_stream.erb b/app/views/organizations/staff/staff/update_activation.turbo_stream.erb deleted file mode 100644 index e0a94f453..000000000 --- a/app/views/organizations/staff/staff/update_activation.turbo_stream.erb +++ /dev/null @@ -1,5 +0,0 @@ -<%= turbo_stream.replace_all ".staff_deactivate_toggle_#{@staff.id}", - partial: "deactivate_toggle", - locals: {staff: @staff} -%> -<%= turbo_stream.replace "flash", partial: "layouts/shared/flash_messages" %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 65b95729b..cbb7cc4f0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -174,7 +174,7 @@ en: layouts: shared: footer: - title: "Pet Rescue" + organization_name: "%{name}" call: "If you are a pet adoption or foster organization and want a website like this one, for free," action: "Click Here" company: "Company" @@ -195,7 +195,7 @@ en: dashboard: "Dashboard" demo: "This is a demo site" no_tenant_footer: - title: "Open Pet Rescue" + title: "Homeward Tails" about: "About Us" rescues: 'Rescues' ruby_for_good: 'Ruby For Good' @@ -371,6 +371,10 @@ en: authorization_error: "You are not authorized to perform this action." try_again: "Error. Please try again." organizations: + activations: + update: + activated: "%{staff} was activated." + deactivated: "%{staff} was deactivated." home: index: every_paw: "Where every paw finds a home" @@ -660,10 +664,6 @@ en: help_text: label: "Label" help_text: "help text" - staff: - update_activation: - activated: "%{staff} was activated." - deactivated: "%{staff} was deactivated." external_form_upload: index: description: "If you collect information from adopters from a third party service, like Google Forms, you can export a CSV file from Google Forms and upload it here. We will import the questions and answers for any adopters who have an account on your Homeward Tails website, providing they use the same email address. Then you will be able to see the information for each adopter when reviewing applications." diff --git a/config/routes.rb b/config/routes.rb index fd81dbee3..457c1b4bb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -35,6 +35,7 @@ # Staff Routes namespace :staff do resource :organization, only: %i[edit update] + resources :staff, only: %i[index] resource :custom_page, only: %i[edit update] resources :external_form_upload, only: %i[index create] resources :default_pet_tasks @@ -82,10 +83,6 @@ resources :form_answers, only: [:index] end - resources :staff do - patch "update_activation" - end - namespace :custom_form do resources :forms do resources :questions @@ -114,6 +111,9 @@ end end + # Activate/Deactivate users + resource :activations, only: [:update] + # File Purging delete "staff/attachments/:id/purge", to: "attachments#purge", as: "staff_purge_attachment" delete "attachments/:id/purge_avatar", to: "attachments#purge_avatar", as: "purge_avatar" diff --git a/test/controllers/organizations/activations_controller_test.rb b/test/controllers/organizations/activations_controller_test.rb new file mode 100644 index 000000000..5704fe61e --- /dev/null +++ b/test/controllers/organizations/activations_controller_test.rb @@ -0,0 +1,19 @@ +require "test_helper" +require "action_policy/test_helper" + +class Organizations::ActivationsControllerTest < ActionDispatch::IntegrationTest + setup do + @organization = ActsAsTenant.current_tenant + @staff = create(:admin) + sign_in @staff + end + + test "update activation should modify user deactivated at state" do + user = create(:super_admin) + sign_in user + + assert_changes -> { User.find(@staff.id).deactivated_at } do + patch activations_url(user_id: @staff.id), as: :turbo_stream + end + end +end diff --git a/test/controllers/organizations/staff/staff_controller_test.rb b/test/controllers/organizations/staff/staff_controller_test.rb index cf78aaeb1..502d91ceb 100644 --- a/test/controllers/organizations/staff/staff_controller_test.rb +++ b/test/controllers/organizations/staff/staff_controller_test.rb @@ -11,16 +11,6 @@ class Organizations::Staff::StaffControllerTest < ActionDispatch::IntegrationTes context "authorization" do include ActionPolicy::TestHelper - context "#update_activation" do - should "be authorized" do - assert_authorized_to( - :update_activation?, @staff, with: Organizations::UserPolicy - ) do - patch staff_staff_update_activation_url(@staff) - end - end - end - context "#index" do should "be authorized" do assert_authorized_to( @@ -48,14 +38,4 @@ class Organizations::Staff::StaffControllerTest < ActionDispatch::IntegrationTes end end end - - test "update activation should respond with turbo_stream when toggled on staff page" do - user = create(:super_admin) - sign_in user - - patch staff_staff_update_activation_url(@staff), as: :turbo_stream - - assert_equal Mime[:turbo_stream], response.media_type - assert_response :success - end end diff --git a/test/policies/organizations/activations_policy_test.rb b/test/policies/organizations/activations_policy_test.rb new file mode 100644 index 000000000..e4306687a --- /dev/null +++ b/test/policies/organizations/activations_policy_test.rb @@ -0,0 +1,196 @@ +require "test_helper" + +class Organizations::ActivationsPolicyTest < ActiveSupport::TestCase + include PetRescue::PolicyAssertions + + setup do + @policy = -> { Organizations::ActivationsPolicy.new(@user_being_updated, user: @user) } + end + + context "when resource being updated is admin" do + context "#update?" do + setup do + @user_being_updated = create(:admin) + @action = -> { @policy.call.apply(:update?) } + end + + context "when user is nil" do + setup do + @user = nil + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is adopter" do + setup do + @user = create(:adopter) + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is fosterer" do + setup do + @user = create(:fosterer) + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is admin" do + setup do + @user = create(:admin) + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is super admin" do + setup do + @user = create(:super_admin) + end + + should "return true" do + assert_equal true, @action.call + end + + context "when staff is self" do + setup do + @user_being_updated = @user + end + + should "return false" do + assert_equal false, @action.call + end + end + end + end + end + + context "when resource being updated is fosterer" do + context "#update?" do + setup do + @user_being_updated = create(:fosterer) + @action = -> { @policy.call.apply(:update?) } + end + + context "when user is nil" do + setup do + @user = nil + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is adopter" do + setup do + @user = create(:adopter) + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is fosterer" do + setup do + @user = create(:fosterer) + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is admin" do + setup do + @user = create(:admin) + end + + should "return true" do + assert_equal true, @action.call + end + end + + context "when user is super admin" do + setup do + @user = create(:super_admin) + end + + should "return true" do + assert_equal true, @action.call + end + end + end + end + + context "when resource being updated is adopter" do + context "#update?" do + setup do + @user_being_updated = create(:adopter) + @action = -> { @policy.call.apply(:update?) } + end + + context "when user is nil" do + setup do + @user = nil + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is adopter" do + setup do + @user = create(:adopter) + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is fosterer" do + setup do + @user = create(:fosterer) + end + + should "return false" do + assert_equal false, @action.call + end + end + + context "when user is admin" do + setup do + @user = create(:admin) + end + + should "return true" do + assert_equal true, @action.call + end + end + + context "when user is super admin" do + setup do + @user = create(:super_admin) + end + + should "return true" do + assert_equal true, @action.call + end + end + end + end +end diff --git a/test/policies/organizations/user_policy_test.rb b/test/policies/organizations/user_policy_test.rb index 7a34f28c4..0971ffc5f 100644 --- a/test/policies/organizations/user_policy_test.rb +++ b/test/policies/organizations/user_policy_test.rb @@ -74,70 +74,4 @@ class Organizations::UserPolicyTest < ActiveSupport::TestCase end end end - - context "#update_activation?" do - setup do - @action = -> { @policy.call.apply(:update_activation?) } - end - - context "when user is nil" do - setup do - @user = nil - end - - should "return false" do - assert_equal false, @action.call - end - end - - context "when user is adopter" do - setup do - @user = create(:adopter) - end - - should "return false" do - assert_equal false, @action.call - end - end - - context "when user is fosterer" do - setup do - @user = create(:fosterer) - end - - should "return false" do - assert_equal false, @action.call - end - end - - context "when user is staff" do - setup do - @user = create(:admin) - end - - should "return false" do - assert_equal false, @action.call - end - end - - context "when user is staff admin" do - setup do - @user = create(:super_admin) - end - - should "return true" do - assert_equal true, @action.call - end - - context "when staff is self" do - setup do - @staff = @user - end - - should "return false" do - assert_equal false, @action.call - end - end - end - end end