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

Initial work for Downtime Index page transition to Design System #2027

Merged
merged 1 commit into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 5 additions & 1 deletion app/controllers/downtimes_controller.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
56 changes: 56 additions & 0 deletions app/views/downtimes/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<% content_for :page_title, 'Downtime messages' %>

<div class="page-title">
<h1>Downtime messages</h1>
<p class="lead">Show a message on a published transaction start page for a specific time.</p>
</div>

<table class="table table-bordered table-striped" data-module="filterable-table">
<caption class="h2 remove-top-margin">
<h2 class="remove-top-margin remove-bottom-margin">Services</h2>
</caption>
<thead>
<tr class="table-header">
<th>Service start page</th>
<th>Service status</th>
<th>Action</th>
</tr>
<tr class="if-no-js-hide table-header-secondary">
<td colspan="3">
<form>
<label class="remove-bottom-margin" for="table-filter">Filter services</label>
<p class="help-inline">For example ‘driving’ or ‘scheduled downtime’</p>
<input id="table-filter" type="text" class="form-control normal js-filter-table-input">
</form>
</td>
</tr>
</thead>
<tbody>
<% @transactions.each do |transaction| %>
<tr>
<td>
<h3 class="publication-table-title">
<%= link_to transaction.title, Downtime.for(transaction.artefact).present? ?
edit_edition_downtime_path(transaction) :
new_edition_downtime_path(transaction) %>
</h3>
<%= link_to "/#{transaction.slug}", "#{Plek.website_root}/#{transaction.slug}", class: 'link-muted' %>
</td>
<% if downtime = Downtime.for(transaction.artefact) %>
<td>
Scheduled downtime<br />
<span class="text-muted"><%= downtime_datetime(downtime) %></span>
</td>
<td>
<%= link_to 'Edit downtime', edit_edition_downtime_path(transaction), class: 'btn btn-info' %>
</td>
<% else %>
<td>Live</td>
<td>
<%= link_to 'Add downtime', new_edition_downtime_path(transaction), class: 'btn btn-default' %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
20 changes: 19 additions & 1 deletion app/views/layouts/design_system.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,26 @@
} %>

<div class="govuk-width-container">
<main class="govuk-main-wrapper govuk-main-wrapper--auto-spacing" id="main-content" role="main">

<main class="govuk-main-wrapper govuk-main-wrapper--auto-spacing" id="main-content" role="main">
<% [:success, :info, :warning, :danger, :notice, :alert].select { |k| flash[k].present? }.each do |k| %>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be using the design system components (Error Alert, Success Alert, Notice), rather than copying this pattern from the legacy layout template?

Copy link
Contributor Author

@patrickpatrickpatrick patrickpatrickpatrick Jan 31, 2024

Choose a reason for hiding this comment

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

I thought that implementing the design system component would be a separate task in of itself. I think the flash message probably shouldn't have been removed initially or should have done part as part of the layout card, which is why I'm putting it back for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we need a team discussion around this, as I would expect that without using the components from the design system, the look of the flash messages won't be acceptable for releasing these pages, in which case we need to get a story for doing that done ASAP.

I think we probably need a discussion around how we're going to release pages (i.e. turn the default state of the toggle to on) anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

<%
case k
when :notice
alert_class = "success"
when :alert
alert_class = "danger"
else
alert_class = k
end
%>
<div class="alert alert-<%= alert_class %>"
data-module="auto-track-event"
data-track-action="alert-<%= alert_class %>"
data-track-label="<%= strip_tags(flash[k]) %>">
<%= flash[k] %>
</div>
<% end %>
<% if yield(:title).present? %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
Expand Down
4 changes: 4 additions & 0 deletions config/features.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
25 changes: 25 additions & 0 deletions test/functional/downtimes_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions test/integration/downtime_integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
118 changes: 118 additions & 0 deletions test/integration/legacy_downtime_integration_test.rb
Original file line number Diff line number Diff line change
@@ -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
14 changes: 14 additions & 0 deletions test/integration/routes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading