Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make organisations field searchable #3172

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions app/views/devise/invitations/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,23 @@
autocomplete: "off",
} %>

<%= render "govuk_publishing_components/components/select", {
id: "user_organisation_id",
name: "user[organisation_id]",
label: "Organisation",
options: options_for_organisation_select(selected: f.object.organisation_id)
} %>
<div data-module="accessible-autocomplete">
<%= render "govuk_publishing_components/components/select", {
id: "user_organisation_id",
name: "user[organisation_id]",
label: "Organisation",
options: options_for_organisation_select(selected: f.object.organisation_id)
} %>

<div class="govuk-button-group">
<%= render "govuk_publishing_components/components/button", {
text: "Clear selection",
type: "button",
classes: "js-autocomplete__clear-button",
secondary_solid: true
} %>
</div>
</div>

<% if policy(User).assign_role? %>
<%= render "govuk_publishing_components/components/select", {
Expand Down
128 changes: 128 additions & 0 deletions test/integration/inviting_users_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -384,4 +384,132 @@ class InvitingUsersTest < ActionDispatch::IntegrationTest
end
end
end

context "with JavaScript enabled" do
setup do
use_javascript_driver

create(:organisation, name: "ABCDEF")
create(:organisation, name: "GHIJKL")
@organisation = create(:organisation, name: "MNOPQR")
create(:organisation, name: "STUVWX")
create(:organisation, name: "YZ1234")

superadmin = create(:superadmin_user)
visit root_path
signin_with(superadmin)

visit new_user_invitation_path
fill_in "Name", with: "H from Steps"
fill_in "Email", with: "h@from.steps"
select "Superadmin", from: "Role"

@autocomplete_input_element = find(".autocomplete__input")
@select_element = find("#user_organisation_id-select", visible: false)
end

should "be able to invite a user" do
assert_select_with_autocomplete(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @organisation.name,
option_value: @organisation.id.to_s,
unique_partial_string: "MNO",
)

click_button "Create user and send email"

new_user = User.find_by(email: "h@from.steps", role: Roles::Superadmin.name)
assert_not_nil new_user
assert_equal new_user.organisation, @organisation
end

should("not show an 'Add' button") { assert_no_selector "button", text: "Add" }

should "reset the value of the select element when it no longer matches what's shown in the autocomplete input" do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would you feel about extracting these tests into more "component" style tests? That way we'd only need to test it once as we're reusing the component across multiple pages.

As it stands we're testing this behaviour twice across the two integration tests. We could then restrict the two test files modified in this PR to only test a user inputting some text into the autocomplete and inviting a user.

assert_select_with_autocomplete(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @organisation.name,
option_value: @organisation.id.to_s,
unique_partial_string: "MNO",
)

assert_resets_select_when_desynced_with_autocomplete(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @organisation.name,
unique_partial_string: "MNOP",
)

click_button "Create user and send email"

new_user = User.find_by(email: "h@from.steps", role: Roles::Superadmin.name)
assert_not_nil new_user
assert_nil new_user.organisation
end

should "clear the value of the select and autocomplete elements when clicking the clear button" do
assert_select_with_autocomplete(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @organisation.name,
option_value: @organisation.id.to_s,
unique_partial_string: "MNO",
)

assert_clear_autocomplete_selection_by_click(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
)

click_button "Create user and send email"

new_user = User.find_by(email: "h@from.steps", role: Roles::Superadmin.name)
assert_not_nil new_user
assert_nil new_user.organisation
end

should "clear the value of the select and autocomplete elements when hitting space on the clear button" do
assert_select_with_autocomplete(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @organisation.name,
option_value: @organisation.id.to_s,
unique_partial_string: "MNO",
)

assert_clear_autocomplete_selection_by_space(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
)

click_button "Create user and send email"

new_user = User.find_by(email: "h@from.steps", role: Roles::Superadmin.name)
assert_not_nil new_user
assert_nil new_user.organisation
end

should "clear the value of the select and autocomplete elements when hitting enter on the clear button" do
assert_select_with_autocomplete(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @organisation.name,
option_value: @organisation.id.to_s,
unique_partial_string: "MNO",
)

assert_clear_autocomplete_selection_by_enter(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
)

click_button "Create user and send email"

new_user = User.find_by(email: "h@from.steps", role: Roles::Superadmin.name)
assert_not_nil new_user
assert_nil new_user.organisation
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,16 @@ def assert_select_permission_to_grant_with_javascript

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

@autocomplete_input = find(".autocomplete__input")
@autocomplete_input_element = find(".autocomplete__input")
@select_element = find("#new_permission_id-select", visible: false)
assert_equal "", @autocomplete_input.value
assert_equal "", @select_element.value

# when I type a few characters from a permission called "adding"
@autocomplete_input.fill_in with: "add"
autocomplete_option = find(".autocomplete__option")

# 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

# when I click on the matching option
autocomplete_option.click

# 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
assert_select_with_autocomplete(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @new_permission_to_grant.name,
option_value: @new_permission_to_grant.id.to_s,
unique_partial_string: "add",
)
end

def assert_permissions_unchanged
Expand Down Expand Up @@ -162,14 +152,13 @@ def assert_permissions_unchanged
should "reset the value of the select element when it no longer matches what's shown in the autocomplete input" do
assert_select_permission_to_grant_with_javascript

@autocomplete_input.fill_in with: "addin"
autocomplete_option = find(".autocomplete__option")

assert_equal "addin", @autocomplete_input.value
assert_equal @new_permission_to_grant.name, autocomplete_option.text
assert_equal "", @select_element.value
assert_resets_select_when_desynced_with_autocomplete(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are going to go down a more abstracted approach with our tests, could we make method names for our helpers even more human readable? I know we're following the lead taken by Minitest here, but I'm not the biggest fan of the brevity of Minitest's DSL.

Also, forgive my ignorance but I'm not sure what desynced means!

autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
option_text: @new_permission_to_grant.name,
unique_partial_string: "addin",
)

@autocomplete_input.native.send_keys :escape
click_button "Add and finish"

assert_permissions_unchanged
Expand All @@ -179,10 +168,10 @@ def assert_permissions_unchanged
should "clear the value of the select and autocomplete elements when clicking the clear button" do
assert_select_permission_to_grant_with_javascript

click_button "Clear selection"

assert_equal "", @autocomplete_input.value
assert_equal "", @select_element.value
assert_clear_autocomplete_selection_by_click(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
)

click_button "Add and finish"

Expand All @@ -193,11 +182,10 @@ def assert_permissions_unchanged
should "clear the value of the select and autocomplete elements when hitting space on the clear button" do
assert_select_permission_to_grant_with_javascript

clear_button = find(".js-autocomplete__clear-button")
clear_button.native.send_keys :space

assert_equal "", @autocomplete_input.value
assert_equal "", @select_element.value
assert_clear_autocomplete_selection_by_space(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
)

click_button "Add and finish"

Expand All @@ -208,11 +196,10 @@ def assert_permissions_unchanged
should "clear the value of the select and autocomplete elements when hitting enter on the clear button" do
assert_select_permission_to_grant_with_javascript

clear_button = find(".js-autocomplete__clear-button")
clear_button.native.send_keys :enter

assert_equal "", @autocomplete_input.value
assert_equal "", @select_element.value
assert_clear_autocomplete_selection_by_enter(
autocomplete_input_element: @autocomplete_input_element,
select_element: @select_element,
)

click_button "Add and finish"

Expand Down
67 changes: 67 additions & 0 deletions test/support/autocomplete_helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
module AutocompleteHelpers
def assert_select_with_autocomplete(
autocomplete_input_element:,
select_element:,
option_text:,
option_value:,
unique_partial_string:
)
assert_equal "", autocomplete_input_element.value
assert_equal "", select_element.value

# when I type a few characters from the option that are unique to that option
autocomplete_input_element.fill_in with: unique_partial_string
autocomplete_option = find(".autocomplete__option")

# the autcomplete value reflects what I typed, a matching option appears, but the select element remains empty
assert_equal unique_partial_string, autocomplete_input_element.value
assert_equal option_text, autocomplete_option.text
assert_equal "", select_element.value

# when I click on the matching option
autocomplete_option.click

# the autocomplete and select elements reflect my selection
assert_equal option_text, autocomplete_input_element.value
assert_equal option_value, select_element.value
end

def assert_resets_select_when_desynced_with_autocomplete(
autocomplete_input_element:,
select_element:,
option_text:,
unique_partial_string:
)
autocomplete_input_element.fill_in with: unique_partial_string
autocomplete_option = find(".autocomplete__option")

assert_equal unique_partial_string, autocomplete_input_element.value
assert_equal option_text, autocomplete_option.text
assert_equal "", select_element.value

autocomplete_input_element.native.send_keys :escape
end

def assert_clear_autocomplete_selection_by_click(autocomplete_input_element:, select_element:)
click_button "Clear selection"

assert_equal "", autocomplete_input_element.value
assert_equal "", select_element.value
end

def assert_clear_autocomplete_selection_by_space(autocomplete_input_element:, select_element:)
clear_button = find(".js-autocomplete__clear-button")
clear_button.native.send_keys :space

assert_equal "", autocomplete_input_element.value
assert_equal "", select_element.value
end

def assert_clear_autocomplete_selection_by_enter(autocomplete_input_element:, select_element:)
clear_button = find(".js-autocomplete__clear-button")
clear_button.native.send_keys :enter

assert_equal "", autocomplete_input_element.value
assert_equal "", select_element.value
end
end
2 changes: 2 additions & 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_helpers"

class ActiveRecord::Base
mattr_accessor :shared_connection
Expand Down Expand Up @@ -117,6 +118,7 @@ class ActionDispatch::IntegrationTest
include RemovingAccessHelpers
include UpdatingPermissionsHelpers
include FlashHelpers
include AutocompleteHelpers

def assert_response_contains(content)
assert page.has_content?(content), "Expected to find '#{content}' in:\n#{page.text}"
Expand Down