'
3 | layout 'mailer'
4 | end
5 |
--------------------------------------------------------------------------------
/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | self.abstract_class = true
3 | end
4 |
--------------------------------------------------------------------------------
/app/models/attachment.rb:
--------------------------------------------------------------------------------
1 | class Attachment < ApplicationRecord
2 | belongs_to :message
3 |
4 | has_attached_file :media
5 | validates_attachment_content_type :media, content_type: /video\/.*|audio\/.*|image\/.*|text\/.*|application\/pdf.*/
6 |
7 | before_save :extract_dimensions
8 | serialize :dimensions, Array
9 |
10 | def update_media(url:)
11 | self.media = open(url,
12 | http_basic_authentication: [ENV['TWILIO_ACCOUNT_SID'],
13 | ENV['TWILIO_AUTH_TOKEN']])
14 | end
15 |
16 | def image?
17 | media_content_type.match?(/image\/.*/) ? true : false
18 | end
19 |
20 | def extract_dimensions
21 | return unless image?
22 | tempfile = media.queued_for_write[:original]
23 | return if tempfile.nil?
24 | geometry = Paperclip::Geometry.from_file(tempfile)
25 | self.dimensions = [geometry.width.to_i, geometry.height.to_i]
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/app/models/change_image.rb:
--------------------------------------------------------------------------------
1 | class ChangeImage < ApplicationRecord
2 | has_attached_file :file
3 | belongs_to :user
4 | validates_attachment_content_type :file, content_type: %r{image\/.*}
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/client_edit_marker.rb:
--------------------------------------------------------------------------------
1 | class ClientEditMarker < Marker
2 | end
3 |
--------------------------------------------------------------------------------
/app/models/client_status.rb:
--------------------------------------------------------------------------------
1 | class ClientStatus < ApplicationRecord
2 | belongs_to :department
3 |
4 | validates :name, :icon_color, :department, presence: true
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/concerns/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/app/models/concerns/.keep
--------------------------------------------------------------------------------
/app/models/conversation_ends_marker.rb:
--------------------------------------------------------------------------------
1 | class ConversationEndsMarker < Marker
2 | private
3 |
4 | def set_marker
5 | self.inbound = true
6 | self.read = true
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/models/court_date_csv.rb:
--------------------------------------------------------------------------------
1 | class CourtDateCSV < ApplicationRecord
2 | has_attached_file :file
3 | belongs_to :user
4 | validates_attachment_content_type :file, content_type: %r{text\/.*}
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/court_reminder.rb:
--------------------------------------------------------------------------------
1 | class CourtReminder < TextMessage
2 | belongs_to :court_date_csv
3 |
4 | before_validation :set_court_reminder, on: :create
5 | # validates :court_date_csv, presence: true
6 |
7 | private
8 |
9 | def set_court_reminder
10 | self.inbound = false
11 | self.read = true
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/app/models/feature_flag.rb:
--------------------------------------------------------------------------------
1 | class FeatureFlag < ApplicationRecord
2 | validates :flag, presence: true, uniqueness: true
3 | validates :enabled, inclusion: { in: [true, false] }
4 |
5 | def self.enabled?(flag)
6 | feature = self.find_by(flag: flag)
7 | if feature
8 | feature.enabled
9 | else
10 | false
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/app/models/highlight_blob.rb:
--------------------------------------------------------------------------------
1 | class HighlightBlob < ApplicationRecord
2 | html_fragment :text, scrub: :prune
3 | end
4 |
--------------------------------------------------------------------------------
/app/models/marker.rb:
--------------------------------------------------------------------------------
1 | class Marker < Message
2 | before_validation :set_marker, on: :create
3 |
4 | private
5 |
6 | def set_marker
7 | self.inbound = true
8 | self.send_at = Time.zone.now
9 | self.read = true
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/models/mass_message.rb:
--------------------------------------------------------------------------------
1 | class MassMessage
2 | include ActiveModel::Model
3 | # For validations see:
4 | # http://railscasts.com/episodes/219-active-model?view=asciicast
5 |
6 | validates :message, :reporting_relationships, presence: true
7 |
8 | attr_accessor :user, :message, :send_at, :reporting_relationships
9 |
10 | def initialize(attributes = {})
11 | super
12 | @reporting_relationships ||= []
13 | @reporting_relationships.map!(&:to_i)
14 | end
15 |
16 | def past_message?
17 | return false if send_at.nil?
18 |
19 | if send_at < time_buffer
20 | errors.add(:send_at, I18n.t('activerecord.errors.models.message.attributes.send_at.on_or_after'))
21 |
22 | true
23 | else
24 | false
25 | end
26 | end
27 |
28 | private
29 |
30 | def time_buffer
31 | Time.current - 5.minutes
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/app/models/merge_client.rb:
--------------------------------------------------------------------------------
1 | class MergeClient
2 | include ActiveModel::Model
3 |
4 | attr_accessor :full_name, :phone_number
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/merge_reporting_relationship.rb:
--------------------------------------------------------------------------------
1 | class MergeReportingRelationship
2 | include ActiveModel::Model
3 |
4 | attr_accessor :selected_client_id
5 | end
6 |
--------------------------------------------------------------------------------
/app/models/merged_with_marker.rb:
--------------------------------------------------------------------------------
1 | class MergedWithMarker < Marker
2 | end
3 |
--------------------------------------------------------------------------------
/app/models/report.rb:
--------------------------------------------------------------------------------
1 | class Report < ApplicationRecord
2 | belongs_to :department
3 |
4 | validates :department, presence: true
5 | validates :email, presence: true
6 |
7 | def users
8 | department.users.active
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/app/models/survey.rb:
--------------------------------------------------------------------------------
1 | class Survey < ApplicationRecord
2 | belongs_to :client
3 | belongs_to :user
4 | has_many :survey_response_links, dependent: :nullify
5 | has_many :survey_responses, through: :survey_response_links
6 |
7 | def questions
8 | survey_responses.map(&:survey_question).uniq
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/app/models/survey_question.rb:
--------------------------------------------------------------------------------
1 | class SurveyQuestion < ApplicationRecord
2 | has_many :survey_responses, dependent: :nullify
3 | end
4 |
--------------------------------------------------------------------------------
/app/models/survey_response.rb:
--------------------------------------------------------------------------------
1 | class SurveyResponse < ApplicationRecord
2 | belongs_to :survey_question
3 | has_many :survey_response_links, dependent: :nullify
4 |
5 | scope :active, -> { where(active: true) }
6 | end
7 |
--------------------------------------------------------------------------------
/app/models/survey_response_link.rb:
--------------------------------------------------------------------------------
1 | class SurveyResponseLink < ApplicationRecord
2 | belongs_to :survey
3 | belongs_to :survey_response
4 | end
5 |
--------------------------------------------------------------------------------
/app/models/text_message.rb:
--------------------------------------------------------------------------------
1 | class TextMessage < Message
2 | validates :number_to, presence: true
3 | validates :number_from, presence: true
4 |
5 | before_validation :set_text_message, on: :create
6 |
7 | private
8 |
9 | def set_text_message
10 | return unless reporting_relationship
11 |
12 | if inbound
13 | self.number_from = reporting_relationship.client.phone_number
14 | self.number_to = reporting_relationship.user.department.phone_number
15 | else
16 | self.number_from = reporting_relationship.user.department.phone_number
17 | self.number_to = reporting_relationship.client.phone_number
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/app/models/transfer_marker.rb:
--------------------------------------------------------------------------------
1 | class TransferMarker < Marker
2 | end
3 |
--------------------------------------------------------------------------------
/app/views/admin/users/disable.html.erb:
--------------------------------------------------------------------------------
1 | Disabling an account means that this user will no longer be able to log in. You can re-enable their account at any
2 | time.
3 | <% if @clients_to_disable.any? %>
4 |
5 |
Warning: This user has active clients
6 |
7 |
8 | These clients will no longer be able to text this user.
9 | Incoming texts will be received by the active user most
10 | recently in contact with this client, or the unclaimed user for this department.
11 |
12 |
13 | <% @clients_to_disable.each do |client| %>
14 | - <%= client.full_name %>
15 | <% end %>
16 |
17 |
18 |
19 | <% end %>
20 | <%= link_to 'Disable account', disable_confirm_admin_user_path(resource), {class: 'button'} %>
21 |
22 |
--------------------------------------------------------------------------------
/app/views/attachments/_attachment.html.erb:
--------------------------------------------------------------------------------
1 | <% if attachment.image? %>
2 |
3 |
 %>)
4 |
5 | <% else %>
6 | View Attachment
7 | <% end %>
8 |
--------------------------------------------------------------------------------
/app/views/attachments/_inline_attachment.html.erb:
--------------------------------------------------------------------------------
1 | <% if attachment.image? %>
2 |
3 | <% else %>
4 | Files sent via text are attached to this email.
5 | <% end %>
6 |
--------------------------------------------------------------------------------
/app/views/client_edit_markers/_client_edit_marker.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= client_edit_marker.body %>
5 |
6 |
7 |
8 | <%= client_edit_marker.send_at.strftime('%-m/%-d/%y, %-l:%M%P') %>
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/views/clients/_client_status.html.erb:
--------------------------------------------------------------------------------
1 | <% if current_user.department.client_statuses? && @relationships_by_status.any? %>
2 |
3 | <% @relationships_by_status.each do |status, ids| %>
4 |
14 | <% end %>
15 |
16 | <% end %>
17 |
--------------------------------------------------------------------------------
/app/views/clients/edit.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for(:template_name) { "clients" } %>
2 |
3 | <% content_for(:js) do %>
4 | <%= javascript_include_tag 'clients/edit' %>
5 | <% end %>
6 |
7 |
8 |
9 |
10 | <%= render 'clients/client_form', form_title: 'Edit client', save_text: 'Save changes' %>
11 | <%= render 'clients/client_manage', form_title: 'Edit client', save_text: 'Save changes' %>
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/views/clients/index.js.erb:
--------------------------------------------------------------------------------
1 | $('#client-list').removeClass('hidden');
2 | $('#client-list').replaceWith('<%= j render 'clients/clients' %>');
3 | $('#client-empty-dialog').addClass('hidden');
4 | clientListInit();
5 |
--------------------------------------------------------------------------------
/app/views/clients/new.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for(:js) do %>
2 | <%= javascript_include_tag 'clients/new' %>
3 | <% end %>
4 |
5 |
6 |
7 |
8 | <%= render 'client_form', form_title: 'Add a new client', save_text: 'Save new client' %>
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/views/conversation_ends_markers/_conversation_ends_marker.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= conversation_ends_marker.body %>
5 |
6 |
7 |
8 | <%= conversation_ends_marker.send_at.strftime('%-m/%-d/%y, %-l:%M%P') %>
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/views/court_reminders/_court_reminder.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= court_reminder.body %>
5 |
6 |
7 |
8 | <% if court_reminder.twilio_status == 'undelivered' %>
9 | <%= t('message.status.undelivered') %>
10 | <% else %>
11 | <%= court_reminder.twilio_status %> <%= court_reminder.send_at.to_s(:message_timestamp) %>
12 | <% end %>
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/views/devise/confirmations/new.html.erb:
--------------------------------------------------------------------------------
1 | Resend confirmation instructions
2 |
3 | <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4 | <%= devise_error_messages! %>
5 |
6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
9 |
10 |
11 |
12 | <%= f.submit "Resend confirmation instructions" %>
13 |
14 | <% end %>
15 |
16 | <%= render "devise/shared/links" %>
17 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/confirmation_instructions.html.erb:
--------------------------------------------------------------------------------
1 | Welcome <%= @email %>!
2 |
3 | You can confirm your account email through the link below:
4 |
5 | <%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
6 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/email_changed.html.erb:
--------------------------------------------------------------------------------
1 | Hello <%= @email %>!
2 |
3 | <% if @resource.try(:unconfirmed_email?) %>
4 | We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.
5 | <% else %>
6 | We're contacting you to notify you that your email has been changed to <%= @resource.email %>.
7 | <% end %>
8 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/password_change.html.erb:
--------------------------------------------------------------------------------
1 | Hello <%= @resource.email %>!
2 |
3 | We're contacting you to notify you that your password has been changed.
4 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/reset_password_instructions.html.erb:
--------------------------------------------------------------------------------
1 | Hello <%= @resource.email %>!
2 |
3 | Someone has requested a link to change your password. You can do this through the link below.
4 |
5 | <%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>
6 |
7 | If you didn't request this, please ignore this email.
8 | Your password won't change until you access the link above and create a new one.
9 |
--------------------------------------------------------------------------------
/app/views/devise/mailer/unlock_instructions.html.erb:
--------------------------------------------------------------------------------
1 | Hello <%= @resource.email %>!
2 |
3 | Your account has been locked due to an excessive number of unsuccessful sign in attempts.
4 |
5 | Click the link below to unlock your account:
6 |
7 | <%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
8 |
--------------------------------------------------------------------------------
/app/views/devise/passwords/new.html.erb:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/app/views/devise/shared/_links.html.erb:
--------------------------------------------------------------------------------
1 | <%- if controller_name != 'sessions' %>
2 | <%= link_to "Log in", new_session_path(resource_name) %>
3 | <% end -%>
4 |
5 | <%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
6 | <%= link_to "Forgot your password?", new_password_path(resource_name) %>
7 | <% end -%>
8 |
9 | <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
10 | <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
11 | <% end -%>
12 |
13 | <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
14 | <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
15 | <% end -%>
16 |
17 | <%- if devise_mapping.omniauthable? %>
18 | <%- resource_class.omniauth_providers.each do |provider| %>
19 | <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %>
20 | <% end -%>
21 | <% end -%>
22 |
--------------------------------------------------------------------------------
/app/views/devise/unlocks/new.html.erb:
--------------------------------------------------------------------------------
1 | Resend unlock instructions
2 |
3 | <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
4 | <%= devise_error_messages! %>
5 |
6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true %>
9 |
10 |
11 |
12 | <%= f.submit "Resend unlock instructions" %>
13 |
14 | <% end %>
15 |
16 | <%= render "devise/shared/links" %>
17 |
--------------------------------------------------------------------------------
/app/views/errors/internal_server_error.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
There has been a problem on our end.
8 |
If you can, tell us what you were doing when this
9 | happened
10 | to help us fix the problem.
11 |
Otherwise, try starting from our homepage.
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/views/errors/not_found.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Sorry, the page you are looking for doesn't exist.
8 |
If you followed a link to get here, please let us know.
9 |
10 |
Otherwise, try starting from our homepage.
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/views/layouts/_flash.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
<% if local_assigns[:link_to] %><%= body %><% else %><%= body %><% end %>
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= stylesheet_link_tag :email %>
5 |
6 |
7 | <%= yield %>
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/app/views/merged_with_markers/_merged_with_marker.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= merged_with_marker.body %>
5 |
6 |
7 |
8 | <%= merged_with_marker.send_at.strftime('%-m/%-d/%y, %-l:%M%P') %>
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/views/notification_mailer/message_notification.text.erb:
--------------------------------------------------------------------------------
1 | ClientComm
2 |
3 | <%= "#{@client.first_name} #{@client.last_name}" %> sent you a text message on <%= @message.created_at.strftime("%-m/%d") %>, at <%= @message.created_at.strftime("%-I:%M%p") %>:
4 |
5 | <% if @message.body.present? %>
6 | "<%= @message.body %>"
7 | <% end %>
8 |
9 | <%= '[Image attached, view on ClientComm]' if @message.attachments.present? %>
10 | <% rr = ReportingRelationship.find_by(client: @message.client, user: @message.user) %>
11 | Respond on ClientComm: <%= reporting_relationship_url(rr) %>
12 |
--------------------------------------------------------------------------------
/app/views/reporting_relationships/_scheduled_messages_link.html.erb:
--------------------------------------------------------------------------------
1 | <%= link_to(reporting_relationship_scheduled_messages_index_path(rr), class: 'scheduled-messages-bar') do %>
2 | <%= pluralize(count, 'message') %> scheduled
3 | <% end %>
4 |
--------------------------------------------------------------------------------
/app/views/scheduled_messages/index.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for(:template_name) { "messages" } %>
2 |
3 |
12 |
13 |
18 |
19 | <%= render "reporting_relationships/send_message_form", autofocus: false %>
20 |
21 | <%= render "scheduled_list_modal" %>
22 |
--------------------------------------------------------------------------------
/app/views/text_messages/_text_message.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <% text_message.body.each_line do |body_line| %>
5 | <%= body_line %>
6 | <% end %>
7 | <%= render text_message.attachments %>
8 |
9 |
10 | <%= render 'text_messages/text_message_status', text_message: text_message %>
11 |
12 |
--------------------------------------------------------------------------------
/app/views/text_messages/_text_message_status.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <% if text_message.twilio_status == 'undelivered' %>
3 | <%= t('message.status.undelivered') %>
4 | <% elsif text_message.twilio_status == 'blacklisted' %>
5 | <%= t('message.status.blacklisted') %>
6 | <% elsif [nil, 'queued', 'sent', 'sending'].include? text_message.twilio_status %>
7 | <%= t('message.status.sent') %>
8 | <% elsif text_message.twilio_status == 'maybe_undelivered' %>
9 | <%= t('message.status.maybe_undelivered') %>
10 | <% else %>
11 | <%= text_message.twilio_status %> <%= text_message.send_at.to_s(:message_timestamp) %>
12 | <% end %>
13 |
14 |
--------------------------------------------------------------------------------
/app/views/transfer_markers/_transfer_marker.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= transfer_marker.body %>
5 |
6 |
7 |
8 | <%= transfer_marker.send_at.strftime('%-m/%-d/%y, %-l:%M%P') %>
9 |
10 |
11 |
--------------------------------------------------------------------------------
/bin/brakeman:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Script for running Brakeman tests
4 | # Brakeman is a security scanner https://github.com/presidentbeef/brakeman.
5 |
6 | set -e
7 |
8 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9 |
10 | gem install brakeman -N
11 | brakeman --exit-on-warn .
12 |
--------------------------------------------------------------------------------
/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/bin/bundler-audit:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Script for running bundler-audit tests
4 | # bundler-audit is a gem vulnerability scanner
5 | # https://github.com/rubysec/bundler-audit
6 |
7 | set -e
8 |
9 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
10 |
11 | gem install bundler-audit -N
12 | bundle-audit check --update --ignore CVE-2018-1000544
13 |
--------------------------------------------------------------------------------
/bin/codeclimate:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6 |
7 | bundle exec codeclimate-test-reporter coverage/.resultset.json
8 |
--------------------------------------------------------------------------------
/bin/delayed_job:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
4 | require 'delayed/command'
5 | Delayed::Command.new(ARGV).daemonize
6 |
--------------------------------------------------------------------------------
/bin/pushit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 |
6 | git pull -r
7 | git rebase -i --exec 'git duet-commit --amend --reset-author'
8 |
9 | $script_dir/test
10 |
11 | git push
12 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../config/application', __dir__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/bin/rspec:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path('spring', __dir__)
4 | rescue LoadError => e
5 | raise unless e.message.include?('spring')
6 | end
7 |
8 | require 'pathname'
9 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
10 | Pathname.new(__FILE__).realpath)
11 |
12 | require 'rubygems'
13 | require 'bundler/setup'
14 |
15 | load Gem.bin_path('rspec-core', 'rspec')
16 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 | require 'fileutils'
4 | include FileUtils
5 |
6 | # path to your application root.
7 | APP_ROOT = Pathname.new File.expand_path('..', __dir__)
8 |
9 | def system!(*args)
10 | system(*args) || abort("\n== Command #{args} failed ==")
11 | end
12 |
13 | chdir APP_ROOT do
14 | # This script is a starting point to setup your application.
15 | # Add necessary setup steps to this file.
16 |
17 | puts '== Installing dependencies =='
18 | system! 'gem install bundler --conservative'
19 | system('bundle check') || system!('bundle install')
20 |
21 | # Install JavaScript dependencies if using Yarn
22 | # system('bin/yarn')
23 |
24 | # puts "\n== Copying sample files =="
25 | # unless File.exist?('config/database.yml')
26 | # cp 'config/database.yml.sample', 'config/database.yml'
27 | # end
28 |
29 | puts "\n== Preparing database =="
30 | system! 'bin/rails db:setup'
31 |
32 | puts "\n== Removing old logs and tempfiles =="
33 | system! 'bin/rails log:clear tmp:clear'
34 |
35 | puts "\n== Restarting application server =="
36 | system! 'bin/rails restart'
37 | end
38 |
--------------------------------------------------------------------------------
/bin/spring:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | # This file loads spring without using Bundler, in order to be fast.
4 | # It gets overwritten when you run the `spring binstub` command.
5 |
6 | unless defined?(Spring)
7 | require 'rubygems'
8 | require 'bundler'
9 |
10 | lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
11 | spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
12 | if spring
13 | Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
14 | gem 'spring', spring.version
15 | require 'spring/binstub'
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/bin/test:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6 |
7 | RAILS_ENV=test bundle exec rspec $@
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/bin/update:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require 'pathname'
3 | require 'fileutils'
4 | include FileUtils
5 |
6 | # path to your application root.
7 | APP_ROOT = Pathname.new File.expand_path('..', __dir__)
8 |
9 | def system!(*args)
10 | system(*args) || abort("\n== Command #{args} failed ==")
11 | end
12 |
13 | chdir APP_ROOT do
14 | # This script is a way to update your development environment automatically.
15 | # Add necessary update steps to this file.
16 |
17 | puts '== Installing dependencies =='
18 | system! 'gem install bundler --conservative'
19 | system('bundle check') || system!('bundle install')
20 |
21 | puts "\n== Updating database =="
22 | system! 'bin/rails db:migrate'
23 |
24 | puts "\n== Removing old logs and tempfiles =="
25 | system! 'bin/rails log:clear tmp:clear'
26 |
27 | puts "\n== Restarting application server =="
28 | system! 'bin/rails restart'
29 | end
30 |
--------------------------------------------------------------------------------
/bin/yarn:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | VENDOR_PATH = File.expand_path('..', __dir__)
3 | Dir.chdir(VENDOR_PATH) do
4 | begin
5 | exec "yarnpkg #{ARGV.join(" ")}"
6 | rescue Errno::ENOENT
7 | $stderr.puts 'Yarn executable was not detected in the system.'
8 | $stderr.puts 'Download Yarn at https://yarnpkg.com/en/docs/install'
9 | exit 1
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/co-authors:
--------------------------------------------------------------------------------
1 | Co-Authored-By: Mikela Clemmons
2 | Co-Authored-By: Zachary Auerbach
3 | Co-Authored-By: Tomas Apadoca
4 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative 'config/environment'
4 | require 'dotenv/load' if Rails.env.development?
5 |
6 | run Rails.application
7 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
2 |
3 | require 'bundler/setup' # Set up gems listed in the Gemfile.
4 | require 'bootsnap/setup'
5 |
--------------------------------------------------------------------------------
/config/cable.yml:
--------------------------------------------------------------------------------
1 | production: &default
2 | adapter: postgresql
3 |
4 | development:
5 | <<: *default
6 |
7 | staging:
8 | <<: *default
9 |
10 | test:
11 | adapter: test
12 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative 'application'
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # ApplicationController.renderer.defaults.merge!(
4 | # http_host: 'example.org',
5 | # https: false
6 | # )
7 |
--------------------------------------------------------------------------------
/config/initializers/assets.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Version of your assets, change this if you want to expire all your assets.
4 | Rails.application.config.assets.version = '1.0'
5 |
6 | # Add additional assets to the asset load path
7 | # Rails.application.config.assets.paths << Emoji.images_path
8 |
9 | # Precompile additional assets.
10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
11 | # Rails.application.config.assets.precompile += %w( search.js )
12 | Rails.application.config.assets.precompile += %w[email.scss]
13 | Rails.application.config.assets.precompile += %w[clients/edit.js clients/new.js mass_messages.js messages.js reporting_relationships/welcomes.js]
14 |
--------------------------------------------------------------------------------
/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/config/initializers/cloudwatch.rb:
--------------------------------------------------------------------------------
1 | CLOUD_WATCH = if ENV['AWS_SECRET_ACCESS_KEY']
2 | Aws::CloudWatch::Client.new(
3 | access_key_id: ENV['AWS_ACCESS_KEY_ID'],
4 | secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
5 | region: 'us-east-1'
6 | )
7 | else
8 | Aws::CloudWatch::Client.new(stub_responses: true)
9 | end
10 |
--------------------------------------------------------------------------------
/config/initializers/config.rb:
--------------------------------------------------------------------------------
1 | APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
2 |
--------------------------------------------------------------------------------
/config/initializers/cookies_serializer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Specify a serializer for the signed and encrypted cookie jars.
4 | # Valid options are :json, :marshal, and :hybrid.
5 | Rails.application.config.action_dispatch.cookies_serializer = :json
6 |
--------------------------------------------------------------------------------
/config/initializers/fake_twilio.rb:
--------------------------------------------------------------------------------
1 | if Rails.env.test?
2 | require File.expand_path(Rails.root.join('spec', 'fake_twilio_client'))
3 | Twilio::REST.send(:remove_const, :Client)
4 | Twilio::REST::Client = FakeTwilioClient
5 | end
6 |
--------------------------------------------------------------------------------
/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | Rails.application.config.filter_parameters += %i[
5 | body
6 | password
7 | ]
8 |
9 | Rails.application.config.filter_parameters << lambda do |param_name, value|
10 | value.gsub!(/.+/, '[FILTERED]') if %w[From To].include?(param_name) && value.respond_to?(:gsub!)
11 | end
12 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 | ActiveSupport::Inflector.inflections(:en) do |inflect|
18 | inflect.acronym 'CSV'
19 | end
20 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 |
--------------------------------------------------------------------------------
/config/initializers/mixpanel.rb:
--------------------------------------------------------------------------------
1 | mixpanel_token = ENV['MIXPANEL_TOKEN']
2 | return if mixpanel_token.nil?
3 |
4 | MIXPANEL_TRACKER = Mixpanel::Tracker.new(mixpanel_token)
5 | # silence local SSL errors
6 | if Rails.env.development?
7 | Mixpanel.config_http do |http|
8 | http.verify_mode = OpenSSL::SSL::VERIFY_NONE
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/config/initializers/new_framework_defaults.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 | #
3 | # This file contains migration options to ease your Rails 5.0 upgrade.
4 | #
5 | # Read the Rails 5.0 release notes for more info on each option.
6 |
7 | # Enable per-form CSRF tokens. Previous versions had false.
8 | Rails.application.config.action_controller.per_form_csrf_tokens = true
9 |
10 | # Enable origin-checking CSRF mitigation. Previous versions had false.
11 | Rails.application.config.action_controller.forgery_protection_origin_check = true
12 |
13 | # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
14 | # Previous versions had false.
15 | ActiveSupport.to_time_preserves_timezone = true
16 |
17 | # Require `belongs_to` associations by default. Previous versions had false.
18 | Rails.application.config.active_record.belongs_to_required_by_default = true
19 |
20 | # Configure SSL options to enable HSTS with subdomains. Previous versions had false.
21 | Rails.application.config.ssl_options = { hsts: { subdomains: true } }
22 |
--------------------------------------------------------------------------------
/config/initializers/new_framework_defaults_5_1.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 | #
3 | # This file contains migration options to ease your Rails 5.1 upgrade.
4 | #
5 | # Once upgraded flip defaults one by one to migrate to the new default.
6 | #
7 | # Read the Guide for Upgrading Ruby on Rails for more info on each option.
8 |
9 | # Make `form_with` generate non-remote forms.
10 | Rails.application.config.action_view.form_with_generates_remote_forms = false
11 |
12 | # Unknown asset fallback will return the path passed in when the given
13 | # asset is not present in the asset pipeline.
14 | # Rails.application.config.assets.unknown_asset_fallback = false
15 |
--------------------------------------------------------------------------------
/config/initializers/paperclip.rb:
--------------------------------------------------------------------------------
1 | Paperclip::UriAdapter.register
2 |
3 | Paperclip.options[:content_type_mappings] = {
4 | amr: 'application/octet-stream',
5 | '3gp': 'application/octet-stream'
6 | }
7 |
--------------------------------------------------------------------------------
/config/initializers/premailer_rails.rb:
--------------------------------------------------------------------------------
1 | Premailer::Rails.config[:line_length] = 180
2 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rails.application.config.session_store :cookie_store, key: '_clientcomm_session'
4 |
--------------------------------------------------------------------------------
/config/initializers/time_formats.rb:
--------------------------------------------------------------------------------
1 | Time::DATE_FORMATS[:message_timestamp] = '%-m/%-d/%y at %I:%M%P'
2 |
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/config/spring.rb:
--------------------------------------------------------------------------------
1 | %w(
2 | .ruby-version
3 | .rbenv-vars
4 | tmp/restart.txt
5 | tmp/caching-dev.txt
6 | ).each { |path| Spring.watch(path) }
7 |
--------------------------------------------------------------------------------
/db/migrate/20170511080820_create_clients.rb:
--------------------------------------------------------------------------------
1 | class CreateClients < ActiveRecord::Migration[5.0]
2 | def change
3 | create_table :clients do |t|
4 | t.string :first_name
5 | t.string :last_name
6 | t.datetime :birth_date
7 | t.string :phone_number
8 | t.boolean :active, default: true, null: false
9 |
10 | t.timestamps null: false
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/db/migrate/20170517213000_add_user_ref_to_clients.rb:
--------------------------------------------------------------------------------
1 | class AddUserRefToClients < ActiveRecord::Migration[5.0]
2 | def change
3 | add_reference :clients, :user, foreign_key: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170519034001_add_full_name_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddFullNameToUsers < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :users, :full_name, :string, default: ""
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170519215508_create_messages.rb:
--------------------------------------------------------------------------------
1 | class CreateMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | create_table :messages do |t|
4 | t.references :client, foreign_key: true
5 | t.references :user, foreign_key: true
6 | t.string :body, default: ""
7 | t.string :number_from, null: false
8 | t.string :number_to, null: false
9 | t.boolean :inbound, default: false, null: false
10 | t.string :twilio_sid
11 | t.string :twilio_status
12 |
13 | t.timestamps
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/db/migrate/20170523081015_add_index_to_messages.rb:
--------------------------------------------------------------------------------
1 | class AddIndexToMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | add_index :messages, :twilio_sid
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170608050028_add_read_to_messages.rb:
--------------------------------------------------------------------------------
1 | class AddReadToMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :messages, :read, :boolean, default: false
4 |
5 | # read defaults to false, but all messages that exist when the migration
6 | # happens should have read = true
7 | Message.update(read: true)
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20170619175734_create_attachments.rb:
--------------------------------------------------------------------------------
1 | class CreateAttachments < ActiveRecord::Migration[5.0]
2 | def change
3 | create_table :attachments do |t|
4 | t.string :url, null: false
5 | t.string :content_type
6 | t.references :message, foreign_key: true, null: false
7 | t.integer :height
8 | t.integer :width
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/db/migrate/20170706230335_add_send_date_to_messages.rb:
--------------------------------------------------------------------------------
1 | class AddSendDateToMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :messages, :send_date, :datetime
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170711222129_devise_invitable_add_to_users.rb:
--------------------------------------------------------------------------------
1 | class DeviseInvitableAddToUsers < ActiveRecord::Migration[5.0]
2 | def up
3 | change_table :users do |t|
4 | t.string :invitation_token
5 | t.datetime :invitation_created_at
6 | t.datetime :invitation_sent_at
7 | t.datetime :invitation_accepted_at
8 | t.integer :invitation_limit
9 | t.references :invited_by, polymorphic: true
10 | t.integer :invitations_count, default: 0
11 | t.index :invitations_count
12 | t.index :invitation_token, unique: true # for invitable
13 | t.index :invited_by_id
14 | end
15 | end
16 |
17 | def down
18 | change_table :users do |t|
19 | t.remove_references :invited_by, polymorphic: true
20 | t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/db/migrate/20170714175419_rename_send_date_to_send_at_in_messages.rb:
--------------------------------------------------------------------------------
1 | class RenameSendDateToSendAtInMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | rename_column :messages, :send_date, :send_at
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170718001857_remove_birth_date_from_clients.rb:
--------------------------------------------------------------------------------
1 | class RemoveBirthDateFromClients < ActiveRecord::Migration[5.0]
2 | def change
3 | remove_column :clients, :birth_date, :datetime
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170728173551_add_email_subscribe_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddEmailSubscribeToUser < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :users, :email_subscribe, :boolean, default: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170731233514_add_archived_to_client.rb:
--------------------------------------------------------------------------------
1 | class AddArchivedToClient < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :clients, :archived, :boolean, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170801221946_add_lock_version_to_messages.rb:
--------------------------------------------------------------------------------
1 | class AddLockVersionToMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :messages, :lock_version, :integer, default: 0
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170801222108_add_sent_to_messages.rb:
--------------------------------------------------------------------------------
1 | class AddSentToMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :messages, :sent, :boolean, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170803184914_set_send_at_on_messages.rb:
--------------------------------------------------------------------------------
1 | class SetSendAtOnMessages < ActiveRecord::Migration[5.0]
2 | def change
3 | Message.all.each do |message|
4 | message.update(send_at: message.created_at) if message.send_at.nil?
5 | end
6 |
7 | change_column :messages, :send_at, :datetime, null: false
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20170804173345_remove_archived_from_client.rb:
--------------------------------------------------------------------------------
1 | class RemoveArchivedFromClient < ActiveRecord::Migration[5.0]
2 | def change
3 | remove_column :clients, :archived, :boolean
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170815171039_create_active_admin_comments.rb:
--------------------------------------------------------------------------------
1 | class CreateActiveAdminComments < ActiveRecord::Migration::Current
2 | def self.up
3 | create_table :active_admin_comments do |t|
4 | t.string :namespace
5 | t.text :body
6 | t.references :resource, polymorphic: true
7 | t.references :author, polymorphic: true
8 | t.timestamps
9 | end
10 | add_index :active_admin_comments, [:namespace]
11 | end
12 |
13 | def self.down
14 | drop_table :active_admin_comments
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/db/migrate/20170823233745_add_notes_to_clients.rb:
--------------------------------------------------------------------------------
1 | class AddNotesToClients < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :clients, :notes, :text
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170901230857_add_last_contacted_at_to_clients.rb:
--------------------------------------------------------------------------------
1 | class AddLastContactedAtToClients < ActiveRecord::Migration[5.0]
2 | def up
3 | add_column :clients, :last_contacted_at, :datetime, null: false, default: -> { 'NOW()' }
4 | add_column :clients, :has_unread_messages, :boolean, null: false, default: false
5 | end
6 |
7 | def down
8 | remove_column :clients, :last_contacted_at
9 | remove_column :clients, :has_unread_messages
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/db/migrate/20170911173225_add_index_to_clients.rb:
--------------------------------------------------------------------------------
1 | class AddIndexToClients < ActiveRecord::Migration[5.0]
2 | def change
3 | add_index :clients, :phone_number, unique: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170911215234_add_active_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddActiveToUser < ActiveRecord::Migration[5.0]
2 | def change
3 | add_column :users, :active, :boolean, null: false, default: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170913221609_add_has_message_error_to_clients.rb:
--------------------------------------------------------------------------------
1 | class AddHasMessageErrorToClients < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :clients, :has_message_error, :boolean, default: false, null: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170920220501_make_last_contacted_at_nullable.rb:
--------------------------------------------------------------------------------
1 | class MakeLastContactedAtNullable < ActiveRecord::Migration[5.1]
2 | def up
3 | change_column :clients, :last_contacted_at, :datetime, null: true, default: nil
4 | end
5 |
6 | def down
7 | change_column :clients, :last_contacted_at, :datetime, null: false, default: -> { 'NOW()' }
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20170926210630_create_templates.rb:
--------------------------------------------------------------------------------
1 | class CreateTemplates < ActiveRecord::Migration[5.1]
2 | def up
3 | create_table :templates do |t|
4 | t.string :title
5 | t.text :body
6 | end
7 | end
8 |
9 | def down
10 | drop_table :templates
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20170926211409_add_templates_ref_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddTemplatesRefToUsers < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :templates, :user, foreign_key: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20170929175554_add_feature_flags_table.rb:
--------------------------------------------------------------------------------
1 | class AddFeatureFlagsTable < ActiveRecord::Migration[5.1]
2 | def up
3 | create_table :feature_flags do |t|
4 | t.string :flag
5 | t.boolean :enabled, null: false
6 | end
7 |
8 | FeatureFlag.create!(
9 | flag: "mass_messages",
10 | enabled: (ENV["MASS_MESSAGES"] == 'true')
11 | )
12 |
13 | FeatureFlag.create!(
14 | flag: "allow_signups",
15 | enabled: (ENV["ALLOW_SIGNUPS"] == 'true')
16 | )
17 |
18 | FeatureFlag.create!(
19 | flag: "templates",
20 | enabled: false
21 | )
22 | end
23 |
24 | def down
25 | drop_table :feature_flags
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/db/migrate/20171003212709_rename_attachment_to_legacy_attachment.rb:
--------------------------------------------------------------------------------
1 | class RenameAttachmentToLegacyAttachment < ActiveRecord::Migration[5.1]
2 | def change
3 | rename_table :attachments, :legacy_attachments
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20171003215315_create_paperclip_attachments.rb:
--------------------------------------------------------------------------------
1 | class CreatePaperclipAttachments < ActiveRecord::Migration[5.1]
2 | def self.up
3 | create_table :attachments do |t|
4 | t.references :message, foreign_key: true, null: false
5 | t.attachment :media
6 | end
7 | end
8 |
9 | def self.down
10 | drop_table :attachments
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20171004220005_migrate_old_attachments.rb:
--------------------------------------------------------------------------------
1 | class MigrateOldAttachments < ActiveRecord::Migration[5.1]
2 | def up
3 | LegacyAttachment.all.each do |old_attachment|
4 | new_attachment = Attachment.new
5 | new_attachment.media_remote_url = old_attachment.url
6 | new_attachment.message_id = old_attachment.message_id
7 | new_attachment.save!
8 | end
9 |
10 | drop_table :legacy_attachments
11 | end
12 |
13 | class LegacyAttachment < ApplicationRecord; end
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20171009214412_remove_devise_invitable.rb:
--------------------------------------------------------------------------------
1 | class RemoveDeviseInvitable < ActiveRecord::Migration[5.1]
2 | def up
3 | change_table :users do |t|
4 | t.remove_references :invited_by, polymorphic: true
5 | t.remove :invitations_count, :invitation_limit, :invitation_sent_at, :invitation_accepted_at, :invitation_token, :invitation_created_at
6 | end
7 | end
8 |
9 | def down
10 | change_table :users do |t|
11 | t.string :invitation_token
12 | t.datetime :invitation_created_at
13 | t.datetime :invitation_sent_at
14 | t.datetime :invitation_accepted_at
15 | t.integer :invitation_limit
16 | t.references :invited_by, polymorphic: true
17 | t.integer :invitations_count, default: 0
18 | t.index :invitations_count
19 | t.index :invitation_token, unique: true # for invitable
20 | t.index :invited_by_id
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/db/migrate/20171009234615_remove_signups.rb:
--------------------------------------------------------------------------------
1 | class RemoveSignups < ActiveRecord::Migration[5.1]
2 | def change
3 | flag = FeatureFlag.find_by(flag: 'allow_signups')
4 | flag.destroy if flag.present?
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/db/migrate/20171009235722_make_full_name_non_nullable.rb:
--------------------------------------------------------------------------------
1 | class MakeFullNameNonNullable < ActiveRecord::Migration[5.1]
2 | def up
3 | User.where(full_name: nil).each do |user|
4 | user.update!(full_name: user.email)
5 | end
6 |
7 | change_column :users, :full_name, :string, null: false, default: nil
8 | end
9 |
10 | def down
11 | change_column :users, :full_name, :string, null: true, default: ''
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/db/migrate/20171010185346_add_desk_phone_number_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddDeskPhoneNumberToUser < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :desk_phone_number, :string, null: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20171016161803_rename_user_desk_phone_number_to_phone_number.rb:
--------------------------------------------------------------------------------
1 | class RenameUserDeskPhoneNumberToPhoneNumber < ActiveRecord::Migration[5.1]
2 | def change
3 | rename_column :users, :desk_phone_number, :phone_number
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20171016173705_add_unclaimed_user_to_unclaimed_clients.rb:
--------------------------------------------------------------------------------
1 | class AddUnclaimedUserToUnclaimedClients < ActiveRecord::Migration[5.1]
2 | def change
3 | Client.where(user_id: nil).each do |client|
4 | User.find_by(email: ENV['UNCLAIMED_EMAIL']).clients << client
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20171017184404_add_client_statuses_table.rb:
--------------------------------------------------------------------------------
1 | class AddClientStatusesTable < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :client_statuses do |t|
4 | t.string :name, null: false
5 | end
6 |
7 | add_reference :clients, :client_status, foreign_key: true
8 | end
9 | end
10 |
11 | class ClientStatus < ApplicationRecord
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20171020012824_add_follup_up_date_to_client_statuses.rb:
--------------------------------------------------------------------------------
1 | class AddFollupUpDateToClientStatuses < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :client_statuses, :followup_date, :integer
4 | ClientStatus.reset_column_information
5 |
6 | active_status = ClientStatus.find_by(name: 'Active')
7 | active_status.update!(followup_date: 25) if active_status
8 |
9 | training_status = ClientStatus.find_by(name: 'Training')
10 | training_status.update!(followup_date: 25) if training_status
11 |
12 | exited_status = ClientStatus.find_by(name: 'Exited')
13 | exited_status.update!(followup_date: 85) if exited_status
14 |
15 | change_column_null :client_statuses, :followup_date, false
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/db/migrate/20171021000847_rename_email_subscribe_to_message_notification_emails.rb:
--------------------------------------------------------------------------------
1 | class RenameEmailSubscribeToMessageNotificationEmails < ActiveRecord::Migration[5.1]
2 | def change
3 | rename_column :users, :email_subscribe, :message_notification_emails
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20171030170455_create_departments.rb:
--------------------------------------------------------------------------------
1 | class CreateDepartments < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :departments do |t|
4 | t.string :name
5 | t.string :phone_number
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20171030170543_add_departments_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddDepartmentsToUsers < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :users, :department, foreign_key: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20171031180320_create_reporting_relationships.rb:
--------------------------------------------------------------------------------
1 | class CreateReportingRelationships < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :reporting_relationships do |t|
4 | t.references :user, foreign_key: true
5 | t.references :client, foreign_key: true
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20171101221037_add_active_to_reporting_relationship.rb:
--------------------------------------------------------------------------------
1 | class AddActiveToReportingRelationship < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :reporting_relationships, :active, :boolean, default: true, null: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20171107212003_move_active_from_clients_to_reporting_relationships.rb:
--------------------------------------------------------------------------------
1 | class MoveActiveFromClientsToReportingRelationships < ActiveRecord::Migration[5.1]
2 | def up
3 | Client.all.find_each do |client|
4 | ReportingRelationship.find_or_create_by(
5 | user_id: client['user_id'],
6 | client: client
7 | ) do |rr|
8 | rr.active = client[:active]
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20171109222018_add_user_to_department.rb:
--------------------------------------------------------------------------------
1 | class AddUserToDepartment < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :departments, :user, foreign_key: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20171129184319_add_metadata_values_to_reporting_relationship.rb:
--------------------------------------------------------------------------------
1 | class AddMetadataValuesToReportingRelationship < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :reporting_relationships, :notes, :text
4 | add_column :reporting_relationships, :last_contacted_at, :datetime
5 | add_column :reporting_relationships, :has_unread_messages, :boolean, default: false, null: false
6 | add_column :reporting_relationships, :has_message_error, :boolean, default: false, null: false
7 | add_reference :reporting_relationships, :client_status, foreign_key: true
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20180105005217_create_survey_questions.rb:
--------------------------------------------------------------------------------
1 | class CreateSurveyQuestions < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :survey_questions do |t|
4 | t.text :text
5 |
6 | t.timestamps
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20180105005654_create_survey_responses.rb:
--------------------------------------------------------------------------------
1 | class CreateSurveyResponses < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :survey_responses do |t|
4 | t.text :text
5 | t.references :survey_question, foreign_key: true
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20180105010123_create_surveys.rb:
--------------------------------------------------------------------------------
1 | class CreateSurveys < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :surveys do |t|
4 | t.references :client, foreign_key: true
5 | t.references :user, foreign_key: true
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20180105182759_create_survey_response_links.rb:
--------------------------------------------------------------------------------
1 | class CreateSurveyResponseLinks < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :survey_response_links do |t|
4 | t.references :survey, foreign_key: true
5 | t.references :survey_response, foreign_key: true
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20180112232629_remove_columns_from_client.rb:
--------------------------------------------------------------------------------
1 | class RemoveColumnsFromClient < ActiveRecord::Migration[5.1]
2 | def change
3 | remove_column :clients, :notes, :text
4 | remove_reference :clients, :client_status, foreign_key: true
5 | remove_column :clients, :active, :boolean
6 | remove_column :clients, :has_message_error, :boolean
7 | remove_column :clients, :has_unread_messages, :boolean
8 | remove_column :clients, :last_contacted_at, :datetime
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20180201222656_add_last_twilio_update_to_message.rb:
--------------------------------------------------------------------------------
1 | class AddLastTwilioUpdateToMessage < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :messages, :last_twilio_update, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180206221711_add_transfer_marker_to_messages.rb:
--------------------------------------------------------------------------------
1 | class AddTransferMarkerToMessages < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :messages, :transfer_marker, :bool, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180209191924_create_reports.rb:
--------------------------------------------------------------------------------
1 | class CreateReports < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :reports do |t|
4 | t.string :email, null: false
5 | t.references :department, foreign_key: true, null: false
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20180220183545_add_icon_color_to_client_status.rb:
--------------------------------------------------------------------------------
1 | class AddIconColorToClientStatus < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :client_statuses, :icon_color, :string, limit: 7
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180220194359_add_department_to_client_status.rb:
--------------------------------------------------------------------------------
1 | class AddDepartmentToClientStatus < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :client_statuses, :department, key: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180222191401_add_in_treatment_group_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddInTreatmentGroupToUsers < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :in_treatment_group, :boolean, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180222202720_remove_in_treatment_group_from_users.rb:
--------------------------------------------------------------------------------
1 | class RemoveInTreatmentGroupFromUsers < ActiveRecord::Migration[5.1]
2 | def change
3 | remove_column :users, :in_treatment_group, :boolean
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180228011744_make_followup_date_nullable_on_client_statuses.rb:
--------------------------------------------------------------------------------
1 | class MakeFollowupDateNullableOnClientStatuses < ActiveRecord::Migration[5.1]
2 | def change
3 | change_column_null :client_statuses, :followup_date, true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180305231922_add_autoreply_to_department.rb:
--------------------------------------------------------------------------------
1 | class AddAutoreplyToDepartment < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :departments, :unclaimed_response, :text
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180307215710_add_treatment_group_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddTreatmentGroupToUser < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :treatment_group, :text
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180311020035_change_user_treatment_group_to_string.rb:
--------------------------------------------------------------------------------
1 | class ChangeUserTreatmentGroupToString < ActiveRecord::Migration[5.1]
2 | def change
3 | change_column :users, :treatment_group, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180411193449_add_node_id_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddNodeIdToUser < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :node_id, :bigint
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180413174714_add_node_ids_to_client.rb:
--------------------------------------------------------------------------------
1 | class AddNodeIdsToClient < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :clients, :node_client_id, :bigint
4 | add_column :clients, :node_comm_id, :bigint
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/db/migrate/20180419203735_add_category_to_reporting_relationship.rb:
--------------------------------------------------------------------------------
1 | class AddCategoryToReportingRelationship < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :reporting_relationships, :category, :string, default: 'no_cat'
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180426170351_add_category_feature_flag.rb:
--------------------------------------------------------------------------------
1 | class AddCategoryFeatureFlag < ActiveRecord::Migration[5.1]
2 | def up
3 | FeatureFlag.create!(
4 | flag: 'categories',
5 | enabled: false
6 | )
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/db/migrate/20180507185215_add_like_message_to_message.rb:
--------------------------------------------------------------------------------
1 | class AddLikeMessageToMessage < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :messages, :like_message, foreign_key: { to_table: :messages }
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180516173227_add_id_number_to_clients.rb:
--------------------------------------------------------------------------------
1 | class AddIdNumberToClients < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :clients, :id_number, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180516175755_create_client_id_feature_flag.rb:
--------------------------------------------------------------------------------
1 | class CreateClientIdFeatureFlag < ActiveRecord::Migration[5.1]
2 | def up
3 | FeatureFlag.find_or_create_by(flag: 'client_id_number').update!(enabled: false)
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180516183029_create_hide_notes_feature_flag.rb:
--------------------------------------------------------------------------------
1 | class CreateHideNotesFeatureFlag < ActiveRecord::Migration[5.1]
2 | def up
3 | FeatureFlag.find_or_create_by(flag: 'hide_notes').update!(enabled: false)
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180518203229_create_court_date_csv.rb:
--------------------------------------------------------------------------------
1 | class CreateCourtDateCSV < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :court_date_csvs do |t|
4 | t.attachment :file
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20180605211155_add_admin_user_to_court_date_csv.rb:
--------------------------------------------------------------------------------
1 | class AddAdminUserToCourtDateCSV < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :court_date_csvs, :admin_user, foreign_key: { to_table: :admin_users }, null: false, default: 1
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180606182912_add_court_date_csv_to_message.rb:
--------------------------------------------------------------------------------
1 | class AddCourtDateCSVToMessage < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :messages, :court_date_csv, foreign_key: { to_table: :court_date_csvs }
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180608172907_make_to_and_from_nullable_on_message.rb:
--------------------------------------------------------------------------------
1 | class MakeToAndFromNullableOnMessage < ActiveRecord::Migration[5.1]
2 | def up
3 | change_column :messages, :number_to, :string, null: true
4 | change_column :messages, :number_from, :string, null: true
5 | end
6 |
7 | def down
8 | change_column :messages, :number_to, :string, null: false, default: '+15555555555'
9 | change_column :messages, :number_from, :string, null: false, default: '+15555555555'
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/db/migrate/20180613212947_add_court_date_to_client.rb:
--------------------------------------------------------------------------------
1 | class AddCourtDateToClient < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :clients, :next_court_date_at, :date, null: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180618172611_add_court_dates_feature_flag.rb:
--------------------------------------------------------------------------------
1 | class AddCourtDatesFeatureFlag < ActiveRecord::Migration[5.1]
2 | def up
3 | FeatureFlag.create!(
4 | flag: 'court_dates',
5 | enabled: false
6 | )
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/db/migrate/20180618234037_add_scheduled_message_count_feature_flag.rb:
--------------------------------------------------------------------------------
1 | class AddScheduledMessageCountFeatureFlag < ActiveRecord::Migration[5.1]
2 | def up
3 | FeatureFlag.create!(
4 | flag: 'scheduled_message_count',
5 | enabled: false
6 | )
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/db/migrate/20180620203710_add_next_court_date_set_by_user_to_client.rb:
--------------------------------------------------------------------------------
1 | class AddNextCourtDateSetByUserToClient < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :clients, :next_court_date_set_by_user, :boolean, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180626210517_add_user_client_index_to_reporting_relationship.rb:
--------------------------------------------------------------------------------
1 | class AddUserClientIndexToReportingRelationship < ActiveRecord::Migration[5.1]
2 | def change
3 | add_index :reporting_relationships, %i[client_id user_id]
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180627173300_remove_locking_from_messages.rb:
--------------------------------------------------------------------------------
1 | class RemoveLockingFromMessages < ActiveRecord::Migration[5.1]
2 | def change
3 | remove_column :messages, :lock_version, :integer
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180627210514_mark_inactive_messages_as_read.rb:
--------------------------------------------------------------------------------
1 | class Message < ApplicationRecord
2 | belongs_to :reporting_relationship, class_name: 'ReportingRelationship', foreign_key: 'reporting_relationship_id'
3 | end
4 |
5 | class ReportingRelationship < ApplicationRecord
6 | has_many :messages, dependent: :nullify
7 | end
8 |
9 | class MarkInactiveMessagesAsRead < ActiveRecord::Migration[5.1]
10 | def change
11 | msgs = Message.joins(:reporting_relationship).where(read: false, reporting_relationships: { active: false })
12 | msgs.update(read: true)
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20180628172800_add_dimensions_to_attachments.rb:
--------------------------------------------------------------------------------
1 | class Attachment < ApplicationRecord
2 | belongs_to :message
3 |
4 | has_attached_file :media
5 | validates_attachment_content_type :media, content_type: %r{video\/.*|audio\/.*|image\/.*|text\/.*|application\/pdf.*}
6 | serialize :dimensions, Array
7 |
8 | def image?
9 | media_content_type.match?(%r{image\/.*}) ? true : false
10 | end
11 | end
12 |
13 | class AddDimensionsToAttachments < ActiveRecord::Migration[5.1]
14 | def up
15 | add_column :attachments, :dimensions, :string
16 | Attachment.reset_column_information
17 | Attachment.find_each(batch_size: 50).with_index do |att, i|
18 | next unless att.image?
19 | path = "/tmp/#{i}"
20 | att.media.copy_to_local_file(:original, path)
21 | f = open(path)
22 | geometry = Paperclip::Geometry.from_file(f)
23 | att.dimensions = [geometry.width.to_i, geometry.height.to_i]
24 | att.save!
25 | end
26 | end
27 |
28 | def down
29 | remove_column :attachments, :dimensions, :string
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/db/migrate/20180703172919_create_change_image.rb:
--------------------------------------------------------------------------------
1 | class CreateChangeImage < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :change_images do |t|
4 | t.attachment :file
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/db/migrate/20180703180216_add_admin_user_to_change_image.rb:
--------------------------------------------------------------------------------
1 | class AddAdminUserToChangeImage < ActiveRecord::Migration[5.1]
2 | def change
3 | add_reference :change_images, :admin_user, foreign_key: { to_table: :admin_users }, null: false, default: 1
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180719184142_add_has_unread_messages_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddHasUnreadMessagesToUser < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :has_unread_messages, :boolean, default: false, null: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180724180654_add_cron_to_delayed_jobs.rb:
--------------------------------------------------------------------------------
1 | class AddCronToDelayedJobs < ActiveRecord::Migration[5.1]
2 | def self.up
3 | add_column :delayed_jobs, :cron, :string
4 | end
5 |
6 | def self.down
7 | remove_column :delayed_jobs, :cron
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20180730232332_add_index_to_messages_send_at.rb:
--------------------------------------------------------------------------------
1 | class AddIndexToMessagesSendAt < ActiveRecord::Migration[5.1]
2 | def change
3 | add_index :messages, :send_at
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180731175831_drop_active_admin_comments_table.rb:
--------------------------------------------------------------------------------
1 | class DropActiveAdminCommentsTable < ActiveRecord::Migration[5.1]
2 | def self.up
3 | drop_table :active_admin_comments
4 | end
5 |
6 | def self.down
7 | create_table :active_admin_comments do |t|
8 | t.string :namespace
9 | t.text :body
10 | t.references :resource, polymorphic: true
11 | t.references :author, polymorphic: true
12 | t.timestamps
13 | end
14 | add_index :active_admin_comments, [:namespace]
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/db/migrate/20180731212736_add_admin_flag_to_user.rb:
--------------------------------------------------------------------------------
1 | class AddAdminFlagToUser < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :users, :admin, :boolean, default: false
4 |
5 | User.where('email ILIKE ?', '%codeforamerica.org').each do |user|
6 | user.update!(admin: true)
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20180806183847_create_highlight_blobs.rb:
--------------------------------------------------------------------------------
1 | class CreateHighlightBlobs < ActiveRecord::Migration[5.1]
2 | def change
3 | create_table :highlight_blobs do |t|
4 | t.text :text
5 |
6 | t.timestamps
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20180813181128_drop_templates.rb:
--------------------------------------------------------------------------------
1 | class DropTemplates < ActiveRecord::Migration[5.1]
2 | def up
3 | drop_table :templates
4 | end
5 |
6 | def down
7 | create_table :templates do |t|
8 | t.string :title
9 | t.text :body
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20180816181102_remove_scheduled_message_jobs.rb:
--------------------------------------------------------------------------------
1 | class RemoveScheduledMessageJobs < ActiveRecord::Migration[5.1]
2 | def up
3 | Delayed::Job.where('handler ilike ?', '%ScheduledMessageJob%').destroy_all
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20180816222016_cleanup_message_history.rb:
--------------------------------------------------------------------------------
1 | class CleanupMessageHistory < ActiveRecord::Migration[5.1]
2 | def up
3 | # rubocop:disable Rails/SkipsModelValidations
4 | past_messages = TextMessage.where(sent: false).where(inbound: false).where('send_at < ?', Time.zone.now - 1.hour)
5 | past_messages.where.not(twilio_sid: nil).update_all(sent: true)
6 | past_messages.where(twilio_sid: nil).update_all(twilio_status: 'undelivered', sent: true)
7 | # rubocop:enable Rails/SkipsModelValidations
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20180921232040_add_active_to_survey_responses.rb:
--------------------------------------------------------------------------------
1 | class AddActiveToSurveyResponses < ActiveRecord::Migration[5.1]
2 | def change
3 | add_column :survey_responses, :active, :boolean, null: false, default: true
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/deploy/playbooks/inventories/cc-gwen/group_vars/all/vars:
--------------------------------------------------------------------------------
1 | primary_user:
2 | gwen
3 | users:
4 | - { name: gwen, comment: "Gwen Rino primary user", state: "present" }
5 | - { name: tomas, comment: "Tomas", state: "present" }
6 | - { name: zak, comment: "Zak", state: "present" }
7 | - { name: andrew, comment: "Andrew", state: "present" }
8 | - { name: mikela, comment: "Mikela Clemmons", state: "absent" }
9 |
--------------------------------------------------------------------------------
/deploy/playbooks/inventories/cc-gwen/hosts:
--------------------------------------------------------------------------------
1 | [data]
2 | ec2-54-224-241-222.compute-1.amazonaws.com
3 |
4 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/defaults/main.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/deploy/playbooks/roles/users/defaults/main.yml
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/andrew.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDQ3ckfbrWuJUxqDxdz4/+2aG7Wdq6dRLGk9vfx1GBTcUUf0k+/mRFIGfHHfHcQJtz1ByUN5LMcyUHxTEVcrab8OK8e/mRS3IZezFFyuMtCpW515m6y5rvyJ/VHTJxYPqPUWOLeBq8kGHnwt2dt8EU/ARvCAbj1AEto2jTpgOwURRSwEWJDmPsI6OvwU4k8MIe1a9Y3b20gLaWEBvf9IB+UEnULahQ4B4BfyHwhy9gY8ip49Ukr8gfqizCd4n7v3WmdJgu2Zs8o89FO8iwS0EtQMh9/V+otBtbwGdztpZH0/cAXf5kQWUkm+autS1cez7fKSVkuBkkMtMVhPVvUwoWWYYRCqhFAJwoZrAYK75DkD1V2PGucldVpwIYd9JsxIZJjq14X0v+sHbW/07okxA0gbFoe93j5VkN3rnJnmTUUq68FHbju/60LiwTR7fO0Ct2LXNX6ryJxFHjS0ucyqjgJlE6ZNN6X2lot2wai7S+T4k8g9raXMVeh4oIDJFgPu8LkGEuWdZFh9Fyqmmtvg8iOUH+8UZlcRqRLF+vDHfC3Qd7G856gNd0iAG+Q83fH7Yogux0beDmnSZ+EyvrG3N05PswKSxJeYW4uU5qgV5/tKDXJ1aQB85B0Fe1BCGvp+zQ/fi1n9Llpo0iENjymn0S56zJqjVrudGadcomNs/duUw== hyd415@gmail.com
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/andrewhyder.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDQ3ckfbrWuJUxqDxdz4/+2aG7Wdq6dRLGk9vfx1GBTcUUf0k+/mRFIGfHHfHcQJtz1ByUN5LMcyUHxTEVcrab8OK8e/mRS3IZezFFyuMtCpW515m6y5rvyJ/VHTJxYPqPUWOLeBq8kGHnwt2dt8EU/ARvCAbj1AEto2jTpgOwURRSwEWJDmPsI6OvwU4k8MIe1a9Y3b20gLaWEBvf9IB+UEnULahQ4B4BfyHwhy9gY8ip49Ukr8gfqizCd4n7v3WmdJgu2Zs8o89FO8iwS0EtQMh9/V+otBtbwGdztpZH0/cAXf5kQWUkm+autS1cez7fKSVkuBkkMtMVhPVvUwoWWYYRCqhFAJwoZrAYK75DkD1V2PGucldVpwIYd9JsxIZJjq14X0v+sHbW/07okxA0gbFoe93j5VkN3rnJnmTUUq68FHbju/60LiwTR7fO0Ct2LXNX6ryJxFHjS0ucyqjgJlE6ZNN6X2lot2wai7S+T4k8g9raXMVeh4oIDJFgPu8LkGEuWdZFh9Fyqmmtvg8iOUH+8UZlcRqRLF+vDHfC3Qd7G856gNd0iAG+Q83fH7Yogux0beDmnSZ+EyvrG3N05PswKSxJeYW4uU5qgV5/tKDXJ1aQB85B0Fe1BCGvp+zQ/fi1n9Llpo0iENjymn0S56zJqjVrudGadcomNs/duUw== hyd415@gmail.com
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/anule.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDWNSi25/rzu7PQTH4MVeCdqAQE3Jadu4yvReyU+jxtVdIR8JRCwFjm7mLvATj7i1Q1PPrAST6cxkM74a3syp0x8jPkJIPWsdHT3IQQNwtTdtQUGP+bVzuZpsj+EMxO8B2YZyEpBAU6EhSsfeKOqyZOv9Qy8a6bA46n22XFxHNZWhvg0sG+NgQIhUhhq+Ve6Ip9lVSjKQPBloZBq0jIZxfKNlRxnIEjAPIMJjG9hmvRrsESG0p3Bo5OMqkTpsKHn5VzNbcVVmVIQSh/Jj2mybMwda2X+yALf7il8qZa/icueYs4IaTP7DrKDe872Bv6tKWtJIRC+eIz/fHojWX+2F7A1NnNtd3liwu435aw0ERb1pHlmVj64muXylMpYA0aJZ3BOYJ7xh0BR/lV3ChojyjSwna0R09UdsyGbDZrg16ZE4hxbBiF9EeAn7Vr2TJeesvP1yaFfHI0QYgy964NCU2t/yj4Md3ob/gqGi3SwvJbVvscHfZcOUyJaWJJPGZTMIivhpecJ1ksP6G5FCmNkFIK2oDfswPLaC6yc9SyHoCIU/K/npE79Fy+0V3SLAbZlepa6EIiAoGxTouVVkRuM9OUZgP96d2Sm26BhF8vmCpZ8L70GoNv1UY5nyxnxfZRV+qsJ46IvEjh/FuZRS5HEoHsbCNF6OfPWE1EoOsBqm7xoQ== anule@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/ashcampo.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDWgTrDevp8kWduEu/Gee5vp8uSAyEBdcHop8crTXyRO5uytU4+o9rgCkbrpfJaIPxdiRmlX4ebvR+MQ+Hy9QqfiR9XZzqspyN9mxDC7mLA0pdymCHBs4xcvkFjl952gek9E5qhmfTwUQP8lk6kD1CzdTg5VB8seDnP8gRwn0+wlZOhbtaHA4YqO7tvTgFCppsuL/VUu4AFJFIwvW4DlVb2YY1BgbaZk0G9XPcz07VheaOnWMH4L7LECUffdf68+iyXyhEo6CY299Y0X7zvhoORFYEpl+eVcdHXeqoy1cSaaI98PQywkrYFFk6cpIf3AbLbHBJfh+6HE9jMW1wa8azslBn9HYeWr8v8xibolKFzaFov6t4F21/cqZUGd5H+2TRSpUrxvrPdBIblfd/JmXxQpGpqAv35GeiMzMZRahGPzYv9vgbsbRG26Ea4t+Jmkfl1YoEkctRCSyAG5865x9fs40qaHaKsgX8Fm4bj8jGQ8lEOovjzieN8DVJ8tBpryzDuUp4aIVnPI5FE3/x3WFCLdC/COrqVChiuC+rQirAmQnUX6ZGFR44j0ucTk1kG6KOcSsxaGKWgf01kFfSLqfBK2+K3X9tz9UbG3cfw2nRpay/GzJbl3MeZ7ZvUbsP+zKYB6YeE7UHJiK7vewSbWKRUL4SUz4z5cwSZs7EfEN1LcQ== acampo@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/bensheldon.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCgovrlBGJ9RuABh5kr2HWw4dPPKmhZ3GAm82dCK66T4cC1A3AE4u3G8n0Mky+ovbztH50tOTPx/GcGooBQzFwkHyIGO3EF4Jq5XBWbiVlz+yRYFIcthFeuBeY0GqdbJ/aVrzPeJD23MgxCJyZcDnsIlEVM6vP7AhGruYZcoZzl6Cnpsab0EljHXybpgrZ0GSsAUvAjnK0QdCiwesm+aQjEw+aFhFa7uh6gMTXa0yOhm7LKliC0COSCS3x7evm1IwRgK/5isJ3gB2wmJ6bpHXsq7ijbIHrrEElwY45M38davnsTi1bQnna2shRArmvdglKZXvl522/r7i1G27BRGi07CYjD3zVFxb2LEn5lFnyVy3Kqky4NCCT4UsNUqwsbrFpMyC3CGehafqFSgCo1mvn29CVNDhliNwQQCpIhLZlqqw7f3KaA3xiZhJ5h87f4/3e6TXM+8VgNcNZSL1yDoETses0IHVM+Yz/uhPdQ7E+gnhf9Ap/XeUZ7EmyeSa8St4kvNrJZLCw6uPl5luXx8jH4QFsOrhCZaUhG3tivpYY20NZu6CS83eT1TH6Lj3PQxxhKqe/seETzTODI8+cyvH3/zmYRkTvsMacBZAmM7WeA8eJKvlxSOOqr+nb8odktNYUwYv/RZuIVTRpX9yJz0DpjoBRRTl9Z4bqRnXaCZpA3w== ben@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/bgolder.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDhCQXFMrwmbm2XvEyUVSxoZsCtHXer2L62HtDJViDmjhw9j0Po8gYM/Bz8osVnH+0p3myds4eFp5itd35ugIw/6iKv5L7Cf2J3zj7OAwzGayCgNQ6jtDJN5e7l7rsFheTgRull9XlGOnqK5dAI1JTQkl47ftT5pSGGrlCy47rVFKM8ngWTb2XTr3VmpbxHS5AjXnkx1xfVNCwSvM9UInPE8MMk/aNLuMrlFF3+neJO6NeqJzRQcNbnm7nVDxUETv3S3cM3FxYYso3Sh7vQ371wCaal1WhZV4rBEAcgPR/G66RC3JJ0mXrSLlIGgBK9QiMyIgmQm1Sawd/pES3PbAQiqUI/bLA5HvhyLQeXnOZgSY4NdP0vSRzDSnBqL5EIxhXSaPyGgJXDeYHv/7t4qqIYwtBs+p9WMdvukbrKb6ciUfBQ3ZgVkDOF2T5/ORpGtjacxkm410FXbUze2J5r5inlkakEs4vwOYT8t3fgv7ug1nabsRk/GneBn/YQ0T6aDpdCyWnNmkAKYkoHG8AKmY+2WtMce0yGZvJJpM9Lt/taKhp91vG58F3UeqOhuMdWn7sQyLNCZZfEfs7O41m2++k1oshrgBDHqxAWIPs3FxeNS7sgpPYraX6RkvFrbHku2/2AlxE3tO5n7wssiyEHWI2AhClZ8f2Cy58yO5eES6Q3Vw== bgolder@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/eric.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC5BOJdNlPu1Pl+4PZSR5cAUDEo3EunjREmW/+Ha5xqlaAmGiWwmz9zsXMaXMMcOq22feA9J81bs8TrOcE1Xv1PTyiTzYmsvW7LmQWaLK9LKWTQQQA3PSI01hCtun8I8EQSE7mtid4CDHy03Xwk2n5oGyfDpmzujs/MeeTw8CtCW/IMhtfRCF+vYA8ssxClsVYrU0yvSnI9TTx5C6CHcqJ3tjwmxjvkatwI0oA1D5VhyayEu8igwKjOvliN11AHKFr81ufHWW1G/r6z7SD+sMDqmMQDi4ZiYV7yQnHdZ+b8fcwxabQ00ULFUnOmLLa/FvhrtS07odaQ0dZq4nnTVWGa4R5OXIvnTXIFswhDlTZxaGYcR+pEKj2zzt7/cdiNrBcTj5QKI7aLNuZLhiMp0hFwdVdSgHFxAmYDzn3f8hO5lzl4LdNqr8Vmn9gkZqfPvxRNFyJodv2EnYOV7xIhVjtb4ZXi2jZWZlt0QWH3nvtA89CpVg8/ryNVLSBxytbTvZKdhzf3ZbyZEd0+LKBJCs4rhC0as4O3Ssacc4iWT5RkBIcqwQHbehwVNP7aRcmpDUts5RNXJpcYSHKn20XOFrMSEaRg6dQ9LDVAsYOHqKizyn5blJYT4IeLiDmgakkX3jhIsh7pJJOulj4vU4y7Ml6/ZOEi9LrNFTKefUPy8zxGOw== eric@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/gwen.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDqVKEXP6NOU/iVdxZyy1tYqUDVuhj3eaodRX4GuB/JbSA3uiggvVs/qUjTvrm1KFSoS+vhqciRy4M3H4uzIqFKau3BL7UlqmwkP/NfpOYrEH90ye57a1Qmoa9QOFWGVDMODT8dqKk9nPlb+nVsTuTzJS01RsUmfnBfPVuqk8IwOrQvvbmgXLJZZHJ2mTly9pTAtAFGShJeRnkGR6PQrtDIENxqk8/8+wTfLoetN4baB4plsXi5XPNllNaKJARvIwSLFWbQHEQL4yiPVydY8p1ylcAaTF0WdtjIUbCEz3Rnl29tD4y+Y17KBT1PXmBM3nQJxTgoz2N4rYRys48rBcaNGP7a3LwbbVfFcqhM7Au8kWChGcZHHTSzZXYHwyiuRFPSpoW8ncfXnk1TH9Hx8EM3L8N9m2u79vWSu2vxHXIvdbLLvABVo5YPpLRKk89T+WMu+6E+pZRGw/DQVQKl609lH8niaccG8/1n4MLrk4G4gmliO90C8ln6jJKFhvObQ+fc3Hn8Z/BKlVVTSfYI2sZQPdow3De7Z0TQlMfVP9jYAX3PqI1zPN4y9IDVgjL3rT3PciQyMOrmtKoQWWLT7x3rR5LeXI40AevyG7A2CSeT/mwEaPRx47RXY4GY5pig7dKfSH0Q2sBjtFlfy46pE2Zt637QgmChCzf+jWb/Cz6BdQ== gwen@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/mikela.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAfsApsVvt+xfS2jo5ZeSZRc74g+5XI7SEBjojCj5WgdyMx62t059XNUJJXeSk2Zs94zV3pjuKN3PyDHvyIv354beJJVfykarcK+rLRxqQPiVWMIfCIN1JVsaJlz2WOMqsl4A9nh+WAsuQNIIAGCOqvcit3Hb5+qJeJ9mAnfEcuei4xdcaRsrc1kK7xV2tvcUPuxckkl+As3PgX5UR82ADyzZ/pCngsKX5it4xnATxTxAaO5Xy+mzAXMp5BHMyM6vad0QfKPFKRwONla/usvx9bLvGifowXD+Z3AlBMp4EggjfZeesq3XuXO2y4bKpExHLqr2m+fhofOqu/LtzR8ICUlRefZNbJEFf+SNq6Sv+2cRRqjSKqxQPHCFITO5omGgErzdV8evmvuGW5qIzPNiaybcqXaUOV/6WQF5sc3y0eckkDUb05cTkvY2pRI9EnWjzyY7IEBTzsAeFOG9a5vG74WYo3wt4y2dr2HIXViko9jbfq0++4Vl/5n6d7aM8HO3Njt8ermbYx8bU/H/AiICS3a65Ymj6xe1SWAy3TBlvRJOognOCVylmi+WE0n3wRfGCCfTZRr8PJZy9QLzvJsqr1jqZzayIak45naqNsLhbFoHc7AZjpC/aMiF8U21GR5DA7UQGOzLNkQRK+xuTHKW7VQMLEnnKyw8PjmMwq8= mikela@yourstruly
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/tgrathwell.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCcwJAfXLzns/HjN62EHe8aleR0RPKequ50PnB4PN7tR5P6s5VLCEPhGh1qKY+xZVJoILB+Q6J+ZEuQdzn24HcWVvGd/shOeQ+Bu2CYAvRiVlXNlRVGjGQNTILt52ZAPtOgwUzge3ew4SaajBnRqiOa9SGWTro5jmEzf0nW+PDnKJvEyc+Bu7hriCIIPmc/SddvOIdA2kRJxKffVZV+kF6JF4ep1qff3E0ONl9AvjYs0PKmZ/jBI1mac13LimxGaiW0IAy9i4mSsDXOE5NrrPuAL8zWL0UMhaWUr8LOHKF3j5Abm+52TxbUtLlEIUa1nf+xUggqPx59WHnUkxt+SavXLaRY7SIDC74/mYW6YtjGNWMmJcNlN/Sgob6Qs4NSgtLpmfi/7h3gqoaBt9zQsS3imtiPuwXPFqPUYSAB5EqRU1lOCds7vFBnSgOJxWxQSh6POmWaqBWX6UbA2a1/GaYrA8cc9gDpLE9RLDAqOEwkL43N90wKrzLoqRKAHlMgL/gnU7XnrH21XTvrYBgCIMcRlM0CUV3ifd98EjPSj/EBM6RsD5/8d1B5HkiuAX1ie/aDVLKm392w40N09p0nBXINwMc3HN/tHeLmbq64ronZTeiNvTv5UvwdHPoUdw5SCL/cwEEZulMkNM/N9EbUWrQza3FPHD8O+i9mSqP4KKujBw== tgrathwell@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/tomas.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDH7E+Xd9Zk0vkj1aViSdHbfG8OEQ8PoRTEMgznuyCfGj2bUAqpw5LtVoN/TYpQ8pQdGi9GeCm6a5fiHY3RcgwOz7P+JZOwKf0FcUTnL/6ZDp2x4EoOp/e+2M+XtrXj4xEqMfq8tuKpjIqRB9/ptVnk2/q0ag+9+/ir/ZEAEPKw5TUxwgn6t6otVFlz3yiV+PNclkfOkJdU06wx61fFOGlcY54Y1JZ/kqb9Spx2ep3fee/bWWE1m4cQwCZCQ13bG2z6//90MKOd/viSkpDL6gT9YM7lE029TDFRCYdWUuMBEs+C0dwOcY8AADW+bDzftIPjvJyWrgzk5HzLCcO0tdDXIwnJ6YkKDCKLZ6r3jfSBJBKP7Phdz9Y54l5MwMLsRZ/hCKMX59D8Lv0lkOl0ZowPYvSGfW/QEsnlkMokR78qRcW/Iyj6Z4OGK432jUzNFwng17vFgBvazAiQKWy/hXXKcUPJeaKWwc1q4sdB0GVsPGUqAmkVSonOoJnrX630nP/WuDQE6Rw4dIm1ZUbES6KJ4zTU9u86/646ACRqUU26xR46kwDwO0mr1VtvTm054j9cGWqu58qOldvoHVY2QyRFf//SKuTCyZWcWtviC/UyGclhlvs1+hYWGa44HoMarCKjU8+DuQHt7nw4/YzKWGjtMHrGs5YnPoIDzvwH4Altaw== tomas@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/pubkeys/zak.pub:
--------------------------------------------------------------------------------
1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDlgG+Yepuof2fQwAQHK8Nc/fIddk3oTJTONXvGx0O0f3hKid31rsAPqM7+nIKYXL4fb9QVdWOyi0a/AquOms4yPFbDFFTKH/uCPaEAxu338lGtbuCEvvUMF48p5cZvXc0ELVOtag7VJ+RCTcyv2WOW8c7tZuyUM/IZjnq4KWVv25TtBOwmOxk0xiQop9Y1lMyS+VQSmSTUCoIc/lF6YRQ3t9yb5pMgQ5UKyPJupWxu1PTkOiO08+7DgOlRNpvv/LdyGnP6q5m5XQPXHKmpSQUKZ7hHmDYzUXrkhYBIm2sUiFITBaILUvJCCeNbAHJKU9X5mqw/BMchfVi7E0EHNNAD zak@codeforamerica.org
2 |
--------------------------------------------------------------------------------
/deploy/playbooks/roles/users/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: ensure that all members of sudo are nopasswd
3 | lineinfile: dest=/etc/sudoers.d/30-sudo_group owner=root group=root mode=0440 line="%sudo ALL=(ALL) NOPASSWD:ALL" state=present create=yes validate='visudo -cf %s'
4 | - name: "ensure users have an account"
5 | user:
6 | name: "{{ item.name }}"
7 | comment: "{{ item.comment }}"
8 | groups: admin,sudo
9 | update_password: on_create
10 | shell: /bin/bash
11 | remove: yes
12 | state: "{{ item.state }}"
13 | with_items:
14 | - "{{ users }}"
15 | - name: "ensure users have an authorized key"
16 | authorized_key:
17 | user: "{{ item.name }}"
18 | key: "{{ lookup('file', './pubkeys/' + item.name + '.pub') }}"
19 | state: "{{ item.state }}"
20 | when: item.state == "present"
21 | with_items:
22 | - "{{ users }}"
23 |
--------------------------------------------------------------------------------
/deploy/terraform/app/apply.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APPLY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 |
5 | terraform apply \
6 | -var-file=<(lpass show --notes "${1}") \
7 | ${APPLY_DIR}
8 |
--------------------------------------------------------------------------------
/deploy/terraform/app/plan.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APPLY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 |
5 | terraform plan \
6 | -var-file=<(lpass show --notes "${1}") \
7 | ${APPLY_DIR}
8 |
--------------------------------------------------------------------------------
/deploy/terraform/apply.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | terraform get
3 |
4 | APPLY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 |
6 | terraform apply \
7 | -var-file=<(lpass show --notes "${1}") \
8 | ${APPLY_DIR}
9 |
--------------------------------------------------------------------------------
/deploy/terraform/email/apply.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APPLY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 |
5 | terraform apply \
6 | -var-file=<(lpass show --notes "${1}") \
7 | ${APPLY_DIR}
8 |
9 |
--------------------------------------------------------------------------------
/deploy/terraform/email/plan.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APPLY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 |
5 | terraform plan \
6 | -var-file=<(lpass show --notes "${1}") \
7 | ${APPLY_DIR}
8 |
9 |
--------------------------------------------------------------------------------
/deploy/terraform/plan.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | terraform get
3 |
4 | APPLY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 |
6 | terraform plan \
7 | -var-file=<(lpass show --notes "${1}") \
8 | ${APPLY_DIR}
9 |
--------------------------------------------------------------------------------
/heroku_run_on_all_deploys:
--------------------------------------------------------------------------------
1 | command="echo '$1' |rails c"
2 | deploys=('try' 'demo' 'slco' '5cbc' 'danecrc' 'pima' 'baltimore' 'cccounty' 'georgiadcs' 'multco')
3 | for deploy in "${deploys[@]}"
4 | do
5 | heroku run $command --app clientcomm-$deploy
6 | done
7 |
--------------------------------------------------------------------------------
/lib/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/lib/assets/.keep
--------------------------------------------------------------------------------
/lib/scripts/copy_database:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | pg_dump $DATABASE_URL > /tmp/backup
4 | psql $MIGRATION_TEST_DATABASE_URL < /tmp/backup
5 |
--------------------------------------------------------------------------------
/lib/scripts/heroku_run_copy_database:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | heroku pg:reset --app clientcomm-migration-test --confirm clientcomm-migration-test
4 | heroku run ./lib/scripts/copy_database --app $1
5 |
--------------------------------------------------------------------------------
/lib/tasks/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/lib/tasks/.keep
--------------------------------------------------------------------------------
/lib/tasks/delayed_cron_job.rake:
--------------------------------------------------------------------------------
1 | namespace :delayed_cron_job do
2 | task reset: :environment do
3 | Delayed::Job.where.not(cron: nil).destroy_all
4 | DeadManSwitchJob.perform_later
5 | ScheduledMessageCronJob.set(cron: "*/#{APP_CONFIG['scheduled_message_rate']} * * * *").perform_later
6 | DeadManSwitchJob.set(cron: '* * * * *').perform_later
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/tasks/notes_to_id_number.rake:
--------------------------------------------------------------------------------
1 | namespace :migrations do
2 | task notes_to_id_number: :environment do
3 | rrs = ReportingRelationship.where.not(notes: [nil, ''])
4 | if rrs.pluck(:client_id).length != rrs.pluck(:client_id).uniq.length
5 | puts 'Warning conflicting RRS for a client'
6 | return
7 | end
8 | rrs.each do |rr|
9 | puts rr.notes
10 | ctrack = rr.notes.scan(/\d+/).first
11 | rr.client.update!(id_number: ctrack) if ctrack
12 | puts rr.client.id_number
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/tasks/reports.rake:
--------------------------------------------------------------------------------
1 | require 'csv'
2 |
3 | namespace :reports do
4 | task generate_and_send_reports: :environment do
5 | end_date = Time.zone.now
6 | if end_date.wday.to_s == ENV['REPORT_DAY']
7 | Department.all.each do |department|
8 | recipients = department.reports.pluck(:email)
9 | metrics = department.message_metrics(end_date)
10 | recipients.each do |recipient|
11 | NotificationMailer.report_usage(recipient, metrics, end_date.to_s)
12 | .deliver_later
13 | end
14 | end
15 | end
16 | end
17 |
18 | task long_messages: :environment do
19 | io = $stdout.dup
20 | CSV(io) do |csv|
21 | csv << %w[name email client id length send_at]
22 | Message.messages.where('length(body) > 1600').find_each do |msg|
23 | csv << [msg.user.full_name, msg.user.email, msg.client.full_name, msg.id, msg.body.length, msg.send_at.strftime('%Y-%m-%d %H:%M:%S %Z')]
24 | end
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/lib/tasks/surveys.rake:
--------------------------------------------------------------------------------
1 | namespace :surveys do
2 | task scheduled_messages: :environment do
3 | users = User.select('users.id, users.full_name, users.email, messages.send_at, left(messages.body, 20) as body')
4 | .joins(:messages).where("messages.send_at - messages.created_at > '1 hour'::interval")
5 | .where(messages: { send_at: (Time.zone.now - 48.hours)..(Time.zone.now - 24.hours) })
6 | .where(messages: { sent: true })
7 |
8 | users.each do |user|
9 | puts ''
10 | puts "#{user[:full_name]} <#{user[:email]}>"
11 | puts "message: #{user[:body]}..."
12 | puts "on: #{user[:send_at].in_time_zone(Time.zone).strftime('%A, %B %-d, %-l:%M%p; %Z')}"
13 | puts '################################'
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/clientcomm_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/clientcomm_01.png
--------------------------------------------------------------------------------
/public/clientcomm_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/clientcomm_02.png
--------------------------------------------------------------------------------
/public/clientcomm_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/clientcomm_03.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/favicon.ico
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/public/twilio_alert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/twilio_alert.png
--------------------------------------------------------------------------------
/public/twilio_deploy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/twilio_deploy.png
--------------------------------------------------------------------------------
/public/twilio_develop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/public/twilio_develop.png
--------------------------------------------------------------------------------
/release-tasks.sh:
--------------------------------------------------------------------------------
1 | rake db:migrate
2 | rake delayed_cron_job:reset
3 |
--------------------------------------------------------------------------------
/spec/channels/clients_channel_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe ClientsChannel, type: :channel do
4 | let(:user) { create :user }
5 |
6 | before do
7 | stub_connection current_user: user
8 | end
9 |
10 | it 'subscribes' do
11 | subscribe
12 |
13 | expect(subscription).to be_confirmed
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/channels/messages_channel_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe MessagesChannel, type: :channel do
4 | let(:user) { create :user }
5 | let(:client) { create :client, user: user }
6 |
7 | before do
8 | stub_connection current_user: user
9 | end
10 |
11 | subject { subscribe(client_id: client.id) }
12 |
13 | it 'subscribes' do
14 | subject
15 |
16 | expect(subscription).to be_confirmed
17 | end
18 |
19 | context 'accessing clients that do not belong to the current_user' do
20 | let(:user2) { create :user }
21 |
22 | before do
23 | stub_connection current_user: user2
24 | end
25 |
26 | it 'rejects the subscription' do
27 | subject
28 |
29 | expect(subscription).to be_rejected
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/spec/channels/scheduled_messages_channel_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe ScheduledMessagesChannel, type: :channel do
4 | let(:user) { create :user }
5 | let(:client) { create :client, user: user }
6 |
7 | before do
8 | stub_connection current_user: user
9 | end
10 |
11 | subject { subscribe(client_id: client.id) }
12 |
13 | it 'subscribes' do
14 | subject
15 |
16 | expect(subscription).to be_confirmed
17 | end
18 |
19 | context 'accessing clients that do not belong to the current_user' do
20 | let(:user2) { create :user }
21 |
22 | before do
23 | stub_connection current_user: user2
24 | end
25 |
26 | it 'rejects the subscription' do
27 | subject
28 |
29 | expect(subscription).to be_rejected
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/spec/factories/attachments.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :attachment do
3 | message { build :text_message, inbound: true }
4 | media { Rack::Test::UploadedFile.new(Rails.root.join('spec', 'fixtures', 'fluffy_cat.jpg'), 'image/png') }
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/change_image.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :change_image do
3 | file { Rack::Test::UploadedFile.new(Rails.root.join('spec', 'fixtures', 'fluffy_cat.jpg'), 'image/png') }
4 | user { create :user }
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/client_edit_marker.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :client_edit_marker do
3 | reporting_relationship { create :reporting_relationship }
4 | body { "i am a client edit marker #{SecureRandom.hex(17)}" }
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/client_statuses.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :client_status do
3 | sequence(:name) { Faker::Lorem.unique.word }
4 | followup_date { nil }
5 | icon_color { "\##{SecureRandom.hex(3)}" }
6 | department do
7 | create :department
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/factories/conversation_ends_marker.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :conversation_ends_marker do
3 | reporting_relationship { create :reporting_relationship }
4 | body { "i am a 'conversation ends' marker #{SecureRandom.hex(17)}" }
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/court_date_csvs.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :court_date_csv do
3 | file { Rack::Test::UploadedFile.new(Rails.root.join('spec', 'fixtures', 'court_dates.csv'), 'text/csv') }
4 | user { create :user }
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/court_reminders.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :court_reminder do
3 | reporting_relationship { create :reporting_relationship }
4 | body { "i am a court reminder #{SecureRandom.hex(17)}" }
5 | court_date_csv { create :court_date_csv }
6 | send_at { Time.zone.now + 2.days }
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/spec/factories/departments.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :department do
3 | sequence(:name) { |n| "Department#{n}" }
4 | phone_number { "+1760555#{Faker::PhoneNumber.unique.subscriber_number}" }
5 |
6 | after(:create) do |dept, evaluator|
7 | unless evaluator.unclaimed_user
8 | dept.update!(unclaimed_user: create(:user, phone_number: nil, full_name: 'Unclaimed', department: dept))
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/factories/highlight_blobs.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :highlight_blob do
3 | text 'MyText'
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/factories/merged_with_marker.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :merged_with_marker do
3 | reporting_relationship { create :reporting_relationship }
4 | body { "i am a 'merged with' marker #{SecureRandom.hex(17)}" }
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/reporting_relationships.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :reporting_relationship do
3 | user { create :user }
4 | client { create :client }
5 | category { ReportingRelationship::CATEGORIES.keys.first }
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/factories/reports.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :report do
3 | email { Faker::Internet.unique.email }
4 | department nil
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/survey_questions.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :survey_question do
3 | text { Faker::Lorem.sentence }
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/factories/survey_response_links.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :survey_response_link do
3 | survey nil
4 | survey_response nil
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/survey_responses.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :survey_response do
3 | text { Faker::Lorem.sentence }
4 | survey_question nil
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/surveys.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :survey do
3 | client nil
4 | user nil
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/templates.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :template do
3 | user { create :user }
4 | sequence(:title) { Faker::Lorem.sentence(4, false, 0) }
5 | sequence(:body) { Faker::Lorem.sentence }
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/spec/factories/text_message.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :text_message do
3 | reporting_relationship { create :reporting_relationship }
4 | body { "i am a message #{SecureRandom.hex(17)}" }
5 | inbound { [true, false].sample }
6 | sequence(:twilio_sid) { |n| (n.to_s + SecureRandom.hex(17))[0..33] }
7 | twilio_status { inbound ? %w[receiving received].sample : %w[accepted queued sending sent delivered undelivered failed].sample }
8 | send_at { Time.current }
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/factories/transfer_marker.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :transfer_marker do
3 | reporting_relationship { create :reporting_relationship }
4 | body { "i am a transfer marker #{SecureRandom.hex(17)}" }
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/factories/users.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :user do
3 | email { Faker::Internet.unique.email }
4 | password { Faker::Internet.unique.password }
5 | full_name { Faker::Name.name }
6 | phone_number { "+1760555#{Faker::PhoneNumber.unique.subscriber_number}" }
7 |
8 | transient do
9 | dept_phone_number { "+1760555#{Faker::PhoneNumber.unique.subscriber_number}" }
10 | end
11 |
12 | department do
13 | create :department, phone_number: dept_phone_number
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/fake_twilio_client.rb:
--------------------------------------------------------------------------------
1 | require 'cgi'
2 |
3 | class FakeTwilioClient
4 | # source: https://robots.thoughtbot.com/testing-sms-interactions
5 | FakeResponse = Struct.new(:sid, :status)
6 |
7 | def initialize(_account_sid, _auth_token)
8 | self
9 | end
10 |
11 | def api
12 | self
13 | end
14 |
15 | def messages(_sid = nil)
16 | self
17 | end
18 |
19 | def num_media
20 | '0'
21 | end
22 |
23 | def media
24 | self
25 | end
26 |
27 | def list
28 | []
29 | end
30 |
31 | def account
32 | self
33 | end
34 |
35 | def fetch(_params = nil)
36 | self
37 | end
38 |
39 | def update(_params)
40 | nil
41 | end
42 |
43 | def lookups
44 | self
45 | end
46 |
47 | def v1
48 | self
49 | end
50 |
51 | def phone_numbers(phone_number)
52 | @phone_number = CGI.unescape(phone_number)
53 | self
54 | end
55 |
56 | def phone_number
57 | @phone_number
58 | end
59 |
60 | # rubocop:disable Lint/UnusedMethodArgument
61 | def create(**kwargs)
62 | FakeResponse.new(SecureRandom.hex(17), 'delivered')
63 | end
64 | # rubocop:enable Lint/UnusedMethodArgument
65 | end
66 |
--------------------------------------------------------------------------------
/spec/features/feature_flags_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | feature 'feature flags' do
4 | describe 'mass messages' do
5 | let(:myuser) { create :user }
6 |
7 | before do
8 | login_as(myuser, scope: :user)
9 | end
10 |
11 | context 'enabled' do
12 | before do
13 | FeatureFlag.create!(flag: 'mass_messages', enabled: true)
14 | end
15 |
16 | it 'shows mass messages button' do
17 | visit clients_path
18 | expect(page).to have_content 'Mass message'
19 | end
20 | end
21 |
22 | context 'disabled' do
23 | it 'does not show mass messages button' do
24 | visit clients_path
25 | expect(page).not_to have_content 'Mass message'
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/spec/features/user_sends_message_that_errors_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | feature 'receiving messages', active_job: true do
4 | let(:message_body) { 'You have an appointment tomorrow at 10am' }
5 | let(:client_1) { create :client, users: [myuser] }
6 | let(:myuser) { create :user }
7 | let(:rr) { myuser.reporting_relationships.find_by(client: client_1) }
8 |
9 | before do
10 | login_as(myuser, scope: :user)
11 | end
12 |
13 | scenario 'client has blacklisted messages from clientcomm', :js, active_job: true do
14 | step 'when the client has texted stop' do
15 | visit reporting_relationship_path(rr)
16 |
17 | error = Twilio::REST::RestError.new('Blacklisted', 21610, 403)
18 | expect_any_instance_of(FakeTwilioClient).to receive(:create).and_raise(error)
19 |
20 | fill_in 'Send a text message', with: message_body
21 |
22 | perform_enqueued_jobs do
23 | click_on 'send_message'
24 | expect(page).to have_content message_body
25 | expect(page).to have_css '.blacklisted', text: I18n.t('message.status.blacklisted')
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/spec/features/user_views_court_reminder_on_conversation_page_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | feature 'creating and editing scheduled messages', active_job: true do
4 | let(:userone) { create :user }
5 | let(:clientone) { create :client, user: userone }
6 | let(:rrone) { ReportingRelationship.find_by(client: clientone, user: userone) }
7 | let(:past_date) { Time.zone.now - 1.month }
8 | let!(:reminder) { create :court_reminder, reporting_relationship: rrone, send_at: past_date }
9 | scenario 'user views court reminder', :js do
10 | step 'when user logs in' do
11 | login_as(userone, scope: :user)
12 | end
13 |
14 | step 'when user goes to messages page' do
15 | visit reporting_relationship_path(rrone)
16 | expect(page).to have_content reminder.body
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/fixtures/bad_court_dates.csv:
--------------------------------------------------------------------------------
1 | ofndr_num,(expression),lname,crt_dt,crt_tm,crt_rm
2 | 111,1873D,BROCK, not 5/8/2018,8:30,37
3 | 202,1867J,SABRINA,5/16/2018,9:00,5
4 | 202,1868D,MISTY,5/8/2018,14:00,N45
5 | 321,1868D,BLAINE,5/8/2018,14:00,MH
6 | 867,1890J,NORMAN,5/22/2018,10:00,1
7 |
--------------------------------------------------------------------------------
/spec/fixtures/cat_contact.vcf:
--------------------------------------------------------------------------------
1 | BEGIN:VCARD
2 | N:Snowball;Lumpy;;Cat Contact;
3 | ADR;INTL;PARCEL;WORK:;;1 Main St.;Cat Town;Catafornia;11111;USA
4 | EMAIL;INTERNET:lumpy.snowball@gmail.com
5 | END:VCARD
6 |
--------------------------------------------------------------------------------
/spec/fixtures/court_dates.csv:
--------------------------------------------------------------------------------
1 | ofndr_num,(expression),lname,crt_dt,crt_tm,crt_rm
2 | 111,1873D,BROCK,5/8/2018,8:30,37
3 | 202,1867J,SABRINA,5/16/2018,9:00,5
4 | 202,1868D,MISTY,5/8/2018,14:00,N45
5 | 321,1868D,BLAINE,5/8/2018,14:00,MH
6 | 867,1890J,NORMAN,5/22/2018,10:00,1
7 |
--------------------------------------------------------------------------------
/spec/fixtures/court_locs.csv:
--------------------------------------------------------------------------------
1 | crt_loc_cd,crt_loc_desc,vld_flg
2 | 1873D,LITTLEROOT TOWN,Y
3 | 1867J,PEWTER CITY,Y
4 | 1868D,GOLDENROD COURT,Y
5 | 1890J,FORTREE JUSTICE,Y
6 |
--------------------------------------------------------------------------------
/spec/fixtures/fluffy_cat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/spec/fixtures/fluffy_cat.jpg
--------------------------------------------------------------------------------
/spec/fixtures/large_image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/spec/fixtures/large_image.jpg
--------------------------------------------------------------------------------
/spec/fixtures/test_import_one_client.csv:
--------------------------------------------------------------------------------
1 | last_name,first_name,phone_number,user
2 | McCatFace,Cat,12125556230,test@example.com
3 |
--------------------------------------------------------------------------------
/spec/fixtures/test_import_two_clients.csv:
--------------------------------------------------------------------------------
1 | last_name,first_name,phone_number,user
2 | McPersonFace,Person,14155553329,test@example.com
3 | McCatFace,Cat,12125556230,test@example.com
4 |
--------------------------------------------------------------------------------
/spec/javascripts/helpers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/spec/javascripts/helpers/.gitkeep
--------------------------------------------------------------------------------
/spec/lib/voice_service_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe VoiceService do
4 | describe '#generate_text_response' do
5 | it 'takes a string and responds with twiml' do
6 | response = subject.generate_text_response(message: 'Hello there')
7 | expect(response).to eq 'Hello there'
8 | end
9 | end
10 |
11 | describe '#dial_number' do
12 | it 'takes a phone number and responds with twiml to dial that number' do
13 | response = subject.dial_number(phone_number: '+12425551212')
14 | expect(response).to eq '+12425551212'
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/models/change_image_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe ChangeImage, type: :model do
4 | describe 'validations' do
5 | it { should belong_to :user }
6 |
7 | it {
8 | should validate_attachment_content_type(:file)
9 | .allowing('image/png')
10 | .rejecting('text/whatever')
11 | }
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/models/client_status_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe ClientStatus, type: :model do
4 | it { should belong_to :department }
5 | it { should validate_presence_of :name }
6 | it { should validate_presence_of :icon_color }
7 | end
8 |
--------------------------------------------------------------------------------
/spec/models/court_date_csv_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe CourtDateCSV, type: :model do
4 | describe 'validations' do
5 | it { should belong_to :user }
6 |
7 | it {
8 | should validate_attachment_content_type(:file)
9 | .allowing('text/csv')
10 | .rejecting('png/whatever')
11 | }
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/models/court_reminder_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe CourtReminder, type: :model do
4 | it { should belong_to :court_date_csv }
5 | # it { should validate_presence_of :court_date_csv }
6 | end
7 |
--------------------------------------------------------------------------------
/spec/models/highlight_blob_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe HighlightBlob, type: :model
4 |
--------------------------------------------------------------------------------
/spec/models/report_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Report, type: :model do
4 | it { should belong_to :department }
5 |
6 | describe 'validations' do
7 | it { should validate_presence_of :email }
8 | end
9 |
10 | describe 'users' do
11 | let(:department) { create :department }
12 | let(:active_users) { create_list :user, 5, department: department }
13 | let(:inactive_users) { create_list :user, 5, department: department, active: false }
14 | let(:report) { create :report, department: department }
15 |
16 | it 'returns active users' do
17 | active_users << department.unclaimed_user
18 | expect(report.users).to match_array(active_users)
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/models/survey_question_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe SurveyQuestion, type: :model do
4 | it { should have_many :survey_responses }
5 | end
6 |
--------------------------------------------------------------------------------
/spec/models/survey_response_link_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe SurveyResponseLink, type: :model do
4 | it { should belong_to :survey }
5 | it { should belong_to :survey_response }
6 | end
7 |
--------------------------------------------------------------------------------
/spec/models/survey_response_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe SurveyResponse, type: :model do
4 | it { should belong_to(:survey_question) }
5 | it { should have_many(:survey_response_links) }
6 | end
7 |
--------------------------------------------------------------------------------
/spec/models/survey_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Survey, type: :model do
4 | let!(:user) { create :user }
5 | let!(:client) { create :client, user: user }
6 | let!(:survey) { create :survey, user: user, client: client }
7 |
8 | it { should belong_to :user }
9 | it { should belong_to :client }
10 | it { should have_many(:survey_responses).through(:survey_response_links) }
11 |
12 | describe '#questions' do
13 | before do
14 | create_list :survey_question, 2 do |question|
15 | survey.survey_responses << create_list(:survey_response, 3, survey_question: question)
16 | end
17 | end
18 |
19 | it 'returns only the unique questions for the survey' do
20 | expect(survey.questions.count).to eq(2)
21 | expect(survey.questions).to contain_exactly(SurveyQuestion.first, SurveyQuestion.last)
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/requests/admin/department_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'Department', type: :request, active_job: true do
4 | let(:department_name) { 'Main' }
5 | let(:department_phone_number) { '+14155551212' }
6 | let(:admin_user) { create :user, admin: true }
7 |
8 | before do
9 | login_as admin_user
10 | end
11 |
12 | describe 'POST#create' do
13 | context 'with valid parameters' do
14 | it 'creates a department' do
15 | post admin_departments_path params: {
16 | department: {
17 | name: department_name,
18 | phone_number: department_phone_number
19 | }
20 | }
21 |
22 | new_department = Department.last
23 | expect(new_department.phone_number).to eq(department_phone_number)
24 | expect(new_department.name).to eq(department_name)
25 | end
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/spec/requests/help_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'Help requests', type: :request do
4 | context 'unauthenticated' do
5 | let(:help_link) { 'help me omg' }
6 |
7 | before do
8 | @help_link = ENV['HELP_LINK']
9 | ENV['HELP_LINK'] = help_link
10 | end
11 |
12 | after { ENV['HELP_LINK'] = @help_link }
13 |
14 | subject { get help_index_path }
15 |
16 | it 'redirects the user to the github help page' do
17 | subject
18 | expect_analytics_events_happened('help_page_click')
19 | expect(response).to redirect_to help_link
20 | end
21 |
22 | context 'no help page is set' do
23 | let(:help_link) { '' }
24 |
25 | it 'raises a 404 error' do
26 | expect { subject }.to raise_error(ActionController::RoutingError)
27 | end
28 | end
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/spec/requests/layout_request_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'Layouts', type: :request do
4 | describe 'Navigation bar' do
5 | context 'help link' do
6 | let(:help_link) { 'help me omg' }
7 |
8 | before do
9 | @help_link = ENV['HELP_LINK']
10 | ENV['HELP_LINK'] = help_link
11 |
12 | sign_in create :user
13 | end
14 |
15 | after { ENV['HELP_LINK'] = @help_link }
16 |
17 | subject { get root_path }
18 |
19 | it 'displays a help link' do
20 | subject
21 |
22 | expect(response.body).to include 'Help'
23 | end
24 |
25 | context 'there is no help link set' do
26 | let(:help_link) { nil }
27 |
28 | it 'does not display a help link' do
29 | subject
30 |
31 | expect(response.body).to_not include 'Help'
32 | end
33 | end
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/spec/requests/login_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'Root Paths', type: :request do
4 | subject { get root_path }
5 |
6 | context 'Unauthenticated' do
7 | it 'shows the login page' do
8 | subject
9 | expect(response.body).to include('Log in')
10 | end
11 | end
12 |
13 | context 'Disabled' do
14 | let(:inactive_user) { create :user, active: false }
15 |
16 | it 'shows the login page' do
17 | sign_in inactive_user
18 |
19 | subject
20 |
21 | expect(response.body).to include('Log in')
22 | expect(response.body).to include('Sorry, this account has been disabled.')
23 | end
24 | end
25 |
26 | context 'Authenticated' do
27 | let(:user) { create :user, dept_phone_number: '+12431551212' }
28 |
29 | it 'shows the clients index page' do
30 | sign_in user
31 |
32 | subject
33 |
34 | expect(response.body).to include('My clients')
35 | expect(response.body).to include('(243) 155-1212')
36 | end
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/spec/requests/messages_analytics_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'Tracking of message analytics events', type: :request do
4 | context 'GET#index' do
5 | it 'tracks a visit to the message index' do
6 | user = create :user
7 | sign_in user
8 | client = create :client, user: user
9 | rr = user.reporting_relationships.find_by(client: client)
10 | get reporting_relationship_path(rr)
11 | expect(response.code).to eq '200'
12 |
13 | expect_analytics_events('client_messages_view' => {
14 | 'client_id' => client.id,
15 | 'has_unread_messages' => false,
16 | 'hours_since_contact' => 0,
17 | 'messages_all_count' => 0,
18 | 'messages_received_count' => 0,
19 | 'messages_sent_count' => 0,
20 | 'messages_attachments_count' => 0
21 | })
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/requests/registrations_analytics_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'RegistrationsController', type: :request do
4 | describe 'GET#new' do
5 | it 'redirects to the sign in page' do
6 | get new_user_registration_path
7 | expect(response).to redirect_to '/users/sign_in'
8 | end
9 | end
10 |
11 | describe 'POST#create' do
12 | it 'redirects to the sign in page' do
13 | post user_registration_path
14 | expect(response).to redirect_to '/users/sign_in'
15 | expect(flash[:notice]).to include('Contact an administrator')
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/requests/sessions_analytics_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'Tracking of session analytics events', type: :request do
4 | context 'GET#new' do
5 | it 'tracks a visit to the log in page' do
6 | get new_user_session_path
7 | expect(response.code).to eq '200'
8 | expect_analytics_events_happened('login_view')
9 | end
10 | end
11 |
12 | context 'POST#resource' do
13 | it 'tracks a user successfully logging in' do
14 | userone = create :user
15 | sign_in userone
16 | expect_analytics_events_happened('login_success')
17 | end
18 |
19 | it 'tracks a user erroring when trying to log in' do
20 | # an unsaved user shouldn't be able to log in
21 | userone = build :user
22 | sign_in userone
23 | expect_analytics_events_happened('login_error')
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/spec/requests/welcomes_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | describe 'Reporting Relationship Welcome Requests', type: :request, active_job: true do
4 | include ActiveJob::TestHelper
5 |
6 | let(:user) { create :user }
7 | let!(:client) { create :client, user: user }
8 | let(:rr) { ReportingRelationship.find_by(user: user, client: client) }
9 |
10 | context 'unauthenticated' do
11 | it 'rejects unauthenticated user' do
12 | get new_reporting_relationship_welcome_path rr
13 | expect(response.code).to eq '302'
14 | expect(response).to redirect_to new_user_session_path
15 | end
16 | end
17 |
18 | context 'authenticated' do
19 | before do
20 | sign_in user
21 | end
22 |
23 | describe 'GET#new' do
24 | subject { get new_reporting_relationship_welcome_path(rr) }
25 |
26 | it 'tracks a visit to the welcome form' do
27 | subject
28 | expect(response.code).to eq '200'
29 | expect_analytics_events(
30 | 'welcome_prompt_view' => {
31 | 'client_id' => client.id
32 | }
33 | )
34 | end
35 | end
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/spec/support/active_job.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.include ActiveJob::TestHelper, active_job: true
3 |
4 | config.before(:each) do |example|
5 | next if example.metadata[:type] != :job || example.metadata[:active_job].blank?
6 | clear_enqueued_jobs
7 | clear_performed_jobs
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/support/database_cleaner.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.use_transactional_fixtures = false
3 |
4 | config.before(:suite) do
5 | DatabaseCleaner.clean_with(:truncation)
6 | end
7 |
8 | config.before(:each) do |example|
9 | DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction
10 | DatabaseCleaner.start
11 | end
12 |
13 | config.after(:each) do
14 | DatabaseCleaner.clean
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/spec/support/match_html.rb:
--------------------------------------------------------------------------------
1 | RSpec::Matchers.define :match_html do |expected|
2 | def clean_html(s)
3 | s = s.squish.gsub(/>(\s)+, '><')
4 | Nokogiri::HTML.fragment(s).to_xhtml(indent: 2, save_options: Nokogiri::XML::Node::SaveOptions::AS_HTML)
5 | end
6 |
7 | match do |actual|
8 | @actual = clean_html(actual)
9 | @expected = clean_html(expected)
10 | values_match? @expected, @actual
11 | end
12 |
13 | failure_message do |_actual|
14 | diff = RSpec::Support::Differ.new.diff_as_string(@actual, @expected)
15 | "HTML did not match.\nACTUAL:\n#{@actual}\n\nEXPECTED:\n#{@expected}\n\nDIFF:#{diff}"
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/support/request_helper.rb:
--------------------------------------------------------------------------------
1 | module RequestHelper
2 | def sign_in(user)
3 | post_params = { user: { email: user.email, password: user.password } }
4 | post user_session_path, params: post_params
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/support/responsive_helper.rb:
--------------------------------------------------------------------------------
1 | module ResponsiveHelper
2 | def resize_window_to_mobile
3 | resize_window_by([640, 480])
4 | end
5 |
6 | def resize_window_to_tablet
7 | resize_window_by([960, 640])
8 | end
9 |
10 | def resize_window_to_default
11 | resize_window_by([1024, 768])
12 | end
13 |
14 | private
15 |
16 | def resize_window_by(size)
17 | Capybara.page.driver.browser.manage.window.resize_to(size[0], size[1])
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/spec/support/wait_for_ajax.rb:
--------------------------------------------------------------------------------
1 | module WaitForAjax
2 | def wait_for_ajax
3 | wait_for 'all ajax requests to complete' do
4 | finished_all_ajax_requests?
5 | end
6 | end
7 |
8 | private
9 |
10 | def finished_all_ajax_requests?
11 | page.evaluate_script('window.$ !== undefined') &&
12 | page.evaluate_script('$.active').zero?
13 | end
14 | end
15 |
16 | RSpec.configure do |config|
17 | config.include WaitForAjax
18 | end
19 |
--------------------------------------------------------------------------------
/vendor/assets/javascripts/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/vendor/assets/javascripts/.keep
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codeforamerica/clientcomm-rails/3bb430ac6c323bb8d28b1407e769711fc9f4ea0f/vendor/assets/stylesheets/.keep
--------------------------------------------------------------------------------