From db874ac120648c3f32dd6304c2baba06833d3f7c Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Wed, 19 Jun 2024 14:10:14 +0000 Subject: [PATCH 1/6] Add basic `Boost` model and migration --- app/models/boost.rb | 6 ++ config/locales/en.yml | 10 +++- db/migrate/20240619100722_create_boosts.rb | 12 ++++ db/schema.rb | 11 +++- spec/factories.rb | 7 +++ spec/models/boost_spec.rb | 64 ++++++++++++++++++++++ 6 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 app/models/boost.rb create mode 100644 db/migrate/20240619100722_create_boosts.rb create mode 100644 spec/models/boost_spec.rb diff --git a/app/models/boost.rb b/app/models/boost.rb new file mode 100644 index 00000000..671a7675 --- /dev/null +++ b/app/models/boost.rb @@ -0,0 +1,6 @@ +class Boost < ApplicationRecord + validates :name, :filter, presence: true + validates :boost_amount, numericality: { + greater_than_or_equal_to: -1.0, less_than_or_equal_to: 1.0 + } +end diff --git a/config/locales/en.yml b/config/locales/en.yml index cf9b342d..7c891b6f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -30,4 +30,12 @@ # available at https://guides.rubyonrails.org/i18n.html. en: - hello: "Hello world" + activerecord: + attributes: + boost: + name: Name + active: Activate boost + boost_amount: Boost amount + filter: Filter expression + created_at: Created + updated_at: Updated diff --git a/db/migrate/20240619100722_create_boosts.rb b/db/migrate/20240619100722_create_boosts.rb new file mode 100644 index 00000000..94f00ff9 --- /dev/null +++ b/db/migrate/20240619100722_create_boosts.rb @@ -0,0 +1,12 @@ +class CreateBoosts < ActiveRecord::Migration[7.1] + def change + create_table :boosts do |t| + t.string :name, null: false + t.boolean :active, null: false + t.float :boost_amount, null: false + t.text :filter, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index f47b81d2..e99f369a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,16 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_04_11_142717) do +ActiveRecord::Schema[7.1].define(version: 2024_06_19_100722) do + create_table "boosts", charset: "utf8mb3", force: :cascade do |t| + t.string "name", null: false + t.boolean "active", null: false + t.float "boost_amount", null: false + t.text "filter", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "recommended_links", charset: "utf8mb3", force: :cascade do |t| t.string "title" t.string "link" diff --git a/spec/factories.rb b/spec/factories.rb index 169b70b0..61989a37 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,4 +1,11 @@ FactoryBot.define do + factory :boost do + name { "Boost" } + active { true } + boost_amount { 0.5 } + filter { 'document_type: ANY("press_release")' } + end + factory :recommended_link do title { "Tax online" } link { "https://www.tax.service.gov.uk/" } diff --git a/spec/models/boost_spec.rb b/spec/models/boost_spec.rb new file mode 100644 index 00000000..27b97309 --- /dev/null +++ b/spec/models/boost_spec.rb @@ -0,0 +1,64 @@ +RSpec.describe Boost, type: :model do + let(:boost) { build(:boost) } + + describe "validations" do + describe "name" do + it "accepts valid values" do + boost.name = "Test" + + expect(boost).to be_valid + end + + it "refuses empty values" do + boost.name = "" + + expect(boost).not_to be_valid + expect(boost.errors[:name]).not_to be_empty + end + end + + describe "filter" do + it "accepts valid values" do + boost.filter = "something" + + expect(boost).to be_valid + end + + it "refuses empty values" do + boost.filter = "" + + expect(boost).not_to be_valid + expect(boost.errors[:filter]).not_to be_empty + end + end + + describe "boost_amount" do + it "accepts valid values" do + boost.boost_amount = 0.5 + + expect(boost).to be_valid + end + + it "refuses too low values" do + boost.boost_amount = -1.1 + + expect(boost).not_to be_valid + expect(boost.errors[:boost_amount]).not_to be_empty + end + + it "refuses too high values" do + boost.boost_amount = 1.1 + + expect(boost).not_to be_valid + expect(boost.errors[:boost_amount]).not_to be_empty + end + + it "refuses empty values" do + boost.boost_amount = nil + + expect(boost).not_to be_valid + expect(boost.errors[:boost_amount]).not_to be_empty + end + end + end +end From 8eba2458c28c96845c9553091f21355062e921c2 Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Tue, 18 Jun 2024 10:33:33 +0000 Subject: [PATCH 2/6] Add ability to view list of all boosts --- app/controllers/boosts_controller.rb | 5 ++++ app/helpers/application_helper.rb | 5 ++++ app/helpers/boosts_helper.rb | 9 ++++++++ app/views/boosts/index.html.erb | 34 ++++++++++++++++++++++++++++ config/routes.rb | 1 + spec/system/boosts_spec.rb | 24 ++++++++++++++++++++ 6 files changed, 78 insertions(+) create mode 100644 app/controllers/boosts_controller.rb create mode 100644 app/helpers/boosts_helper.rb create mode 100644 app/views/boosts/index.html.erb create mode 100644 spec/system/boosts_spec.rb diff --git a/app/controllers/boosts_controller.rb b/app/controllers/boosts_controller.rb new file mode 100644 index 00000000..ec98fea9 --- /dev/null +++ b/app/controllers/boosts_controller.rb @@ -0,0 +1,5 @@ +class BoostsController < ApplicationController + def index + @boosts = Boost.order(:name) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 3304a221..62c4a5ff 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -8,6 +8,11 @@ def navigation_items href: recommended_links_path, active: controller.controller_name == "recommended_links", }, + { + text: "Boosts", + href: boosts_path, + active: controller.controller_name == "boosts", + }, { text: current_user.name, href: Plek.new.external_url_for("signon"), diff --git a/app/helpers/boosts_helper.rb b/app/helpers/boosts_helper.rb new file mode 100644 index 00000000..c678679a --- /dev/null +++ b/app/helpers/boosts_helper.rb @@ -0,0 +1,9 @@ +module BoostsHelper + def boost_status_tag(boost) + if boost.active? + content_tag(:span, "Active", class: "govuk-tag govuk-tag--blue") + else + content_tag(:span, "Not active", class: "govuk-tag govuk-tag--grey") + end + end +end diff --git a/app/views/boosts/index.html.erb b/app/views/boosts/index.html.erb new file mode 100644 index 00000000..4e281c4d --- /dev/null +++ b/app/views/boosts/index.html.erb @@ -0,0 +1,34 @@ +<%= render "common/page_title", title: "Boosts" %> + +
+ <% if @boosts.any? %> + <%= render "govuk_publishing_components/components/input", { + label: { + text: "Filter boosts" + }, + name: "table-filter", + type: "search", + search_icon: true, + tabindex: 0 + } %> + +
+ <%= GovukPublishingComponents::AppHelpers::TableHelper.helper(self) do |t| %> + <%= t.head do %> + <%= t.header Boost.human_attribute_name(:name) %> + <%= t.header "Status" %> + <% end %> + <%= t.body do %> + <% @boosts.each do |boost| %> + <%= t.row do %> + <%= t.cell link_to(boost.name, boost_path(boost), class:'govuk-link') %> + <%= t.cell boost_status_tag(boost) %> + <% end %> + <% end %> + <% end %> + <% end %> +
+ <% else %> +

No boosts have been set up yet.

+ <% end %> +
diff --git a/config/routes.rb b/config/routes.rb index de497c17..bd825833 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,6 +5,7 @@ GovukHealthcheck::ActiveRecord, ) + resources :boosts resources :recommended_links, path: "/recommended-links" root "recommended_links#index" diff --git a/spec/system/boosts_spec.rb b/spec/system/boosts_spec.rb new file mode 100644 index 00000000..727b2a87 --- /dev/null +++ b/spec/system/boosts_spec.rb @@ -0,0 +1,24 @@ +RSpec.describe "Boosts" do + scenario "Viewing boosts" do + given_several_boosts + + when_i_visit_the_boosts_page + + then_all_boosts_are_displayed + end + + def given_several_boosts + @boost1 = create(:boost, name: "Boost 1") + @boost2 = create(:boost, name: "Boost 2") + end + + def when_i_visit_the_boosts_page + visit "/" + click_on "Boosts" + end + + def then_all_boosts_are_displayed + expect(page).to have_link("Boost 1") + expect(page).to have_link("Boost 2") + end +end From 58793209c0803150a8e22e892e72c4655ea1523e Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Wed, 19 Jun 2024 13:11:03 +0000 Subject: [PATCH 3/6] Add ability to view an individual boost --- app/assets/stylesheets/application.scss | 5 ++++ app/controllers/boosts_controller.rb | 4 +++ app/helpers/boosts_helper.rb | 4 +++ app/views/boosts/show.html.erb | 38 +++++++++++++++++++++++++ spec/system/boosts_spec.rb | 30 +++++++++++++++++++ 5 files changed, 81 insertions(+) create mode 100644 app/views/boosts/show.html.erb diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 22b018c4..61ab0758 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -52,3 +52,8 @@ .js-hidden { display: none; } + +// Display filter expressions with less large font size +.app-filter-expression { + font-size: 16px; +} diff --git a/app/controllers/boosts_controller.rb b/app/controllers/boosts_controller.rb index ec98fea9..88846bef 100644 --- a/app/controllers/boosts_controller.rb +++ b/app/controllers/boosts_controller.rb @@ -2,4 +2,8 @@ class BoostsController < ApplicationController def index @boosts = Boost.order(:name) end + + def show + @boost = Boost.find(params[:id]) + end end diff --git a/app/helpers/boosts_helper.rb b/app/helpers/boosts_helper.rb index c678679a..2d0a3657 100644 --- a/app/helpers/boosts_helper.rb +++ b/app/helpers/boosts_helper.rb @@ -6,4 +6,8 @@ def boost_status_tag(boost) content_tag(:span, "Not active", class: "govuk-tag govuk-tag--grey") end end + + def filter_expression_code(boost) + content_tag(:code, boost.filter, class: "app-filter-expression") + end end diff --git a/app/views/boosts/show.html.erb b/app/views/boosts/show.html.erb new file mode 100644 index 00000000..bf949723 --- /dev/null +++ b/app/views/boosts/show.html.erb @@ -0,0 +1,38 @@ +<%= render "govuk_publishing_components/components/breadcrumbs", { + breadcrumbs: [ + { + title: "Boosts", + url: boosts_path + }, + { + title: @boost.name, + } + ] +} %> + +<%= render "common/page_title", title: @boost.name %> + +<%= render "govuk_publishing_components/components/summary_list", { + items: [ + { + field: "Status", + value: boost_status_tag(@boost) + }, + { + field: Boost.human_attribute_name(:boost_amount), + value: @boost.boost_amount + }, + { + field: Boost.human_attribute_name(:filter), + value: filter_expression_code(@boost) + }, + { + field: Boost.human_attribute_name(:created_at), + value: @boost.created_at.to_formatted_s(:govuk_date) + }, + { + field: Boost.human_attribute_name(:updated_at), + value: @boost.updated_at.to_formatted_s(:govuk_date) + } + ] +} %> diff --git a/spec/system/boosts_spec.rb b/spec/system/boosts_spec.rb index 727b2a87..cf3f428f 100644 --- a/spec/system/boosts_spec.rb +++ b/spec/system/boosts_spec.rb @@ -7,18 +7,48 @@ then_all_boosts_are_displayed end + scenario "Viewing a single boost" do + given_a_boost + + when_i_go_to_view_the_boost + + then_i_can_see_the_details_of_the_boost + end + def given_several_boosts @boost1 = create(:boost, name: "Boost 1") @boost2 = create(:boost, name: "Boost 2") end + def given_a_boost + @boost = create( + :boost, + name: "Boost", + active: true, + boost_amount: 0.42, + filter: 'foo: ANY("bar")', + ) + end + def when_i_visit_the_boosts_page visit "/" click_on "Boosts" end + def when_i_go_to_view_the_boost + visit boosts_path + click_on "Boost" + end + def then_all_boosts_are_displayed expect(page).to have_link("Boost 1") expect(page).to have_link("Boost 2") end + + def then_i_can_see_the_details_of_the_boost + expect(page).to have_selector("h1", text: "Boost") + expect(page).to have_content("Status Active") + expect(page).to have_content("Boost amount 0.42") + expect(page).to have_content('Filter expression foo: ANY("bar")') + end end From a717c133cbbff9ee56b2fcd42735165474f1ed57 Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Wed, 19 Jun 2024 13:33:15 +0000 Subject: [PATCH 4/6] Add ability to create a new boost --- app/controllers/boosts_controller.rb | 19 ++++++++ app/controllers/controls_controller.rb | 28 +++++++++++ app/views/boosts/_form.html.erb | 59 +++++++++++++++++++++++ app/views/boosts/index.html.erb | 8 ++++ app/views/boosts/new.html.erb | 15 ++++++ spec/system/boosts_spec.rb | 65 ++++++++++++++++++++++++++ 6 files changed, 194 insertions(+) create mode 100644 app/controllers/controls_controller.rb create mode 100644 app/views/boosts/_form.html.erb create mode 100644 app/views/boosts/new.html.erb diff --git a/app/controllers/boosts_controller.rb b/app/controllers/boosts_controller.rb index 88846bef..d14c480f 100644 --- a/app/controllers/boosts_controller.rb +++ b/app/controllers/boosts_controller.rb @@ -6,4 +6,23 @@ def index def show @boost = Boost.find(params[:id]) end + + def new + @boost = Boost.new + end + + def create + @boost = Boost.new(boost_params) + if @boost.save + redirect_to @boost, notice: "Boost created successfully" + else + render "new", status: :unprocessable_entity + end + end + +private + + def boost_params + params.require(:boost).permit(:name, :active, :boost_amount, :filter) + end end diff --git a/app/controllers/controls_controller.rb b/app/controllers/controls_controller.rb new file mode 100644 index 00000000..9409c279 --- /dev/null +++ b/app/controllers/controls_controller.rb @@ -0,0 +1,28 @@ +class ControlsController < ApplicationController + def index + @controls = Control.order(:name) + end + + def show + @control = Control.find(params[:id]) + end + + def new + @control = Control.new + end + + def create + @control = Control.new(control_params) + if @control.save + redirect_to @control, notice: "Control created successfully" + else + render "new", status: :unprocessable_entity + end + end + +private + + def control_params + params.require(:control).permit(:name, :active, :boost_amount, :filter) + end +end diff --git a/app/views/boosts/_form.html.erb b/app/views/boosts/_form.html.erb new file mode 100644 index 00000000..04b3ac57 --- /dev/null +++ b/app/views/boosts/_form.html.erb @@ -0,0 +1,59 @@ +<%= form_for(boost) do |f| %> + <% if boost.errors.any? %> + <%= render "govuk_publishing_components/components/error_summary", { + id: "error-summary", + title: "There is a problem", + description: "The boost could not be updated because some fields are missing or incorrect.", + items: error_summary_items(boost) + } %> + <% end %> + + <%= render "govuk_publishing_components/components/input", { + label: { + text: Boost.human_attribute_name(:name) + }, + id: "boost_name", + name: "boost[name]", + value: boost.name, + error_items: error_items(boost, :name) + } %> + + <%= render "govuk_publishing_components/components/input", { + label: { + text: Boost.human_attribute_name(:boost_amount) + }, + hint: "A value between -1.0 and 1.0 used to influence the order of search results.", + id: "boost_boost_amount", + name: "boost[boost_amount]", + value: boost.boost_amount, + error_items: error_items(boost, :boost_amount) + } %> + + <%= render "govuk_publishing_components/components/textarea", { + label: { + text: Boost.human_attribute_name(:filter) + }, + hint: "Determines which documents are affected by this boost. See #{link_to 'Vertex AI Search filter syntax', 'https://cloud.google.com/retail/docs/filter-and-order#filter', class: 'govuk-link'} for details.".html_safe, + id: "boost_filter", + name: "boost[filter]", + value: boost.filter, + error_items: error_items(boost, :filter) + } %> + + <%= hidden_field_tag "boost[active]", "0" %> + <%= render "govuk_publishing_components/components/checkboxes", { + name: "boost[active]", + items: [ + { + label: Boost.human_attribute_name(:active), + hint: "Boosts that are not active will not affect search results.", + value: "1", + checked: boost.active? + } + ] + } %> + + <%= render "govuk_publishing_components/components/button", { + text: "Save" + } %> +<% end %> diff --git a/app/views/boosts/index.html.erb b/app/views/boosts/index.html.erb index 4e281c4d..8676808b 100644 --- a/app/views/boosts/index.html.erb +++ b/app/views/boosts/index.html.erb @@ -1,5 +1,13 @@ <%= render "common/page_title", title: "Boosts" %> +
+ <%= render "govuk_publishing_components/components/button", { + text: "New boost", + href: new_boost_path, + inline_layout: true + } %> +
+
<% if @boosts.any? %> <%= render "govuk_publishing_components/components/input", { diff --git a/app/views/boosts/new.html.erb b/app/views/boosts/new.html.erb new file mode 100644 index 00000000..a7f66505 --- /dev/null +++ b/app/views/boosts/new.html.erb @@ -0,0 +1,15 @@ +<%= render "govuk_publishing_components/components/breadcrumbs", { + breadcrumbs: [ + { + title: "Boosts", + url: boosts_path + }, + { + title: "New boost" + } + ] +} %> + +<%= render "common/page_title", title: "New boost" %> + +<%= render "form", boost: @boost %> diff --git a/spec/system/boosts_spec.rb b/spec/system/boosts_spec.rb index cf3f428f..21ba6df7 100644 --- a/spec/system/boosts_spec.rb +++ b/spec/system/boosts_spec.rb @@ -15,6 +15,24 @@ then_i_can_see_the_details_of_the_boost end + scenario "Creating a new boost" do + when_i_visit_the_boosts_page + and_i_choose_to_create_a_new_boost + and_i_submit_the_form_with_valid_details + + then_the_boost_has_been_created + and_i_can_see_its_details + end + + scenario "Attempting to create a boost with invalid data" do + when_i_visit_the_boosts_page + and_i_choose_to_create_a_new_boost + and_i_submit_the_form_with_invalid_details + + then_the_boost_has_not_been_created + and_i_can_see_what_errors_i_need_to_fix + end + def given_several_boosts @boost1 = create(:boost, name: "Boost 1") @boost2 = create(:boost, name: "Boost 2") @@ -40,6 +58,36 @@ def when_i_go_to_view_the_boost click_on "Boost" end + def and_i_choose_to_create_a_new_boost + click_on "New boost" + end + + def and_i_submit_the_form_with_valid_details + fill_in "Name", with: "New boost" + fill_in "Boost amount", with: 0.42 + fill_in "Filter", with: 'foo: ANY("bar")' + check "Activate boost" + click_on "Save" + end + + def and_i_submit_the_form_with_invalid_details + fill_in "Name", with: "" + fill_in "Boost amount", with: 42.0 + fill_in "Filter", with: "" + check "Activate boost" + click_on "Save" + end + + def then_the_boost_has_not_been_created + expect(Boost.count).to eq(0) + end + + def and_i_can_see_what_errors_i_need_to_fix + expect(page).to have_content("Name can't be blank") + expect(page).to have_content("Filter expression can't be blank") + expect(page).to have_content("Boost amount must be less than or equal to 1.0") + end + def then_all_boosts_are_displayed expect(page).to have_link("Boost 1") expect(page).to have_link("Boost 2") @@ -51,4 +99,21 @@ def then_i_can_see_the_details_of_the_boost expect(page).to have_content("Boost amount 0.42") expect(page).to have_content('Filter expression foo: ANY("bar")') end + + def then_the_boost_has_been_created + expect(Boost.count).to eq(1) + + boost = Boost.first + expect(boost.name).to eq("New boost") + expect(boost).to be_active + expect(boost.boost_amount).to eq(0.42) + expect(boost.filter).to eq('foo: ANY("bar")') + end + + def and_i_can_see_its_details + expect(page).to have_selector("h1", text: "New boost") + expect(page).to have_content("Status Active") + expect(page).to have_content("Boost amount 0.42") + expect(page).to have_content('Filter expression foo: ANY("bar")') + end end From b44676e71830a4f4a82b4aea570140262b506b11 Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Wed, 19 Jun 2024 13:36:47 +0000 Subject: [PATCH 5/6] Add ability to edit an existing boost --- app/controllers/boosts_controller.rb | 13 ++++++ app/controllers/controls_controller.rb | 28 ------------ app/views/boosts/edit.html.erb | 19 +++++++++ app/views/boosts/show.html.erb | 8 ++++ spec/system/boosts_spec.rb | 59 ++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 28 deletions(-) delete mode 100644 app/controllers/controls_controller.rb create mode 100644 app/views/boosts/edit.html.erb diff --git a/app/controllers/boosts_controller.rb b/app/controllers/boosts_controller.rb index d14c480f..c1bb69a8 100644 --- a/app/controllers/boosts_controller.rb +++ b/app/controllers/boosts_controller.rb @@ -20,6 +20,19 @@ def create end end + def edit + @boost = Boost.find(params[:id]) + end + + def update + @boost = Boost.find(params[:id]) + if @boost.update(boost_params) + redirect_to @boost, notice: "Boost updated successfully" + else + render "edit", status: :unprocessable_entity + end + end + private def boost_params diff --git a/app/controllers/controls_controller.rb b/app/controllers/controls_controller.rb deleted file mode 100644 index 9409c279..00000000 --- a/app/controllers/controls_controller.rb +++ /dev/null @@ -1,28 +0,0 @@ -class ControlsController < ApplicationController - def index - @controls = Control.order(:name) - end - - def show - @control = Control.find(params[:id]) - end - - def new - @control = Control.new - end - - def create - @control = Control.new(control_params) - if @control.save - redirect_to @control, notice: "Control created successfully" - else - render "new", status: :unprocessable_entity - end - end - -private - - def control_params - params.require(:control).permit(:name, :active, :boost_amount, :filter) - end -end diff --git a/app/views/boosts/edit.html.erb b/app/views/boosts/edit.html.erb new file mode 100644 index 00000000..a3eb5006 --- /dev/null +++ b/app/views/boosts/edit.html.erb @@ -0,0 +1,19 @@ +<%= render "govuk_publishing_components/components/breadcrumbs", { + breadcrumbs: [ + { + title: "Boosts", + url: boosts_path + }, + { + title: @boost.name, + url: boost_path(@boost) + }, + { + title: "Edit" + } + ] +} %> + +<%= render "common/page_title", title: @boost.name %> + +<%= render "form", boost: @boost %> diff --git a/app/views/boosts/show.html.erb b/app/views/boosts/show.html.erb index bf949723..8f82abab 100644 --- a/app/views/boosts/show.html.erb +++ b/app/views/boosts/show.html.erb @@ -12,6 +12,14 @@ <%= render "common/page_title", title: @boost.name %> +
+ <%= render "govuk_publishing_components/components/button", { + text: "Edit boost", + href: edit_boost_path(@boost), + inline_layout: true + } %> +
+ <%= render "govuk_publishing_components/components/summary_list", { items: [ { diff --git a/spec/system/boosts_spec.rb b/spec/system/boosts_spec.rb index 21ba6df7..834e572c 100644 --- a/spec/system/boosts_spec.rb +++ b/spec/system/boosts_spec.rb @@ -33,6 +33,28 @@ and_i_can_see_what_errors_i_need_to_fix end + scenario "Editing an existing boost" do + given_a_boost + + when_i_go_to_view_the_boost + and_i_choose_to_edit_it + and_i_submit_the_form_with_updated_details + + then_the_boost_has_been_updated + and_i_can_see_the_new_details + end + + scenario "Attempting to edit a boost with invalid data" do + given_a_boost + + when_i_go_to_view_the_boost + and_i_choose_to_edit_it + and_i_submit_the_form_with_invalid_details + + then_the_boost_has_not_been_updated + and_i_can_see_what_errors_i_need_to_fix + end + def given_several_boosts @boost1 = create(:boost, name: "Boost 1") @boost2 = create(:boost, name: "Boost 2") @@ -78,6 +100,18 @@ def and_i_submit_the_form_with_invalid_details click_on "Save" end + def and_i_choose_to_edit_it + click_on "Edit" + end + + def and_i_submit_the_form_with_updated_details + fill_in "Name", with: "Updated boost" + fill_in "Boost amount", with: 0.84 + fill_in "Filter", with: 'foo: ANY("bubble")' + uncheck "Activate boost" + click_on "Save" + end + def then_the_boost_has_not_been_created expect(Boost.count).to eq(0) end @@ -116,4 +150,29 @@ def and_i_can_see_its_details expect(page).to have_content("Boost amount 0.42") expect(page).to have_content('Filter expression foo: ANY("bar")') end + + def then_the_boost_has_been_updated + @boost.reload + + expect(@boost.name).to eq("Updated boost") + expect(@boost).not_to be_active + expect(@boost.boost_amount).to eq(0.84) + expect(@boost.filter).to eq('foo: ANY("bubble")') + end + + def and_i_can_see_the_new_details + expect(page).to have_selector("h1", text: "Updated boost") + expect(page).to have_content("Status Not active") + expect(page).to have_content("Boost amount 0.84") + expect(page).to have_content('Filter expression foo: ANY("bubble")') + end + + def then_the_boost_has_not_been_updated + @boost.reload + + expect(@boost.name).to eq("Boost") + expect(@boost).to be_active + expect(@boost.boost_amount).to eq(0.42) + expect(@boost.filter).to eq('foo: ANY("bar")') + end end From 58dad81cb3d079ace65ba222a71cc72f2cbf1840 Mon Sep 17 00:00:00 2001 From: Christian Sutter Date: Wed, 19 Jun 2024 13:39:24 +0000 Subject: [PATCH 6/6] Add ability to delete an existing boost --- app/controllers/boosts_controller.rb | 10 ++++++++++ app/views/boosts/show.html.erb | 1 + spec/system/boosts_spec.rb | 22 ++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/app/controllers/boosts_controller.rb b/app/controllers/boosts_controller.rb index c1bb69a8..0b58d413 100644 --- a/app/controllers/boosts_controller.rb +++ b/app/controllers/boosts_controller.rb @@ -33,6 +33,16 @@ def update end end + def destroy + @boost = Boost.find(params[:id]) + + if @boost.destroy + redirect_to boosts_path, notice: "Boost deleted successfully" + else + redirect_to @boost, alert: "Boost could not be deleted. Try again later." + end + end + private def boost_params diff --git a/app/views/boosts/show.html.erb b/app/views/boosts/show.html.erb index 8f82abab..5b55338d 100644 --- a/app/views/boosts/show.html.erb +++ b/app/views/boosts/show.html.erb @@ -18,6 +18,7 @@ href: edit_boost_path(@boost), inline_layout: true } %> + <%= delete_button "Delete boost", boost_path(@boost), is_inline: true %>
<%= render "govuk_publishing_components/components/summary_list", { diff --git a/spec/system/boosts_spec.rb b/spec/system/boosts_spec.rb index 834e572c..96bdb2ac 100644 --- a/spec/system/boosts_spec.rb +++ b/spec/system/boosts_spec.rb @@ -55,6 +55,16 @@ and_i_can_see_what_errors_i_need_to_fix end + scenario "Deleting an existing boost" do + given_a_boost + + when_i_go_to_view_the_boost + and_i_choose_to_delete_it + + then_the_boost_has_been_deleted_locally + and_i_am_notified_of_the_deletion + end + def given_several_boosts @boost1 = create(:boost, name: "Boost 1") @boost2 = create(:boost, name: "Boost 2") @@ -112,6 +122,10 @@ def and_i_submit_the_form_with_updated_details click_on "Save" end + def and_i_choose_to_delete_it + click_on "Delete" + end + def then_the_boost_has_not_been_created expect(Boost.count).to eq(0) end @@ -175,4 +189,12 @@ def then_the_boost_has_not_been_updated expect(@boost.boost_amount).to eq(0.42) expect(@boost.filter).to eq('foo: ANY("bar")') end + + def then_the_boost_has_been_deleted_locally + expect(Boost.count).to eq(0) + end + + def and_i_am_notified_of_the_deletion + expect(page).to have_content("Boost deleted successfully") + end end