Skip to content

Commit 2fee011

Browse files
committed
Revert "Revert "[GOVUKAPP-3136] Add app chat feedback form""
1 parent 099236d commit 2fee011

File tree

13 files changed

+637
-5
lines changed

13 files changed

+637
-5
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
class Contact::GovukApp::ChatFeedbackController < ApplicationController
2+
include ThrottlingManager
3+
4+
def new; end
5+
6+
def create
7+
ticket = AppChatFeedbackTicket.new(chat_feedback_params)
8+
9+
if ticket.valid?
10+
ticket.save
11+
redirect_to contact_govuk_app_confirmation_path
12+
else
13+
decrement_throttle_counts
14+
15+
@errors = ticket.errors.messages
16+
@ticket = ticket
17+
render "new"
18+
end
19+
end
20+
21+
private
22+
23+
def chat_feedback_params
24+
params[:chat_feedback].slice(
25+
:giraffe,
26+
:feedback,
27+
:reply,
28+
:name,
29+
:email,
30+
).permit!
31+
end
32+
end

app/controllers/contact/govuk_app_controller.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ def create
66
return render "new"
77
end
88

9-
if type == "problem"
9+
case type
10+
when "problem"
1011
redirect_to contact_govuk_app_report_problem_path(params: phone_details_params)
11-
else
12+
when "suggestion"
1213
redirect_to contact_govuk_app_make_suggestion_path
14+
when "chat_feedback"
15+
redirect_to contact_govuk_app_chat_feedback_path
1316
end
1417
end
1518

@@ -29,7 +32,7 @@ def type
2932
def blank_or_invalid_type?
3033
return true unless params[:contact]
3134

32-
%w[problem suggestion].exclude?(type)
35+
%w[problem suggestion chat_feedback].exclude?(type)
3336
end
3437

3538
def errors
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class AppChatFeedbackTicketCreator < TicketCreator
2+
def subject
3+
"Leave feedback about GOV.UK Chat"
4+
end
5+
6+
def body
7+
<<~MULTILINE_STRING
8+
[Requester]
9+
#{requester_sentence}
10+
11+
[Please leave your feedback]
12+
#{ticket_params[:feedback]}
13+
MULTILINE_STRING
14+
end
15+
16+
def priority
17+
NORMAL_PRIORTIY
18+
end
19+
20+
def tags
21+
%w[govuk_app govuk_app_chat]
22+
end
23+
24+
private
25+
26+
def requester_sentence
27+
requester = ticket_params[:requester] || {}
28+
if requester[:name] && requester[:email]
29+
requester[:name] + " <#{requester[:email]}>"
30+
elsif requester[:email]
31+
requester[:email]
32+
else
33+
"Anonymous"
34+
end
35+
end
36+
end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class AppChatFeedbackTicket < AppTicket
2+
include ReplyValidation
3+
4+
attr_accessor :feedback
5+
6+
validates :feedback, presence: { message: "Enter your feedback" }
7+
validates :feedback, length: {
8+
maximum: MAX_FIELD_CHARACTERS,
9+
message: "Your feedback must be #{MAX_FIELD_CHARACTERS} characters or less",
10+
}
11+
12+
def save
13+
AppChatFeedbackTicketCreator.new(ticket_params).send if valid_ticket?
14+
end
15+
16+
private
17+
18+
def ticket_params
19+
named = name.presence || "Not submitted"
20+
params = { feedback: }
21+
params[:requester] = { name: named, email: } if can_reply?
22+
params
23+
end
24+
end
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<% content_for :head do %>
2+
<meta name="robots" content="noindex">
3+
<% end %>
4+
5+
<%
6+
ga4_english_strings = {
7+
page_title: t("controllers.contact.govuk_app.chat_feedback.new.title", locale: :en),
8+
questions: {
9+
feedback: t("controllers.contact.govuk_app.chat_feedback.new.feedback", locale: :en),
10+
reply: t("controllers.contact.govuk_app.shared.can_we_reply", locale: :en),
11+
email: t("controllers.contact.govuk_app.shared.email", locale: :en),
12+
name: t("controllers.contact.govuk_app.shared.name", locale: :en),
13+
},
14+
send_message: t("controllers.contact.govuk_app.chat_feedback.new.send_feedback", locale: :en)
15+
}
16+
17+
ga4_form_tracker_json = {
18+
event_name: "form_response",
19+
type: "contact",
20+
section: ga4_english_strings[:questions].values.join(", "),
21+
action: ga4_english_strings[:send_message],
22+
tool_name: ga4_english_strings[:page_title]
23+
}.to_json
24+
%>
25+
26+
<% if @errors
27+
ga4_erroring_sections = @errors.keys.map do |error_key|
28+
ga4_english_strings[:questions][error_key]
29+
end
30+
31+
ga4_auto_tracker_json = {
32+
event_name: 'form_error',
33+
type: 'contact',
34+
action: 'error',
35+
text: @errors.values.map { |field_errors| field_errors.join(', ') }.join(', '),
36+
section: ga4_erroring_sections.join(', '),
37+
tool_name: ga4_english_strings[:page_title]
38+
}.to_json
39+
40+
content_for :error_summary do
41+
render partial: "shared/error_summary", locals: { ga4_auto_tracker_json: ga4_auto_tracker_json }
42+
end
43+
end %>
44+
45+
<% content_for :title do t("controllers.contact.govuk_app.chat_feedback.new.title") end %>
46+
47+
<%= form_tag contact_govuk_app_chat_feedback_path, method: :post, class: "contact-form", data: { module: "ga4-form-tracker", ga4_form: ga4_form_tracker_json } do |f| %>
48+
<%= render partial: "shared/spam_honeypot", locals: { form_name: "chat_feedback" } %>
49+
50+
<%= render "govuk_publishing_components/components/character_count", {
51+
textarea: {
52+
value: @ticket ? @ticket.feedback : nil,
53+
error_message: @errors ? @errors[:feedback].first : nil,
54+
label: {
55+
text: t("controllers.contact.govuk_app.chat_feedback.new.feedback"),
56+
heading_size: "m"
57+
},
58+
name: "chat_feedback[feedback]"
59+
},
60+
id: "feedback",
61+
maxlength: 1200
62+
} %>
63+
64+
<% reply_inputs = capture do %>
65+
<%= render "govuk_publishing_components/components/input", {
66+
label: {
67+
text: t("controllers.contact.govuk_app.shared.email"),
68+
heading_size: "s"
69+
},
70+
name: "chat_feedback[email]",
71+
id: "email",
72+
value: @ticket ? @ticket.email : nil,
73+
error_message: @errors ? @errors[:email].first : nil,
74+
width: 20,
75+
hint: "We will only use this to reply to your message"
76+
} %>
77+
78+
<%= render "govuk_publishing_components/components/input", {
79+
label: {
80+
text: t("controllers.contact.govuk_app.shared.name"),
81+
heading_size: "s"
82+
},
83+
name: "chat_feedback[name]",
84+
id: "name",
85+
value: @ticket ? @ticket.name : nil,
86+
width: 20
87+
} %>
88+
89+
<br />
90+
<%= t("controllers.contact.govuk_app.shared.personal_information_html") %>
91+
<% end %>
92+
93+
<%= render "govuk_publishing_components/components/radio", {
94+
name: "chat_feedback[reply]",
95+
error_message: @errors ? @errors[:reply].first : nil,
96+
heading: t("controllers.contact.govuk_app.shared.can_we_reply"),
97+
heading_size: "m",
98+
heading_level: 0,
99+
id: "reply",
100+
items: [
101+
{
102+
value: "yes",
103+
text: t("controllers.contact.govuk_app.shared.yes"),
104+
conditional: reply_inputs,
105+
checked: @ticket ? @ticket.reply == "yes" : false,
106+
},
107+
{
108+
value: "no",
109+
text: t("controllers.contact.govuk_app.shared.no"),
110+
checked: @ticket ? @ticket.reply == "no" : false,
111+
}
112+
]
113+
} %>
114+
115+
<p class="govuk-body">
116+
Find out how we use your personal information in the <a class="govuk-link" href="/government/publications/govuk-chat-privacy-notice">privacy notice</a>.
117+
</p>
118+
119+
<%= render "govuk_publishing_components/components/button", {
120+
text: t("controllers.contact.govuk_app.chat_feedback.new.send_feedback"),
121+
margin_bottom: true
122+
} %>
123+
<% end %>

app/views/contact/govuk_app/new.html.erb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ end %>
5656
{
5757
value: "suggestion",
5858
text: t("controllers.contact.govuk_app.new.radio_suggestion_text")
59+
},
60+
{
61+
value: "chat_feedback",
62+
text: t("controllers.contact.govuk_app.new.radio_chat_feedback_text")
5963
}
6064
]
6165
} %>

config/locales/en.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ en:
2727
radio_heading: What would you like to do?
2828
radio_problem_text: Report a problem with the app
2929
radio_suggestion_text: Make a suggestion for improving the app
30+
radio_chat_feedback_text: Leave feedback about GOV.UK Chat
3031
continue_text: Continue
3132
description_html: |
3233
<p class="govuk-body">You can use this form to report a problem with the app or make a suggestion for improving the app.</p>
@@ -50,6 +51,11 @@ en:
5051
new:
5152
title: Make a suggestion about the GOV.UK app
5253
what_is_your_suggestion: What is your suggestion?
54+
chat_feedback:
55+
new:
56+
title: Leave feedback about GOV.UK Chat
57+
feedback: Please leave your feedback
58+
send_feedback: Send feedback
5359
govuk:
5460
contact_govuk:
5561
title: "Contact GOV.UK"

config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141

4242
get "make-suggestion", to: "suggestions#new"
4343
post "make-suggestion", to: "suggestions#create"
44+
45+
get "leave-feedback-about-govuk-chat", to: "chat_feedback#new", as: "chat_feedback"
46+
post "leave-feedback-about-govuk-chat", to: "chat_feedback#create"
4447
end
4548

4649
root to: redirect("/contact")
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
require "rails_helper"
2+
3+
RSpec.describe AppChatFeedbackTicketCreator do
4+
let(:ticket_params) do
5+
{
6+
requester: {
7+
email: "someone@example.com",
8+
name: "Someone",
9+
},
10+
feedback: "Some feedback",
11+
}
12+
end
13+
14+
let(:support_ticket) { AppChatFeedbackTicketCreator.new(ticket_params) }
15+
16+
it "should inherit from TicketCreator" do
17+
expect(AppChatFeedbackTicketCreator.superclass).to eq(TicketCreator)
18+
end
19+
20+
it "includes priority" do
21+
expect(support_ticket.priority).to eq("normal")
22+
end
23+
24+
it "includes tags" do
25+
expect(support_ticket.tags).to eq(%w[govuk_app govuk_app_chat])
26+
end
27+
28+
it "includes subject" do
29+
expect(support_ticket.subject).to eq("Leave feedback about GOV.UK Chat")
30+
end
31+
32+
describe "#body" do
33+
it "returns body text" do
34+
body = <<~MULTILINE_STRING
35+
[Requester]
36+
Someone <someone@example.com>
37+
38+
[Please leave your feedback]
39+
Some feedback
40+
MULTILINE_STRING
41+
42+
expect(support_ticket.body).to eq(body)
43+
end
44+
45+
it "returns anonymous without requester " do
46+
ticket_params.delete(:requester)
47+
body = <<~MULTILINE_STRING
48+
[Requester]
49+
Anonymous
50+
MULTILINE_STRING
51+
expect(support_ticket.body).to include(body)
52+
end
53+
54+
it "returns only email if name isn't present" do
55+
ticket_params[:requester].delete(:name)
56+
body = <<~MULTILINE_STRING
57+
[Requester]
58+
someone@example.com
59+
MULTILINE_STRING
60+
expect(support_ticket.body).to include(body)
61+
end
62+
end
63+
end

0 commit comments

Comments
 (0)