Skip to content

Commit 9bfd94f

Browse files
committed
add diy_email_address screen + spec tests etc
1 parent c5f476a commit 9bfd94f

File tree

8 files changed

+261
-3
lines changed

8 files changed

+261
-3
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
module Diy
2+
class DiyEmailAddressController < BaseController
3+
before_action :require_diy_intake
4+
5+
def self.show?(diy_intake)
6+
# TODO: Use this version after GYR1-877 merged:
7+
# diy_intake.email_address.blank? && diy_intake.email_notification_opt_in_yes?
8+
# TEMP:
9+
diy_intake.email_notification_opt_in_yes?
10+
end
11+
12+
def edit
13+
@form = DiyEmailAddressForm.new
14+
end
15+
16+
def update
17+
diy_intake = current_diy_intake
18+
form_params = params.fetch(:diy_email_address_form, {}).permit(*DiyEmailAddressForm.attribute_names)
19+
@form = DiyEmailAddressForm.new(diy_intake, form_params)
20+
if @form.valid?
21+
@form.save
22+
after_update_success
23+
track_question_answer
24+
redirect_to(diy_continue_to_fsa_path)
25+
else
26+
after_update_failure
27+
track_validation_error
28+
render :edit
29+
end
30+
end
31+
32+
private
33+
34+
def tracking_data
35+
{}
36+
end
37+
end
38+
end

app/controllers/diy/diy_notification_preference_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def update
1515
after_update_success
1616
track_question_answer
1717
session[:diy_intake_id] = diy_intake.id
18-
redirect_to(diy_continue_to_fsa_path)
18+
redirect_to(diy_diy_email_address_path)
1919
else
2020
after_update_failure
2121
track_validation_error
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class DiyEmailAddressForm < Form
2+
include FormAttributes
3+
attr_accessor :diy_intake
4+
set_attributes_for :diy_intake, :email_address
5+
# TODO need?
6+
set_attributes_for :confirmation, :email_address_confirmation
7+
8+
validates :email_address, presence: true, 'valid_email_2/email': { mx: true }
9+
# TODO need?
10+
validates :email_address, confirmation: true
11+
validates :email_address_confirmation, presence: true
12+
13+
def initialize(diy_intake = nil, params = {})
14+
@diy_intake = diy_intake
15+
super(params)
16+
end
17+
18+
def save
19+
diy_intake.update!(attributes_for(:diy_intake))
20+
end
21+
22+
def self.existing_attributes(diy_intake)
23+
HashWithIndifferentAccess.new(diy_intake.attributes)
24+
end
25+
end

app/lib/navigation/diy_navigation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class DiyNavigation
66
Diy::QualificationsController,
77
Diy::FileYourselfController,
88
Diy::DiyNotificationPreferenceController,
9-
#Diy::DiyEmailAddressController,
9+
Diy::DiyEmailAddressController,
1010
Diy::ContinueToFsaController
1111
].freeze
1212
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<% @main_question = t("views.questions.email_address.title") %>
2+
3+
<section class="slab slab--white question-layout">
4+
<div class="grid">
5+
<div class="grid__item question-wrapper">
6+
<div class="main-content-inner">
7+
<%= image_tag("questions/email-address.svg", alt: "") %>
8+
9+
<%= form_with model: @form, url: diy_diy_email_address_path, local: true, method: "put", builder: VitaMinFormBuilder, html: { class: "form-card form-card--long" } do |f| %>
10+
<h1 class="h2"><%= @main_question %></h1>
11+
<p class="text--help">
12+
<%=t("views.questions.email_address.info") %>
13+
</p>
14+
15+
<div class="form-card__content">
16+
<%= f.cfa_input_field(:email_address, t("views.questions.email_address.email_address"), classes: ["form-width--long"]) %>
17+
<%= f.cfa_input_field(:email_address_confirmation, t("views.questions.email_address.email_address_confirmation"), classes: ["form-width--long"]) %>
18+
</div>
19+
20+
<%= f.continue %>
21+
</div>
22+
</div>
23+
</div>
24+
</div>
25+
</section>
26+
27+
<% end %>

app/views/diy/diy_notification_preference/edit.html.erb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
<%= f.cfa_checkbox(:email_notification_opt_in, t("views.questions.notification_preference.options.email_notification_opt_in"), options: { checked_value: "yes", unchecked_value: "no" }) %>
2626
<div class="question-with-follow-up">
2727
<div class="question-with-follow-up__question">
28-
<%= f.cfa_checkbox(:sms_notification_opt_in, t("views.questions.notification_preference.options.sms_notification_opt_in"), options: { checked_value: "yes", unchecked_value: "no", "data-follow-up": "#sms-opt-in" }) %>
28+
<%# TODO remove once phone_number screen added.
29+
<X= f.cfa_checkbox(:sms_notification_opt_in, t("views.questions.notification_preference.options.sms_notification_opt_in"), options: { checked_value: "yes", unchecked_value: "no", "data-follow-up": "#sms-opt-in" }) X>
30+
%>
2931
</div>
3032

3133
<p class="text--small spacing-above-25">
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
require "rails_helper"
2+
3+
RSpec.describe Diy::DiyEmailAddressController do
4+
render_views
5+
6+
test_email_address = 'test@test.test'
7+
8+
let(:diy_intake) { create(:diy_intake, email_address: test_email_address) }
9+
10+
before do
11+
allow(subject).to receive(:current_diy_intake).and_return(diy_intake)
12+
allow(MixpanelService).to receive(:send_event)
13+
end
14+
15+
describe ".show?" do
16+
context "when they do not have an email address and opted in to email" do
17+
let!(:diy_intake) { create :diy_intake, email_notification_opt_in: "yes" }
18+
xit "returns true" do
19+
pry
20+
expect(described_class.show?(diy_intake)).to eq true
21+
end
22+
end
23+
24+
context "when they have an email" do
25+
let!(:diy_intake) { create :diy_intake, email_notification_opt_in: "yes", email_address: "email@example.test" }
26+
xit "returns false" do
27+
expect(described_class.show?(diy_intake)).to eq false
28+
end
29+
end
30+
31+
context "when they have not opted in to email" do
32+
let!(:diy_intake) { create :diy_intake, email_notification_opt_in: "no" }
33+
xit "returns false" do
34+
expect(described_class.show?(diy_intake)).to eq false
35+
end
36+
end
37+
end
38+
39+
describe "#edit" do
40+
it "renders successfully" do
41+
get :edit, session: { diy_intake_id: diy_intake.id }
42+
expect(response).to be_successful
43+
end
44+
end
45+
46+
describe "#update" do
47+
context "with valid params" do
48+
let(:params) do
49+
{
50+
diy_email_address_form: {
51+
email_address: "iloveplant@example.test",
52+
email_address_confirmation: "iloveplant@example.test",
53+
}
54+
}
55+
end
56+
57+
it "sets the email address on the diy_intake" do
58+
expect do
59+
post :update, params: params, session: { diy_intake_id: diy_intake.id }
60+
end.to change { diy_intake.reload.email_address }
61+
.from(test_email_address)
62+
.to("iloveplant@example.test")
63+
end
64+
65+
it "sends an event to mixpanel without the email address data" do
66+
post :update, params: params, session: { diy_intake_id: diy_intake.id }
67+
68+
expect(MixpanelService).to have_received(:send_event).with(hash_including(
69+
event_name: "question_answered",
70+
data: {}
71+
))
72+
end
73+
end
74+
75+
context "with non-matching email addresses" do
76+
let(:params) do
77+
{
78+
diy_email_address_form: {
79+
email_address: "iloveplant@example.test",
80+
email_address_confirmation: "iloveplarnt@example.test",
81+
}
82+
}
83+
end
84+
85+
it "shows validation errors" do
86+
post :update, params: params, session: { diy_intake_id: diy_intake.id }
87+
88+
expect(response.body).to include("Please double check that the email addresses match.")
89+
end
90+
91+
it "sends an event to mixpanel with relevant data" do
92+
post :update, params: params, session: { diy_intake_id: diy_intake.id }
93+
94+
expect(MixpanelService).to have_received(:send_event).with(hash_including(
95+
event_name: "validation_error",
96+
data: {
97+
invalid_email_address_confirmation: true
98+
})
99+
)
100+
end
101+
end
102+
103+
context "with an invalid email address" do
104+
let(:params) do
105+
{
106+
diy_email_address_form: {
107+
email_address: "iloveplant@example.",
108+
email_address_confirmation: "iloveplant@example.",
109+
}
110+
}
111+
end
112+
113+
it "shows validation errors" do
114+
post :update, params: params, session: { diy_intake_id: diy_intake.id }
115+
116+
expect(response.body).to include("Please enter a valid email address.")
117+
end
118+
119+
it "sends an event to mixpanel with relevant data" do
120+
post :update, params: params, session: { diy_intake_id: diy_intake.id }
121+
122+
expect(MixpanelService).to have_received(:send_event).with(hash_including(
123+
event_name: "validation_error",
124+
data: {
125+
invalid_email_address: true
126+
}
127+
))
128+
end
129+
end
130+
end
131+
end
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require "rails_helper"
2+
3+
describe DiyEmailAddressForm do
4+
# TODO remove this initial `email_address` value as part of GYR1-877.
5+
let(:diy_intake) { create :diy_intake, email_address: 'test@test.test' }
6+
7+
context "validations" do
8+
it_behaves_like "email address validation", EmailAddressForm do
9+
let(:form_object) { diy_intake }
10+
end
11+
end
12+
13+
describe "#save" do
14+
it "saves the email address" do
15+
expect {
16+
described_class.new(diy_intake, {
17+
email_address: "mango@fruitnames.test",
18+
email_address_confirmation: "mango@fruitnames.test"
19+
}).save
20+
}.to change(diy_intake, :email_address).to("mango@fruitnames.test")
21+
end
22+
23+
context "when the email address gets updated to a new address" do
24+
let(:diy_intake) { create :diy_intake, email_address: "martin@fruitnames.test" }
25+
it "saves the updated email address" do
26+
expect {
27+
described_class.new(diy_intake, {
28+
email_address: "mango@fruitnames.test",
29+
email_address_confirmation: "mango@fruitnames.test"
30+
}).save
31+
}.to change(diy_intake, :email_address).to("mango@fruitnames.test")
32+
end
33+
end
34+
end
35+
end

0 commit comments

Comments
 (0)