Skip to content
28 changes: 28 additions & 0 deletions app/controllers/group_forms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,40 @@ def create
end
end

def edit
@group_form = GroupForm.find_by(form_id: params[:id])
authorize @group_form

form = FormRepository.find(form_id: @group_form.form_id)

@group_select = Forms::GroupSelect.new(group: @group, form: form)
end

def update
@group_form = GroupForm.find_by(form_id: params[:id])
authorize @group_form

form = Form.find(params[:id])
@group_select = Forms::GroupSelect.new(group: group_select_params[:group], form: form)

receiving_group = Group.find(@group_select.group)

form.move_to_group(receiving_group.external_id)
form.reload

redirect_to group_path(params[:group_id]) # doesn't set_group already give us the @group?
end

private

def set_group
@group = Group.find_by!(external_id: params[:group_id])
end

def group_select_params
params.require(:forms_group_select).permit(:group)
end

def name_input_params
params.require(:forms_name_input).permit(:name)
end
Expand Down
12 changes: 12 additions & 0 deletions app/input_objects/forms/group_select.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Forms::GroupSelect < BaseInput
attr_accessor :form, :group

def groups
# TODO: change this to Groups in the Logged In User's Organisation only
Group.all
end

def to_partial_path
"input_objects/forms/group_select"
end
end
15 changes: 15 additions & 0 deletions app/policies/group_form_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,20 @@ class GroupFormPolicy < ApplicationPolicy
def new?
Pundit.policy!(user, record.group).show?
end

alias_method :create?, :new?

def edit?
organisation_admin_or_super_admin?
end

def update?
organisation_admin_or_super_admin?
end

private

def organisation_admin_or_super_admin?
user.super_admin? || user.is_organisations_admin?(record.group.organisation)
end
end
30 changes: 30 additions & 0 deletions app/views/group_forms/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<% set_page_title(title_with_error_prefix(t('page_titles.move_form'), @group_select.errors.any?)) %>
<% content_for :back_link, govuk_back_link_to(group_path(@group), "Back to #{@group_select.group.name}") %>

<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">

<h1 class="govuk-heading-l">
<span class="govuk-caption-l"><%= t("groups.status_caption.#{@group_select.group.status}") %></span><span class="govuk-visually-hidden"> - </span>
Move form to a different group
</h1>

<%= govuk_summary_list(classes: "govuk-summary-list--no-border") do |summary_list|
summary_list.with_row do |row|
row.with_key { "Form name" }
row.with_value { @group_select.form.name }
end;
summary_list.with_row do |row|
row.with_key { "Group name" }
row.with_value { @group_select.group.name }
end;
end %>

<p> You can move draft forms into active or trial groups. Live forms can only be moved into active groups. </p>
<p> We’ll tell the group admins and editors that this form has been moved and they may no longer have access to it. </p>

<%= render @group_select, url: group_form_path(group_id: @group_select.group.id, id: @group_select.form.id) %>
</div>
</div>

<%= init_autocomplete_script(show_all_values: true, raw_attribute: false, source: false) %>
39 changes: 39 additions & 0 deletions app/views/input_objects/forms/_group_select.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<%= form_with(model: @group_select, method: :patch, url:) do |f| %>
<% if @group_select&.errors.any? %>
<%= f.govuk_error_summary %>
<% end %>

<% if @group_select.groups.length < 11 %>
<%= f.govuk_collection_radio_buttons(:group,
@group_select.groups,
:id, ->(option) { option.name },
legend: { text: 'What group do you want to move it to?', size: 'm', tag: 'h2' },
'data-test-id': 'group-radio'
) %>
<% elsif @group_select.groups.length < 31 %>
<%= f.govuk_collection_select(:group,
@group_select.groups,
:id, ->(option) { option.name },
class: ['govuk-!-width-three-quarters'],
options: { prompt: "prompt" },
label: { text: 'What group do you want to move it to?', size: 'm', tag: 'h2' },
'data-test-id': 'group-select'
) %>
<% else %>
<%= render DfE::Autocomplete::View.new(f,
attribute_name: :group,
form_field: f.govuk_collection_select(:group,
@group_select.groups,
:id,
->(option) { option.name },
class: ['govuk-!-width-three-quarters'],
options: { prompt: "prompt" },
label: { text: 'What group do you want to move it to?', size: 'm', tag: 'h2' },
),
html_attributes: { 'data-show-all-values' => 'true', 'data-test-id': 'group-autocomplete' }
) %>
<% end %>

<%= f.govuk_submit %>

<% end %>
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,7 @@ en:
mou_signature_confirmation: You’ve agreed to the MOU
mou_signature_new: GOV.UK Forms Memorandum of Understanding
mou_signatures: Memorandum of Understanding agreements
move_form: Move form to a different group
name_settings: Ask for a person’s name
new_page: Edit question
new_secondary_skip: 'Route for any other answer: set questions to skip'
Expand Down
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
end

resources :groups do
resources :forms, controller: :group_forms, only: %i[new create]
resources :forms, controller: :group_forms, only: %i[new create edit update]
resources :members, controller: :group_members, only: %i[index new create]
member do
get "delete", to: "groups#delete"
Expand Down
12 changes: 12 additions & 0 deletions spec/features/group_form/move_form_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require "rails_helper"

feature "Move a form", type: :feature do
describe "moving a form to another group" do
let(:group) { create(:group, organisation: organisation_admin_user.organisation) }
let(:form) { create(:form_record) }

scenario "organisation admin can move a form to another group" do
given_i_am_logged_in_as_an_organisation_admin
end
end
end
22 changes: 22 additions & 0 deletions spec/input_objects/forms/group_select_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require "rails_helper"

RSpec.describe Forms::GroupSelect, type: :model do
let(:group_select) { described_class.new }

describe "groups" do
it "returns groups" do
create_list(:group, 3)
expect(group_select.groups.count).to eq(3)
end

it "returns an empty array when there are no groups" do
expect(group_select.groups).to be_empty
end
end

describe "to_partial_path" do
it "returns the correct partial path" do
expect(group_select.to_partial_path).to eq("input_objects/forms/group_select")
end
end
end
8 changes: 7 additions & 1 deletion spec/policies/group_form_policy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@
context "when user can access group" do
let(:user) { build :user, groups: [group] }

it { is_expected.to permit_all_actions }
it { is_expected.to permit_actions(%i[new create]) }
end

context "when user cannot access group" do
let(:user) { build :user }

it { is_expected.to forbid_all_actions }
end

context "when user is org admin" do
let(:user) { build :organisation_admin_user, organisation: group.organisation }

it { is_expected.to permit_all_actions }
end
end
47 changes: 39 additions & 8 deletions spec/requests/group_forms_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@
let(:group) { create :group }
let(:nonexistent_group) { "foobar" }

let(:valid_attributes) do
{ name: "Test form" }
end
let(:invalid_attributes) do
{ name: "" }
end

before do
create(:membership, user: standard_user, group:)
login_as_standard_user
Expand Down Expand Up @@ -55,7 +48,45 @@
end
end

context "when moving forms" do
let(:form) { create(:form_record) }

before do
login_as_organisation_admin_user
allow(FormRepository).to receive(:find).and_return(form)

group.group_forms.build(form_id: form.id)
group.organisation = organisation_admin_user.organisation
group.save!
end

describe "GET /edit" do
it "returns 200 response" do
get edit_group_form_url(group, id: form.id)

expect(response).to have_http_status :ok
end
end

describe "PATCH /update" do
let(:other_group) { create(:group, organisation: organisation_admin_user.organisation) }

it "redirects to the group" do
patch group_form_url(group, id: form.id), params: { forms_group_select: { group: other_group.id } }

expect(response).to redirect_to(group_url(group))
end
end
end

describe "POST /" do
let(:valid_attributes) do
{ name: "Test form" }
end
let(:invalid_attributes) do
{ name: "" }
end

context "with valid parameters" do
let(:new_form_id) { 1 }

Expand Down Expand Up @@ -99,7 +130,7 @@
post group_forms_url(group), params: { forms_name_input: invalid_attributes }

expect(assigns[:name_input]).to be_truthy
expect(response).to render_template("group_forms/new")
expect(response).to render_template("group_form/new")
expect(response).to render_template("input_objects/forms/_name_input")
expect(response.body).to include I18n.t("error_summary.heading")
end
Expand Down
4 changes: 4 additions & 0 deletions spec/routing/group_forms_routing_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
it "routes to #create" do
expect(post: "/groups/1/forms").to route_to("group_forms#create", group_id: "1")
end

it "routes to #edit" do
expect(get: "/groups/1/forms/1/edit").to route_to("group_forms#edit", group_id: "1", id: "1")
end
end

describe "path helpers" do
Expand Down
68 changes: 68 additions & 0 deletions spec/views/group_forms/edit.html.erb_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require "rails_helper"

RSpec.describe "group_forms/edit.html.erb", type: :view do
let(:group) { create(:group) }
let(:form) { create :form_record }
let(:group_select) { Forms::GroupSelect.new(group: group, form: form) }

before do
group.group_forms.build(form_id: form.id)
group.save!

assign(:id, form.id)
assign(:form, form)
assign(:group, group)
assign(:group_form, group.group_forms.first)
assign(:group_select, group_select)
end

it "renders the page title" do
render
expect(rendered).to have_css("h1", text: /Move form/)
end

it "renders the page title with error prefix when form has errors" do
skip "not sure we need this at the moment"

render
expect(view.content_for(:page_title)).to eq("Error: Move Form")
end

it "sets the back link to the group" do
render
expect(view.content_for(:back_link)).to match(group_path(group))
end

context "when there are fewer than 10 groups" do
before do
allow(group_select).to receive(:groups).and_return(build_list(:group, 9))
end

it "renders radio buttons" do
render
expect(rendered).to have_css("[data-test-id=\"group-radio\"]")
end
end

context "when there are more than 10 groups" do
before do
allow(group_select).to receive(:groups).and_return(build_list(:group, 11))
end

it "renders the group select form" do
render
expect(rendered).to have_css("[data-test-id=\"group-select\"]")
end
end

context "when there are more than 30 groups" do
before do
allow(group_select).to receive(:groups).and_return(build_list(:group, 31))
end

it "renders the autocomplete" do
render
expect(rendered).to have_css("[data-test-id=\"group-autocomplete\"]")
end
end
end