diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 9049eda502..e7d624b9b7 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -46,17 +46,15 @@ def handle_short_url(url_list)
# volunteer/supervisor/casa_admin controller uses to send SMS
# returns appropriate flash notice for SMS
def deliver_sms_to(resource, body_msg)
- if resource.phone_number.blank?
+ if resource.phone_number.blank? || !resource.casa_org.twilio_enabled?
return "blank"
end
- acc_sid = current_user.casa_org.twilio_account_sid
- api_key = current_user.casa_org.twilio_api_key_sid
- api_secret = current_user.casa_org.twilio_api_key_secret
+
body = body_msg
to = resource.phone_number
from = current_user.casa_org.twilio_phone_number
- twilio = TwilioService.new(api_key, api_secret, acc_sid)
+ @twilio = TwilioService.new(current_user.casa_org)
req_params = {
From: from,
Body: body,
@@ -64,21 +62,25 @@ def deliver_sms_to(resource, body_msg)
}
begin
- twilio_res = twilio.send_sms(req_params)
+ twilio_res = @twilio.send_sms(req_params)
twilio_res.error_code.nil? ? "sent" : "error"
- rescue Twilio::REST::RestError
+ rescue Twilio::REST::RestError => error
+ @error = error
+ "error"
+ rescue # unverfied error isnt picked up by Twilio::Rest::RestError
+ # https://www.twilio.com/docs/errors/21608
+ @error = "Phone number is unverifiied"
"error"
end
end
def sms_acct_creation_notice(resource_name, sms_status)
- if sms_status === "blank"
- return "New #{resource_name} created successfully."
- end
- if sms_status === "error"
- return "New #{resource_name} created successfully. SMS not sent due to error."
- end
- if sms_status === "sent"
+ case sms_status
+ when "blank"
+ "New #{resource_name} created successfully."
+ when "error"
+ "New #{resource_name} created successfully. SMS not sent. Error: #{@error}."
+ when "sent"
"New #{resource_name} created successfully. SMS has been sent!"
end
end
diff --git a/app/controllers/casa_admins_controller.rb b/app/controllers/casa_admins_controller.rb
index 515f8fed9b..490d3b80c1 100644
--- a/app/controllers/casa_admins_controller.rb
+++ b/app/controllers/casa_admins_controller.rb
@@ -41,7 +41,7 @@ def create
service = ::CreateCasaAdminService.new(current_organization, params, current_user)
@casa_admin = service.build
authorize @casa_admin
- sms_status = "blank"
+ sms_status = "blank" # shami: why hard code here if deliver_sms_to takes care of this?
begin
casa_admin = service.create!
diff --git a/app/controllers/casa_org_controller.rb b/app/controllers/casa_org_controller.rb
index 87e3a4f8db..3a5d3c395f 100644
--- a/app/controllers/casa_org_controller.rb
+++ b/app/controllers/casa_org_controller.rb
@@ -49,7 +49,8 @@ def casa_org_update_params
:twilio_account_sid,
:twilio_phone_number,
:twilio_api_key_sid,
- :twilio_api_key_secret
+ :twilio_api_key_secret,
+ :twilio_enabled
)
end
diff --git a/app/controllers/users/passwords_controller.rb b/app/controllers/users/passwords_controller.rb
index 93f1fd65b2..3bc76ff9d7 100644
--- a/app/controllers/users/passwords_controller.rb
+++ b/app/controllers/users/passwords_controller.rb
@@ -6,7 +6,6 @@ class Users::PasswordsController < Devise::PasswordsController
def create
@email, @phone_number = [params[resource_name][:email], params[resource_name][:phone_number]]
@resource = @email.blank? ? User.find_by(phone_number: @phone_number) : User.find_by(email: @email)
-
valid_params?(@email, @phone_number) ? send_password : render_error
return if @errors
@@ -33,15 +32,18 @@ def send_password_reset_sms
# for case where user enters ONLY a phone number, generate a new reset token to use;
# otherwise, use the same reset token as sent by devise mailer
@reset_token ||= @resource.generate_password_reset_token
-
create_short_url
- twilio_service = TwilioService.new(@resource.casa_org.twilio_api_key_sid, @resource.casa_org.twilio_api_key_secret, @resource.casa_org.twilio_account_sid)
- sms_params = {
- From: @resource.casa_org.twilio_phone_number,
- Body: password_reset_msg(@resource.display_name, @short_io_service.short_url),
- To: @phone_number
- }
- twilio_service.send_sms(sms_params)
+ begin
+ twilio_service = TwilioService.new(@resource.casa_org)
+ sms_params = {
+ From: @resource.casa_org.twilio_phone_number,
+ Body: password_reset_msg(@resource.display_name, @short_io_service.short_url),
+ To: @phone_number
+ }
+ twilio_service.send_sms(sms_params)
+ rescue => e
+ Rails.logger.error("send SMS failed: #{e}")
+ end
end
def valid_params?(email, phone_number)
diff --git a/app/controllers/volunteers_controller.rb b/app/controllers/volunteers_controller.rb
index 84f1e6e171..8790dae554 100644
--- a/app/controllers/volunteers_controller.rb
+++ b/app/controllers/volunteers_controller.rb
@@ -99,10 +99,12 @@ def resend_invitation
def send_reactivation_alert
authorize @volunteer
if @volunteer.save
- send_sms_to(volunteers_phone_number, "Hello #{@volunteer.display_name}, \n \n Your CASA/Prince George’s County volunteer console account has been reactivated. You can login using the credentials you were already using. \n \n If you have any questions, please contact your most recent Case Supervisor for assistance. \n \n CASA/Prince George’s County")
- redirect_to edit_volunteer_path(@volunteer), notice: "Volunteer reactivation alert sent"
- else
- redirect_to edit_volunteer_path(@volunteer), alert: "Volunteer reactivation alert failed"
+ begin
+ send_sms_to(volunteers_phone_number, "Hello #{@volunteer.display_name}, \n \n Your CASA/Prince George’s County volunteer console account has been reactivated. You can login using the credentials you were already using. \n \n If you have any questions, please contact your most recent Case Supervisor for assistance. \n \n CASA/Prince George’s County")
+ redirect_to edit_volunteer_path(@volunteer), notice: "Volunteer reactivation alert sent"
+ rescue
+ redirect_to edit_volunteer_path(@volunteer), notice: "Volunteer reactivation alert not sent. Twilio is disabled for #{@volunteer.casa_org.name}."
+ end
end
end
@@ -162,7 +164,7 @@ def volunteers_phone_number
end
def send_sms_to(phone_number, body)
- twilio = TwilioService.new(current_user.casa_org.twilio_api_key_sid, current_user.casa_org.twilio_api_key_secret, current_user.casa_org.twilio_account_sid)
+ twilio = TwilioService.new(current_user.casa_org)
req_params = {From: current_user.casa_org.twilio_phone_number, Body: body, To: phone_number}
twilio_res = twilio.send_sms(req_params)
diff --git a/app/javascript/application.js b/app/javascript/application.js
index db83def93f..8906ac7607 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -33,4 +33,6 @@ require('./src/select')
require('./src/sidebar')
require('./src/tooltip')
require('./src/session_timeout_poller.js')
+require('./src/casa_org')
+require('./src/sms_reactivation_toggle')
require('./src/display_app_metric.js')
diff --git a/app/javascript/src/casa_org.js b/app/javascript/src/casa_org.js
new file mode 100644
index 0000000000..39a42f3313
--- /dev/null
+++ b/app/javascript/src/casa_org.js
@@ -0,0 +1,46 @@
+function twilioToggle () {
+ const phoneNumber = $('#casa_org_twilio_phone_number')
+ const accSid = $('#casa_org_twilio_account_sid')
+ const keySid = $('#casa_org_twilio_api_key_sid')
+ const secret = $('#casa_org_twilio_api_key_secret')
+
+ if ($('.accordionTwilio').is(':checked')) {
+ addCheckedAttr(phoneNumber)
+ addCheckedAttr(accSid)
+ addCheckedAttr(keySid)
+ addCheckedAttr(secret)
+ } else {
+ removeCheckedAttr(phoneNumber)
+ removeCheckedAttr(accSid)
+ removeCheckedAttr(keySid)
+ removeCheckedAttr(secret)
+ }
+}
+
+function addCheckedAttr (el) {
+ el.attr('required', true)
+ el.setAttribute('aria-disabled', false)
+ el.setAttribute('aria-required', true)
+ el.removeAttr('disabled')
+}
+
+function removeCheckedAttr (el) {
+ el.removeAttr('required')
+ el.setAttribute('aria-required', false)
+ el.setAttribute('aria-disabled', true)
+ el.attr('disabled', true)
+}
+
+$('document').ready(() => {
+ $('.accordionTwilio').attr('data-bs-toggle', 'collapse')
+ $('.accordionTwilio').attr('data-bs-target', '#collapseTwilio')
+ $('.accordionTwilio').attr('aria-expanded', 'false')
+
+ if ($('.accordionTwilio').is(':checked')) {
+ $('.accordionTwilio').attr('aria_expanded')
+ $('.accordionTwilio').removeClass('collapsed')
+ $('#collapseTwilio').addClass('show')
+ }
+
+ ($('.accordionTwilio').on('click', twilioToggle))
+})
diff --git a/app/javascript/src/sms_reactivation_toggle.js b/app/javascript/src/sms_reactivation_toggle.js
new file mode 100644
index 0000000000..506223e4d0
--- /dev/null
+++ b/app/javascript/src/sms_reactivation_toggle.js
@@ -0,0 +1,16 @@
+
+$('document').ready(() => {
+ if ($('#twilio_disabled').length) {
+ $('#twilio_disabled').removeClass('main-btn danger-btn-outline btn-hover btn-sm my-1')
+ $('#twilio_disabled').addClass('main-btn deactive-btn btn-sm my-1')
+ $('#twilio_tooltip').attr('data-bs-toggle', 'tooltip')
+ $('#twilio_tooltip').attr('data-bs-placement', 'bottom')
+ $('#twilio_tooltip').attr('data-turbo', 'false')
+ $('#twilio_tooltip').attr('title', "Twilio is not enabled for this user's CASA org")
+
+ $('#twilio_disabled').on('click', function (event) {
+ event.preventDefault()
+ console.log('tooltip?')
+ })
+ }
+})
diff --git a/app/models/casa_org.rb b/app/models/casa_org.rb
index 357987434e..92dfb1ba4a 100644
--- a/app/models/casa_org.rb
+++ b/app/models/casa_org.rb
@@ -8,7 +8,7 @@ class CasaOrg < ApplicationRecord
validates :name, presence: true, uniqueness: true
validates_with CasaOrgValidator
- validate :validate_twilio_credentials, if: -> { twilio_account_sid.present? || twilio_api_key_sid.present? || twilio_api_key_secret.present? }, on: :update
+ validate :validate_twilio_credentials, if: -> { twilio_enabled || twilio_account_sid.present? || twilio_api_key_sid.present? || twilio_api_key_secret.present? }, on: :update
has_many :users, dependent: :destroy
has_many :casa_cases, dependent: :destroy
@@ -128,6 +128,7 @@ def normalize_phone_number
# twilio_account_sid :string
# twilio_api_key_secret :string
# twilio_api_key_sid :string
+# twilio_enabled :boolean default(FALSE)
# twilio_phone_number :string
# created_at :datetime not null
# updated_at :datetime not null
diff --git a/app/notifications/delivery_methods/sms.rb b/app/notifications/delivery_methods/sms.rb
index 7ed412b89b..b7cd92b227 100644
--- a/app/notifications/delivery_methods/sms.rb
+++ b/app/notifications/delivery_methods/sms.rb
@@ -5,7 +5,7 @@ def deliver
short_io_api = ShortUrlService.new
short_io_api.create_short_url(case_contact_url)
shortened_url = short_io_api.short_url
- twilio_api = TwilioService.new(sender.casa_org.twilio_api_key_sid, sender.casa_org.twilio_api_key_secret, sender.casa_org.twilio_account_sid)
+ twilio_api = TwilioService.new(sender.casa_org)
twilio_api.send_sms({From: sender.casa_org.twilio_phone_number, Body: case_contact_flagged_msg(sender.display_name, shortened_url), To: recipient.phone_number})
end
end
diff --git a/app/services/sms_reminder_service.rb b/app/services/sms_reminder_service.rb
index 02d828ea23..301ee3793b 100644
--- a/app/services/sms_reminder_service.rb
+++ b/app/services/sms_reminder_service.rb
@@ -3,10 +3,10 @@ module SmsReminderService
BASE_URL = Rails.application.credentials[:BASE_URL]
def send_reminder(user, message)
- return if !user[:receive_sms_notifications] || user[:phone_number].blank?
+ return if !user[:receive_sms_notifications] || user[:phone_number].blank? || !user.casa_org.twilio_enabled?
user_casa_org = user.casa_org
- twilio_service = TwilioService.new(user_casa_org.twilio_api_key_sid, user_casa_org.twilio_api_key_secret, user_casa_org.twilio_account_sid)
+ twilio_service = TwilioService.new(user_casa_org)
sms_params = {
From: user_casa_org.twilio_phone_number,
Body: message,
diff --git a/app/services/twilio_service.rb b/app/services/twilio_service.rb
index b135d64b10..0c9d96cd2e 100644
--- a/app/services/twilio_service.rb
+++ b/app/services/twilio_service.rb
@@ -2,32 +2,48 @@
require "twilio-ruby"
class TwilioService
- attr_writer :api_key, :api_secret, :acc_sid
+ class TwilioCasaOrgError < StandardError; end
+ attr_writer :api_key, :api_secret, :acc_sid, :casa_org
- def initialize(api_key, api_secret, acc_sid)
- @api_key = api_key
- @api_secret = api_secret
- @acc_sid = acc_sid
- @client = Twilio::REST::Client.new(api_key, api_secret, acc_sid)
+ def initialize(casa_org)
+ @api_key = casa_org.twilio_api_key_sid
+ @api_secret = casa_org.twilio_api_key_secret
+ @acc_sid = casa_org.twilio_account_sid
+ @enabled = casa_org.twilio_enabled
+ end
+
+ def client # lazy create client only if twilio enabled
+ @client = Twilio::REST::Client.new(@api_key, @api_secret, @acc_sid)
+ end
+
+ def enabled?
+ @enabled
end
# this method takes in a hash
# required keys are: From:, To:, Body:
# to send a short url, set URL: key in hash
def send_sms(params)
+ # return unless casa_org twilio enabled
+ # add check here, Twilio client
+ if !enabled?
+ return nil
+ end
from = params[:From]
body = params.key?(:URL) ? params[:Body] + params[:URL] : params[:Body]
to = params[:To]
# returns a twilio API message object
# refer to docs: https://www.twilio.com/docs/sms/api/message-resource#message-properties
begin
- @client.messages.create(
+ client
+ client.messages.create(
from: from,
body: body,
to: to
)
- rescue => e
- Rails.logger.error("send SMS failed: #{e}")
+ rescue => error
+ Rails.logger.error("send SMS failed: #{error}") # help a person know whats going on, these messages can be inspected (Twilio)
+ error
end
end
end
diff --git a/app/views/casa_org/edit.html.erb b/app/views/casa_org/edit.html.erb
index 1b680abd5e..fcc59a3559 100644
--- a/app/views/casa_org/edit.html.erb
+++ b/app/views/casa_org/edit.html.erb
@@ -32,28 +32,38 @@
<%= form.label :court_report_template, "Court report template" %>
<%= form.file_field :court_report_template, class: "form-control" %>
-
- <%= form.label :twilio_phone_number, "Twilio Phone Number" %>
- <%= form.text_field :twilio_phone_number, class: "form-control" %>
-
-
- <%= form.label :twilio_account_sid, "Twilio Account SID" %>
- <%= form.text_field :twilio_account_sid, class: "form-control" %>
-
-
- <%= form.label :twilio_api_key_sid, "Twilio API Key SID" %>
- <%= form.text_field :twilio_api_key_sid, class: "form-control" %>
-
-
- <%= form.label :twilio_api_key_secret, "Twilio API Key Secret" %>
- <%= form.text_field :twilio_api_key_secret, class: "form-control" %>
-
Organization Features
<%= form.check_box :show_driving_reimbursement, class: 'form-check-input' %>
<%= form.label :show_driving_reimbursement, "Show driving reimbursement", class: 'form-check-label mb-2' %>
+
+
+ <%= form.check_box :twilio_enabled, class: 'form-check-input accordionTwilio' %>
+ <%= form.label :twilio_enabled, "Enable Twilio", class: 'form-check-label mb-2' %>
+
+
+
+
+ <%= form.label :twilio_phone_number, "Twilio Phone Number" %>
+ <%= form.text_field :twilio_phone_number, class: "form-control", autocomplete: :on %>
+
+
+ <%= form.label :twilio_account_sid, "Twilio Account SID" %>
+ <%= form.text_field :twilio_account_sid, class: "form-control", autocomplete: :on %>
+
+
+ <%= form.label :twilio_api_key_sid, "Twilio API Key SID" %>
+ <%= form.text_field :twilio_api_key_sid, class: "form-control", autocomplete: :on %>
+
+
+ <%= form.label :twilio_api_key_secret, "Twilio API Key Secret" %>
+ <%= form.text_field :twilio_api_key_secret, class: "form-control", autocomplete: :on %>
+
+
+
+
<%= button_tag(
type: "submit",
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb
index 98e1b65c98..2a844e6abb 100644
--- a/app/views/users/edit.html.erb
+++ b/app/views/users/edit.html.erb
@@ -123,19 +123,28 @@
<%= form.check_box :receive_email_notifications, class: "toggle-email-notifications form-check-input" %>
<%= form.label :receive_email_notifications, "Email Me", class: "form-check-label" %>
-
- <%= form.check_box :receive_sms_notifications, class: "toggle-sms-notifications form-check-input" %>
- <%= form.label :receive_sms_notifications, "Text Me", class: "form-check-label" %>
-
-
- <%= form.collection_check_boxes("sms_notification_event_ids", SmsNotificationEvent.where(user_type: @user.type),
-:id, :name) do |event| %>
-
- <%= event.check_box(class: "form-check-input form-check-input", id: "toggle-sms-notification-event") %>
- <%= event.label(class: "form-check-label") %>
-
- <% end %>
-
+
+ <% if @user.casa_org.twilio_enabled? %>
+
+ <%= form.check_box :receive_sms_notifications, class: "toggle-sms-notifications form-check-input" %>
+ <%= form.label :receive_sms_notifications, "Text Me", class: "form-check-label" %>
+
+
+ <%= form.collection_check_boxes("sms_notification_event_ids", SmsNotificationEvent.where(user_type: @user.type),
+ :id, :name) do |event| %>
+
+ <%= event.check_box(class: "form-check-input form-check-input", id: "toggle-sms-notification-event") %>
+ <%= event.label(class: "form-check-label") %>
+
+ <% end %>
+
+ <% else %>
+
+ <%= form.check_box :receive_sms_notifications, class: "toggle-sms-notifications form-check-input", disabled: true %>
+ <%= form.label :receive_sms_notifications, "Enable Twilio For Text Messaging", class: "form-check-label" %>
+
+ <% end %>
+
<%= form.submit "Save Preferences", class: "main-btn primary-btn btn-hover mb-3 save-preference" %>
diff --git a/app/views/volunteers/_manage_active.html.erb b/app/views/volunteers/_manage_active.html.erb
index 222a1d9be2..adb7cfc089 100644
--- a/app/views/volunteers/_manage_active.html.erb
+++ b/app/views/volunteers/_manage_active.html.erb
@@ -31,8 +31,9 @@
<% end %>
<% if current_user.casa_admin? %>
<%= link_to send_reactivation_alert_volunteer_path(user),
- class: "main-btn danger-btn-outline btn-hover btn-sm my-1" do %>
- Send Reactivation Alert (SMS)
+ id: "#{current_user.casa_org.twilio_enabled? ? "twilio_enabled" : "twilio_disabled"}",
+ class: "main-btn danger-btn-outline btn-hover btn-sm my-1" do %>
+ <%= current_user.casa_org.twilio_enabled? ? "Send Reactivation Alert (SMS)" : "Enable Twilio To Send Reactivation Alert (SMS)" %>
<% end %>
<% end %>
diff --git a/db/migrate/20230517133521_add_twilio_enabled_to_casa_orgs.rb b/db/migrate/20230517133521_add_twilio_enabled_to_casa_orgs.rb
new file mode 100644
index 0000000000..dcf9c26262
--- /dev/null
+++ b/db/migrate/20230517133521_add_twilio_enabled_to_casa_orgs.rb
@@ -0,0 +1,5 @@
+class AddTwilioEnabledToCasaOrgs < ActiveRecord::Migration[7.0]
+ def change
+ add_column :casa_orgs, :twilio_enabled, :boolean, default: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 8ccc79b8c1..f6f1af37eb 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2023_04_20_212437) do
+ActiveRecord::Schema[7.0].define(version: 2023_05_17_133521) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -140,6 +140,7 @@
t.string "twilio_account_sid"
t.string "twilio_api_key_sid"
t.string "twilio_api_key_secret"
+ t.boolean "twilio_enabled", default: false
t.index ["slug"], name: "index_casa_orgs_on_slug", unique: true
end
diff --git a/lib/tasks/case_contact_types_reminder.rb b/lib/tasks/case_contact_types_reminder.rb
index 24960959f0..689b0f2f5f 100644
--- a/lib/tasks/case_contact_types_reminder.rb
+++ b/lib/tasks/case_contact_types_reminder.rb
@@ -40,8 +40,7 @@ def send_sms_messages(volunteer, uncontacted_case_contact_type_names)
if !valid_casa_twilio_creds(volunteer_casa_org)
return
end
-
- twilio_service = TwilioService.new(volunteer_casa_org.twilio_api_key_sid, volunteer_casa_org.twilio_api_key_secret, volunteer_casa_org.twilio_account_sid)
+ twilio_service = TwilioService.new(volunteer_casa_org)
sms_params = {
From: volunteer_casa_org.twilio_phone_number,
Body: nil,
@@ -64,7 +63,7 @@ def send_sms_messages(volunteer, uncontacted_case_contact_type_names)
end
def valid_casa_twilio_creds(casa_org)
- casa_org.twilio_phone_number? && casa_org.twilio_account_sid? && casa_org.twilio_api_key_sid? && casa_org.twilio_api_key_secret?
+ casa_org.twilio_enabled? && casa_org.twilio_phone_number? && casa_org.twilio_account_sid? && casa_org.twilio_api_key_sid? && casa_org.twilio_api_key_secret?
end
def last_reminder_within_quarter(volunteer)
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 69d3242b30..37d41faa45 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -108,7 +108,7 @@ def unknown_organization
end
it "sms status is error" do
- expect(controller.send(:sms_acct_creation_notice, "admin", "error")).to eq("New admin created successfully. SMS not sent due to error.")
+ expect(controller.send(:sms_acct_creation_notice, "admin", "error")).to eq("New admin created successfully. SMS not sent. Error: .")
end
it "sms status is sent" do
diff --git a/spec/factories/casa_orgs.rb b/spec/factories/casa_orgs.rb
index 4ee21d68f3..46fc375a08 100644
--- a/spec/factories/casa_orgs.rb
+++ b/spec/factories/casa_orgs.rb
@@ -8,5 +8,6 @@
twilio_api_key_secret { "open sesame" }
twilio_api_key_sid { "Aladdin" }
twilio_phone_number { "+15555555555" }
+ twilio_enabled { true }
end
end
diff --git a/spec/lib/tasks/case_contact_types_reminder_spec.rb b/spec/lib/tasks/case_contact_types_reminder_spec.rb
index 9762fc606b..c71406dea4 100644
--- a/spec/lib/tasks/case_contact_types_reminder_spec.rb
+++ b/spec/lib/tasks/case_contact_types_reminder_spec.rb
@@ -48,7 +48,7 @@
end
context "volunteer with contacted contact types within last 60 days, sms notifications on, and no reminder in last quarter" do
- it "should send not sms reminder" do
+ it "should not send sms reminder" do
CaseContact.update_all(occurred_at: 1.months.ago)
responses = CaseContactTypesReminder.new.send!
expect(responses.count).to match 0
@@ -85,4 +85,15 @@
expect(responses[0][:messages][2].body).to match CaseContactTypesReminder::THIRD_MESSAGE + "https://42ni.short.gy/jzTwdF"
end
end
+
+ context "volunteer with a casa_org that doesn't have Twilio enabled" do
+ it "should not send a sms reminder" do
+ pending "Failure/Error: client.messages.list(limit: 1) WebMock::NetConnectNotAllowedError:"
+
+ casa_org.update(twilio_enabled: false)
+ uncontacted_case_contact_type_names = uncontacted_case_contact_types(volunteer)
+ response = CaseContactTypesReminder.send_sms_messages(volunteer, uncontacted_case_contact_type_names)
+ expect(response).to be_nil
+ end
+ end
end
diff --git a/spec/models/volunteer_spec.rb b/spec/models/volunteer_spec.rb
index bf1fd3d6f9..06453aba78 100644
--- a/spec/models/volunteer_spec.rb
+++ b/spec/models/volunteer_spec.rb
@@ -3,27 +3,32 @@
RSpec.describe Volunteer, type: :model do
describe ".email_court_report_reminder" do
let!(:casa_org) { build(:casa_org) }
-
+ let!(:casa_org_twilio_disabled) { build(:casa_org, twilio_enabled: false) }
# Should send email for this case
let!(:casa_case1) { create(:casa_case, casa_org: casa_org) }
let!(:court_date1) { create(:court_date, casa_case: casa_case1, court_report_due_date: Date.current + 7.days) }
- # Should NOT send emails for these two cases
+ # Should NOT send emails for these cases
let!(:casa_case2) { build(:casa_case, casa_org: casa_org) }
let!(:court_date2) { create(:court_date, casa_case: casa_case2, court_report_due_date: Date.current + 8.days) }
let!(:casa_case3) { build(:casa_case, casa_org: casa_org, court_report_submitted_at: Time.current, court_report_status: :submitted) }
let!(:court_date3) { create(:court_date, casa_case: casa_case3, court_report_due_date: Date.current + 7.days) }
let!(:casa_case4) { build(:casa_case, casa_org: casa_org) }
let!(:court_date4) { create(:court_date, casa_case: casa_case4, court_report_due_date: Date.current + 7.days) }
+ let!(:casa_case5) { create(:casa_case, casa_org: casa_org_twilio_disabled) }
+ let!(:court_date5) { create(:court_date, casa_case: casa_case5, court_report_due_date: Date.current + 7.days) }
let(:case_assignment1) { build(:case_assignment, casa_org: casa_org, casa_case: casa_case1) }
let(:case_assignment2) { build(:case_assignment, casa_org: casa_org, casa_case: casa_case2) }
let(:case_assignment3) { build(:case_assignment, casa_org: casa_org, casa_case: casa_case3) }
let(:case_assignment_unassigned) { build(:case_assignment, casa_org: casa_org, casa_case: casa_case4, active: false) }
+ let(:case_assignment5) { build(:case_assignment, casa_org: casa_org_twilio_disabled, casa_case: casa_case5) }
+
let!(:v1) { create(:volunteer, casa_org: casa_org, case_assignments: [case_assignment1, case_assignment2, case_assignment3]) }
let!(:v2) { build_stubbed(:volunteer, casa_org: casa_org, active: false) }
let!(:v3) { build_stubbed(:volunteer, casa_org: casa_org) }
let!(:v4) { build_stubbed(:volunteer, casa_org: casa_org, case_assignments: [case_assignment_unassigned]) }
+ let!(:v5) { create(:volunteer, casa_org: casa_org_twilio_disabled, case_assignments: [case_assignment5]) }
before do
stub_const("Volunteer::COURT_REPORT_SUBMISSION_REMINDER", 7.days)
@@ -54,6 +59,11 @@
expect(CourtReportDueSmsReminderService).to_not receive(:court_report_reminder).with(v4, anything)
described_class.send_court_report_reminder
end
+
+ it "should return nil when twilio is disabled" do
+ response = CourtReportDueSmsReminderService.court_report_reminder(v5, Date.current + 7.days)
+ expect(response).to eq(nil)
+ end
end
describe "#activate" do
diff --git a/spec/requests/casa_admins_spec.rb b/spec/requests/casa_admins_spec.rb
index daffeff978..480976f9a4 100644
--- a/spec/requests/casa_admins_spec.rb
+++ b/spec/requests/casa_admins_spec.rb
@@ -425,7 +425,19 @@
expect(@twilio_activation_error_stub).to have_been_requested.times(1)
expect(response).to have_http_status(:redirect)
follow_redirect!
- expect(flash[:notice]).to match(/New admin created successfully. SMS not sent due to error./)
+ expect(flash[:notice]).to match(/New admin created successfully. SMS not sent. Error: ./)
+ end
+
+ it "does not send SMS when Twilio is not enabled" do
+ org = create(:casa_org, twilio_enabled: false)
+ admin = build(:casa_admin, casa_org: org)
+
+ sign_in admin
+ params[:phone_number] = "+12222222222"
+ subject
+ expect(response).to have_http_status(:redirect)
+ follow_redirect!
+ expect(flash[:notice]).to match(/New admin created successfully./)
end
end
diff --git a/spec/requests/supervisors_spec.rb b/spec/requests/supervisors_spec.rb
index a48331bb9e..c87df9a3a5 100644
--- a/spec/requests/supervisors_spec.rb
+++ b/spec/requests/supervisors_spec.rb
@@ -298,7 +298,20 @@
expect(@twilio_activation_error_stub).to have_been_requested.times(1)
expect(response).to have_http_status(:redirect)
follow_redirect!
- expect(flash[:notice]).to match(/New supervisor created successfully. SMS not sent due to error./)
+ expect(flash[:notice]).to match(/New supervisor created successfully. SMS not sent. Error: ./)
+ end
+
+ it "does not send a SMS if the casa_org does not have Twilio enabled" do
+ org = create(:casa_org, twilio_enabled: false)
+ admin = build(:casa_admin, casa_org: org)
+
+ sign_in admin
+
+ params[:supervisor][:phone_number] = "+12222222222"
+ post supervisors_url, params: params
+ expect(response).to have_http_status(:redirect)
+ follow_redirect!
+ expect(flash[:notice]).to match(/New supervisor created successfully./)
end
end
diff --git a/spec/requests/users/passwords_spec.rb b/spec/requests/users/passwords_spec.rb
index 9fc523a6db..15635a47db 100644
--- a/spec/requests/users/passwords_spec.rb
+++ b/spec/requests/users/passwords_spec.rb
@@ -10,7 +10,7 @@
before do
allow(TwilioService).to(
receive(:new).with(
- org.twilio_api_key_sid, org.twilio_api_key_secret, org.twilio_account_sid
+ org
).and_return(twillio_service_double)
)
@@ -104,5 +104,21 @@
expect(request.parsed_body).to include("User does not exist.")
end
end
+
+ context "when twilio is disabled" do
+ let(:params) { {user: {email: user.email, phone_number: user.phone_number}} }
+
+ before do
+ org.update(twilio_enabled: false)
+ end
+
+ it "does not send an sms, only an email" do
+ expect_any_instance_of(User).to receive(:send_reset_password_instructions).once
+ request
+ expect(flash[:notice]).to(
+ eq("You will receive an email or SMS with instructions on how to reset your password in a few minutes.")
+ )
+ end
+ end
end
end
diff --git a/spec/requests/volunteers_spec.rb b/spec/requests/volunteers_spec.rb
index 5e091f3c38..21f44e6c42 100644
--- a/spec/requests/volunteers_spec.rb
+++ b/spec/requests/volunteers_spec.rb
@@ -179,7 +179,20 @@
expect(@twilio_activation_error_stub).to have_been_requested.times(1)
expect(response).to have_http_status(:redirect)
follow_redirect!
- expect(flash[:notice]).to match(/New volunteer created successfully. SMS not sent due to error./)
+ expect(flash[:notice]).to match(/New volunteer created successfully. SMS not sent. Error: ./)
+ end
+
+ it "does not send a SMS if the casa_org does not have Twilio enabled" do
+ org = create(:casa_org, twilio_enabled: false)
+ admin = build(:casa_admin, casa_org: org)
+
+ sign_in admin
+
+ params[:volunteer][:phone_number] = "+12222222222"
+ post volunteers_url, params: params
+ expect(response).to have_http_status(:redirect)
+ follow_redirect!
+ expect(flash[:notice]).to match(/New volunteer created successfully./)
end
end
@@ -367,6 +380,18 @@
expect(response).to redirect_to(edit_volunteer_path(volunteer))
expect(response.status).to match 302
end
+
+ it "does not send a reactivation SMS when Casa Org has Twilio disabled" do
+ org = create(:casa_org, twilio_enabled: false)
+ adm = create(:casa_admin, casa_org: org)
+ vol = create(:volunteer, casa_org: org)
+
+ sign_in adm
+
+ get send_reactivation_alert_volunteer_path(vol)
+ expect(response).to redirect_to(edit_volunteer_path(vol))
+ expect(flash[:notice]).to match(/Volunteer reactivation alert not sent. Twilio is disabled for #{org.name}/)
+ end
end
describe "GET /impersonate" do
diff --git a/spec/services/court_report_due_sms_reminder_service_spec.rb b/spec/services/court_report_due_sms_reminder_service_spec.rb
index 8154b513b8..79d972cabc 100644
--- a/spec/services/court_report_due_sms_reminder_service_spec.rb
+++ b/spec/services/court_report_due_sms_reminder_service_spec.rb
@@ -41,5 +41,15 @@
expect(response).to be_nil
end
end
+
+ context "when volunteer's casa_org does not have twilio enabled" do
+ let(:org) { create(:casa_org, twilio_enabled: false) }
+ let(:volunteer_2) { create(:volunteer, casa_org: org) }
+
+ it "should not send a SMS" do
+ response = CourtReportDueSmsReminderService.court_report_reminder(volunteer_2, report_due_date)
+ expect(response).to be_nil
+ end
+ end
end
end
diff --git a/spec/services/no_contact_made_sms_reminder_service_spec.rb b/spec/services/no_contact_made_sms_reminder_service_spec.rb
index 0bf119a1f7..1125366b60 100644
--- a/spec/services/no_contact_made_sms_reminder_service_spec.rb
+++ b/spec/services/no_contact_made_sms_reminder_service_spec.rb
@@ -41,5 +41,15 @@
expect(response).to be_nil
end
end
+
+ context "when volunteer's casa_org does not have twilio enabled" do
+ let(:casa_org) { create(:casa_org, twilio_enabled: false) }
+ let(:volunteer) { create(:volunteer, casa_org: casa_org) }
+
+ it "should not send a SMS" do
+ response = NoContactMadeSmsReminderService.no_contact_made_reminder(volunteer, contact_type)
+ expect(response).to be_nil
+ end
+ end
end
end
diff --git a/spec/services/sms_reminder_service_spec.rb b/spec/services/sms_reminder_service_spec.rb
index 66f91dc146..c6b6074569 100644
--- a/spec/services/sms_reminder_service_spec.rb
+++ b/spec/services/sms_reminder_service_spec.rb
@@ -39,5 +39,15 @@
expect(response).to be_nil
end
end
+
+ context "when a volunteer's casa_org does not have twilio enabled" do
+ let(:casa_org_twilio_disabled) { create(:casa_org, twilio_enabled: false) }
+ let(:volunteer_twilio_disabled) { create(:volunteer, casa_org: casa_org_twilio_disabled) }
+
+ it "should not send a SMS" do
+ response = SmsReminderService.send_reminder(volunteer_twilio_disabled, message)
+ expect(response).to be_nil
+ end
+ end
end
end
diff --git a/spec/services/twilio_service_spec.rb b/spec/services/twilio_service_spec.rb
index 84572e2a4f..11a6028f66 100644
--- a/spec/services/twilio_service_spec.rb
+++ b/spec/services/twilio_service_spec.rb
@@ -8,14 +8,22 @@
WebMockHelper.twilio_success_stub
WebMockHelper.short_io_stub
WebMock.disable_net_connect!
- @acc_sid = "articuno34"
- @api_key = "Aladdin"
- @api_secret = "open sesame"
@short_url = ShortUrlService.new
- @twilio = TwilioService.new(@api_key, @api_secret, @acc_sid)
+ end
+
+ let!(:casa_org) do
+ create(
+ :casa_org,
+ twilio_phone_number: "+15555555555",
+ twilio_account_sid: "articuno34",
+ twilio_api_key_sid: "Aladdin",
+ twilio_api_key_secret: "open sesame",
+ twilio_enabled: true
+ )
end
it "can send a SMS with a short url successfully" do
+ @twilio = TwilioService.new(casa_org)
@short_url.create_short_url("https://www.google.com")
params = {
From: "+15555555555",
@@ -31,5 +39,32 @@
expect(response.body).to match "Execute Order 66 - https://42ni.short.gy/jzTwdF"
end
end
+
+ context "when twilio is disabled" do
+ let!(:casa_org_twilio_disabled) do
+ create(
+ :casa_org,
+ twilio_phone_number: "+15555555553",
+ twilio_account_sid: "zapdos43",
+ twilio_api_key_sid: "Jasmine",
+ twilio_api_key_secret: "hakuna matata",
+ twilio_enabled: false
+ )
+ end
+
+ it "retruns nil" do
+ @short_url = ShortUrlService.new
+ @twilio = TwilioService.new(casa_org_twilio_disabled)
+ @short_url.create_short_url("https://www.google.com")
+ params = {
+ From: "+15555555555",
+ Body: "Execute Order 66 - ",
+ To: "+12222222222",
+ URL: @short_url.short_url
+ }
+ response = @twilio.send_sms(params)
+ expect(response).to eq nil
+ end
+ end
end
end
diff --git a/spec/services/volunteers_emails_export_csv_service_spec.rb b/spec/services/volunteers_emails_export_csv_service_spec.rb
index ed2444397b..f5bce294b9 100644
--- a/spec/services/volunteers_emails_export_csv_service_spec.rb
+++ b/spec/services/volunteers_emails_export_csv_service_spec.rb
@@ -9,19 +9,28 @@
active_volunteer = create(:volunteer, :with_casa_cases, casa_org: casa_org)
inactive_volunteer = create(:volunteer, :inactive, casa_org: casa_org)
other_org_volunteer = create(:volunteer, casa_org: other_casa_org)
- volunteer_with_old_emails = create(:volunteer, old_emails: ["old_email@example.com"], casa_org: casa_org)
active_volunteer_cases = active_volunteer.casa_cases.active.map { |c| [c.case_number, c.in_transition_age?] }.to_h
csv = described_class.new(casa_org).call
results = csv.split("\n")
- expect(results.count).to eq(3)
+ expect(results.count).to eq(2)
expect(results[0].split(",")).to eq(["Email", "Old Emails", "Case Number", "Volunteer Name", "Case Transition Aged Status"])
expect(results[1]).to eq("#{active_volunteer.email},No Old Emails,\"#{active_volunteer_cases.keys.join(", ")}\",#{active_volunteer.display_name},\"#{active_volunteer_cases.values.join(", ")}\"")
- expect(results[2]).to eq("#{volunteer_with_old_emails.email},#{volunteer_with_old_emails.old_emails.join(", ")},\"\",#{volunteer_with_old_emails.display_name},\"\"")
expect(csv).to match(/#{active_volunteer.email}/)
expect(csv).not_to match(/#{inactive_volunteer.email}/)
expect(csv).not_to match(/#{other_org_volunteer.email}/)
end
+
+ it "Exports correct data from volunteers, including old emails" do
+ casa_org_2 = create(:casa_org)
+ volunteer_with_old_emails = create(:volunteer, old_emails: ["old_email@example.com"], casa_org: casa_org_2)
+ csv = described_class.new(casa_org_2).call
+
+ results = csv.split("\n")
+ expect(results.count).to eq(2)
+ expect(results[0].split(",")).to eq(["Email", "Old Emails", "Case Number", "Volunteer Name", "Case Transition Aged Status"])
+ expect(results[1]).to eq("#{volunteer_with_old_emails.email},#{volunteer_with_old_emails.old_emails.join(", ")},\"\",#{volunteer_with_old_emails.display_name},\"\"")
+ end
end
end
diff --git a/spec/system/casa_org/edit_spec.rb b/spec/system/casa_org/edit_spec.rb
index bdd0320ce1..ebfdb9d79c 100644
--- a/spec/system/casa_org/edit_spec.rb
+++ b/spec/system/casa_org/edit_spec.rb
@@ -119,6 +119,7 @@
end
it "has twilio API data required for SMS" do
+ expect(page).to have_text("Enable Twilio")
expect(page).to have_text("Twilio Account SID")
expect(page).to have_text("Twilio API Key SID")
expect(page).to have_text("Twilio API Key Secret")