diff --git a/app/controllers/downtimes_controller.rb b/app/controllers/downtimes_controller.rb index 9bf06afbe..1fdb248f1 100644 --- a/app/controllers/downtimes_controller.rb +++ b/app/controllers/downtimes_controller.rb @@ -1,10 +1,14 @@ class DowntimesController < ApplicationController before_action :require_govuk_editor - before_action :load_edition + before_action :load_edition, except: [:index] before_action :process_params, only: %i[create update] layout "design_system" + def index + @transactions = TransactionEdition.published.order_by(%i[title asc]) + end + def new @downtime = Downtime.new(artefact: @edition.artefact) end diff --git a/app/views/downtimes/index.html.erb b/app/views/downtimes/index.html.erb new file mode 100644 index 000000000..56db37586 --- /dev/null +++ b/app/views/downtimes/index.html.erb @@ -0,0 +1,56 @@ +<% content_for :page_title, 'Downtime messages' %> + +
+

Downtime messages

+

Show a message on a published transaction start page for a specific time.

+
+ + + + + + + + + + + + + + + <% @transactions.each do |transaction| %> + + + <% if downtime = Downtime.for(transaction.artefact) %> + + + <% else %> + + + <% end %> + + <% end %> + +
+

Services

+
Service start pageService statusAction
+
+ +

For example ‘driving’ or ‘scheduled downtime’

+ +
+
+

+ <%= link_to transaction.title, Downtime.for(transaction.artefact).present? ? + edit_edition_downtime_path(transaction) : + new_edition_downtime_path(transaction) %> +

+ <%= link_to "/#{transaction.slug}", "#{Plek.website_root}/#{transaction.slug}", class: 'link-muted' %> +
+ Scheduled downtime
+ <%= downtime_datetime(downtime) %> +
+ <%= link_to 'Edit downtime', edit_edition_downtime_path(transaction), class: 'btn btn-info' %> + Live + <%= link_to 'Add downtime', new_edition_downtime_path(transaction), class: 'btn btn-default' %> +
diff --git a/app/views/layouts/design_system.html.erb b/app/views/layouts/design_system.html.erb index 17a6138f4..2bc7775bb 100644 --- a/app/views/layouts/design_system.html.erb +++ b/app/views/layouts/design_system.html.erb @@ -17,8 +17,26 @@ } %>
-
+
+ <% [:success, :info, :warning, :danger, :notice, :alert].select { |k| flash[k].present? }.each do |k| %> + <% + case k + when :notice + alert_class = "success" + when :alert + alert_class = "danger" + else + alert_class = k + end + %> +
+ <%= flash[k] %> +
+ <% end %> <% if yield(:title).present? %>
diff --git a/config/features.rb b/config/features.rb index 6976dc26e..3c078be3b 100644 --- a/config/features.rb +++ b/config/features.rb @@ -20,4 +20,8 @@ feature :design_system_downtime_edit, default: false, description: "A transition of the edit downtime page to the GOV.UK Design System" + + feature :design_system_downtime_index_page, + default: false, + description: "A transition of the downtime index page to use the GOV.UK Design System" end diff --git a/config/routes.rb b/config/routes.rb index 7f51b36b1..e723dbf8c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,6 +12,9 @@ put "resolve", on: :member end + constraints FeatureConstraint.new("design_system_downtime_index_page") do + get "downtimes" => "downtimes#index" + end get "downtimes" => "legacy_downtimes#index" resources :artefacts, only: %i[new create update] diff --git a/test/functional/downtimes_controller_test.rb b/test/functional/downtimes_controller_test.rb index d3c9dc571..3f1cac741 100644 --- a/test/functional/downtimes_controller_test.rb +++ b/test/functional/downtimes_controller_test.rb @@ -95,6 +95,31 @@ class DowntimesControllerTest < ActionController::TestCase end end + context "#index" do + should "list all published transaction editions" do + unpublished_transaction_edition = FactoryBot.create(:transaction_edition) + transaction_editions = FactoryBot.create_list(:transaction_edition, 2, :published) + + get :index + + assert_response :ok + assert_select "h3.publication-table-title", count: 0, text: unpublished_transaction_edition.title + transaction_editions.each do |edition| + assert_select "h3.publication-table-title", text: edition.title + end + end + + should "redirect to root page if welsh_editor" do + login_as_welsh_editor + + get :index + + assert_response :redirect + assert_redirected_to controller: "root", action: "index" + assert_includes flash[:danger], "do not have permission" + end + end + def edition @edition ||= FactoryBot.create(:transaction_edition) end diff --git a/test/integration/downtime_integration_test.rb b/test/integration/downtime_integration_test.rb index eb2cbf2e8..4c624046c 100644 --- a/test/integration/downtime_integration_test.rb +++ b/test/integration/downtime_integration_test.rb @@ -14,6 +14,9 @@ class DowntimeIntegrationTest < JavascriptIntegrationTest WebMock.reset! stub_any_publishing_api_put_content stub_any_publishing_api_publish + + test_strategy = Flipflop::FeatureSet.current.test! + test_strategy.switch!(:design_system_downtime_index_page, true) end test "Scheduling new downtime" do diff --git a/test/integration/legacy_downtime_integration_test.rb b/test/integration/legacy_downtime_integration_test.rb new file mode 100644 index 000000000..05bf29049 --- /dev/null +++ b/test/integration/legacy_downtime_integration_test.rb @@ -0,0 +1,118 @@ +require "integration_test_helper" + +class LegacyDowntimeIntegrationTest < JavascriptIntegrationTest + setup do + setup_users + + @edition = FactoryBot.create( + :transaction_edition, + :published, + title: "Apply to become a driving instructor", + slug: "apply-to-become-a-driving-instructor", + ) + + WebMock.reset! + stub_any_publishing_api_put_content + stub_any_publishing_api_publish + end + + test "Scheduling new downtime" do + DowntimeScheduler.stubs(:schedule_publish_and_expiry) + + visit root_path + click_link "Downtime" + click_link "Apply to become a driving instructor" + + enter_start_time first_of_july_next_year_at_midday_bst + enter_end_time first_of_july_next_year_at_six_pm_bst + + assert_match("midday to 6pm on #{day} 1 July", page.find_field("Message").value) + click_button "Schedule downtime message" + + assert page.has_content?("downtime message scheduled") + assert page.has_content?("Scheduled downtime") + assert page.has_content?("midday to 6pm on 1 July") + end + + test "Rescheduling downtime" do + DowntimeScheduler.stubs(:schedule_publish_and_expiry) + create_downtime + + visit root_path + click_link "Downtime" + click_link "Edit downtime" + enter_end_time first_of_july_next_year_at_nine_thirty_pm_bst + + assert_match("This service will be unavailable from midday to 9:30pm on #{day} 1 July.", page.find_field("Message").value) + click_on "Re-schedule downtime message" + + assert page.has_content?("downtime message re-scheduled") + assert page.has_content?("midday to 9:30pm on 1 July") + end + + test "Cancelling downtime" do + PublishingApiWorkflowBypassPublisher.stubs(:call) + create_downtime + + visit root_path + click_link "Downtime" + click_link "Edit downtime" + click_on "Cancel downtime" + + assert page.has_content?("downtime message cancelled") + assert_no_downtime_scheduled + end + + def enter_start_time(start_time) + complete_date_inputs("downtime_start_time", start_time) + end + + def enter_end_time(end_time) + complete_date_inputs("downtime_end_time", end_time) + end + + def complete_date_inputs(input_id, time) + select time.year.to_s, from: "#{input_id}_1i" + select time.strftime("%B"), from: "#{input_id}_2i" + select time.day.to_s, from: "#{input_id}_3i" + select time.hour.to_s, from: "#{input_id}_4i" + select time.strftime("%M"), from: "#{input_id}_5i" + end + + def next_year + Time.zone.now.next_year.year + end + + def date_in_the_past + Time.zone.local(Time.zone.now.last_year.year, 1, 1, 12, 0) + end + + def first_of_july_next_year_at_midday_bst + Time.zone.local(next_year, 7, 1, 12, 0) + end + + def first_of_july_next_year_at_six_pm_bst + Time.zone.local(next_year, 7, 1, 18, 0) + end + + def first_of_july_next_year_at_nine_thirty_pm_bst + Time.zone.local(next_year, 7, 1, 21, 30) + end + + def day + first_of_july_next_year_at_six_pm_bst.strftime("%A") + end + + def create_downtime + Downtime.create!( + artefact: @edition.artefact, + start_time: first_of_july_next_year_at_midday_bst, + end_time: first_of_july_next_year_at_six_pm_bst, + message: "foo", + ) + end + + def assert_no_downtime_scheduled + assert_equal 0, Downtime.count + end +end diff --git a/test/integration/routes_test.rb b/test/integration/routes_test.rb index a03db01b5..f4257591d 100644 --- a/test/integration/routes_test.rb +++ b/test/integration/routes_test.rb @@ -37,4 +37,18 @@ class RoutesTest < ActionDispatch::IntegrationTest assert_routing("/editions/1/downtime/new", controller: "legacy_downtimes", action: "new", edition_id: "1") end + + should "route to new downtimes controller index action when 'design_system_downtime_index_page' toggle is enabled" do + test_strategy = Flipflop::FeatureSet.current.test! + test_strategy.switch!(:design_system_downtime_index_page, true) + + assert_routing("/downtimes", controller: "downtimes", action: "index") + end + + should "route to legacy downtimes controller index action when 'design_system_downtime_index_page' toggle is disabled" do + test_strategy = Flipflop::FeatureSet.current.test! + test_strategy.switch!(:design_system_downtime_index_page, false) + + assert_routing("/downtimes", controller: "legacy_downtimes", action: "index") + end end