Skip to content

Commit

Permalink
Refactor Integration tests for updating apps with many permissions
Browse files Browse the repository at this point in the history
The tests in this file kept this DRY but were a little tricky to figure
out at a glance what each test was doing. We've refactored them a fair
bit to remove some of the abstractions and make them easier to read,
while still looping over the two use cases of updating one's own
permissions and updating those of another user.

This refactor was prompted by the addition of a new Accessible
Autocomplete component to the Organisations page. We've added a new
AutocompleteHelper in this commit to perform some simple Autocomplete
actions and prevent us needing to re-write a few lines of code to find
and select an option.

It's used here for updating permissions tests, and will be used in the
next commit in inviting users tests when adding autocomplete to the
organisation field.

Apologies for multiple changes going on in this commit, it's
essentially:
- Adding a new Autocomplete Helper for reuse in other areas of the
  service that use the Accessible Autocomplete.
- Refactoring the tests to use this new helper and to improve
  readability.

Co-authored-by: Ynda Jas <yndajas@gmail.com>
  • Loading branch information
yndajas authored and Gweaton committed Sep 26, 2024
1 parent 749b3f3 commit 5939e1e
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,152 +3,151 @@
class UpdatingPermissionsForAppsWithManyPermissionsTest < ActionDispatch::IntegrationTest
# Also see: Account::UpdatingPermissionsTest, Users::UpdatingPermissionsTest

def shared_setup
@grantee_is_self = rand(2).zero?

@application = create(:application)
@old_permissions_to_keep = create_list(:supported_permission, 3, application: @application)
@old_permission_to_remove_without_javascript = create(:supported_permission, application: @application)
@new_permissions_to_leave = create_list(:supported_permission, 4, application: @application)
@new_permission_to_grant = create(:supported_permission, application: @application, name: "adding")

@current_user = create(:superadmin_user)
@grantee = @grantee_is_self ? @current_user : create(:user)
@grantee.grant_application_signin_permission(@application)
@grantee.grant_application_permissions(@application, [*@old_permissions_to_keep, @old_permission_to_remove_without_javascript].map(&:name))
autocomplete_helper = AutocompleteHelper.new

def navigate_to_update_my_own_permissions_page
visit new_user_session_path
signin_with @current_user

visit account_applications_path
click_link "Update permissions for #{@application.name}"
end

def assert_select_permission_to_grant_with_javascript
@grantee_is_self ? assert_edit_self : assert_edit_other_user(@grantee)
def navigate_to_update_other_user_permissions_page
visit new_user_session_path
signin_with @current_user

visit user_applications_path(@grantee)
click_link "Update permissions for #{@application.name}"
end

@autocomplete_input = find(".autocomplete__input")
@select_element = find("#new_permission_id-select", visible: false)
assert_equal "", @autocomplete_input.value
assert_equal "", @select_element.value
def navigate_to_update_permissions_page
@updating_own_permissions ? navigate_to_update_my_own_permissions_page : navigate_to_update_other_user_permissions_page
end

# when I type a few characters from a permission called "adding"
@autocomplete_input.fill_in with: "add"
autocomplete_option = find(".autocomplete__option")
[
{ description: "updating my own permissions", updating_own_permissions: true },
{ description: "updating someone else's permissions", updating_own_permissions: false },
].each do |context_hash|
context context_hash[:description] do
setup do
@updating_own_permissions = context_hash[:updating_own_permissions]
end

# the autcomplete value reflects what I typed, a matching option appears, but the select element remains empty
assert_equal "add", @autocomplete_input.value
assert_equal @new_permission_to_grant.name, autocomplete_option.text
assert_equal "", @select_element.value
context "updating permissions" do
setup do
@application = create(:application)
create_list(:supported_permission, 8, application: @application)

# when I click on the matching option
autocomplete_option.click
@current_user = create(:superadmin_user)
@grantee = @updating_own_permissions ? @current_user : create(:user)

# the autocomplete and select elements reflect my selection
assert_equal @new_permission_to_grant.name, @autocomplete_input.value
assert_equal @new_permission_to_grant.id.to_s, @select_element.value
end
@grantee.grant_application_signin_permission(@application)

context "with apps that have more than eight permissions" do
context "with JavaScript disabled" do
setup { shared_setup }
@existing_permission = create(:supported_permission, application: @application)
@grantee.grant_application_permissions(@application, [@existing_permission.name])
@new_permission_to_grant = create(:supported_permission, application: @application)
end

should "be able to grant permissions" do
@grantee_is_self ? assert_edit_self : assert_edit_other_user(@grantee)
context "when JS is enabled" do
setup do
use_javascript_driver
navigate_to_update_permissions_page
end

click_link "Update permissions for #{@application.name}"
select @new_permission_to_grant.name
click_button "Add and finish"
should "I should be able to grant myself some permissions from the autocomplete" do
autocomplete_helper.select_autocomplete_option(@new_permission_to_grant.name)
click_button "Add and finish"

click_link "Update permissions for #{@application.name}"
uncheck @old_permission_to_remove_without_javascript.name
click_button "Update permissions"
assert @grantee.has_permission?(@new_permission_to_grant)
assert_flash_content([@new_permission_to_grant.name, @existing_permission.name])
assert @grantee.has_permission?(@existing_permission)
end

expected_permissions = [*@old_permissions_to_keep, @new_permission_to_grant]
assert_flash_content(expected_permissions.map(&:name))
expected_permissions.each { |expected_permission| assert @grantee.has_permission?(expected_permission) }
should "be able to add multiple permissions one after the other when clicking 'add'" do
newer_permission_to_grant = create(:supported_permission, application: @application)

unexpected_permissions = [@old_permission_to_remove_without_javascript, *@new_permissions_to_leave]
refute_flash_content(unexpected_permissions.map(&:name))
unexpected_permissions.each { |unexpected_permission| assert_not @grantee.has_permission?(unexpected_permission) }
end
autocomplete_helper.select_autocomplete_option(@new_permission_to_grant.name)
click_button "Add"

context "when the grantee already has some but not all permissions" do
should "display the new and current permissions forms" do
@grantee_is_self ? assert_edit_self : assert_edit_other_user(@grantee)
assert @grantee.has_permission?(@new_permission_to_grant)
assert_flash_content("You have successfully added the permission '#{@new_permission_to_grant.name}'.")

click_link "Update permissions for #{@application.name}"
autocomplete_helper.select_autocomplete_option(newer_permission_to_grant.name)
click_button "Add"

assert_selector ".govuk-label", text: "Add a permission"
assert_selector "legend", text: "Current permissions"
assert @grantee.has_permission?(newer_permission_to_grant)
assert_flash_content("You have successfully added the permission '#{newer_permission_to_grant.name}'.")
end
end
end

context "when the grantee has all permissions" do
setup do
@grantee.grant_application_permissions(@application, [*@new_permissions_to_leave, @new_permission_to_grant].map(&:name))
context "when JS is disabled" do
setup do
navigate_to_update_permissions_page
end

should "be able to grant myself some permissions from the select element" do
select @new_permission_to_grant.name
click_button "Add and finish"
assert @grantee.has_permission?(@new_permission_to_grant)
assert @grantee.has_permission?(@existing_permission)
end
end

should "only display the current permissions form" do
@grantee_is_self ? assert_edit_self : assert_edit_other_user(@grantee)
should "should be able to remove permissions by unchecking them" do
navigate_to_update_permissions_page

click_link "Update permissions for #{@application.name}"
uncheck @existing_permission.name
click_button "Update permissions"

assert_no_selector ".govuk-label", text: "Add a permission"
assert_selector "legend", text: "Current permissions"
assert_not @grantee.has_permission?(@existing_permission)
end
end

context "when the grantee has no permissions" do
context "displaying different forms based on the number of the user's permissions" do
setup do
old_permission_ids = [*@old_permissions_to_keep, @old_permission_to_remove_without_javascript].pluck(:id)
UserApplicationPermission.where(user: @grantee, supported_permission_id: old_permission_ids).destroy_all
@current_user = create(:superadmin_user)
@grantee = @updating_own_permissions ? @current_user : create(:user)
@application = create(:application)
@supported_permissions = create_list(:supported_permission, 9, application: @application)
end

should "only display the new permissions form" do
@grantee_is_self ? assert_edit_self : assert_edit_other_user(@grantee)

click_link "Update permissions for #{@application.name}"

assert_selector ".govuk-label", text: "Add a permission"
assert_no_selector "legend", text: "Current permissions"
context "when the grantee already has the signin permission but not all other permissions" do
setup do
@grantee.grant_application_signin_permission(@application)
@grantee.grant_application_permissions(@application, @supported_permissions.first(3).map(&:name))
navigate_to_update_permissions_page
end

should "display the new and current permissions forms" do
assert assert_selector ".govuk-label", text: "Add a permission"
assert assert_selector "legend", text: "Current permissions"
end
end
end
end

context "with JavaScript enabled" do
setup do
use_javascript_driver
shared_setup
end

should "be able to grant permissions" do
assert_select_permission_to_grant_with_javascript

click_button "Add and finish"
context "when I have all permissions, including signin" do
setup do
@grantee.grant_application_permissions(@application, @application.supported_permissions.map(&:name))
navigate_to_update_permissions_page
end

expected_permissions = [*@old_permissions_to_keep, @new_permission_to_grant, @old_permission_to_remove_without_javascript]
assert_flash_content(expected_permissions.map(&:name))
expected_permissions.each { |expected_permission| assert @grantee.has_permission?(expected_permission) }

unexpected_permissions = @new_permissions_to_leave
refute_flash_content(unexpected_permissions.map(&:name))
unexpected_permissions.each { |unexpected_permission| assert_not @grantee.has_permission?(unexpected_permission) }
end

should "grant permissions then redirect back to the form when clicking 'Add'" do
assert_select_permission_to_grant_with_javascript

click_button "Add"

expected_permissions = [*@old_permissions_to_keep, @new_permission_to_grant, @old_permission_to_remove_without_javascript]
expected_permissions.each { |expected_permission| assert @grantee.has_permission?(expected_permission) }
should "only display the current permissions form" do
assert assert_no_selector ".govuk-label", text: "Add a permission"
assert assert_selector "legend", text: "Current permissions"
end
end

unexpected_permissions = @new_permissions_to_leave
unexpected_permissions.each { |unexpected_permission| assert_not @grantee.has_permission?(unexpected_permission) }
context "when I only have the signin permission" do
setup do
@grantee.grant_application_signin_permission(@application)
navigate_to_update_permissions_page
end

h1_content = @grantee_is_self ? "Update permissions for #{@application.name}" : "Update #{@grantee.name}'s permissions for #{@application.name}"
assert page.has_selector?("h1", text: h1_content)
assert_flash_content("You have successfully added the permission '#{@new_permission_to_grant.name}'.")
should "only display the new permissions form" do
assert assert_selector ".govuk-label", text: "Add a permission"
assert assert_no_selector "legend", text: "Current permissions"
end
end
end
end
end
Expand Down
12 changes: 12 additions & 0 deletions test/support/autocomplete_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require "capybara/rails"

class AutocompleteHelper
include Capybara::DSL

def select_autocomplete_option(string)
autocomplete_input_element = find(".autocomplete__input")
autocomplete_input_element.fill_in with: string
autocomplete_option = find(".autocomplete__option")
autocomplete_option.click
end
end
1 change: 1 addition & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def assert_not_authorised
require "support/removing_access_helpers"
require "support/updating_permissions_helpers"
require "support/flash_helpers"
require "support/autocomplete_helper"

class ActiveRecord::Base
mattr_accessor :shared_connection
Expand Down

0 comments on commit 5939e1e

Please sign in to comment.