From d255cb633b4e6d3cc1c2173302bed8a600e02441 Mon Sep 17 00:00:00 2001 From: pezholio Date: Mon, 3 Jun 2024 15:48:48 +0100 Subject: [PATCH] Allow an item to be created or edited This adds a new controller that inherits from the main `EditionsController` and overrides some of the default behaviour to allow our items to be edited/created. We also add a new edit/new view to override the main editions views which are already quite overloaded with logic. At the moment, creation and editing fails when sending data to the Publishing API, but this is a start. --- .../admin/object_store/items_controller.rb | 27 +++++++++++ .../admin/object_store/items_helper.rb | 39 +++++++++++++++ .../email_addresses/_form.html.erb | 21 +++++++++ .../admin/object_store/items/edit.html.erb | 10 ++++ .../admin/object_store/items/new.html.erb | 10 ++++ config/routes.rb | 6 +++ .../object_store/create_email_test.rb | 32 +++++++++++++ .../object_store/edit_email_test.rb | 22 +++++++++ .../admin/object_store/items_helper_test.rb | 47 +++++++++++++++++++ 9 files changed, 214 insertions(+) create mode 100644 app/controllers/admin/object_store/items_controller.rb create mode 100644 app/helpers/admin/object_store/items_helper.rb create mode 100644 app/views/admin/object_store/email_addresses/_form.html.erb create mode 100644 app/views/admin/object_store/items/edit.html.erb create mode 100644 app/views/admin/object_store/items/new.html.erb create mode 100644 test/integration/object_store/create_email_test.rb create mode 100644 test/integration/object_store/edit_email_test.rb create mode 100644 test/unit/app/helpers/admin/object_store/items_helper_test.rb diff --git a/app/controllers/admin/object_store/items_controller.rb b/app/controllers/admin/object_store/items_controller.rb new file mode 100644 index 00000000000..56d8128d5d9 --- /dev/null +++ b/app/controllers/admin/object_store/items_controller.rb @@ -0,0 +1,27 @@ +module Admin::ObjectStore + class ItemsController < Admin::EditionsController + private + + def edition_class + ObjectStore::Item + end + + def permitted_edition_attributes + (super << ObjectStore.field_names_for_item_type(params[:item_type])).flatten + end + + def show_or_edit_path + if params[:save].present? + edit_admin_object_store_item_path(@edition.item_type, @edition) + else + admin_object_store_item_path @edition + end + end + + def new_edition + edition = edition_class.new(item_type: params[:item_type]) + edition.assign_attributes(new_edition_params) + edition + end + end +end diff --git a/app/helpers/admin/object_store/items_helper.rb b/app/helpers/admin/object_store/items_helper.rb new file mode 100644 index 00000000000..3a65e24e6f0 --- /dev/null +++ b/app/helpers/admin/object_store/items_helper.rb @@ -0,0 +1,39 @@ +module Admin + module ObjectStore + module ItemsHelper + def edition_name(edition) + edition.item_type.titleize + end + + def render_partial_path(edition, partial_name) + render partial: partial_path(edition, partial_name), object: edition, as: edition.item_type + end + + def partial_path(edition, partial_name) + dirname = edition.item_type.pluralize + File.join("admin", "object_store", dirname, partial_name) + end + + def object_store_item_form(edition) + form_for edition, url: form_url_for_object_store_item(edition), as: edition.item_type do |form| + yield(form) + concat render("govuk_publishing_components/components/button", { + text: "Save", + value: "save", + name: "save", + data_attributes: { + module: "gem-track-click", + "track-category": "form-button", + "track-action": "object-store-item-button", + "track-label": "Save", + }, + }) + end + end + + def form_url_for_object_store_item(edition) + admin_object_store_items_path(item_type: edition.item_type) + end + end + end +end diff --git a/app/views/admin/object_store/email_addresses/_form.html.erb b/app/views/admin/object_store/email_addresses/_form.html.erb new file mode 100644 index 00000000000..e656d7dda0a --- /dev/null +++ b/app/views/admin/object_store/email_addresses/_form.html.erb @@ -0,0 +1,21 @@ +<%= object_store_item_form(email_address) do |form| %> + <%= render "govuk_publishing_components/components/input", { + label: { + text: "Title", + }, + heading_size: "m", + value: form.object.title, + name: "edition[title]", + id: "edition_title", + } %> + + <%= render "govuk_publishing_components/components/input", { + label: { + text: "Email address", + }, + heading_size: "m", + value: form.object.email_address, + name: "edition[email_address]", + id: "edition_email_address", + } %> +<% end %> diff --git a/app/views/admin/object_store/items/edit.html.erb b/app/views/admin/object_store/items/edit.html.erb new file mode 100644 index 00000000000..f4e82ca0fde --- /dev/null +++ b/app/views/admin/object_store/items/edit.html.erb @@ -0,0 +1,10 @@ +<% content_for :page_title, "Object Store - Edit #{edition_name(@edition)}" %> +<% content_for :context, "Object Store" %> +<% content_for :title, "Edit #{edition_name(@edition)}" %> +<% content_for :error_summary, render(Admin::ErrorSummaryComponent.new(object: @edition, parent_class: "edition")) %> + +
+
+ <%= render_partial_path(@edition, "form") %> +
+
diff --git a/app/views/admin/object_store/items/new.html.erb b/app/views/admin/object_store/items/new.html.erb new file mode 100644 index 00000000000..f459ffe250f --- /dev/null +++ b/app/views/admin/object_store/items/new.html.erb @@ -0,0 +1,10 @@ +<% content_for :page_title, "Object Store - New #{edition_name(@edition)}" %> +<% content_for :context, "Object Store" %> +<% content_for :title, "New #{edition_name(@edition)}" %> +<% content_for :error_summary, render(Admin::ErrorSummaryComponent.new(object: @edition, parent_class: "edition")) %> + +
+
+ <%= render_partial_path(@edition, "form") %> +
+
diff --git a/config/routes.rb b/config/routes.rb index b477a1ce910..761a0386dac 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -424,6 +424,12 @@ def redirect(path, options = { prefix: Whitehall.router_prefix }) get :confirm_destroy end post "/link-checker-api-callback" => "link_checker_api#callback" + + namespace :object_store do + scope "/:item_type", constraints: { item_type: Regexp.compile(ObjectStore.item_types.join("|")) } do + resources :items, path: "/" + end + end end end diff --git a/test/integration/object_store/create_email_test.rb b/test/integration/object_store/create_email_test.rb new file mode 100644 index 00000000000..0501ba26f37 --- /dev/null +++ b/test/integration/object_store/create_email_test.rb @@ -0,0 +1,32 @@ +require "test_helper" +require "capybara/rails" + +class CreateEmailTest < ActionDispatch::IntegrationTest + include Capybara::DSL + + setup do + login_as_admin + end + + test "allows an email object to be created" do + visit new_admin_object_store_item_path(item_type: "email_address") + + fill_in "Title", with: "Some Title" + fill_in "Email address", with: "foo@example.com" + click_on "Save" + + created_object = ObjectStore::Item.find_by(title: "Some Title") + + assert_not_nil created_object + assert created_object.email_address, "foo@example.com" + end + + test "shows errors when missing fields blank" do + visit new_admin_object_store_item_path(item_type: "email_address") + + click_on "Save" + + assert_text "Title can't be blank" + assert_text "Email address can't be blank" + end +end diff --git a/test/integration/object_store/edit_email_test.rb b/test/integration/object_store/edit_email_test.rb new file mode 100644 index 00000000000..4b0c5c68142 --- /dev/null +++ b/test/integration/object_store/edit_email_test.rb @@ -0,0 +1,22 @@ +require "test_helper" +require "capybara/rails" + +class EditEmailTest < ActionDispatch::IntegrationTest + include Capybara::DSL + + setup do + login_as_admin + end + + test "allows an email object to be updated" do + item = create(:object_store_item, item_type: "email_address", email_address: "foo@example.com") + visit edit_admin_object_store_item_path(item_type: "email_address", id: item.id) + + fill_in "Email address", with: "bar@example.com" + click_on "Save" + + item.reload + + assert item.email_address, "bar@example.com" + end +end diff --git a/test/unit/app/helpers/admin/object_store/items_helper_test.rb b/test/unit/app/helpers/admin/object_store/items_helper_test.rb new file mode 100644 index 00000000000..55fe89d562b --- /dev/null +++ b/test/unit/app/helpers/admin/object_store/items_helper_test.rb @@ -0,0 +1,47 @@ +require "test_helper" + +class Admin::ObjectStore::ItemsHelperTest < ActionView::TestCase + include Admin::ObjectStore::ItemsHelper + + test "#edition_name returns the title for an edition" do + edition = build(:object_store_item, item_type: "email_address") + assert_equal edition_name(edition), "Email Address" + end + + test "#partial_path should return a path for an edition" do + edition = build(:object_store_item, item_type: "email_address") + path = partial_path(edition, "form") + assert_equal path, "admin/object_store/email_addresses/form" + end + + test "#render_partial_path should render the correct path with the edition" do + edition = build(:object_store_item, item_type: "email_address") + partial_name = "form" + + expects(:render).with(partial: partial_path(edition, partial_name), object: edition, as: edition.item_type) + + render_partial_path(edition, partial_name) + end + + test "#object_store_item_form renders a form" do + edition = build(:object_store_item, item_type: "email_address") + + html = object_store_item_form(edition) do |_form| + concat("Some text here") + end + + assert_includes html, "Some text here" + assert_includes html, form_url_for_object_store_item(edition) + assert_includes html, render("govuk_publishing_components/components/button", { + text: "Save", + value: "save", + name: "save", + data_attributes: { + module: "gem-track-click", + "track-category": "form-button", + "track-action": "object-store-item-button", + "track-label": "Save", + }, + }) + end +end