Browse Source
* Set up failing test for new soft validation design * remove unneeded js controller * remove unneeded controller and spec * rename net income validation override column * spec form changes (to allow tests to run) * validation spec changes * replace all instances of override_net_income_validatiom * passing first test * Add to form and import styling * remove unneeded code from interruption screen view * Update test & code - failing last new expectation * Display 2 previous question answers in the informative text * extract displaying of the informative text into a helper * Add tests for helper * Remove some of the previous soft validations set up * fix some failing specs * Fix more tests * lint * Reset earnings question prefix and suffix to initial values instead of nil * make it route backwards on a no * test and linter fixes * refactor next_page * stryling * more changes * fix specs * update real form * design tweaks * delete commented out tests * content changes * content changes * changes to informative/hint text * More robust styles for interuption panel, use smart quotes * Rubocop Co-authored-by: Kat <katrina@madetech.com> Co-authored-by: Paul Robert Lloyd <me+git@paulrobertlloyd.com> Co-authored-by: baarkerlounger <db@slothlife.xyz>pull/374/head
Dushan
3 years ago
committed by
GitHub
39 changed files with 322 additions and 291 deletions
@ -1,21 +0,0 @@ |
|||||||
class SoftValidationsController < ApplicationController |
|
||||||
before_action :authenticate_user! |
|
||||||
|
|
||||||
def show |
|
||||||
@case_log = CaseLog.find(params[:case_log_id]) |
|
||||||
page_id = request.env["PATH_INFO"].split("/")[-2] |
|
||||||
page = @case_log.form.get_page(page_id) |
|
||||||
if page_requires_soft_validation_override?(page) |
|
||||||
errors = @case_log.soft_errors.values.first |
|
||||||
render json: { show: true, label: errors.message, hint: errors.hint_text } |
|
||||||
else |
|
||||||
render json: { show: false } |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
|
|
||||||
def page_requires_soft_validation_override?(page) |
|
||||||
@case_log.soft_errors.present? && @case_log.soft_errors.keys.first == page.soft_validations&.first&.id |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1,16 @@ |
|||||||
|
module InteruptionScreenHelper |
||||||
|
def display_informative_text(informative_text, case_log) |
||||||
|
translation_questions = informative_text["argument"].map { |x| case_log.form.get_question(x) } |
||||||
|
begin |
||||||
|
case translation_questions.count |
||||||
|
when 2 |
||||||
|
translation = I18n.t(informative_text["translation"], informative_text["argument"][0].to_sym => translation_questions[0].answer_label(case_log), informative_text["argument"][1].to_sym => translation_questions[1].answer_label(case_log)) |
||||||
|
when 1 |
||||||
|
translation = I18n.t(informative_text["translation"], informative_text["argument"][0].to_sym => translation_questions[0].answer_label(case_log)) |
||||||
|
end |
||||||
|
rescue StandardError |
||||||
|
return "" |
||||||
|
end |
||||||
|
translation.to_s.html_safe |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,23 @@ |
|||||||
|
<%= govuk_panel( |
||||||
|
title_text: title_text, |
||||||
|
classes: 'app-panel--interruption', |
||||||
|
) do %> |
||||||
|
<%= display_informative_text(informative_text, case_log) %> |
||||||
|
<%= f.govuk_radio_buttons_fieldset question.id.to_sym, |
||||||
|
legend: { text: question.header }, |
||||||
|
hint: { text: question.hint_text&.html_safe } do %> |
||||||
|
<% question.answer_options.map do |key, options| %> |
||||||
|
<% if key.starts_with?("divider") %> |
||||||
|
<%= f.govuk_radio_divider %> |
||||||
|
<% else %> |
||||||
|
<%= f.govuk_radio_button question.id, |
||||||
|
key, |
||||||
|
label: { text: options['value'] }, |
||||||
|
hint: { text: options['hint'] }, |
||||||
|
**stimulus_html_attributes(question) |
||||||
|
%> |
||||||
|
<% end %> |
||||||
|
<% end %> |
||||||
|
<% end %> |
||||||
|
<%= f.govuk_submit "Save and continue", accesskey: "s", class: "app-button--inverse govuk-!-margin-bottom-0" %> |
||||||
|
<% end %> |
@ -1,15 +0,0 @@ |
|||||||
<div class="govuk-form-group govuk-form-group--error" |
|
||||||
data-controller="soft-validations" |
|
||||||
data-soft-validations-target="override" |
|
||||||
style='display:none;'> |
|
||||||
|
|
||||||
<%= f.govuk_check_boxes_fieldset page.soft_validations&.first&.id.to_sym, |
|
||||||
legend: { text: "soft-validations-placeholder-message", size: "l" }, |
|
||||||
hint: { text: "soft-validations-placeholder-hint-text" } do %> |
|
||||||
|
|
||||||
<%= f.govuk_check_box page.soft_validations&.first&.id, page.soft_validations&.first&.id, |
|
||||||
label: { text: "Yes" }, |
|
||||||
checked: @case_log[page.soft_validations&.first&.id] == "Yes" |
|
||||||
%> |
|
||||||
<% end %> |
|
||||||
</div> |
|
@ -1,28 +0,0 @@ |
|||||||
import { Controller } from "@hotwired/stimulus" |
|
||||||
|
|
||||||
export default class extends Controller { |
|
||||||
static targets = [ "override" ] |
|
||||||
|
|
||||||
initialize() { |
|
||||||
let url = window.location.href + "/soft-validations" |
|
||||||
let div = this.overrideTarget |
|
||||||
fetch(url, { headers: { accept: "application/json" } }) |
|
||||||
.then(response => response.json()) |
|
||||||
.then((response) => { |
|
||||||
if(response["show"]){ |
|
||||||
div.style.display = "block" |
|
||||||
let innerHTML = div.innerHTML |
|
||||||
innerHTML = innerHTML.replace("soft-validations-placeholder-message", response["label"]) |
|
||||||
innerHTML = innerHTML.replace("soft-validations-placeholder-hint-text", response["hint"]) |
|
||||||
div.innerHTML = innerHTML |
|
||||||
} else { |
|
||||||
div.style.display = "none" |
|
||||||
let buttons = document.getElementsByName(`case_log[override_net_income_validation][]`) |
|
||||||
Object.entries(buttons).map(([idx, button]) => { |
|
||||||
button.checked = false |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,31 @@ |
|||||||
|
$app-button-shadow-size: $govuk-border-width-form-element; |
||||||
|
$app-button-inverse-background-colour: govuk-colour("white"); |
||||||
|
$app-button-inverse-foreground-colour: $govuk-brand-colour; |
||||||
|
$app-button-inverse-shadow-colour: govuk-shade($app-button-inverse-foreground-colour, 30%); |
||||||
|
$app-button-inverse-hover-background-colour: govuk-tint($app-button-inverse-foreground-colour, 90%); |
||||||
|
|
||||||
|
.app-button--inverse, |
||||||
|
.app-button--inverse:link, |
||||||
|
.app-button--inverse:visited { |
||||||
|
color: $app-button-inverse-foreground-colour; |
||||||
|
background-color: $app-button-inverse-background-colour; |
||||||
|
box-shadow: 0 $app-button-shadow-size 0 $app-button-inverse-shadow-colour; |
||||||
|
} |
||||||
|
|
||||||
|
.app-button--inverse:hover { |
||||||
|
color: $app-button-inverse-foreground-colour; |
||||||
|
background-color: $app-button-inverse-hover-background-colour; |
||||||
|
} |
||||||
|
|
||||||
|
.app-button--inverse:focus:not(:hover) { |
||||||
|
color: $govuk-focus-text-colour; |
||||||
|
background-color: $govuk-focus-colour; |
||||||
|
} |
||||||
|
|
||||||
|
.app-button--inverse:active, |
||||||
|
.app-button--inverse:focus { |
||||||
|
border-color: $govuk-focus-colour; |
||||||
|
color: $app-button-inverse-foreground-colour; |
||||||
|
background-color: $app-button-inverse-hover-background-colour; |
||||||
|
box-shadow: inset 0 0 0 2px $govuk-focus-colour; |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
.app-panel--interruption { |
||||||
|
background-color: govuk-colour("blue"); |
||||||
|
color: govuk-colour("white"); |
||||||
|
text-align: left; |
||||||
|
|
||||||
|
p, |
||||||
|
.govuk-body, |
||||||
|
.govuk-label, |
||||||
|
.govuk-fieldset__legend, |
||||||
|
.govuk-hint { |
||||||
|
color: govuk-colour("white"); |
||||||
|
} |
||||||
|
|
||||||
|
a:not(:focus) { |
||||||
|
color: inherit; |
||||||
|
} |
||||||
|
|
||||||
|
*:last-child { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
.govuk-radios__label::before, |
||||||
|
& ::after { |
||||||
|
color: govuk-colour("black"); |
||||||
|
border-color: govuk-colour("black"); |
||||||
|
background-color: govuk-colour("white"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
class RenameNetIncomeValidationOverrideColumn < ActiveRecord::Migration[7.0] |
||||||
|
def change |
||||||
|
rename_column :case_logs, :override_net_income_validation, :net_income_value_check |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,65 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe InteruptionScreenHelper do |
||||||
|
form_handler = FormHandler.instance |
||||||
|
let(:form) { form_handler.get_form("test_form") } |
||||||
|
let(:subsection) { form.get_subsection("household_characteristics") } |
||||||
|
let(:user) { FactoryBot.create(:user) } |
||||||
|
let(:case_log) do |
||||||
|
FactoryBot.create( |
||||||
|
:case_log, |
||||||
|
:in_progress, |
||||||
|
ecstat1: 1, |
||||||
|
earnings: 750, |
||||||
|
incfreq: 0, |
||||||
|
owning_organisation: user.organisation, |
||||||
|
managing_organisation: user.organisation, |
||||||
|
) |
||||||
|
end |
||||||
|
|
||||||
|
describe "display_informative_text" do |
||||||
|
context "when 2 out of 2 arguments are given" do |
||||||
|
it "returns correct informative text" do |
||||||
|
informative_text = { |
||||||
|
"translation" => "soft_validations.net_income.hint_text", |
||||||
|
"argument" => %w[ecstat1 earnings], |
||||||
|
} |
||||||
|
expect(display_informative_text(informative_text, case_log)) |
||||||
|
.to eq("<p>You told us the main tenant’s working situation is: <strong>Full-time – 30 hours or more</strong></p><p>The household income you have entered is <strong>£750.00 every week</strong></p>") |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when 1 out of 1 arguments is given" do |
||||||
|
it "returns correct informative text" do |
||||||
|
informative_text = { |
||||||
|
"translation" => "test.one_argument", |
||||||
|
"argument" => %w[ecstat1], |
||||||
|
} |
||||||
|
expect(display_informative_text(informative_text, case_log)) |
||||||
|
.to eq("This is based on the tenant’s work situation: Full-time – 30 hours or more") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when 2 out of 1 arguments are given" do |
||||||
|
it "returns correct informative text" do |
||||||
|
informative_text = { |
||||||
|
"translation" => "test.one_argument", |
||||||
|
"argument" => %w[ecstat1 earnings], |
||||||
|
} |
||||||
|
expect(display_informative_text(informative_text, case_log)) |
||||||
|
.to eq("This is based on the tenant’s work situation: Full-time – 30 hours or more") |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when 1 out of 2 arguments are given" do |
||||||
|
it "returns an empty string" do |
||||||
|
informative_text = { |
||||||
|
"translation" => "soft_validations.net_income.hint_text", |
||||||
|
"argument" => %w[ecstat1], |
||||||
|
} |
||||||
|
expect(display_informative_text(informative_text, case_log)) |
||||||
|
.to eq("") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1,54 +0,0 @@ |
|||||||
require "rails_helper" |
|
||||||
|
|
||||||
RSpec.describe SoftValidationsController, type: :request do |
|
||||||
let(:params) { { case_log_id: case_log.id } } |
|
||||||
let(:url) { "/logs/#{case_log.id}/net-income/soft-validations" } |
|
||||||
let(:user) { FactoryBot.create(:user) } |
|
||||||
|
|
||||||
context "when a user is not signed in" do |
|
||||||
let(:case_log) { FactoryBot.create(:case_log, :in_progress) } |
|
||||||
|
|
||||||
describe "GET #show" do |
|
||||||
it "redirects to the sign in page" do |
|
||||||
get url, headers: headers, params: {} |
|
||||||
expect(response).to redirect_to("/users/sign-in") |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context "when a user is signed in" do |
|
||||||
before do |
|
||||||
sign_in user |
|
||||||
get url, params: {} |
|
||||||
end |
|
||||||
|
|
||||||
describe "GET #show" do |
|
||||||
context "when a soft validation is triggered" do |
|
||||||
let(:case_log) { FactoryBot.create(:case_log, :soft_validations_triggered) } |
|
||||||
|
|
||||||
it "returns a success response" do |
|
||||||
expect(response).to be_successful |
|
||||||
end |
|
||||||
|
|
||||||
it "returns a json with the soft validation fields" do |
|
||||||
json_response = JSON.parse(response.body) |
|
||||||
expect(json_response["show"]).to eq(true) |
|
||||||
expect(json_response["label"]).to match(/Are you sure this is correct?/) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context "when no soft validation is triggered" do |
|
||||||
let(:case_log) { FactoryBot.create(:case_log, :in_progress) } |
|
||||||
|
|
||||||
it "returns a success response" do |
|
||||||
expect(response).to be_successful |
|
||||||
end |
|
||||||
|
|
||||||
it "returns a json without the soft validation fields" do |
|
||||||
json_response = JSON.parse(response.body) |
|
||||||
expect(json_response["show"]).to eq(false) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
Loading…
Reference in new issue