Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
12 changes: 11 additions & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,17 @@ module UsersController

if survey.save
set_status_created
render json: GreenlightStatusSerializer.new(survey.greenlight_status)

greenlight_status = survey.greenlight_status
if greenlight_status.status.pending? || greenlight_status.status.recovery?
StatusAlertAdminsWorker.perform_async(
user.id,
greenlight_status.status,
current_user.id,
)
end

render json: GreenlightStatusSerializer.new(greenlight_status)
else
error_response(survey.greenlight_status)
end
Expand Down
23 changes: 23 additions & 0 deletions app/workers/status_alert_admins_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true
class StatusAlertAdminsWorker < ApplicationWorker
def perform(symptom_holder_id, status, reporter = nil)
symptom_holder = User.find(symptom_holder_id)
locations = symptom_holder.locations.includes(:location_accounts)

users_to_notify = Set.new

locations.map(&:location_accounts).flatten.each do |la|
if la.permission_level.admin? &&
la.user.id != reporter &&
la.user.id != symptom_holder_id
users_to_notify.add(la.user)
end
end

users_to_notify.each do |u|
next unless u.email?

StatusAlertUserWorker.perform_async(u.id, symptom_holder_id, status)
end
end
end
48 changes: 48 additions & 0 deletions app/workers/status_alert_user_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true
class StatusAlertUserWorker < ApplicationWorker
def html_template
Erubi::Engine.new(<<~HTML
<h2><%= I18n.t('emails.status_alert.title', status_color: status_color) %></h2>
<p>
<%= I18n.t('emails.status_alert.salutation', name: user.first_name) %>
</p>
<p>
<%= I18n.t(
'emails.status_alert.body',
user: symptom_holder.full_name,
status_color: status_color,
) %>
</p>
<%= I18n.t('greenlight_team') %>
</p>
HTML
).src
end

def text_template
Erubi::Engine.new(<<~SMS
<%= I18n.t(
'texts.status_alert',
user: symptom_holder.full_name,
status_color: status_color,
) %>
SMS
).src
end

def perform(user_id, symptom_holder_id, status)
user = User.find(user_id)
symptom_holder = User.find(symptom_holder_id)
status_color = I18n.t("greenlight_status.#{status}") +
' (' + I18n.t("greenlight_status.colors.#{status}") + ')'

I18n.with_locale(user.locale) do
SendGridEmail.new(
to: user.name_with_email,
subject: I18n.t('emails.status_alert.subject'),
html: eval(html_template),
text: eval(text_template),
).run
end
end
end
18 changes: 18 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,25 @@ en:
You requested to reset your password and here's the link!
Note that this link expires in 1 hour and can only be used once.
action: Click Here to Reset Password
status_alert:
subject: Greenlight Status Alert
salutation: "Hi, %{name}"
title: "A %{status_color} Status Submitted"
body: "%{user} submitted a %{status_color} status."
texts:
magic_sign_in: "Greenlight Magic Sign In: %{link}"
reminder: "Greenlight reminding you to send out your symptom surveys!"
password_reset: "Greenlight Password Reset: %{link}"
status_alert: "Greenlight: %{user} submitted a %{status_color} status."
greenlight_status:
absent: Absent
cleared: Cleared
not_submitted: Not Submitted
pending: Pending
recovery: Recovery
colors:
absent: Blue
cleared: Green
not_submitted: Gray
pending: Yellow
recovery: Red
19 changes: 19 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,25 @@ es:
para %{people} por Greenlight para WG Pearson.
action: Haga Clic Aquí para Iniciar Sesión y Enviar su Encuesta
closing: Disfruta tu día,
status_alert:
subject: Greenlight Alerta de estado
salutation: "Hola %{name}"
title: "Un estado %{status_color} enviado"
body: "%{user} presentó un estado %{status_color}."
texts:
magic_sign_in: "Greenlight Iniciar Sesión con Magia: %{link}"
reminder: "Greenlight le recuerda que envíe sus encuestas de síntomas para WG Pearson!"
password_reset: "Greenlight Restablecimiento de contraseña: %{link}"
status_alert: "Greenlight: %{user} presentó un estado %{status_color}."
greenlight_status:
absent: Ausente
cleared: Aprobado
not_submitted: No Enviado
pending: Pendiente
recovery: Recuperación
colors:
absent: Azul
cleared: Verde
not_submitted: Gris
pending: Amarillo
recovery: Rojo
6 changes: 3 additions & 3 deletions spec/fabricators/location_account_fabricator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
Fabricator(:location_account) do
user nil
location nil
extenal_id "MyText"
role "MyText"
permission_level "MyText"
external_id { Faker::Alphanumeric.unique.alpha(number: 10) }
role "unknown"
permission_level "none"
title "MyText"
attendance_status "MyText"
approved_by_user_at "2020-09-14 17:49:37"
Expand Down
114 changes: 114 additions & 0 deletions spec/requests/symptom_survey_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,119 @@
expect(user.last_greenlight_status.status).to eq(GreenlightStatus::RECOVERY)
end
end

describe 'notify email' do
let(:location_a) { Fabricate(:location) }
let(:location_b) { Fabricate(:location) }
let(:symptom_holder) { Fabricate(:user) }
let(:reporter) { Fabricate(:user) }
let(:location_a_admin_a) { Fabricate(:user) }
let(:location_a_admin_b) { Fabricate(:user) }
let(:location_b_admin) { Fabricate(:user) }

before do
[location_a, location_b].each do |loc|
Fabricate(:location_account, user: symptom_holder, location: loc)
end

[location_a_admin_a, location_a_admin_b].each do |u|
Fabricate(
:location_account,
user: u,
location: location_a,
permission_level: 'admin',
)
end

[location_b_admin, reporter].each do |u|
Fabricate(
:location_account,
user: u,
location: location_b,
permission_level: 'admin',
)
end
end

it "does not send alert emails for cleared status" do
post_json("/v1/users/#{symptom_holder.id}/symptom-surveys", body: {
medicalEvents: []
}, user: reporter)

expect(StatusAlertAdminsWorker.jobs.size).to eq(0)
end

MedicalEvent::SYMPTOMS.each do |symptom|
it "sends alert emails for pending status" do
post_json("/v1/users/#{symptom_holder.id}/symptom-surveys", body: {
medicalEvents: [{
eventType: symptom,
occurredAt: Time.current.iso8601
}]
}, user: reporter)

expect_work(StatusAlertAdminsWorker)

expect(StatusAlertUserWorker.jobs.size).to eq(3)
StatusAlertUserWorker.drain

sent_mails = Mail::TestMailer.deliveries
expect(sent_mails.size).to eq(3)

remaining_receivers = [
location_a_admin_a,
location_a_admin_b,
location_b_admin,
].map(&:name_with_email).to_set

sent_mails.each do |sent_mail|
expect(sent_mail[:subject].to_s).to include('Greenlight Status')
expect(sent_mail.html_part.to_s).to include(
"#{symptom_holder.full_name} submitted a Pending (Yellow) status"
)

remaining_receivers.delete sent_mail.To&.value
end

expect(remaining_receivers).to be_empty
end
end

MedicalEvent::RECOVERY_TRIGGERS.each do |trigger|
it "sends alert emails for recovery status" do
post_json("/v1/users/#{symptom_holder.id}/symptom-surveys", body: {
medicalEvents: [{
eventType: trigger,
occurredAt: Time.current.iso8601
}]
}, user: reporter)

expect_work(StatusAlertAdminsWorker)

expect(StatusAlertUserWorker.jobs.size).to eq(3)
StatusAlertUserWorker.drain

sent_mails = Mail::TestMailer.deliveries
expect(sent_mails.size).to eq(3)

remaining_receivers = [
location_a_admin_a,
location_a_admin_b,
location_b_admin,
].map(&:name_with_email).to_set

sent_mails.each do |sent_mail|
expect(sent_mail[:subject].to_s).to include('Greenlight Status')
expect(sent_mail.html_part.to_s).to include(
"#{symptom_holder.full_name} submitted a Recovery (Red) status"
)

remaining_receivers.delete sent_mail.To&.value
end

expect(remaining_receivers).to be_empty
end
end
end
end
end