├── log └── .keep ├── storage └── .keep ├── tmp └── .keep ├── vendor └── .keep ├── .ruby-version ├── lib ├── assets │ └── .keep ├── tasks │ ├── .keep │ ├── one_offs.rake │ ├── bundler_audit.rake │ └── alphabetize_columns.rake └── generators │ └── screen │ ├── anyone │ ├── templates │ │ ├── anyone │ │ │ ├── form_controller.template │ │ │ ├── form_model_spec.template │ │ │ ├── form_view.template │ │ │ ├── form_controller_spec.template │ │ │ └── form_model.template │ │ └── details │ │ │ ├── form_view.template │ │ │ ├── form_controller.template │ │ │ ├── form_model.template │ │ │ ├── form_controller_spec.template │ │ │ └── form_model_spec.template │ └── USAGE │ ├── templates │ ├── form_view.template │ ├── form_controller_spec.template │ ├── form_controller.template │ ├── form_model.template │ └── form_model_spec.template │ ├── USAGE │ └── screen_generator.rb ├── public ├── favicon.ico ├── apple-touch-icon.png ├── apple-touch-icon-precomposed.png └── robots.txt ├── app ├── assets │ ├── images │ │ ├── .keep │ │ ├── ad2.png │ │ ├── app.png │ │ ├── ak_id.png │ │ ├── globe.png │ │ ├── house.png │ │ ├── memo.png │ │ ├── proof.png │ │ ├── send.png │ │ ├── gen150.png │ │ ├── renewal.png │ │ ├── scanner.png │ │ ├── gen142iar.png │ │ ├── important.png │ │ ├── mel_daniella.jpg │ │ ├── direct_deposit.png │ │ ├── dollar-banknote.png │ │ ├── pregnant-woman.png │ │ ├── cfa_alaska_logos.png │ │ ├── verification-upload-icon.png │ │ └── emojis │ │ │ └── white-heavy-check-mark.svg │ ├── javascripts │ │ ├── channels │ │ │ └── .keep │ │ ├── templates │ │ │ ├── file_uploading.hbs │ │ │ └── uploaded_file_detail.hbs │ │ ├── cable.js │ │ └── application.js │ ├── config │ │ └── manifest.js │ └── stylesheets │ │ ├── overrides.scss │ │ ├── application.scss │ │ └── molecules │ │ └── _show-more.scss ├── models │ ├── concerns │ │ └── .keep │ ├── show_rules.rb │ ├── application_record.rb │ ├── navigator.rb │ └── interview.rb ├── controllers │ ├── concerns │ │ └── .keep │ ├── application_controller.rb │ ├── residency_controller.rb │ ├── client_details_controller.rb │ ├── which_program_controller.rb │ ├── fee_agent_details_controller.rb │ ├── other_information_controller.rb │ ├── add_id_verification_controller.rb │ ├── what_living_expenses_controller.rb │ ├── expenses_payment_details_controller.rb │ ├── important_confirmations_controller.rb │ ├── rights_and_responsibilities_controller.rb │ ├── anyone_tribe_controller.rb │ ├── quest_card_controller.rb │ ├── any_not_listed_controller.rb │ ├── lets_start_controller.rb │ ├── how_it_works_controller.rb │ ├── any_away_from_home_controller.rb │ ├── anyone_stopped_work_controller.rb │ ├── how_to_take_photos_controller.rb │ ├── important_details_controller.rb │ ├── anyone_filing_tax_return_controller.rb │ ├── attach_documents_signpost_controller.rb │ ├── needed_documents_signpost_controller.rb │ ├── anyone_convicted_drug_felony_controller.rb │ ├── cama_details_controller.rb │ ├── tribe_details_controller.rb │ ├── success_controller.rb │ ├── any_not_listed_names_controller.rb │ ├── stopped_work_details_controller.rb │ ├── any_away_from_home_names_controller.rb │ ├── citizen_controller.rb │ ├── filing_tax_return_details_controller.rb │ ├── convicted_drug_felony_details_controller.rb │ ├── interview_type_controller.rb │ ├── yes_no_forms_controller.rb │ ├── approved_for_disability_controller.rb │ ├── verification_guidance_controller.rb │ ├── pregnant_controller.rb │ ├── static_pages_controller.rb │ ├── parent_not_in_home_controller.rb │ ├── interim_assistance_controller.rb │ ├── want_direct_deposit_controller.rb │ ├── children_in_home_controller.rb │ └── admin │ │ ├── application_controller.rb │ │ └── interviews_controller.rb ├── views │ ├── layouts │ │ ├── mailer.text.erb │ │ ├── mailer.html.erb │ │ ├── confirmation.html.erb │ │ ├── application.html.erb │ │ ├── signpost.html.erb │ │ └── left_aligned.html.erb │ ├── fields │ │ ├── download_link_field │ │ │ ├── _show.html.erb │ │ │ ├── _index.html.erb │ │ │ └── _form.html.erb │ │ └── date_time │ │ │ ├── _index.html.erb │ │ │ └── _show.html.erb │ ├── children_in_home │ │ └── edit.html.erb │ ├── quest_card │ │ └── edit.html.erb │ ├── anyone_tribe │ │ └── edit.html.erb │ ├── anyone_filing_tax_return │ │ └── edit.html.erb │ ├── pregnant │ │ └── edit.html.erb │ ├── shared │ │ ├── _next_step_link.html.erb │ │ ├── _how_it_works_step1.html.erb │ │ ├── _footer.html.erb │ │ ├── _header.html.erb │ │ ├── _how_it_works_step3.html.erb │ │ ├── _how_it_works_vertical.html.erb │ │ └── _how_it_works_step2.html.erb │ ├── how_it_works │ │ └── edit.html.erb │ ├── citizen │ │ └── edit.html.erb │ ├── anyone_convicted_drug_felony │ │ └── edit.html.erb │ ├── needed_documents_signpost │ │ └── edit.html.erb │ ├── parent_not_in_home │ │ └── edit.html.erb │ ├── approved_for_disability │ │ └── edit.html.erb │ ├── other_information │ │ └── edit.html.erb │ ├── cama_details │ │ └── edit.html.erb │ ├── any_away_from_home_names │ │ └── edit.html.erb │ ├── any_not_listed_names │ │ └── edit.html.erb │ ├── filing_tax_return_details │ │ └── edit.html.erb │ ├── lets_start │ │ └── edit.html.erb │ ├── want_direct_deposit │ │ └── edit.html.erb │ ├── any_away_from_home │ │ └── edit.html.erb │ ├── tribe_details │ │ └── edit.html.erb │ ├── success │ │ └── edit.html.erb │ ├── anyone_stopped_work │ │ └── edit.html.erb │ ├── fee_agent_details │ │ └── edit.html.erb │ ├── client_details │ │ └── edit.html.erb │ ├── forms │ │ └── index.html.erb │ ├── how_to_take_photos │ │ └── edit.html.erb │ ├── rights_and_responsibilities │ │ └── edit.html.erb │ ├── stopped_work_details │ │ └── edit.html.erb │ ├── attach_documents_signpost │ │ └── edit.html.erb │ ├── important_confirmations │ │ └── edit.html.erb │ ├── interim_assistance │ │ └── edit.html.erb │ ├── interview_type │ │ └── edit.html.erb │ ├── which_program │ │ └── edit.html.erb │ ├── residency │ │ └── edit.html.erb │ ├── convicted_drug_felony_details │ │ └── edit.html.erb │ ├── important_details │ │ └── edit.html.erb │ ├── expenses_payment_details │ │ └── edit.html.erb │ └── any_not_listed │ │ └── edit.html.erb ├── jobs │ └── application_job.rb ├── forms │ ├── null_form.rb │ ├── cama_details_form.rb │ ├── other_information_form.rb │ ├── want_direct_deposit_form.rb │ ├── tribe_details_form.rb │ ├── anyone_tribe_form.rb │ ├── stopped_work_details_form.rb │ ├── any_not_listed_names_form.rb │ ├── citizen_form.rb │ ├── pregnant_form.rb │ ├── any_away_from_home_names_form.rb │ ├── anyone_stopped_work_form.rb │ ├── expenses_payment_details_form.rb │ ├── quest_card_form.rb │ ├── any_not_listed_form.rb │ ├── filing_tax_return_details_form.rb │ ├── any_away_from_home_form.rb │ ├── anyone_filing_tax_return_form.rb │ ├── approved_for_disability_form.rb │ ├── children_in_home_form.rb │ ├── interim_assistance_form.rb │ ├── parent_not_in_home_form.rb │ ├── anyone_convicted_drug_felony_form.rb │ ├── rights_and_responsibilities_form.rb │ ├── interview_type_form.rb │ ├── important_confirmations_form.rb │ ├── add_id_verification_form.rb │ ├── which_program_form.rb │ ├── client_details_form.rb │ ├── attributes.rb │ ├── fee_agent_details_form.rb │ ├── residency_form.rb │ ├── convicted_drug_felony_details_form.rb │ └── what_living_expenses_form.rb ├── lib │ └── pdfs │ │ ├── FA1.pdf │ │ └── GEN 50C - Fillable.pdf ├── channels │ └── application_cable │ │ ├── channel.rb │ │ └── connection.rb ├── mailers │ └── application_mailer.rb ├── helpers │ ├── application_helper.rb │ └── credentials_helper.rb ├── fields │ └── download_link_field.rb ├── validators │ └── ten_digit_phone_number_validator.rb └── decorators │ └── verification_guidance_interview_decorator.rb ├── .rspec ├── Procfile ├── bin ├── release_tasks ├── bundle ├── rake ├── rails ├── yarn ├── spring ├── update ├── setup └── bin_helpers.rb ├── package.json ├── spec ├── support │ ├── factory_bot.rb │ ├── shared_examples │ │ ├── forms_controller_always_shows.rb │ │ ├── yes_no_forms_controller_with_enum_values.rb │ │ ├── yes_no_forms_controller_with_boolean_values.rb │ │ ├── forms_controller_unsuccessful_update.rb │ │ ├── forms_controller_successful_update.rb │ │ ├── forms_controller_base_behavior.rb │ │ └── anyone_form.rb │ └── pdf_helper.rb ├── fixtures │ ├── image.jpg │ ├── image2.jpg │ └── document.pdf ├── factories │ ├── navigator.rb │ └── interview.rb ├── forms │ ├── anyone_tribe_form_spec.rb │ ├── anyone_stopped_work_form_spec.rb │ ├── anyone_filing_tax_return_form_spec.rb │ ├── anyone_convicted_drug_felony_form_spec.rb │ ├── citizen_form_spec.rb │ ├── pregnant_form_spec.rb │ ├── children_in_home_form_spec.rb │ ├── parent_not_in_home_form_spec.rb │ ├── want_direct_deposit_form_spec.rb │ ├── any_not_listed_form_spec.rb │ ├── any_away_from_home_form_spec.rb │ ├── interim_assistance_form_spec.rb │ ├── other_information_form_spec.rb │ ├── cama_details_form_spec.rb │ ├── tribe_details_form_spec.rb │ ├── rights_and_responsibilities_form_spec.rb │ ├── any_not_listed_names_form_spec.rb │ ├── approved_for_disability_form_spec.rb │ ├── filing_tax_return_details_form_spec.rb │ └── stopped_work_details_form_spec.rb ├── controllers │ ├── how_it_works_controller_spec.rb │ ├── lets_start_controller_spec.rb │ ├── how_to_take_photos_controller_spec.rb │ ├── important_details_controller_spec.rb │ ├── success_controller_spec.rb │ ├── attach_documents_signpost_controller_spec.rb │ ├── needed_documents_signpost_controller_spec.rb │ ├── other_information_controller_spec.rb │ ├── citizen_controller_spec.rb │ ├── anyone_tribe_controller_spec.rb │ ├── quest_card_controller_spec.rb │ ├── any_not_listed_controller_spec.rb │ ├── any_away_from_home_controller_spec.rb │ ├── anyone_stopped_work_controller_spec.rb │ ├── what_living_expenses_controller_spec.rb │ ├── anyone_filing_tax_return_controller_spec.rb │ ├── rights_and_responsibilities_controller_spec.rb │ ├── anyone_convicted_drug_felony_controller_spec.rb │ ├── expenses_payment_details_controller_spec.rb │ ├── residency_controller_spec.rb │ ├── important_confirmations_controller_spec.rb │ ├── client_details_controller_spec.rb │ ├── fee_agent_details_controller_spec.rb │ ├── which_program_controller_spec.rb │ ├── static_pages_controller_spec.rb │ ├── any_away_from_home_names_controller_spec.rb │ ├── any_not_listed_names_controller_spec.rb │ ├── cama_details_controller_spec.rb │ ├── tribe_details_controller_spec.rb │ ├── approved_for_disability_controller_spec.rb │ ├── pregnant_controller_spec.rb │ ├── interim_assistance_controller_spec.rb │ ├── stopped_work_details_controller_spec.rb │ ├── filing_tax_return_details_controller_spec.rb │ ├── convicted_drug_felony_details_controller_spec.rb │ ├── parent_not_in_home_controller_spec.rb │ ├── verification_guidance_controller_spec.rb │ ├── want_direct_deposit_controller_spec.rb │ └── add_id_verification_controller_spec.rb ├── models │ └── show_rules_spec.rb ├── helpers │ └── application_helper_spec.rb └── features │ └── admin │ └── admin_dashboard_spec.rb ├── config ├── spring.rb ├── environment.rb ├── initializers │ ├── mime_types.rb │ ├── filter_parameter_logging.rb │ ├── lograge.rb │ ├── application_controller_renderer.rb │ ├── cookies_serializer.rb │ ├── backtrace_silencers.rb │ ├── wrap_parameters.rb │ ├── assets.rb │ ├── inflections.rb │ └── content_security_policy.rb ├── boot.rb ├── cable.yml ├── storage.yml ├── credentials.yml.enc ├── routes.rb ├── locales │ └── en.yml ├── application.rb └── puma.rb ├── config.ru ├── db ├── migrate │ ├── 20181214225739_add_other_info_to_interview.rb │ ├── 20181214223641_add_cama_details_to_interview.rb │ ├── 20181219224028_add_citizen_to_navigator.rb │ ├── 20181219234644_add_pregnant_to_navigator.rb │ ├── 20181214203147_add_expenses_payment_details.rb │ ├── 20181203183628_add_any_not_listed_to_interview.rb │ ├── 20181214171249_add_has_quest_card_to_interview.rb │ ├── 20181203223218_add_any_not_listed_names_to_interview.rb │ ├── 20181219232206_add_children_in_home_to_navigator.rb │ ├── 20181129020745_add_explained_rights_to_interview.rb │ ├── 20181204002341_add_any_away_from_home_to_interview.rb │ ├── 20181204004815_add_any_away_from_home_names_to_interview.rb │ ├── 20181220005252_add_parent_not_in_home_to_navigator.rb │ ├── 20181220234431_add_interim_assistance_to_navigator.rb │ ├── 20181221180854_add_want_direct_deposit_to_navigator.rb │ ├── 20181220231345_add_approved_for_disability_to_interview.rb │ ├── 20181212001148_add_tribe_to_interview.rb │ ├── 20181206201205_add_anyone_convicted_drug_felony_to_interview.rb │ ├── 20181214173701_add_tax_return.rb │ ├── 20181220002827_change_citizen_column_type.rb │ ├── 20181213214058_add_stopped_work_to_interview.rb │ ├── 20181121224900_add_fee_agent_fields_to_interview.rb │ ├── 20181206222204_add_residency_fields.rb │ ├── 20181214234524_add_important_confirmations_to_interview.rb │ ├── 20181122004152_add_client_details_to_interview.rb │ ├── 20181120172602_create_interviews_and_navigators.rb │ ├── 20181207183301_add_anyone_convicted_details_to_interview.rb │ ├── 20181127222200_add_selected_program_types_to_interview.rb │ ├── 20190123184639_create_active_storage_tables.active_storage.rb │ └── 20181217184940_add_living_expenses_to_interview.rb └── seeds.rb ├── Rakefile ├── .gitignore ├── LICENSE └── Gemfile /log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /storage/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tmp/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.5.3 -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/channels/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec rails server -p $PORT 2 | release: ./bin/release_tasks -------------------------------------------------------------------------------- /bin/release_tasks: -------------------------------------------------------------------------------- 1 | bundle exec rake db:migrate 2 | bundle exec rake one_offs:run_all 3 | -------------------------------------------------------------------------------- /app/views/fields/download_link_field/_show.html.erb: -------------------------------------------------------------------------------- 1 | <%= link_to("Download", field.to_s) %> 2 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | end 3 | -------------------------------------------------------------------------------- /app/models/show_rules.rb: -------------------------------------------------------------------------------- 1 | class ShowRules 2 | def self.defaults_to_true 3 | true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/forms/null_form.rb: -------------------------------------------------------------------------------- 1 | class NullForm < Form 2 | def self.existing_attributes(_) 3 | {} 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/lib/pdfs/FA1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/lib/pdfs/FA1.pdf -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alaska-fee-agent-assister", 3 | "private": true, 4 | "dependencies": {} 5 | } 6 | -------------------------------------------------------------------------------- /spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /app/controllers/residency_controller.rb: -------------------------------------------------------------------------------- 1 | class ResidencyController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /app/assets/images/ad2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/ad2.png -------------------------------------------------------------------------------- /app/assets/images/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/app.png -------------------------------------------------------------------------------- /spec/fixtures/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/spec/fixtures/image.jpg -------------------------------------------------------------------------------- /spec/fixtures/image2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/spec/fixtures/image2.jpg -------------------------------------------------------------------------------- /app/assets/images/ak_id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/ak_id.png -------------------------------------------------------------------------------- /app/assets/images/globe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/globe.png -------------------------------------------------------------------------------- /app/assets/images/house.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/house.png -------------------------------------------------------------------------------- /app/assets/images/memo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/memo.png -------------------------------------------------------------------------------- /app/assets/images/proof.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/proof.png -------------------------------------------------------------------------------- /app/assets/images/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/send.png -------------------------------------------------------------------------------- /app/controllers/client_details_controller.rb: -------------------------------------------------------------------------------- 1 | class ClientDetailsController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/controllers/which_program_controller.rb: -------------------------------------------------------------------------------- 1 | class WhichProgramController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /spec/fixtures/document.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/spec/fixtures/document.pdf -------------------------------------------------------------------------------- /app/assets/images/gen150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/gen150.png -------------------------------------------------------------------------------- /app/assets/images/renewal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/renewal.png -------------------------------------------------------------------------------- /app/assets/images/scanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/scanner.png -------------------------------------------------------------------------------- /app/channels/application_cable/channel.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Channel < ActionCable::Channel::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/fee_agent_details_controller.rb: -------------------------------------------------------------------------------- 1 | class FeeAgentDetailsController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/controllers/other_information_controller.rb: -------------------------------------------------------------------------------- 1 | class OtherInformationController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css 4 | -------------------------------------------------------------------------------- /app/assets/images/gen142iar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/gen142iar.png -------------------------------------------------------------------------------- /app/assets/images/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/important.png -------------------------------------------------------------------------------- /app/controllers/add_id_verification_controller.rb: -------------------------------------------------------------------------------- 1 | class AddIdVerificationController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/controllers/what_living_expenses_controller.rb: -------------------------------------------------------------------------------- 1 | class WhatLivingExpensesController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /spec/factories/navigator.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :navigator do 3 | interview_type { "application" } 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/images/mel_daniella.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/mel_daniella.jpg -------------------------------------------------------------------------------- /app/channels/application_cable/connection.rb: -------------------------------------------------------------------------------- 1 | module ApplicationCable 2 | class Connection < ActionCable::Connection::Base 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/lib/pdfs/GEN 50C - Fillable.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/lib/pdfs/GEN 50C - Fillable.pdf -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /app/assets/images/direct_deposit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/direct_deposit.png -------------------------------------------------------------------------------- /app/assets/images/dollar-banknote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/dollar-banknote.png -------------------------------------------------------------------------------- /app/assets/images/pregnant-woman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/pregnant-woman.png -------------------------------------------------------------------------------- /app/controllers/expenses_payment_details_controller.rb: -------------------------------------------------------------------------------- 1 | class ExpensesPaymentDetailsController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/controllers/important_confirmations_controller.rb: -------------------------------------------------------------------------------- 1 | class ImportantConfirmationsController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout "mailer" 4 | end 5 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/assets/images/cfa_alaska_logos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/cfa_alaska_logos.png -------------------------------------------------------------------------------- /app/controllers/rights_and_responsibilities_controller.rb: -------------------------------------------------------------------------------- 1 | class RightsAndResponsibilitiesController < FormsController 2 | layout "left_aligned" 3 | end 4 | -------------------------------------------------------------------------------- /app/views/children_in_home/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Are there any children who live in the home?".html_safe %> 2 | 3 | -------------------------------------------------------------------------------- /app/views/fields/download_link_field/_index.html.erb: -------------------------------------------------------------------------------- 1 | <%= link_to("Download", admin_interview_path(field.to_s, format: :pdf), class: "download-link") %> 2 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /app/controllers/anyone_tribe_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyoneTribeController < YesNoFormsController 2 | def yes_no_method_name 3 | :anyone_tribe 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/quest_card_controller.rb: -------------------------------------------------------------------------------- 1 | class QuestCardController < YesNoFormsController 2 | def yes_no_method_name 3 | :has_quest_card 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/quest_card/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Does the #{applicant_or_client} currently have an Alaska Quest Card?".html_safe %> 2 | -------------------------------------------------------------------------------- /spec/forms/anyone_tribe_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneTribeForm do 4 | it_behaves_like "anyone form", :anyone_tribe 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/images/verification-upload-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codeforamerica/alaska-fee-agent-assister/master/app/assets/images/verification-upload-icon.png -------------------------------------------------------------------------------- /app/controllers/any_not_listed_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyNotListedController < YesNoFormsController 2 | def yes_no_method_name 3 | :any_not_listed 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/lets_start_controller.rb: -------------------------------------------------------------------------------- 1 | class LetsStartController < FormsController 2 | layout "signpost" 3 | 4 | def form_class 5 | NullForm 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /app/controllers/how_it_works_controller.rb: -------------------------------------------------------------------------------- 1 | class HowItWorksController < FormsController 2 | layout "signpost" 3 | 4 | def form_class 5 | NullForm 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def format_phone_number(pn) 3 | "(#{pn[0..2]}) #{pn[3..5]}-#{pn[6..9]}" if pn.present? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/any_away_from_home_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyAwayFromHomeController < YesNoFormsController 2 | def yes_no_method_name 3 | :any_away_from_home 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/anyone_stopped_work_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyoneStoppedWorkController < YesNoFormsController 2 | def yes_no_method_name 3 | :anyone_stopped_work 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/how_to_take_photos_controller.rb: -------------------------------------------------------------------------------- 1 | class HowToTakePhotosController < FormsController 2 | layout "signpost" 3 | 4 | def form_class 5 | NullForm 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/controllers/important_details_controller.rb: -------------------------------------------------------------------------------- 1 | class ImportantDetailsController < FormsController 2 | layout "signpost" 3 | 4 | def form_class 5 | NullForm 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/fields/download_link_field.rb: -------------------------------------------------------------------------------- 1 | require "administrate/field/base" 2 | 3 | class DownloadLinkField < Administrate::Field::Base 4 | def to_s 5 | resource.id 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/anyone_tribe/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Is anyone on the #{application_or_renewal} a member of a federally recognized tribe?".html_safe %> 2 | -------------------------------------------------------------------------------- /spec/forms/anyone_stopped_work_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneStoppedWorkForm do 4 | it_behaves_like "anyone form", :anyone_stopped_work 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/anyone_filing_tax_return_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyoneFilingTaxReturnController < YesNoFormsController 2 | def yes_no_method_name 3 | :anyone_filing_tax_return 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/attach_documents_signpost_controller.rb: -------------------------------------------------------------------------------- 1 | class AttachDocumentsSignpostController < FormsController 2 | layout "signpost" 3 | 4 | def form_class 5 | NullForm 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/controllers/needed_documents_signpost_controller.rb: -------------------------------------------------------------------------------- 1 | class NeededDocumentsSignpostController < FormsController 2 | layout "signpost" 3 | 4 | def form_class 5 | NullForm 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/anyone_filing_tax_return/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Is anyone on the #{application_or_renewal} planning to file a Federal Income Tax Return?".html_safe %> 2 | -------------------------------------------------------------------------------- /spec/forms/anyone_filing_tax_return_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneFilingTaxReturnForm do 4 | it_behaves_like "anyone form", :anyone_filing_tax_return 5 | end 6 | -------------------------------------------------------------------------------- /app/forms/cama_details_form.rb: -------------------------------------------------------------------------------- 1 | class CamaDetailsForm < Form 2 | set_attributes_for :interview, :cama_details 3 | 4 | def save 5 | interview.update(attributes_for(:interview)) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /db/migrate/20181214225739_add_other_info_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddOtherInfoToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :other_info, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/anyone_convicted_drug_felony_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyoneConvictedDrugFelonyController < YesNoFormsController 2 | def yes_no_method_name 3 | :anyone_convicted_drug_felony 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/forms/other_information_form.rb: -------------------------------------------------------------------------------- 1 | class OtherInformationForm < Form 2 | set_attributes_for :interview, :other_info 3 | 4 | def save 5 | interview.update(attributes_for(:interview)) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20181214223641_add_cama_details_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddCamaDetailsToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :cama_details, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/forms/anyone_convicted_drug_felony_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneConvictedDrugFelonyForm do 4 | it_behaves_like "anyone form", :anyone_convicted_drug_felony 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181219224028_add_citizen_to_navigator.rb: -------------------------------------------------------------------------------- 1 | class AddCitizenToNavigator < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :navigators, :citizen, :integer, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181219234644_add_pregnant_to_navigator.rb: -------------------------------------------------------------------------------- 1 | class AddPregnantToNavigator < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :navigators, :pregnant, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/anyone/form_controller.template: -------------------------------------------------------------------------------- 1 | class <%= anyone_class_name %>Controller < YesNoFormsController 2 | def yes_no_method_name 3 | :<%= anyone_model_method %> 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/cama_details_controller.rb: -------------------------------------------------------------------------------- 1 | class CamaDetailsController < FormsController 2 | layout "left_aligned" 3 | 4 | def self.show_rule_sets(interview) 5 | super << interview.selected_cama? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/controllers/tribe_details_controller.rb: -------------------------------------------------------------------------------- 1 | class TribeDetailsController < FormsController 2 | layout "left_aligned" 3 | def self.show_rule_sets(interview) 4 | super << interview.anyone_tribe_yes? 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/views/fields/download_link_field/_form.html.erb: -------------------------------------------------------------------------------- 1 |
2 | <%= f.label field.attribute %> 3 |
4 |
5 | <%= f.text_field field.attribute %> 6 |
7 | -------------------------------------------------------------------------------- /db/migrate/20181214203147_add_expenses_payment_details.rb: -------------------------------------------------------------------------------- 1 | class AddExpensesPaymentDetails < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :expenses_payment_details, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/anyone/form_model_spec.template: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe <%= anyone_class_name %>Form do 4 | it_behaves_like "anyone form", :<%= anyone_model_method %> 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181203183628_add_any_not_listed_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddAnyNotListedToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :any_not_listed, :integer, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181214171249_add_has_quest_card_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddHasQuestCardToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :has_quest_card, :integer, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/success_controller.rb: -------------------------------------------------------------------------------- 1 | class SuccessController < FormsController 2 | layout "confirmation" 3 | 4 | def form_class 5 | NullForm 6 | end 7 | 8 | def next_path 9 | root_path 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/forms/want_direct_deposit_form.rb: -------------------------------------------------------------------------------- 1 | class WantDirectDepositForm < Form 2 | set_attributes_for :navigator, :want_direct_deposit 3 | 4 | def save 5 | interview.navigator.update(attributes_for(:navigator)) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /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" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /db/migrate/20181203223218_add_any_not_listed_names_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddAnyNotListedNamesToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :any_not_listed_names, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/anyone/form_view.template: -------------------------------------------------------------------------------- 1 | <%% content_for :card_title, "Template" %> 2 | 3 | <%% content_for :card_help, "Here's what you do" %> 4 | 5 | <%% content_for :card_body, "Any explanation here" %> 6 | -------------------------------------------------------------------------------- /spec/controllers/how_it_works_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe HowItWorksController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller always shows" 6 | end 7 | -------------------------------------------------------------------------------- /spec/controllers/lets_start_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe LetsStartController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller always shows" 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20181219232206_add_children_in_home_to_navigator.rb: -------------------------------------------------------------------------------- 1 | class AddChildrenInHomeToNavigator < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :navigators, :children_in_home, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/any_not_listed_names_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyNotListedNamesController < FormsController 2 | layout "left_aligned" 3 | 4 | def self.show_rule_sets(interview) 5 | super << interview.any_not_listed_yes? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/controllers/stopped_work_details_controller.rb: -------------------------------------------------------------------------------- 1 | class StoppedWorkDetailsController < FormsController 2 | layout "left_aligned" 3 | def self.show_rule_sets(interview) 4 | super << interview.anyone_stopped_work_yes? 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20181129020745_add_explained_rights_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddExplainedRightsToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :explained_rights, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181204002341_add_any_away_from_home_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddAnyAwayFromHomeToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :any_away_from_home, :integer, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181204004815_add_any_away_from_home_names_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddAnyAwayFromHomeNamesToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :any_away_from_home_names, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181220005252_add_parent_not_in_home_to_navigator.rb: -------------------------------------------------------------------------------- 1 | class AddParentNotInHomeToNavigator < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :navigators, :parent_not_in_home, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181220234431_add_interim_assistance_to_navigator.rb: -------------------------------------------------------------------------------- 1 | class AddInterimAssistanceToNavigator < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :navigators, :interim_assistance, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181221180854_add_want_direct_deposit_to_navigator.rb: -------------------------------------------------------------------------------- 1 | class AddWantDirectDepositToNavigator < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :navigators, :want_direct_deposit, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/controllers/how_to_take_photos_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe HowToTakePhotosController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller always shows" 6 | end 7 | -------------------------------------------------------------------------------- /spec/controllers/important_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ImportantDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller always shows" 6 | end 7 | -------------------------------------------------------------------------------- /spec/controllers/success_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe SuccessController do 4 | it_behaves_like "form controller base behavior", is_last_section: true 5 | it_behaves_like "form controller always shows" 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/any_away_from_home_names_controller.rb: -------------------------------------------------------------------------------- 1 | class AnyAwayFromHomeNamesController < FormsController 2 | layout "left_aligned" 3 | 4 | def self.show_rule_sets(interview) 5 | super << interview.any_away_from_home_yes? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/views/pregnant/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Is the #{application_or_renewal} for someone who is currently pregnant?" %> 2 | 3 | <% content_for :card_help, "If so, the #{applicant_or_client} will have to provide proof of pregnancy." %> 4 | -------------------------------------------------------------------------------- /app/views/shared/_next_step_link.html.erb: -------------------------------------------------------------------------------- 1 | 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 += [:password] 5 | -------------------------------------------------------------------------------- /app/controllers/citizen_controller.rb: -------------------------------------------------------------------------------- 1 | class CitizenController < YesNoFormsController 2 | def yes_no_method_name 3 | :citizen 4 | end 5 | 6 | def yes_value 7 | true 8 | end 9 | 10 | def no_value 11 | false 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/controllers/filing_tax_return_details_controller.rb: -------------------------------------------------------------------------------- 1 | class FilingTaxReturnDetailsController < FormsController 2 | layout "left_aligned" 3 | def self.show_rule_sets(interview) 4 | super << interview.anyone_filing_tax_return_yes? 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20181220231345_add_approved_for_disability_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddApprovedForDisabilityToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :approved_for_disability, :integer, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/how_it_works/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "How it works" %> 2 | 3 | <% content_for :card_body do %> 4 | <%= render "shared/how_it_works_vertical" %> 5 | <% end %> 6 | 7 | <% content_for :card_footer_button_label, "Let's get started" %> 8 | -------------------------------------------------------------------------------- /app/views/shared/_how_it_works_step1.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Conduct an interview.

3 |

We'll guide you through step by step and automatically fill out a digital fee agent interview form.

-------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | require_relative '../config/boot' 8 | require 'rake' 9 | Rake.application.run 10 | -------------------------------------------------------------------------------- /spec/controllers/attach_documents_signpost_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AttachDocumentsSignpostController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller always shows" 6 | end 7 | -------------------------------------------------------------------------------- /spec/controllers/needed_documents_signpost_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe NeededDocumentsSignpostController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller always shows" 6 | end 7 | -------------------------------------------------------------------------------- /spec/models/show_rules_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ShowRules do 4 | describe ".defaults_to_true" do 5 | it "always returns true" do 6 | expect(ShowRules.defaults_to_true).to be true 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20181212001148_add_tribe_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddTribeToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :anyone_tribe, :integer, default: 0 4 | add_column :interviews, :tribe_details, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/tasks/one_offs.rake: -------------------------------------------------------------------------------- 1 | # Place idempotent, one off execution things here so they get auto-ran on deploy 2 | namespace :one_offs do 3 | desc "runs all one_offs, remove things from here after they are deployed" 4 | task run_all: :environment do 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/convicted_drug_felony_details_controller.rb: -------------------------------------------------------------------------------- 1 | class ConvictedDrugFelonyDetailsController < FormsController 2 | layout "left_aligned" 3 | 4 | def self.show_rule_sets(interview) 5 | super << interview.anyone_convicted_drug_felony_yes? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: async 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: alaska-fee-agent-assister_production 11 | -------------------------------------------------------------------------------- /config/initializers/lograge.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | config.lograge.enabled = true 3 | 4 | config.lograge.custom_payload do |controller| 5 | { 6 | interview_id: controller.try(:current_interview).try(:id), 7 | } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20181206201205_add_anyone_convicted_drug_felony_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddAnyoneConvictedDrugFelonyToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :anyone_convicted_drug_felony, :integer, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20181214173701_add_tax_return.rb: -------------------------------------------------------------------------------- 1 | class AddTaxReturn < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :anyone_filing_tax_return, :integer, default: 0 4 | add_column :interviews, :filing_tax_return_details, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/interview_type_controller.rb: -------------------------------------------------------------------------------- 1 | class InterviewTypeController < FormsController 2 | layout "signpost" 3 | 4 | skip_before_action :ensure_interview 5 | 6 | def update_session 7 | session[:current_interview_id] = @form.interview.id 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20181220002827_change_citizen_column_type.rb: -------------------------------------------------------------------------------- 1 | class ChangeCitizenColumnType < ActiveRecord::Migration[5.2] 2 | def change 3 | remove_column :navigators, :citizen, :integer, default: 0 4 | add_column :navigators, :citizen, :boolean, default: false 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/views/citizen/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Is everyone on the #{application_or_renewal} a US citizen?".html_safe %> 2 | 3 | <% content_for :card_help, "If there are any non-citizens, they will need to provide proof of their immigration status." %> 4 | 5 | -------------------------------------------------------------------------------- /app/models/navigator.rb: -------------------------------------------------------------------------------- 1 | class Navigator < ApplicationRecord 2 | belongs_to :interview 3 | 4 | enum interview_type: { unfilled: 0, application: 1, renewal: 2 }, _prefix: :interview_type 5 | enum lived_outside_alaska: { unfilled: 0, yes: 1, no: 2 }, _prefix: :lived_outside_alaska 6 | end 7 | -------------------------------------------------------------------------------- /app/views/shared/_footer.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /db/migrate/20181213214058_add_stopped_work_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddStoppedWorkToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :anyone_stopped_work, :integer, default: 0 4 | add_column :interviews, :stopped_work_details, :text 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/yes_no_forms_controller.rb: -------------------------------------------------------------------------------- 1 | class YesNoFormsController < FormsController 2 | layout "yes_no" 3 | 4 | helper_method :yes_no_method_name, :yes_value, :no_value 5 | 6 | def yes_value 7 | "yes" 8 | end 9 | 10 | def no_value 11 | "no" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /app/controllers/approved_for_disability_controller.rb: -------------------------------------------------------------------------------- 1 | class ApprovedForDisabilityController < YesNoFormsController 2 | def self.show_rule_sets(interview) 3 | super << interview.selected_apa? 4 | end 5 | 6 | def yes_no_method_name 7 | :approved_for_disability 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/forms/tribe_details_form.rb: -------------------------------------------------------------------------------- 1 | class TribeDetailsForm < Form 2 | set_attributes_for :interview, :tribe_details 3 | 4 | validates_presence_of :tribe_details, message: "Make sure to include an answer." 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/javascripts/templates/file_uploading.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Uploading

5 |
6 |
7 |
8 |
-------------------------------------------------------------------------------- /app/controllers/verification_guidance_controller.rb: -------------------------------------------------------------------------------- 1 | class VerificationGuidanceController < FormsController 2 | layout "signpost" 3 | 4 | def edit 5 | @interview = VerificationGuidanceInterviewDecorator.new(current_interview) 6 | end 7 | 8 | def form_class 9 | NullForm 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/shared/_header.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | <%= link_to "Alaska Fee Agent Assister", root_path, class: "main-header__logo" %> 6 |

7 |
8 |
9 |
-------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path('../spring', __FILE__) 4 | rescue LoadError => e 5 | raise unless e.message.include?('spring') 6 | end 7 | APP_PATH = File.expand_path('../config/application', __dir__) 8 | require_relative '../config/boot' 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /lib/generators/screen/templates/form_view.template: -------------------------------------------------------------------------------- 1 | <%% content_for :card_title, "Template" %> 2 | 3 | <%% content_for :card_help, "Here's what you do" %> 4 | 5 | <%% content_for :card_body do %> 6 | <%%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 7 | <%% end %> 8 | <%% end %> 9 | -------------------------------------------------------------------------------- /app/forms/anyone_tribe_form.rb: -------------------------------------------------------------------------------- 1 | class AnyoneTribeForm < Form 2 | set_attributes_for :interview, :anyone_tribe 3 | 4 | validates_inclusion_of :anyone_tribe, { in: %w{yes no}, message: "Make sure to choose an option." } 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/forms/stopped_work_details_form.rb: -------------------------------------------------------------------------------- 1 | class StoppedWorkDetailsForm < Form 2 | set_attributes_for :interview, :stopped_work_details 3 | 4 | validates_presence_of :stopped_work_details, message: "Please include an answer." 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/views/anyone_convicted_drug_felony/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Has anyone on the #{application_or_renewal} been convicted of a drug-related felony?".html_safe %> 2 | 3 | <% content_for :card_body, "People with drug-related felonies can still be eligible if they meet certain conditions." %> 4 | -------------------------------------------------------------------------------- /app/forms/any_not_listed_names_form.rb: -------------------------------------------------------------------------------- 1 | class AnyNotListedNamesForm < Form 2 | set_attributes_for :interview, :any_not_listed_names 3 | 4 | validates_presence_of :any_not_listed_names, message: "Make sure to include an answer." 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/details/form_view.template: -------------------------------------------------------------------------------- 1 | <%% content_for :card_title, "Template" %> 2 | 3 | <%% content_for :card_help, "Here's what you do" %> 4 | 5 | <%% content_for :card_body do %> 6 | <%%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 7 | <%% end %> 8 | <%% end %> 9 | -------------------------------------------------------------------------------- /spec/support/shared_examples/forms_controller_always_shows.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.shared_examples_for "form controller always shows" do 4 | describe "show?" do 5 | it "is always true" do 6 | show_form = subject.class.show?(nil) 7 | expect(show_form).to eq(true) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/forms/citizen_form.rb: -------------------------------------------------------------------------------- 1 | class CitizenForm < Form 2 | set_attributes_for :navigator, :citizen 3 | 4 | def save 5 | interview.navigator.update(attributes_for(:navigator)) 6 | end 7 | 8 | def self.existing_attributes(interview) 9 | HashWithIndifferentAccess.new(interview.navigator.attributes) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/forms/pregnant_form.rb: -------------------------------------------------------------------------------- 1 | class PregnantForm < Form 2 | set_attributes_for :navigator, :pregnant 3 | 4 | def save 5 | interview.navigator.update(attributes_for(:navigator)) 6 | end 7 | 8 | def self.existing_attributes(interview) 9 | HashWithIndifferentAccess.new(interview.navigator.attributes) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/views/needed_documents_signpost/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Great! Now let's go through a few questions to see what other documents are needed." %> 2 | 3 | <% content_for :card_illustration do %> 4 | <% render partial: "components/molecules/progress_step_bar", locals: { current_step: 2, step_count: 3 } %> 5 | <% end %> 6 | -------------------------------------------------------------------------------- /app/views/parent_not_in_home/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Are there any parents who do not live in the home?".html_safe %> 2 | 3 | <% content_for :card_help, "If so, the applicant will have to fill out a Child Support Information form (Appendix D) for each parent not in the home.".html_safe %> 4 | -------------------------------------------------------------------------------- /db/migrate/20181121224900_add_fee_agent_fields_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddFeeAgentFieldsToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :fee_agent_name, :string 4 | add_column :interviews, :fee_agent_email, :string 5 | add_column :interviews, :fee_agent_phone_number, :string 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/forms/any_away_from_home_names_form.rb: -------------------------------------------------------------------------------- 1 | class AnyAwayFromHomeNamesForm < Form 2 | set_attributes_for :interview, :any_away_from_home_names 3 | 4 | validates_presence_of :any_away_from_home_names, message: "Make sure to include an answer." 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/forms/anyone_stopped_work_form.rb: -------------------------------------------------------------------------------- 1 | class AnyoneStoppedWorkForm < Form 2 | set_attributes_for :interview, :anyone_stopped_work 3 | 4 | validates_inclusion_of :anyone_stopped_work, { in: %w{yes no}, message: "Make sure to choose an option." } 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/forms/expenses_payment_details_form.rb: -------------------------------------------------------------------------------- 1 | class ExpensesPaymentDetailsForm < Form 2 | set_attributes_for :interview, :expenses_payment_details 3 | 4 | validates_presence_of :expenses_payment_details, message: "Make sure to include an answer." 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/forms/quest_card_form.rb: -------------------------------------------------------------------------------- 1 | class QuestCardForm < Form 2 | set_attributes_for :interview, :has_quest_card 3 | 4 | validates :has_quest_card, inclusion: { 5 | in: %w(yes no), 6 | message: "Make sure to select yes or no.", 7 | } 8 | 9 | def save 10 | interview.update(attributes_for(:interview)) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20181206222204_add_residency_fields.rb: -------------------------------------------------------------------------------- 1 | class AddResidencyFields < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :navigators, :lived_outside_alaska, :integer, default: 0 4 | add_column :interviews, :arrival_in_alaska, :string 5 | add_column :interviews, :intend_to_stay, :integer, default: 0 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /app/forms/any_not_listed_form.rb: -------------------------------------------------------------------------------- 1 | class AnyNotListedForm < Form 2 | set_attributes_for :interview, :any_not_listed 3 | 4 | validates :any_not_listed, inclusion: { 5 | in: %w(yes no), 6 | message: "Please answer this question", 7 | } 8 | 9 | def save 10 | interview.update(attributes_for(:interview)) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/forms/filing_tax_return_details_form.rb: -------------------------------------------------------------------------------- 1 | class FilingTaxReturnDetailsForm < Form 2 | set_attributes_for :interview, :filing_tax_return_details 3 | 4 | validates_presence_of :filing_tax_return_details, message: "Make sure to include an answer." 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/validators/ten_digit_phone_number_validator.rb: -------------------------------------------------------------------------------- 1 | class TenDigitPhoneNumberValidator < ActiveModel::EachValidator 2 | def validate_each(record, attribute, value) 3 | if value.blank? || !value.match?(/\A\d{10}\z/) 4 | record.errors[attribute] << 5 | "Make sure to enter a valid 10-digit phone number." 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/views/shared/_how_it_works_step3.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Hit send!

3 |

4 | The <%= current_interview&.navigator&.interview_type || "application or renewal" %>, fee agent interview form, and attached verifications will be securely sent to the DPA office within seconds. 5 |

-------------------------------------------------------------------------------- /app/controllers/pregnant_controller.rb: -------------------------------------------------------------------------------- 1 | class PregnantController < YesNoFormsController 2 | def self.show_rule_sets(interview) 3 | super << interview.selected_atap? 4 | end 5 | 6 | def yes_no_method_name 7 | :pregnant 8 | end 9 | 10 | def yes_value 11 | true 12 | end 13 | 14 | def no_value 15 | false 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | begin 5 | exec "yarnpkg", *ARGV 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 | -------------------------------------------------------------------------------- /db/migrate/20181214234524_add_important_confirmations_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddImportantConfirmationsToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :client_sign_and_date, :boolean 4 | add_column :interviews, :fa_sign_and_date, :boolean 5 | add_column :interviews, :all_ssns_included, :boolean 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/controllers/other_information_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe OtherInformationController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | other_info: "Best E. Person", 7 | } 8 | it_behaves_like "form controller always shows" 9 | end 10 | -------------------------------------------------------------------------------- /app/forms/any_away_from_home_form.rb: -------------------------------------------------------------------------------- 1 | class AnyAwayFromHomeForm < Form 2 | set_attributes_for :interview, :any_away_from_home 3 | 4 | validates :any_away_from_home, inclusion: { 5 | in: %w(yes no), 6 | message: "Please answer this question", 7 | } 8 | 9 | def save 10 | interview.update(attributes_for(:interview)) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/forms/anyone_filing_tax_return_form.rb: -------------------------------------------------------------------------------- 1 | class AnyoneFilingTaxReturnForm < Form 2 | set_attributes_for :interview, :anyone_filing_tax_return 3 | 4 | validates_inclusion_of :anyone_filing_tax_return, { in: %w{yes no}, message: "Make sure to choose an option." } 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/forms/approved_for_disability_form.rb: -------------------------------------------------------------------------------- 1 | class ApprovedForDisabilityForm < Form 2 | set_attributes_for :interview, :approved_for_disability 3 | 4 | validates_inclusion_of :approved_for_disability, { in: %w{yes no}, message: "Make sure to choose an option." } 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/forms/children_in_home_form.rb: -------------------------------------------------------------------------------- 1 | class ChildrenInHomeForm < Form 2 | set_attributes_for :navigator, :children_in_home 3 | 4 | def save 5 | interview.navigator.update(attributes_for(:navigator)) 6 | end 7 | 8 | def self.existing_attributes(interview) 9 | HashWithIndifferentAccess.new(interview.navigator.attributes) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/forms/interim_assistance_form.rb: -------------------------------------------------------------------------------- 1 | class InterimAssistanceForm < Form 2 | set_attributes_for :navigator, :interim_assistance 3 | 4 | def save 5 | interview.navigator.update(attributes_for(:navigator)) 6 | end 7 | 8 | def self.existing_attributes(interview) 9 | HashWithIndifferentAccess.new(interview.navigator.attributes) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/forms/parent_not_in_home_form.rb: -------------------------------------------------------------------------------- 1 | class ParentNotInHomeForm < Form 2 | set_attributes_for :navigator, :parent_not_in_home 3 | 4 | def save 5 | interview.navigator.update(attributes_for(:navigator)) 6 | end 7 | 8 | def self.existing_attributes(interview) 9 | HashWithIndifferentAccess.new(interview.navigator.attributes) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/assets/stylesheets/overrides.scss: -------------------------------------------------------------------------------- 1 | .template--homepage .slab--hero h1 { 2 | font-size: 3.6rem; 3 | line-height: 1.3em; 4 | font-weight: 600; 5 | margin-top: 1.5em; 6 | margin-bottom: .5em; 7 | } 8 | 9 | .card { 10 | max-width: 72rem; 11 | margin-left: auto; 12 | margin-right: auto; 13 | } 14 | 15 | .vertical-steps h3 { 16 | font-weight: 600; 17 | } -------------------------------------------------------------------------------- /app/forms/anyone_convicted_drug_felony_form.rb: -------------------------------------------------------------------------------- 1 | class AnyoneConvictedDrugFelonyForm < Form 2 | set_attributes_for :interview, :anyone_convicted_drug_felony 3 | 4 | validates_inclusion_of :anyone_convicted_drug_felony, { in: %w{yes no}, message: "Make sure to choose an option." } 5 | 6 | def save 7 | interview.update(attributes_for(:interview)) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/controllers/static_pages_controller.rb: -------------------------------------------------------------------------------- 1 | class StaticPagesController < ApplicationController 2 | before_action :clear_interview_from_session 3 | 4 | helper_method :current_interview 5 | 6 | def index; end 7 | 8 | private 9 | 10 | def current_interview; end 11 | 12 | def clear_interview_from_session 13 | session[:current_interview_id] = nil 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/factories/interview.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :interview do 3 | trait :with_navigator do 4 | transient do 5 | interview_type { nil } 6 | end 7 | 8 | after(:create) do |interview, evaluator| 9 | create(:navigator, interview: interview, interview_type: evaluator.interview_type) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/controllers/citizen_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe CitizenController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | citizen: true, 7 | } 8 | it_behaves_like "form controller always shows" 9 | it_behaves_like "yes no forms controller with boolean values" 10 | end 11 | -------------------------------------------------------------------------------- /app/controllers/parent_not_in_home_controller.rb: -------------------------------------------------------------------------------- 1 | class ParentNotInHomeController < YesNoFormsController 2 | def self.show_rule_sets(interview) 3 | super << interview.navigator.children_in_home? 4 | end 5 | 6 | def yes_no_method_name 7 | :parent_not_in_home 8 | end 9 | 10 | def yes_value 11 | true 12 | end 13 | 14 | def no_value 15 | false 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/approved_for_disability/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Has the #{applicant_or_client} been approved for Social Security Disability or SSI?".html_safe %> 2 | 3 | <% content_for :card_help, "In order to be eligible for Adult Public Assistance, the #{applicant_or_client} needs to have at least applied for Social Security Disability or SSI." %> 4 | 5 | -------------------------------------------------------------------------------- /spec/controllers/anyone_tribe_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneTribeController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | anyone_tribe: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /spec/controllers/quest_card_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe QuestCardController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | has_quest_card: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /app/controllers/interim_assistance_controller.rb: -------------------------------------------------------------------------------- 1 | class InterimAssistanceController < YesNoFormsController 2 | def self.show_rule_sets(interview) 3 | super << interview.approved_for_disability_no? 4 | end 5 | 6 | def yes_no_method_name 7 | :interim_assistance 8 | end 9 | 10 | def yes_value 11 | true 12 | end 13 | 14 | def no_value 15 | false 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) 7 | # Character.create(name: 'Luke', movie: movies.first) 8 | -------------------------------------------------------------------------------- /spec/controllers/any_not_listed_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyNotListedController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | any_not_listed: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /app/views/other_information/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Any other information that would be helpful for the case worker to know?" %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_textarea :other_info, "Enter any other information or comments.", options: {rows: "4"} %> 6 | <% end %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /lib/tasks/bundler_audit.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | if Rails.env.development? || Rails.env.test? 4 | require "bundler/audit/cli" 5 | 6 | namespace :bundler do 7 | desc "Updates the ruby-advisory-db and runs audit" 8 | task :audit do 9 | %w[update check].each do |command| 10 | Bundler::Audit::CLI.start [command] 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20181122004152_add_client_details_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddClientDetailsToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :client_name, :string 4 | add_column :interviews, :encrypted_client_last_four_ssn, :string 5 | add_column :interviews, :encrypted_client_last_four_ssn_iv, :string 6 | add_column :interviews, :attendee_names, :text 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/controllers/any_away_from_home_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyAwayFromHomeController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | any_away_from_home: "no", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /app/controllers/want_direct_deposit_controller.rb: -------------------------------------------------------------------------------- 1 | class WantDirectDepositController < YesNoFormsController 2 | def self.show_rule_sets(interview) 3 | super << (interview.selected_apa? || interview.selected_atap?) 4 | end 5 | 6 | def yes_no_method_name 7 | :want_direct_deposit 8 | end 9 | 10 | def yes_value 11 | true 12 | end 13 | 14 | def no_value 15 | false 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/controllers/anyone_stopped_work_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneStoppedWorkController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | anyone_stopped_work: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /app/views/shared/_how_it_works_vertical.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= render "shared/how_it_works_step1" %> 4 |
5 |
6 | <%= render "shared/how_it_works_step2" %> 7 |
8 |
9 | <%= render "shared/how_it_works_step3" %> 10 |
11 |
12 | -------------------------------------------------------------------------------- /spec/controllers/what_living_expenses_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe WhatLivingExpensesController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | has_rent_mortgage_expense: "1", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /app/views/shared/_how_it_works_step2.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Attach the <%= current_interview&.navigator&.interview_type || "application or renewal form"%> and verification docs.

3 |

4 | We'll help snap photos or upload the <%= current_interview&.navigator&.interview_type || "forms" %> and any relevant proof. The documents will not be saved on your device. 5 |

-------------------------------------------------------------------------------- /lib/generators/screen/templates/form_controller_spec.template: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe <%= model.camelcase %>Controller do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | signature: "Best E. Person", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /spec/controllers/anyone_filing_tax_return_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneFilingTaxReturnController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | anyone_filing_tax_return: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /spec/controllers/rights_and_responsibilities_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe RightsAndResponsibilitiesController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | explained_rights: "1", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /lib/generators/screen/templates/form_controller.template: -------------------------------------------------------------------------------- 1 | class <%= model.camelcase %>Controller < FormsController 2 | layout "left_aligned" 3 | <%- if options.doc? -%> 4 | # Specify under what conditions controller should be accessible: 5 | # (By default it will always be shown 6 | <%- end -%> 7 | # def self.show_rule_sets(interview) 8 | # super << ShowRules.must_have_supported_county(interview) 9 | # end 10 | end 11 | -------------------------------------------------------------------------------- /app/assets/javascripts/cable.js: -------------------------------------------------------------------------------- 1 | // Action Cable provides the framework to deal with WebSockets in Rails. 2 | // You can generate new channels where WebSocket features live using the `rails generate channel` command. 3 | // 4 | //= require action_cable 5 | //= require_self 6 | //= require_tree ./channels 7 | 8 | (function() { 9 | this.App || (this.App = {}); 10 | 11 | App.cable = ActionCable.createConsumer(); 12 | 13 | }).call(this); 14 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/details/form_controller.template: -------------------------------------------------------------------------------- 1 | class <%= details_class_name %>Controller < FormsController 2 | layout "left_aligned" 3 | <%- if options.doc? -%> 4 | # Specify under what conditions controller should be accessible: 5 | # (By default it will always be shown) 6 | <%- end -%> 7 | def self.show_rule_sets(interview) 8 | super << interview.<%= anyone_model_method %>_yes? 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/controllers/anyone_convicted_drug_felony_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyoneConvictedDrugFelonyController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | anyone_convicted_drug_felony: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /spec/controllers/expenses_payment_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ExpensesPaymentDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | expenses_payment_details: "supporting details", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20181120172602_create_interviews_and_navigators.rb: -------------------------------------------------------------------------------- 1 | class CreateInterviewsAndNavigators < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :interviews, &:timestamps 4 | 5 | create_table :navigators do |t| 6 | t.references :interview 7 | t.integer :interview_type 8 | t.timestamps 9 | end 10 | 11 | change_column_default :navigators, :interview_type, from: nil, to: 0 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/anyone/form_controller_spec.template: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe <%= anyone_class_name %>Controller do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | <%= anyone_model_method %>: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | it_behaves_like "form controller always shows" 10 | end 11 | -------------------------------------------------------------------------------- /app/views/cama_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "If applying for CAMA, please list the specific medical need." %> 2 | 3 | 4 | <% content_for :card_body do %> 5 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 6 | <%= f.cfa_textarea :cama_details, 7 | "List the need and make sure to include the doctor's name and phone number.", 8 | options: {rows: "4"} %> 9 | <% end %> 10 | <% end %> 11 | -------------------------------------------------------------------------------- /spec/support/shared_examples/yes_no_forms_controller_with_enum_values.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.shared_examples_for "yes no forms controller with enum values" do 4 | describe "yes_value" do 5 | it "returns 'yes'" do 6 | expect(controller.yes_value).to eq("yes") 7 | end 8 | end 9 | 10 | describe "no_value" do 11 | it "returns 'no'" do 12 | expect(controller.no_value).to eq("no") 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/views/any_away_from_home_names/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about the people who live in the house but are away from home." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_textarea :any_away_from_home_names, "List their name(s), why they are away, and the expected date to return home.", options: {rows: "4"} %> 6 | <% end %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /app/views/any_not_listed_names/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about the people who live in the home but are not on the #{application_or_renewal}" %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_textarea :any_not_listed_names, "List their name(s) and relationship to the #{applicant_or_client}.", options: {rows: "4"} %> 6 | <% end %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /app/views/filing_tax_return_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about the tax return." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_textarea :filing_tax_return_details, 6 | "Who in the household will be filing and will there be any tax dependent(s)? If so, who?", 7 | options: {rows: "4"} %> 8 | <% end %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /app/views/lets_start/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Let's start with the interview." %> 2 | 3 | <% content_for :card_illustration do %> 4 | <% render partial: "components/molecules/progress_step_bar", locals: { current_step: 1, step_count: 3 } %> 5 | <% end %> 6 | 7 | <% content_for :card_body do %> 8 |

9 | We'll guide you through step-by-step and automatically fill out a digital fee agent interview form. 10 |

11 | <% end %> 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /spec/support/shared_examples/yes_no_forms_controller_with_boolean_values.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.shared_examples_for "yes no forms controller with boolean values" do 4 | describe "yes_value" do 5 | it "returns 'true'" do 6 | expect(controller.yes_value).to eq(true) 7 | end 8 | end 9 | 10 | describe "no_value" do 11 | it "returns 'false'" do 12 | expect(controller.no_value).to eq(false) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/views/want_direct_deposit/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Does the #{applicant_or_client} want to get benefits through direct deposit?".html_safe %> 2 | 3 | <% content_for :card_help do %> 4 |

5 | This is for Alaska Temporary Assistance and Adult Public Assistance benefits. 6 |

7 |

8 | If yes, please have the <%= applicant_or_client %> fill out the Direct Deposit form. 9 |

10 | <% end %> 11 | -------------------------------------------------------------------------------- /spec/controllers/residency_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ResidencyController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | lived_outside_alaska: "yes", 7 | arrival_in_alaska: "Last year", 8 | intend_to_stay: "yes", 9 | } 10 | it_behaves_like "form controller unsuccessful update" 11 | it_behaves_like "form controller always shows" 12 | end 13 | -------------------------------------------------------------------------------- /app/views/any_away_from_home/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Is there anyone on the #{application_or_renewal} who usually lives in the house but is away from home?".html_safe %> 2 | 3 | <% content_for :card_body do %> 4 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /app/views/tribe_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about the people who are in a federally recognized tribe." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_textarea :tribe_details, "List the names of anyone on the #{application_or_renewal} who is in a federally recognized tribe and what tribe they are a part of.", options: {rows: "4"} %> 6 | <% end %> 7 | <% end %> 8 | -------------------------------------------------------------------------------- /spec/controllers/important_confirmations_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ImportantConfirmationsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | client_sign_and_date: "1", 7 | fa_sign_and_date: "1", 8 | all_ssns_included: "1", 9 | } 10 | it_behaves_like "form controller unsuccessful update" 11 | it_behaves_like "form controller always shows" 12 | end 13 | -------------------------------------------------------------------------------- /app/controllers/children_in_home_controller.rb: -------------------------------------------------------------------------------- 1 | class ChildrenInHomeController < YesNoFormsController 2 | def self.show_rule_sets(interview) 3 | [ 4 | interview.navigator.interview_type_application?, 5 | (interview.selected_medicaid || interview.selected_atap), 6 | ] + super 7 | end 8 | 9 | def yes_no_method_name 10 | :children_in_home 11 | end 12 | 13 | def yes_value 14 | true 15 | end 16 | 17 | def no_value 18 | false 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/controllers/client_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ClientDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | client_name: "Best E. Person", 7 | client_last_four_ssn: "1234", 8 | attendee_names: "Anne Dog, Best E. Person", 9 | } 10 | it_behaves_like "form controller unsuccessful update" 11 | it_behaves_like "form controller always shows" 12 | end 13 | -------------------------------------------------------------------------------- /lib/generators/screen/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Create files for adding a new screen to the application. 3 | 4 | Example: 5 | rails generate screen FoodAssistance 6 | 7 | This will create: 8 | app/forms/food_assistance_form.rb 9 | app/controllers/food_assistance_controller.rb 10 | app/views/food_assistance/edit.html.erb 11 | spec/forms/food_assistance_form_spec.rb 12 | spec/controllers/food_assistance_controller_spec.rb 13 | 14 | This will add: 15 | * TBD -------------------------------------------------------------------------------- /spec/controllers/fee_agent_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe FeeAgentDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | fee_agent_name: "Best E. Person", 7 | fee_agent_email: "feeagent@example.com", 8 | fee_agent_phone_number: "555-555-5555", 9 | } 10 | it_behaves_like "form controller unsuccessful update" 11 | it_behaves_like "form controller always shows" 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/pdf_helper.rb: -------------------------------------------------------------------------------- 1 | module PdfHelper 2 | def filled_in_values(file_path) 3 | filled_in_fields = pdftk.get_fields(file_path) 4 | 5 | filled_in_fields.each_with_object({}) do |field, hash| 6 | hash[field.name] = field.value 7 | end 8 | end 9 | 10 | def pdftk 11 | @_pdftk ||= PdfForms.new 12 | end 13 | 14 | def write_raw_pdf_to_temp_file(source:) 15 | temp_pdf = Tempfile.new("pdf", encoding: "ascii-8bit") 16 | temp_pdf << source 17 | temp_pdf 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "config/application" 4 | 5 | namespace :lint do 6 | task :autocorrect do 7 | require "rubocop/rake_task" 8 | RuboCop::RakeTask.new 9 | Rake::Task["rubocop:auto_correct"].execute 10 | end 11 | end 12 | 13 | task :brakeman do 14 | sh "brakeman --no-pager" 15 | end 16 | 17 | task default: %w[lint:autocorrect bundler:audit brakeman spec] 18 | 19 | Rails.application.load_tasks 20 | 21 | task "db:schema:dump": "db:schema:alphabetize_columns" 22 | -------------------------------------------------------------------------------- /app/forms/rights_and_responsibilities_form.rb: -------------------------------------------------------------------------------- 1 | class RightsAndResponsibilitiesForm < Form 2 | set_attributes_for :interview, :explained_rights 3 | 4 | validates :explained_rights, inclusion: { 5 | in: ["1"], 6 | message: "Make sure to agree before continuing.", 7 | } 8 | 9 | def save 10 | interview.update(attributes_for(:interview)) 11 | end 12 | 13 | def self.existing_attributes(interview) 14 | { 15 | explained_rights: checkbox_value(interview.explained_rights), 16 | } 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/views/success/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_illustration do %> 2 |
3 | <% end %> 4 | <% content_for :card_title, "This #{application_or_renewal} has been successfully submitted to the DPA office." %> 5 | 6 | <% content_for :card_body do %> 7 |

8 | <%= "Let the client know to expect a call within a few days or mail from the DPA office within the next two weeks to finalize the #{application_or_renewal} process." %> 9 |

10 | <% end %> 11 | -------------------------------------------------------------------------------- /spec/helpers/application_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ApplicationHelper, type: :helper do 4 | describe "#format_phone_number" do 5 | context "phone number present" do 6 | it "formats a phone number" do 7 | expect(helper.format_phone_number("2024561111")).to eq("(202) 456-1111") 8 | end 9 | end 10 | 11 | context "blank value" do 12 | it "returns nil" do 13 | expect(helper.format_phone_number("")).to be_nil 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/controllers/which_program_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe WhichProgramController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | selected_snap: "1", 7 | selected_medicaid: "1", 8 | selected_general_relief: "1", 9 | selected_atap: "0", 10 | selected_apa: "0", 11 | selected_cama: "0", 12 | } 13 | it_behaves_like "form controller unsuccessful update" 14 | it_behaves_like "form controller always shows" 15 | end 16 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /db/migrate/20181207183301_add_anyone_convicted_details_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddAnyoneConvictedDetailsToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :convicted_drug_felony_name, :string 4 | add_column :interviews, :completed_probation_or_parole, :integer, default: 0 5 | add_column :interviews, :completed_treatment_program, :integer, default: 0 6 | add_column :interviews, :taken_action_towards_rehabilitation, :integer, default: 0 7 | add_column :interviews, :complied_with_reentry, :integer, default: 0 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /spec/controllers/static_pages_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe StaticPagesController, type: :controller do 4 | describe "#index" do 5 | it "renders the homepage" do 6 | get :index 7 | 8 | expect(response).to render_template(:index) 9 | end 10 | 11 | context "with a current interview " do 12 | it "sets the current interview id to nil" do 13 | session[:current_interview_id] = 1 14 | 15 | get :index 16 | 17 | expect(session[:current_interview_id]).to be_nil 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/views/anyone_stopped_work/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Does anyone on this #{application_or_renewal} have work that was stopped or reduced within the last 60 days?".html_safe %> 2 | 3 | <% content_for :card_help, "Please check carefully. This can hold up cases if DPA income checks show higher income than reported." %> 4 | 5 | <% content_for :card_body do %> 6 | 13 | <% end %> -------------------------------------------------------------------------------- /db/migrate/20181127222200_add_selected_program_types_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddSelectedProgramTypesToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :selected_snap, :boolean, default: false 4 | add_column :interviews, :selected_medicaid, :boolean, default: false 5 | add_column :interviews, :selected_general_relief, :boolean, default: false 6 | add_column :interviews, :selected_atap, :boolean, default: false 7 | add_column :interviews, :selected_apa, :boolean, default: false 8 | add_column :interviews, :selected_cama, :boolean, default: false 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/views/fee_agent_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "First, tell us about you, the fee agent." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_input_field :fee_agent_name, "What is the fee agent's name?" %> 6 | <%= f.cfa_input_field :fee_agent_email, "What is the fee agent's email address?", options: { type: "email" } %> 7 | <%= f.cfa_input_field :fee_agent_phone_number, "What is the fee agent's phone number?", classes: ["form-width--phone"], options: { type: "tel" } %> 8 | <% end %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | amazon: 11 | service: S3 12 | access_key_id: <%= Rails.application.credentials.dig(Rails.env.to_sym, :aws, :access_key_id) %> 13 | secret_access_key: <%= Rails.application.credentials.dig(Rails.env.to_sym, :aws, :secret_access_key) %> 14 | region: us-east-1 15 | bucket: <%= Rails.application.credentials.dig(Rails.env.to_sym, :aws, :bucket_name) %> 16 | -------------------------------------------------------------------------------- /app/views/layouts/confirmation.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :content do %> 2 |
3 |
4 |
5 | <%= yield :card_illustration %> 6 |

7 | <%= yield :card_title %> 8 |

9 |
10 | 11 |
12 | <%= yield :card_body %> 13 |
14 |
15 |
16 | <% end %> 17 | 18 | <%= render template: 'layouts/application' %> 19 | -------------------------------------------------------------------------------- /spec/support/shared_examples/forms_controller_unsuccessful_update.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.shared_examples_for "form controller unsuccessful update" do |invalid_params| 4 | describe "#update" do 5 | context "on unsucessful update" do 6 | let(:current_interview) { create(:interview, :with_navigator) } 7 | 8 | before do 9 | session[:current_interview_id] = current_interview.id 10 | 11 | put :update, params: { form: invalid_params || {} } 12 | end 13 | 14 | it "rerenders edit template" do 15 | expect(response).to render_template(:edit) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/client_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about the #{applicant_or_client}." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_input_field :client_name, "What is the #{applicant_or_client}'s name?" %> 6 | <%= f.cfa_input_field :client_last_four_ssn, "What are the last four digits of the #{applicant_or_client}'s SSN?", classes: ["form-width--ssn"], options: { type: "tel" } %> 7 | <%= f.cfa_textarea :attendee_names, "List the name(s) of the person(s) who attended the interview.", options: {rows: "4"} %> 8 | <% end %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /spec/controllers/any_away_from_home_names_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyAwayFromHomeNamesController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | any_away_from_home_names: "Best E. Person", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | 10 | describe "show?" do 11 | it "shows when there is someone who is away from home" do 12 | interview = create :interview, any_away_from_home: "yes" 13 | 14 | show_form = described_class.show? interview 15 | 16 | expect(show_form).to eq(true) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/fields/date_time/_index.html.erb: -------------------------------------------------------------------------------- 1 | <%# 2 | # DateTime Index Partial 3 | 4 | This partial renders a datetime attribute, 5 | to be displayed on a resource’s index page. 6 | 7 | By default, the attribute is rendered 8 | as a localized date & time string. 9 | 10 | ## Local variables: 11 | 12 | - `field`: 13 | An instance of [Administrate::Field::DateTime][1]. 14 | A wrapper around the DateTime value pulled from the database. 15 | 16 | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/DateTime 17 | %> 18 | 19 | <% if field.data %> 20 | <%= field.datetime. 21 | in_time_zone("Alaska")&. 22 | strftime("%m/%d/%Y at %I:%M%p %Z") %> 23 | <% end %> 24 | -------------------------------------------------------------------------------- /app/views/fields/date_time/_show.html.erb: -------------------------------------------------------------------------------- 1 | <%# 2 | # DateTime Show Partial 3 | 4 | This partial renders a datetime attribute, 5 | to be displayed on a resource’s show page. 6 | 7 | By default, the attribute is rendered 8 | as a localized date & time string. 9 | 10 | ## Local variables: 11 | 12 | - `field`: 13 | An instance of [Administrate::Field::DateTime][1]. 14 | A wrapper around the DateTime value pulled from the database. 15 | 16 | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/DateTime 17 | %> 18 | 19 | <% if field.data %> 20 | <%= field.datetime. 21 | in_time_zone("Alaska")&. 22 | strftime("%m/%d/%Y at %I:%M%p %Z") %> 23 | <% end %> 24 | -------------------------------------------------------------------------------- /app/decorators/verification_guidance_interview_decorator.rb: -------------------------------------------------------------------------------- 1 | class VerificationGuidanceInterviewDecorator < SimpleDelegator 2 | def application? 3 | navigator.interview_type_application? 4 | end 5 | 6 | def needs_immigration? 7 | !navigator.citizen? 8 | end 9 | 10 | def needs_pregnancy? 11 | navigator.pregnant? 12 | end 13 | 14 | def needs_eviction_notice? 15 | selected_general_relief? 16 | end 17 | 18 | def needs_direct_deposit? 19 | navigator.want_direct_deposit? 20 | end 21 | 22 | def needs_interim_assistance? 23 | navigator.interim_assistance? 24 | end 25 | 26 | def needs_apa_form? 27 | selected_apa? 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/controllers/any_not_listed_names_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyNotListedNamesController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | any_not_listed_names: "Best E. Person", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | 10 | describe "show?" do 11 | it "shows when there is someone who lives in the house that is not included" do 12 | interview = create :interview, any_not_listed: "yes" 13 | 14 | show_form = described_class.show? interview 15 | 16 | expect(show_form).to eq(true) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/assets/images/emojis/white-heavy-check-mark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/forms/interview_type_form.rb: -------------------------------------------------------------------------------- 1 | class InterviewTypeForm < Form 2 | set_attributes_for :navigator, :interview_type 3 | 4 | validates :interview_type, inclusion: { 5 | in: %w(application renewal), 6 | message: "Please select a valid type", 7 | } 8 | 9 | def save 10 | unless interview.present? 11 | self.interview = Interview.create 12 | interview.create_navigator 13 | end 14 | 15 | interview.navigator.update(attributes_for(:navigator)) 16 | end 17 | 18 | def self.existing_attributes(interview) 19 | if interview.present? 20 | HashWithIndifferentAccess.new(interview.navigator.attributes) 21 | else 22 | {} 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /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 | # Add Yarn node_modules folder to the asset load path. 9 | Rails.application.config.assets.paths << Rails.root.join('node_modules') 10 | 11 | # Precompile additional assets. 12 | # application.js, application.css, and all non-JS/CSS in the app/assets 13 | # folder are already added. 14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) 15 | -------------------------------------------------------------------------------- /app/forms/important_confirmations_form.rb: -------------------------------------------------------------------------------- 1 | class ImportantConfirmationsForm < Form 2 | set_attributes_for :interview, :client_sign_and_date, :fa_sign_and_date, :all_ssns_included 3 | 4 | validation_message = "Make sure to do this so that the case can be properly processed." 5 | 6 | validates :client_sign_and_date, inclusion: { 7 | in: ["1"], 8 | message: validation_message, 9 | } 10 | validates :fa_sign_and_date, inclusion: { 11 | in: ["1"], 12 | message: validation_message, 13 | } 14 | validates :all_ssns_included, inclusion: { 15 | in: ["1"], 16 | message: validation_message, 17 | } 18 | 19 | def save 20 | interview.update(attributes_for(:interview)) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /app/forms/add_id_verification_form.rb: -------------------------------------------------------------------------------- 1 | class AddIdVerificationForm < Form 2 | set_attributes_for :interview, documents: [] 3 | 4 | def save 5 | self.documents ||= [] 6 | documents_to_attach = documents.reject do |document_signed_id| 7 | document_signed_id.blank? || 8 | interview.id_verifications.map(&:signed_id).include?(document_signed_id) 9 | end 10 | interview.id_verifications.attach(documents_to_attach) 11 | interview.id_verifications.each do |document| 12 | document.delete if documents.exclude?(document.signed_id) 13 | end 14 | end 15 | 16 | def self.existing_attributes(interview) 17 | { 18 | documents: interview.id_verifications, 19 | } 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/forms/which_program_form.rb: -------------------------------------------------------------------------------- 1 | class WhichProgramForm < Form 2 | set_attributes_for :interview, :selected_snap, :selected_medicaid, :selected_general_relief, 3 | :selected_atap, :selected_apa, :selected_cama 4 | 5 | validate :at_least_one_program_selected 6 | 7 | def save 8 | interview.update(attributes_for(:interview)) 9 | end 10 | 11 | def self.existing_attributes(interview) 12 | attributes_to_checkbox_values(interview) 13 | end 14 | 15 | private 16 | 17 | def at_least_one_program_selected 18 | return true if attributes_for(:interview).values.any? { |program| program == "1" } 19 | 20 | errors.add(:program_type, "Make sure to select at least one program.") 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | .DS_Store 8 | 9 | # Ignore bundler config. 10 | /.bundle 11 | 12 | # Ignore all logfiles and tempfiles. 13 | /log/* 14 | /tmp/* 15 | !/log/.keep 16 | !/tmp/.keep 17 | 18 | # Ignore uploaded files in development 19 | /storage/* 20 | !/storage/.keep 21 | 22 | /node_modules 23 | /yarn-error.log 24 | 25 | /public/assets 26 | .byebug_history 27 | 28 | # Ignore master key for decrypting credentials and more. 29 | /config/master.key 30 | -------------------------------------------------------------------------------- /app/forms/client_details_form.rb: -------------------------------------------------------------------------------- 1 | class ClientDetailsForm < Form 2 | set_attributes_for :interview, :client_name, :client_last_four_ssn, :attendee_names 3 | 4 | validates_presence_of :client_name, message: "Make sure to include their name." 5 | validates_presence_of :attendee_names, message: "Make sure to tell us who attended the interview." 6 | validates :client_last_four_ssn, length: { is: 4, message: "Make sure to include the last four digits of their SSN." } 7 | 8 | def save 9 | interview.update(attributes_for(:interview)) 10 | end 11 | 12 | def self.existing_attributes(interview) 13 | attributes = interview.attributes 14 | attributes[:client_last_four_ssn] = interview.client_last_four_ssn 15 | HashWithIndifferentAccess.new(attributes) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/forms/index.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :content do %> 2 |
3 |
4 |
5 |

6 | All of the screens!
7 |

8 |
9 | 10 |
11 |
12 | <% FormNavigation.form_controllers.each do |form| %> 13 |
14 | <%= link_to form.to_param.titleize, 15 | screen_path(form.to_param), 16 | class: 'button button--small button--full-mobile' %> 17 |
18 | <% end %> 19 |
20 |
21 |
22 |
23 | <% end %> -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/details/form_model.template: -------------------------------------------------------------------------------- 1 | class <%= details_class_name %>Form < Form 2 | <%- if options.doc? -%> 3 | # Whitelist top-level parameter names for Interview, e.g. 4 | # 5 | # given params: { form: { living_situation: "stable_housing" } } 6 | # 7 | # set_attributes_for :interview, :living_situation 8 | # 9 | # Delete the method if you aren't updating the Interview. 10 | <%- end -%> 11 | set_attributes_for :interview, :attribute_name 12 | 13 | <%- if options.doc? -%> 14 | # Add any validations below. Be sure to include helpful error messages. 15 | <%- end -%> 16 | validates_presence_of :attribute_name, message: "Validation error" 17 | 18 | def save 19 | interview.update(attributes_for(:interview)) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/tasks/alphabetize_columns.rake: -------------------------------------------------------------------------------- 1 | namespace :db do 2 | namespace :schema do 3 | # https://www.pgrs.net/2008/03/13/alphabetize-schema-rb-columns/ 4 | task :alphabetize_columns do 5 | warn "Dumping schema with alphabetized columns" 6 | ActiveRecord::Base.logger.level = Logger::INFO 7 | 8 | class << ActiveRecord::Base.connection 9 | alias_method :old_columns, :columns unless instance_methods.include?("old_columns") 10 | alias_method :old_extensions, :extensions unless instance_methods.include?("old_extensions") 11 | 12 | def columns(*args) 13 | old_columns(*args).sort_by(&:name) 14 | end 15 | 16 | def extensions(*args) 17 | old_extensions(*args).sort 18 | end 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | FZzbI/NsVGvUZjX/nYEJ8sLKZn3FtrMrxiiC68ciiI2mNfecSj23ernRYdFgtqUk/xdz0huL1zaCswQZlt/CWRGdxShtC4LKJiV0XsuvlVnKGr9U6vcbc8PnkT5KZZ3yfqVW82vxpDF/3mH7f8bMlg8szaEJGat8iUGQ/+aGAlbJpTLcHmCtGpCy8thH4B+kmAgJ4TexDUPNwoPWto5uYpDhEPalka3fkat9ODFD6RDqL0OV8D+W6BZ65qrSixzWjnBhiIOOIbAZOt6cFaFJOhZKCsAQa0mFN6nDVgbzzA3CLRf4x5vFWolV4KKdpk2mJ1UD0hf1B+zkEsySqJ1Lkn14wdD4NuJhGjD0AAe/wgT7bQKZJO+CTZ3kqhbtfwxDJYhO5aAz6G+REGxqo/XEDUyXBU5bBB+hAILfzjuzmn1DFiczgyQKF7iMPR4sMyuK1Tepd3XMfE6F4dBAH2d0p3do6kd3EPQLS/jWe4tTPao40yznEUlTpVI2ePhs5qKgYZs/U5uralbZhNr6Fdm5WU6+pAYecxsakMSs6dr13PomvpJCV5vdBZEoSvmcDUCdc4XeRWHoHWaOI/g210K9FF9HiMEYYPkJwVNHmaGBJACQ1mLad0UIsm/XBYfY8jf/CXmWNswd6hN90tozRr1kn9ZJ3/68RnrDxZDl7VSKJpEiYSd0pFZ+m6jqRPWxdnzoVcN00jC8tO8Y6mF/fYM2muH0zJrYWUDezO9CN7OHU+6hRTlGkS8emXacMWb5Xyvlays=--yPWxtVrz0h4GoqWt--Is7WUi15LCgJSG+S/frjvQ== -------------------------------------------------------------------------------- /app/forms/attributes.rb: -------------------------------------------------------------------------------- 1 | class Attributes 2 | def initialize(attribute_names) 3 | @attribute_names = attribute_names 4 | end 5 | 6 | def to_s 7 | symbols_or_hash_keys.flatten.map(&:to_s) 8 | end 9 | 10 | def to_sym 11 | symbols_or_hash_keys.flatten.map(&:to_sym) 12 | end 13 | 14 | def hash_key?(attribute) 15 | hashes = attribute_names.select do |attr| 16 | attr.is_a? Hash 17 | end 18 | 19 | hashes.map(&:keys).flatten.include? attribute.to_sym 20 | end 21 | 22 | private 23 | 24 | attr_reader :attribute_names 25 | 26 | def symbols_or_hash_keys 27 | return [] if attribute_names.nil? 28 | 29 | attribute_names.map do |attr| 30 | if attr.class == Symbol 31 | attr 32 | else 33 | attr.keys 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 3 | mount Cfa::Styleguide::Engine => "/cfa" 4 | 5 | root "static_pages#index" 6 | 7 | namespace :admin do 8 | resources :interviews 9 | 10 | root to: "interviews#index" 11 | end 12 | 13 | resources :screens, controller: :forms, only: %i[show index] do 14 | collection do 15 | FormNavigation.form_controllers.uniq.each do |controller_class| 16 | { get: :edit, put: :update }.each do |method, action| 17 | match "/#{controller_class.to_param}", 18 | action: action, 19 | controller: controller_class.controller_path, 20 | via: method 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /app/forms/fee_agent_details_form.rb: -------------------------------------------------------------------------------- 1 | class FeeAgentDetailsForm < Form 2 | set_attributes_for :interview, :fee_agent_name, :fee_agent_email, :fee_agent_phone_number 3 | 4 | before_validation -> { strip_dashes(:fee_agent_phone_number) } 5 | 6 | validates_presence_of :fee_agent_name, message: "Make sure to include the fee agent's name." 7 | validates :fee_agent_phone_number, ten_digit_phone_number: true 8 | 9 | validates_presence_of :fee_agent_email, message: "Make sure to include the fee agent's email address." 10 | validates :fee_agent_email, 11 | allow_blank: true, 12 | format: { 13 | with: /\A\S+@\S+\.\S+\z/, 14 | message: "Make sure to enter a valid email address.", 15 | } 16 | 17 | def save 18 | interview.update(attributes_for(:interview)) 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/anyone/form_model.template: -------------------------------------------------------------------------------- 1 | class <%= anyone_class_name %>Form < Form 2 | <%- if options.doc? -%> 3 | # Whitelist top-level parameter names for Interview, e.g. 4 | # 5 | # given params: { form: { living_situation: "stable_housing" } } 6 | # 7 | # set_attributes_for :interview, :living_situation 8 | # 9 | # Delete the method if you aren't updating the Interview. 10 | <%- end -%> 11 | set_attributes_for :interview, :<%= anyone_model_method %> 12 | 13 | <%- if options.doc? -%> 14 | # Add any validations below. Be sure to include helpful error messages. 15 | <%- end -%> 16 | validates_inclusion_of :<%= anyone_model_method %>, { in: %w{yes no}, message: "Make sure to choose an option." } 17 | 18 | def save 19 | interview.update(attributes_for(:interview)) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/assets/javascripts/templates/uploaded_file_detail.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

{{filename}}

5 |

6 | 7 | Delete 8 | 9 |

10 |
11 | {{#if isPdf}} 12 |
13 | {{else}} 14 |
15 | Preview of uploaded document {{letter.filename}} 16 |
17 | {{/if}} 18 |
19 | 20 |
-------------------------------------------------------------------------------- /app/helpers/credentials_helper.rb: -------------------------------------------------------------------------------- 1 | module CredentialsHelper 2 | class << self 3 | def secret_key_for_ssn_encryption 4 | environment_credential_for_key(:secret_key_for_ssn_encryption, 5 | alternate_value: "This is a key that is 256 bits!!") 6 | end 7 | 8 | def basic_auth_username 9 | environment_credential_for_key("basic_auth_username", alternate_value: "admin") 10 | end 11 | 12 | def basic_auth_password 13 | environment_credential_for_key("basic_auth_password", alternate_value: "password") 14 | end 15 | 16 | def environment_credential_for_key(key, alternate_value: nil) 17 | if Rails.env.test? || Rails.env.development? 18 | alternate_value 19 | else 20 | Rails.application.credentials[Rails.env.to_sym][key.to_sym] 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/forms/citizen_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe CitizenForm do 4 | describe "#save" do 5 | let(:interview) { create :interview, :with_navigator } 6 | 7 | let(:valid_params) do 8 | { 9 | citizen: "true", 10 | } 11 | end 12 | 13 | it "persists the values to the correct models" do 14 | form = CitizenForm.new(interview, valid_params) 15 | form.valid? 16 | form.save 17 | 18 | interview.reload 19 | 20 | expect(interview.navigator.citizen).to eq true 21 | end 22 | end 23 | 24 | describe ".from_interview" do 25 | it "assigns values from interview" do 26 | interview = create(:interview, navigator: build(:navigator, citizen: true)) 27 | 28 | form = CitizenForm.from_interview(interview) 29 | 30 | expect(form.citizen).to eq true 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/forms/pregnant_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe PregnantForm do 4 | describe "#save" do 5 | let(:interview) { create :interview, :with_navigator } 6 | 7 | let(:valid_params) do 8 | { 9 | pregnant: "true", 10 | } 11 | end 12 | 13 | it "persists the values to the correct models" do 14 | form = PregnantForm.new(interview, valid_params) 15 | form.valid? 16 | form.save 17 | 18 | interview.reload 19 | 20 | expect(interview.navigator.pregnant).to eq(true) 21 | end 22 | end 23 | 24 | describe ".from_interview" do 25 | it "assigns values from interview" do 26 | interview = create(:interview, navigator: build(:navigator, pregnant: true)) 27 | 28 | form = PregnantForm.from_interview(interview) 29 | 30 | expect(form.pregnant).to eq(true) 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/views/how_to_take_photos/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_illustration do %> 2 | 3 | <% end %> 4 | <% content_for :card_title do %> 5 | Taking photos of documents. 6 | Take a moment to scan in any documents that are required. 7 | <% end %> 8 | 9 | <% content_for :card_body do %> 10 |
11 |
12 |

Make sure you are in a well-lit area.

13 |
14 |
15 |

Take a photo from directly above, not at an angle.

16 |
17 |
18 |

Check if the photo is legible and retake if necessary.

19 |
20 |
21 | <% end %> 22 | -------------------------------------------------------------------------------- /spec/controllers/cama_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe CamaDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | cama_details: "Best E. Person", 7 | } 8 | 9 | describe "#show?" do 10 | context "when applying or renewing for cama" do 11 | it "returns true" do 12 | application = create(:interview, selected_cama: true) 13 | 14 | show = CamaDetailsController.show?(application) 15 | expect(show).to eq(true) 16 | end 17 | end 18 | 19 | context "when not applying for cama" do 20 | it "returns false" do 21 | application = create(:interview, selected_cama: false) 22 | 23 | show = CamaDetailsController.show?(application) 24 | expect(show).to eq(false) 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Create files for adding a new "Is anyone?" / "Details?" section. 3 | 4 | Example: 5 | rails generate screen:anyone Veteran 6 | 7 | This will create: 8 | # AnyoneVeteran 9 | 10 | app/forms/anyone_veteran_form.rb 11 | spec/forms/anyone_veteran_form_spec.rb 12 | app/controllers/anyone_veteran_controller.rb 13 | spec/controllers/anyone_veteran_controller_spec.rb 14 | app/views/anyone_veteran/edit.html.erb 15 | 16 | # VeteranDetails 17 | 18 | app/forms/veteran_details_form.rb 19 | spec/forms/veteran_details_form_spec.rb 20 | app/controllers/veteran_details_controller.rb 21 | spec/controllers/veteran_details_controller_spec.rb 22 | app/views/veteran_details/edit.html.erb 23 | 24 | This will add: 25 | * `anyone_veteran` enum to Interview 26 | -------------------------------------------------------------------------------- /app/views/rights_and_responsibilities/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Take a moment to go over their rights and responsibilities." %> 2 | 3 | <% content_for :card_help, "Make sure the #{applicant_or_client} keeps their copy of their rights and responsibilities." %> 4 | 5 | <% content_for :card_body do %> 6 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 7 |
8 | Show more 9 |
10 | <%= render "terms" %> 11 |
12 |
13 | 14 | <%= f.cfa_checkbox_set(:explained_rights, 15 | [{ label: "Yes", method: :explained_rights }], 16 | label_text: "Did you explain the rights and responsibilities and provide a copy to the #{applicant_or_client}?") %> 17 | <% end %> 18 | <% end %> 19 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's 6 | * vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS 10 | * files in this directory. Styles in this file should be added after the last require_* statement. 11 | * It is generally better to create a new file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | 17 | @import 'cfa_styleguide_main'; 18 | 19 | @import 'molecules/show-more'; 20 | 21 | @import 'overrides'; 22 | @import 'custom'; -------------------------------------------------------------------------------- /spec/support/shared_examples/forms_controller_successful_update.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.shared_examples_for "form controller successful update" do |valid_params| 4 | describe "#update" do 5 | context "without interview" do 6 | it "redirects to homepage" do 7 | put :update, params: { form: valid_params } 8 | 9 | expect(response).to redirect_to(root_path) 10 | end 11 | end 12 | 13 | context "with interview" do 14 | let(:current_interview) { create(:interview, :with_navigator) } 15 | 16 | before do 17 | session[:current_interview_id] = current_interview.id 18 | end 19 | 20 | context "on successful update" do 21 | it "redirects to next path" do 22 | put :update, params: { form: valid_params } 23 | 24 | expect(response).to redirect_to(subject.next_path) 25 | end 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /app/forms/residency_form.rb: -------------------------------------------------------------------------------- 1 | class ResidencyForm < Form 2 | set_attributes_for :interview, :arrival_in_alaska, :intend_to_stay 3 | set_attributes_for :navigator, :lived_outside_alaska 4 | 5 | validates_presence_of :lived_outside_alaska, message: "Make sure to select an answer" 6 | validate :arrival_in_alaska_validation 7 | validates_presence_of :intend_to_stay, message: "Make sure to select an answer" 8 | 9 | def save 10 | interview.update(attributes_for(:interview)) 11 | interview.navigator.update(attributes_for(:navigator)) 12 | end 13 | 14 | def self.existing_attributes(interview) 15 | HashWithIndifferentAccess.new(interview.attributes.merge(interview.navigator.attributes)) 16 | end 17 | 18 | def arrival_in_alaska_validation 19 | if lived_outside_alaska == "yes" && arrival_in_alaska.blank? 20 | errors.add(:arrival_in_alaska, "Make sure to include an answer") 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/forms/children_in_home_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ChildrenInHomeForm do 4 | describe "#save" do 5 | let(:interview) { create :interview, :with_navigator } 6 | 7 | let(:valid_params) do 8 | { 9 | children_in_home: "true", 10 | } 11 | end 12 | 13 | it "persists the values to the correct models" do 14 | form = ChildrenInHomeForm.new(interview, valid_params) 15 | form.valid? 16 | form.save 17 | 18 | interview.reload 19 | 20 | expect(interview.navigator.children_in_home).to eq true 21 | end 22 | end 23 | 24 | describe ".from_interview" do 25 | it "assigns values from interview" do 26 | interview = create(:interview, navigator: build(:navigator, children_in_home: true)) 27 | 28 | form = ChildrenInHomeForm.from_interview(interview) 29 | 30 | expect(form.children_in_home).to eq true 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/views/stopped_work_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about work that has stopped or has been reduced in the last 60 days." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_textarea :stopped_work_details, 6 | "

List the person, the job, when and why the job ended or was reduced, and the name and phone number of the employer.

7 | 8 |
9 |
10 | 11 |
12 | 13 |
14 | The more details you can provide, the more likely the #{applicant_or_client} can be approved without issues. 15 |
16 |
", 17 | options: {rows: "4"} %> 18 | <% end %> 19 | <% end %> 20 | -------------------------------------------------------------------------------- /bin/update: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'fileutils' 3 | include FileUtils 4 | 5 | # path to your application root. 6 | APP_ROOT = File.expand_path('..', __dir__) 7 | 8 | def system!(*args) 9 | system(*args) || abort("\n== Command #{args} failed ==") 10 | end 11 | 12 | chdir APP_ROOT do 13 | # This script is a way to update your development environment automatically. 14 | # Add necessary update steps to this file. 15 | 16 | puts '== Installing dependencies ==' 17 | system! 'gem install bundler --conservative' 18 | system('bundle check') || system!('bundle install') 19 | 20 | # Install JavaScript dependencies if using Yarn 21 | # system('bin/yarn') 22 | 23 | puts "\n== Updating database ==" 24 | system! 'bin/rails db:migrate' 25 | 26 | puts "\n== Removing old logs and tempfiles ==" 27 | system! 'bin/rails log:clear tmp:clear' 28 | 29 | puts "\n== Restarting application server ==" 30 | system! 'bin/rails restart' 31 | end 32 | -------------------------------------------------------------------------------- /spec/controllers/tribe_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe TribeDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | tribe_details: "yes", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | 10 | describe "#show?" do 11 | context "when someone in household is tribe" do 12 | it "returns true" do 13 | application = create(:interview, anyone_tribe: "yes") 14 | 15 | show = TribeDetailsController.show?(application) 16 | expect(show).to eq(true) 17 | end 18 | end 19 | 20 | context "when no one in household is tribe" do 21 | it "returns false" do 22 | application = create(:interview, anyone_tribe: "no") 23 | 24 | show = TribeDetailsController.show?(application) 25 | expect(show).to eq(false) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/forms/parent_not_in_home_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ParentNotInHomeForm do 4 | describe "#save" do 5 | let(:interview) { create :interview, :with_navigator } 6 | 7 | let(:valid_params) do 8 | { 9 | parent_not_in_home: "true", 10 | } 11 | end 12 | 13 | it "persists the values to the correct models" do 14 | form = ParentNotInHomeForm.new(interview, valid_params) 15 | form.valid? 16 | form.save 17 | 18 | interview.reload 19 | 20 | expect(interview.navigator.parent_not_in_home).to eq true 21 | end 22 | end 23 | 24 | describe ".from_interview" do 25 | it "assigns values from interview" do 26 | interview = create(:interview, navigator: build(:navigator, parent_not_in_home: true)) 27 | 28 | form = ParentNotInHomeForm.from_interview(interview) 29 | 30 | expect(form.parent_not_in_home).to eq true 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/forms/want_direct_deposit_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe WantDirectDepositForm do 4 | describe "validations" do 5 | context "when want_direct_deposit is provided" do 6 | it "is valid" do 7 | form = WantDirectDepositForm.new( 8 | nil, 9 | want_direct_deposit: false, 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | end 16 | 17 | describe "#save" do 18 | let(:interview) { create :interview, :with_navigator } 19 | 20 | let(:valid_params) do 21 | { 22 | want_direct_deposit: true, 23 | } 24 | end 25 | 26 | it "persists the values to the correct models" do 27 | form = WantDirectDepositForm.new(interview, valid_params) 28 | form.valid? 29 | form.save 30 | 31 | interview.reload 32 | 33 | expect(interview.navigator.want_direct_deposit).to be_truthy 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /app/views/attach_documents_signpost/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Lastly, let's attach the #{application_or_renewal} and any required documents." %> 2 | 3 | <% content_for :card_illustration do %> 4 | <% render partial: "components/molecules/progress_step_bar", locals: { current_step: 3, step_count: 3 } %> 5 | <% end %> 6 | 7 | <% content_for :card_body do %> 8 |
9 |

10 | If you are doing this on a computer, you can scan documents to your computer and upload them in the follow section. 11 |

12 |
13 | 14 |
15 |

16 | If you are doing this on a smartphone or tablet device, you can use the camera on the back of the device to take a picture of any documents. 17 |

18 | 19 |

20 | 21 | Photos will not be saved to your device. 22 | 23 |

24 |
25 | <% end %> 26 | -------------------------------------------------------------------------------- /spec/controllers/approved_for_disability_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ApprovedForDisabilityController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | approved_for_disability: "yes", 7 | } 8 | it_behaves_like "yes no forms controller with enum values" 9 | 10 | describe "#show" do 11 | context "selected APA" do 12 | it "shows" do 13 | application = create(:interview, selected_apa: true) 14 | 15 | show = ApprovedForDisabilityController.show?(application) 16 | expect(show).to eq(true) 17 | end 18 | end 19 | 20 | context "did not select APA" do 21 | it "does not show" do 22 | application = create(:interview, selected_apa: false) 23 | 24 | show = ApprovedForDisabilityController.show?(application) 25 | expect(show).to eq(false) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /app/views/important_confirmations/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Let's review a few important parts of the #{application_or_renewal}." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | 6 | <%= f.cfa_checkbox_set(:client_sign_and_date, 7 | [{ label: "Yes", method: :client_sign_and_date }], 8 | label_text: "Did the #{applicant_or_client} sign and date the #{application_or_renewal} and all other forms needing signature?") %> 9 | 10 | <%= f.cfa_checkbox_set(:fa_sign_and_date, 11 | [{ label: "Yes", method: :fa_sign_and_date }], 12 | label_text: "Did you, as Fee Agent, sign and date the #{application_or_renewal}?") %> 13 | 14 | <%= f.cfa_checkbox_set(:all_ssns_included, 15 | [{ label: "Yes", method: :all_ssns_included }], 16 | label_text: "Are all the household members' social security numbers listed on the #{application_or_renewal}?") %> 17 | <% end %> 18 | <% end %> 19 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # The following keys must be escaped otherwise they will not be retrieved by 20 | # the default I18n backend: 21 | # 22 | # true, false, on, off, yes, no 23 | # 24 | # Instead, surround them with single quotes. 25 | # 26 | # en: 27 | # 'true': 'foo' 28 | # 29 | # To learn more, please read the Rails Internationalization guide 30 | # available at http://guides.rubyonrails.org/i18n.html. 31 | 32 | en: 33 | hello: "Hello world" 34 | -------------------------------------------------------------------------------- /app/views/interim_assistance/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Does the #{applicant_or_client} want to apply for interim assistance?".html_safe %> 2 | 3 | <% content_for :card_body do %> 4 |
5 |

What is interim assistance?

6 |
7 |

Interim Assistance is a state program paying up to $280 per month to people who are waiting for final decisions about whether they are eligible for disability benefits from the SSA.

8 | 9 | Click here to learn more 10 |
11 |
12 | 13 |

If yes, the <%= applicant_or_client %> will need to fill out and return a Preliminary Examination for Interim Assistance Form (AD2) and a Authorization for Reimbursement of Interim Assistance form (GEN 142- IAR).

14 | <% end %> 15 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <% if content_for? :card_title %> 5 | <%= strip_tags(content_for(:card_title)) %> | Fee Agents Assister for Alaska 6 | <% else %> 7 | Fee Agents Assister for Alaska 8 | <% end %> 9 | 10 | <%= csrf_meta_tags %> 11 | <%= csp_meta_tag %> 12 | 13 | <%= stylesheet_link_tag 'application', media: 'all' %> 14 | <%= javascript_include_tag 'application' %> 15 | 16 | 17 | > 18 |
"> 19 |
20 | This site is for example purposes only. 21 |
22 | <%= render 'shared/header' unless content_for? :homepage %> 23 | <%= content_for(:content) ? content_for(:content) : yield %> 24 |
25 | <%= render 'shared/footer' %> 26 | 27 | -------------------------------------------------------------------------------- /spec/controllers/pregnant_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe PregnantController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | pregnant: true, 7 | } 8 | it_behaves_like "yes no forms controller with boolean values" 9 | 10 | describe "#show?" do 11 | context "when applicant is applying for Alaska Temporary Assistance" do 12 | it "returns true" do 13 | application = create(:interview, :with_navigator, selected_atap: true) 14 | 15 | show = PregnantController.show?(application) 16 | expect(show).to eq(true) 17 | end 18 | end 19 | 20 | context "when applicant is not applying for Alaska Temporary Assistance" do 21 | it "returns false" do 22 | application = create(:interview, selected_atap: false) 23 | 24 | skip_step = PregnantController.show?(application) 25 | expect(skip_step).to eq(false) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/controllers/interim_assistance_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe InterimAssistanceController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | interim_assistance: true, 7 | } 8 | it_behaves_like "yes no forms controller with boolean values" 9 | 10 | describe "#show?" do 11 | context "when applicant is approved for disability" do 12 | it "returns false" do 13 | application = create(:interview, approved_for_disability: "yes") 14 | 15 | show = InterimAssistanceController.show?(application) 16 | expect(show).to eq(false) 17 | end 18 | end 19 | 20 | context "when applicant is not approved for disability" do 21 | it "returns true" do 22 | application = create(:interview, approved_for_disability: "no") 23 | 24 | skip_step = InterimAssistanceController.show?(application) 25 | expect(skip_step).to eq(true) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/controllers/stopped_work_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe StoppedWorkDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | stopped_work_details: "Snowboard season is over", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | 10 | describe "#show?" do 11 | context "when someone in household is stopped_work" do 12 | it "returns true" do 13 | application = create(:interview, anyone_stopped_work: "yes") 14 | 15 | show = StoppedWorkDetailsController.show?(application) 16 | expect(show).to eq(true) 17 | end 18 | end 19 | 20 | context "when no one in household is stopped_work" do 21 | it "returns false" do 22 | application = create(:interview, anyone_stopped_work: "no") 23 | 24 | show = StoppedWorkDetailsController.show?(application) 25 | expect(show).to eq(false) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /app/views/layouts/signpost.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :content do %> 2 |
3 |
4 |
5 | <%= yield :card_illustration %> 6 |

7 | <%= yield :card_title %> 8 |

9 | 10 | <% if content_for? :card_help %> 11 |

12 | <%= yield :card_help %> 13 |

14 | <% end %> 15 |
16 | 17 |
18 | <%= yield :card_body %> 19 |
20 | 21 | 28 |
29 |
30 | <% end %> 31 | 32 | <%= render template: 'layouts/application' %> 33 | -------------------------------------------------------------------------------- /db/migrate/20190123184639_create_active_storage_tables.active_storage.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from active_storage (originally 20170806125915) 2 | class CreateActiveStorageTables < ActiveRecord::Migration[5.2] 3 | def change 4 | create_table :active_storage_blobs do |t| 5 | t.string :key, null: false 6 | t.string :filename, null: false 7 | t.string :content_type 8 | t.text :metadata 9 | t.bigint :byte_size, null: false 10 | t.string :checksum, null: false 11 | t.datetime :created_at, null: false 12 | 13 | t.index [:key], unique: true 14 | end 15 | 16 | create_table :active_storage_attachments do |t| 17 | t.string :name, null: false 18 | t.references :record, null: false, polymorphic: true, index: false 19 | t.references :blob, null: false 20 | 21 | t.datetime :created_at, null: false 22 | 23 | t.index %i[record_type record_id name blob_id], name: "index_active_storage_attachments_uniqueness", unique: true 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /spec/controllers/filing_tax_return_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe FilingTaxReturnDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | filing_tax_return_details: "value", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | 10 | describe "#show?" do 11 | context "when someone in household is filing_tax_return" do 12 | it "returns true" do 13 | application = create(:interview, anyone_filing_tax_return: "yes") 14 | 15 | show = FilingTaxReturnDetailsController.show?(application) 16 | expect(show).to eq(true) 17 | end 18 | end 19 | 20 | context "when no one in household is filing_tax_return" do 21 | it "returns false" do 22 | application = create(:interview, anyone_filing_tax_return: "no") 23 | 24 | skip_step = FilingTaxReturnDetailsController.show?(application) 25 | expect(skip_step).to eq(false) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/details/form_controller_spec.template: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe <%= details_class_name %>Controller do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | attribute: "value", 7 | } 8 | it_behaves_like "form controller unsuccessful update" 9 | 10 | describe "#show?" do 11 | context "when someone in household is <%= model_method %>" do 12 | it "returns true" do 13 | application = create(:interview, <%= anyone_model_method %>: "yes") 14 | 15 | show = <%= details_class_name %>Controller.show?(application) 16 | expect(show).to eq(true) 17 | end 18 | end 19 | 20 | context "when no one in household is <%= model_method %>" do 21 | it "returns false" do 22 | application = create(:interview, <%= anyone_model_method %>: "no") 23 | 24 | show = <%= details_class_name %>Controller.show?(application) 25 | expect(show).to eq(false) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /app/views/interview_type/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "What are you helping the client with today?" %> 2 | 3 | <% content_for :card_illustration do %> 4 |
Star
5 | <% end %> 6 | 7 | <% content_for :card_footer do %> 8 | <%= form_with url: current_path, method: :put, local: true do %> 9 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 10 |
11 | <%= f.cfa_single_tap_button(:interview_type, 12 | "Submit an application", 13 | "application", 14 | classes: ["button--primary"]) %> 15 |
16 | 17 |
18 | <%= f.cfa_single_tap_button(:interview_type, 19 | "Submit a renewal", 20 | "renewal", 21 | classes: ["button--primary"]) %> 22 |
23 | <% end %> 24 | <% end %> 25 | <% end %> 26 | -------------------------------------------------------------------------------- /app/controllers/admin/application_controller.rb: -------------------------------------------------------------------------------- 1 | # All Administrate controllers inherit from this `Admin::ApplicationController`, 2 | # making it the ideal place to put authentication logic or other 3 | # before_actions. 4 | # 5 | # If you want to add pagination or other controller-level concerns, 6 | # you're free to overwrite the RESTful controller actions. 7 | module Admin 8 | class ApplicationController < Administrate::ApplicationController 9 | before_action :authenticate_admin 10 | before_action :default_params 11 | 12 | def authenticate_admin 13 | authenticate_or_request_with_http_basic do |username, password| 14 | username == CredentialsHelper.basic_auth_username && password == CredentialsHelper.basic_auth_password 15 | end 16 | end 17 | 18 | def default_params 19 | resource_params = params.fetch(resource_name, {}) 20 | order = resource_params.fetch(:order, "created_at") 21 | direction = resource_params.fetch(:direction, "desc") 22 | params[resource_name] = resource_params.merge(order: order, direction: direction) 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /app/views/which_program/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% if current_interview.navigator.interview_type_renewal? %> 2 | <% content_for :card_title, "What program(s) is the client renewing?" %> 3 | <% else %> 4 | <% content_for :card_title, "What program(s) is the applicant applying for?" %> 5 | <% end %> 6 | 7 | <% content_for :card_body do %> 8 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 9 | <%= f.cfa_checkbox_set(:program_type, 10 | [ 11 | { label: "Food stamps", method: :selected_snap }, 12 | { label: "Medicaid", method: :selected_medicaid }, 13 | { label: "General Relief", method: :selected_general_relief }, 14 | { label: "Alaska Temporary Assistance", method: :selected_atap }, 15 | { label: "Adult Public Assistance", method: :selected_apa }, 16 | { label: "CAMA", method: :selected_cama }, 17 | ]) %> 18 | <% end %> 19 | <% end %> 20 | -------------------------------------------------------------------------------- /spec/controllers/convicted_drug_felony_details_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ConvictedDrugFelonyDetailsController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | convicted_drug_felony_name: "Anne Dog", 7 | completed_probation_or_parole: "1", 8 | } 9 | it_behaves_like "form controller unsuccessful update" 10 | 11 | describe "#show?" do 12 | context "when someone in household is convicted_drug_felony" do 13 | it "returns true" do 14 | application = create(:interview, anyone_convicted_drug_felony: "yes") 15 | 16 | show = ConvictedDrugFelonyDetailsController.show?(application) 17 | expect(show).to eq(true) 18 | end 19 | end 20 | 21 | context "when no one in household is convicted_drug_felony" do 22 | it "returns false" do 23 | application = create(:interview, anyone_convicted_drug_felony: "no") 24 | 25 | show = ConvictedDrugFelonyDetailsController.show?(application) 26 | expect(show).to eq(false) 27 | end 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Code for America 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /spec/controllers/parent_not_in_home_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ParentNotInHomeController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | parent_not_in_home: "true", 7 | } 8 | it_behaves_like "yes no forms controller with boolean values" 9 | 10 | describe "#show?" do 11 | context "when children in home" do 12 | it "returns true" do 13 | application = create(:interview, 14 | navigator: build(:navigator, 15 | interview_type: "application", 16 | children_in_home: true)) 17 | 18 | show = ParentNotInHomeController.show?(application) 19 | expect(show).to eq(true) 20 | end 21 | end 22 | 23 | context "when no children in home" do 24 | it "returns false" do 25 | application = create(:interview, 26 | navigator: build(:navigator, 27 | interview_type: "application", 28 | children_in_home: false)) 29 | 30 | show = ParentNotInHomeController.show?(application) 31 | expect(show).to eq(false) 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /config/initializers/content_security_policy.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Define an application-wide content security policy 4 | # For further information see the following documentation 5 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy 6 | 7 | # Rails.application.config.content_security_policy do |policy| 8 | # policy.default_src :self, :https 9 | # policy.font_src :self, :https, :data 10 | # policy.img_src :self, :https, :data 11 | # policy.object_src :none 12 | # policy.script_src :self, :https 13 | # policy.style_src :self, :https 14 | 15 | # # Specify URI for violation reports 16 | # # policy.report_uri "/csp-violation-report-endpoint" 17 | # end 18 | 19 | # If you are using UJS then enable automatic nonce generation 20 | # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } 21 | 22 | # Report CSP violations to a specified URI 23 | # For further information see the following documentation: 24 | # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only 25 | # Rails.application.config.content_security_policy_report_only = true 26 | -------------------------------------------------------------------------------- /db/migrate/20181217184940_add_living_expenses_to_interview.rb: -------------------------------------------------------------------------------- 1 | class AddLivingExpensesToInterview < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :interviews, :has_rent_mortgage_expense, :boolean, default: false 4 | add_column :interviews, :has_space_rent_expense, :boolean, default: false 5 | add_column :interviews, :has_property_tax_expense, :boolean, default: false 6 | add_column :interviews, :has_child_support_expense, :boolean, default: false 7 | add_column :interviews, :has_home_insurance_expense, :boolean, default: false 8 | add_column :interviews, :has_child_care_expense, :boolean, default: false 9 | add_column :interviews, :has_medical_care_medicine_expense, :boolean, default: false 10 | add_column :interviews, :has_wood_coal_expense, :boolean, default: false 11 | add_column :interviews, :has_telephone_expense, :boolean, default: false 12 | add_column :interviews, :has_water_sewage_expense, :boolean, default: false 13 | add_column :interviews, :has_electricity_expense, :boolean, default: false 14 | add_column :interviews, :has_propane_gas_expense, :boolean, default: false 15 | add_column :interviews, :has_oil_expense, :boolean, default: false 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/forms/any_not_listed_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyNotListedForm do 4 | describe "validations" do 5 | context "when any_not_listed is provided" do 6 | it "is valid" do 7 | form = AnyNotListedForm.new( 8 | nil, 9 | any_not_listed: "yes", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when any_not_listed is not provided" do 17 | it "is invalid" do 18 | form = AnyNotListedForm.new( 19 | nil, 20 | any_not_listed: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:any_not_listed]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | any_not_listed: "yes", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = AnyNotListedForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.any_not_listed).to eq "yes" 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/views/residency/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about the #{applicant_or_client}'s residency." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_radio_set_with_follow_up :lived_outside_alaska, 6 | label_text: "Has the #{applicant_or_client} ever lived outside of Alaska?", 7 | collection: [ 8 | { value: :yes, label: "Yes, they have lived outside of Alaska" }, 9 | { value: :no, label: "No, they have always lived here." }, 10 | ], 11 | first_follow_up: -> { f.cfa_input_field :arrival_in_alaska, 12 | "When was the #{applicant_or_client}'s most recent arrival in Alaska?" } 13 | %> 14 | 15 | <%= f.cfa_radio_set :intend_to_stay, 16 | label_text: "Does the #{applicant_or_client} intend to remain a resident and stay in Alaska?", 17 | help_text: "Answer 'YES' unless they have definite plans to leave Alaska", 18 | collection: [ 19 | { value: :yes, label: "Yes, they intend to remain in Alaska" }, 20 | { value: :no, label: "No, they do not intend to remain in Alaska." }, 21 | ] 22 | %> 23 | <% end %> 24 | <% end %> 25 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "bin_helpers" 4 | 5 | chdir APP_ROOT do 6 | # This script is a starting point to setup your application. 7 | # Add necessary setup steps to this file. 8 | 9 | step "Adding heroku git remotes" do 10 | system!("heroku git:remote -a alaska-fee-agent-assister -r ak-staging") 11 | end 12 | 13 | step "Installing pdftk, a PDF library (requires Homebrew)" do 14 | if cli_installed?("pdftk") 15 | puts "pdftk already installed." 16 | else 17 | puts "Install PDFtk from the developer website." 18 | system!("open https://www.pdflabs.com/tools/pdftk-server/") 19 | abort(colorize(light_red: "\n== Install PDFTK before continuing ==")) 20 | end 21 | end 22 | 23 | step "Installing bundler and gem dependencies" do 24 | system!("gem install bundler --conservative") 25 | system("bundle check") || system!("bundle install") 26 | end 27 | 28 | step "Preparing database" do 29 | system! "bin/rails db:setup" 30 | end 31 | 32 | step "Removing old logs and tempfiles" do 33 | system! "bin/rails log:clear tmp:clear" 34 | end 35 | 36 | step "Restarting application server" do 37 | system! "bin/rails restart" 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require_relative "boot" 2 | 3 | require "rails" 4 | # Pick the frameworks you want: 5 | require "active_model/railtie" 6 | require "active_job/railtie" 7 | require "active_record/railtie" 8 | require "active_storage/engine" 9 | require "action_controller/railtie" 10 | require "action_mailer/railtie" 11 | require "action_view/railtie" 12 | require "action_cable/engine" 13 | require "sprockets/railtie" 14 | # require "rails/test_unit/railtie" 15 | 16 | # Require the gems listed in Gemfile, including any gems 17 | # you've limited to :test, :development, or :production. 18 | Bundler.require(*Rails.groups) 19 | 20 | module AlaskaFeeAgentAssister 21 | class Application < Rails::Application 22 | # Initialize configuration defaults for originally generated Rails version. 23 | config.load_defaults 5.2 24 | 25 | # Settings in config/environments/* take precedence over those specified here. 26 | # Application configuration can go into files in config/initializers 27 | # -- all .rb files in that directory are automatically loaded after loading 28 | # the framework and any gems in your application. 29 | 30 | # Don't generate system test files. 31 | config.generators.system_tests = nil 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/forms/any_away_from_home_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyAwayFromHomeForm do 4 | describe "validations" do 5 | context "when any_away_from_home is provided" do 6 | it "is valid" do 7 | form = AnyAwayFromHomeForm.new( 8 | nil, 9 | any_away_from_home: "no", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when some_attribute is not provided" do 17 | it "is invalid" do 18 | form = AnyAwayFromHomeForm.new( 19 | nil, 20 | any_away_from_home: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:any_away_from_home]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | any_away_from_home: "yes", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = AnyAwayFromHomeForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.any_away_from_home).to eq "yes" 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/views/convicted_drug_felony_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Tell us about the person who has been convicted of a drug-related felony." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_input_field :convicted_drug_felony_name, "What is the person's name?" %> 6 | <%= f.cfa_checkbox_set_with_none(:convicted_drug_felony_details, [ 7 | { 8 | label: "Successfully completed or satisfactorily served a period of probation or parole", 9 | method: :completed_probation_or_parole, 10 | }, 11 | { 12 | label: "Currently serving or successfully completed the mandatory participation in a drug or alcohol treatment program", 13 | method: :completed_treatment_program, 14 | }, 15 | { 16 | label: "Taken action towards rehabilitation, including participation in a drug or alcohol treatment program", 17 | method: :taken_action_towards_rehabilitation, 18 | }, 19 | { 20 | label: "Successfully complied with the requirements of the person's reentry plan", 21 | method: :complied_with_reentry, 22 | }, 23 | ]) %> 24 | <% end %> 25 | <% end %> 26 | -------------------------------------------------------------------------------- /bin/bin_helpers.rb: -------------------------------------------------------------------------------- 1 | require "pathname" 2 | require "fileutils" 3 | include FileUtils 4 | 5 | # path to your application root. 6 | APP_ROOT = Pathname.new File.expand_path("../../", __FILE__) 7 | 8 | COLOR_CODES = { 9 | black: 30, 10 | blue: 34, 11 | brown: 33, 12 | cyan: 36, 13 | dark_gray: 90, 14 | green: 32, 15 | light_blue: 94, 16 | light_cyan: 96, 17 | light_gray: 37, 18 | light_green: 92, 19 | light_purple: 95, 20 | light_red: 91, 21 | light_yellow: 93, 22 | purple: 35, 23 | red: 31, 24 | white: 97, 25 | yellow: 33, 26 | }.freeze 27 | 28 | def system!(*args) 29 | puts colorize(light_cyan: args.join(" ")) 30 | system(*args) || abort(colorize(light_red: "\n== Command #{args} failed ==")) 31 | end 32 | 33 | def step(name) 34 | puts colorize(light_yellow: "\n== #{name} ==") 35 | yield 36 | end 37 | 38 | def colorize(colors_and_strings) 39 | colors_and_strings.map do |color, string| 40 | "\e[#{COLOR_CODES[color]}m#{string}\e[0m" 41 | end.join 42 | end 43 | 44 | def brew_installed?(formulae) 45 | system "brew ls --versions #{formulae}" 46 | end 47 | 48 | def cli_installed?(command_name) 49 | system "which #{command_name}" 50 | end 51 | 52 | def gem_installed?(gem) 53 | system "gem list | grep ^#{gem}[[:space:]]" 54 | end 55 | -------------------------------------------------------------------------------- /spec/forms/interim_assistance_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe InterimAssistanceForm do 4 | describe "validations" do 5 | context "when interim_assistance is provided" do 6 | it "is valid" do 7 | form = InterimAssistanceForm.new( 8 | nil, 9 | interim_assistance: true, 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | end 16 | 17 | describe "#save" do 18 | let(:interview) { create :interview, :with_navigator } 19 | 20 | let(:valid_params) do 21 | { 22 | interim_assistance: true, 23 | } 24 | end 25 | 26 | it "persists the values to the correct models" do 27 | form = InterimAssistanceForm.new(interview, valid_params) 28 | form.valid? 29 | form.save 30 | 31 | interview.reload 32 | 33 | expect(interview.navigator.interim_assistance).to be_truthy 34 | end 35 | end 36 | 37 | describe ".from_interview" do 38 | it "assigns values from interview" do 39 | interview = create(:interview, navigator: build(:navigator, interim_assistance: false)) 40 | 41 | form = InterimAssistanceForm.from_interview(interview) 42 | 43 | expect(form.interim_assistance).to be_falsey 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /app/views/layouts/left_aligned.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :content do %> 2 |
3 |
4 | <%= form_with url: current_path, method: :put, local: true %> 5 |
6 |

7 | <%= yield :card_title %> 8 |

9 | 10 | <% if content_for? :card_help %> 11 |

12 | <%= yield :card_help %> 13 |

14 | <% end %> 15 |
16 | 17 |
18 | <%= yield :card_body %> 19 |
20 | 21 | 32 | 33 |
34 |
35 | <% end %> 36 | 37 | <%= render template: 'layouts/application' %> 38 | -------------------------------------------------------------------------------- /app/controllers/admin/interviews_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class InterviewsController < Admin::ApplicationController 3 | # To customize the behavior of this controller, 4 | # you can overwrite any of the RESTful actions. For example: 5 | # 6 | # def index 7 | # super 8 | # @resources = Interview. 9 | # page(params[:page]). 10 | # per(10) 11 | # end 12 | 13 | # Define a custom finder by overriding the `find_resource` method: 14 | # def find_resource(param) 15 | # Interview.find_by!(slug: param) 16 | # end 17 | 18 | # See https://administrate-prototype.herokuapp.com/customizing_controller_actions 19 | # for more information 20 | 21 | def show 22 | respond_to do |format| 23 | format.html do 24 | super 25 | end 26 | format.pdf do 27 | final_output_file = Tempfile.new(["final_output", ".pdf"], "tmp/") 28 | 29 | PdfForms.new.fill_form( 30 | "app/lib/pdfs/FA1.pdf", 31 | final_output_file.path, 32 | Fa1InterviewPdfDecorator.new(find_resource(params[:id])).attributes, 33 | ) 34 | 35 | send_file final_output_file, type: "application/pdf", disposition: "inline" 36 | end 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /app/views/important_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Let's review some of the important details." %> 2 | 3 | <% content_for :card_body do %> 4 |
5 |
6 |

Fee agent details

7 | <%= current_interview.fee_agent_name %>
8 | <%= current_interview.fee_agent_email %>
9 | <%= format_phone_number(current_interview.fee_agent_phone_number) %> 10 |
11 |
12 |

Applicant details

13 | <%= current_interview.client_name %>
14 | SSN: XXX-XX-<%= current_interview.client_last_four_ssn %> 15 |
16 |
17 |

This <%= application_or_renewal %> is for

18 | <%= "SNAP
".html_safe if current_interview.selected_snap %> 19 | <%= "Medicaid
".html_safe if current_interview.selected_medicaid %> 20 | <%= "General Relief
".html_safe if current_interview.selected_general_relief %> 21 | <%= "Alaska Temporary Assistance
".html_safe if current_interview.selected_atap %> 22 | <%= "Adult Public Assistance
".html_safe if current_interview.selected_apa %> 23 | <%= "CAMA" if current_interview.selected_cama %> 24 |
25 |
26 | <% end %> 27 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | git_source(:github) { |repo| "https://github.com/#{repo}.git" } 3 | 4 | ruby "2.5.3" 5 | 6 | gem "rails", "~> 5.2.1" 7 | 8 | gem "administrate" 9 | gem "administrate-field-enum" 10 | gem "attr_encrypted" 11 | gem "bootsnap", ">= 1.1.0", require: false 12 | gem "cfa-styleguide", git: "https://github.com/codeforamerica/cfa-styleguide-gem" 13 | gem "handlebars_assets" 14 | gem "jbuilder", "~> 2.5" 15 | gem "lograge" 16 | gem "pdf-forms" 17 | gem "pg", ">= 0.18", "< 2.0" 18 | gem "puma", "~> 3.11" 19 | gem "sass-rails", "~> 5.0" 20 | 21 | group :development, :test do 22 | gem "brakeman", require: false 23 | gem "bundler-audit", require: false 24 | gem "byebug", platforms: %i[mri mingw x64_mingw] 25 | gem "factory_bot_rails" 26 | gem "pry-byebug" 27 | gem "rails-controller-testing" 28 | gem "rspec-rails" 29 | end 30 | 31 | group :development do 32 | gem "listen", ">= 3.0.5", "< 3.2" 33 | gem "rubocop", require: false 34 | gem "rubocop-rspec", require: false 35 | gem "spring" 36 | gem "spring-watcher-listen", "~> 2.0.0" 37 | gem "web-console", ">= 3.3.0" 38 | end 39 | 40 | group :test do 41 | gem "capybara" 42 | gem "capybara-selenium" 43 | gem "chromedriver-helper" 44 | gem "rspec_junit_formatter" 45 | end 46 | 47 | gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] 48 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's 5 | // vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. JavaScript code in this file should be added after the last require_* statement. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require cfa_styleguide_main 14 | //= require activestorage 15 | //= require handlebars.runtime 16 | //= require_tree ./templates 17 | //= require_tree . 18 | 19 | var showMore = (function() { 20 | return { 21 | init: function() { 22 | $('.show-more').each(function(index, showmore) { 23 | $(showmore).find('.show-more__button').click(function(e) { 24 | e.preventDefault(); 25 | $(showmore).addClass('is-open'); 26 | }) 27 | }); 28 | } 29 | } 30 | })(); 31 | 32 | $(document).ready(function() { 33 | showMore.init(); 34 | }); 35 | -------------------------------------------------------------------------------- /spec/features/admin/admin_dashboard_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.feature "Admin viewing dashboard" do 4 | include PdfHelper 5 | 6 | context "logged in admin" do 7 | def basic_auth! 8 | encoded_login = ["admin:password"].pack("m*") 9 | page.driver.header "Authorization", "Basic #{encoded_login}" 10 | end 11 | 12 | before do 13 | basic_auth! 14 | end 15 | 16 | scenario "viewing details for an interview" do 17 | interview = create(:interview) 18 | 19 | visit admin_root_path 20 | 21 | expect(page).to have_content("Interview") 22 | 23 | click_on interview.id 24 | 25 | expect(page).to have_content("Interview ##{interview.id}") 26 | end 27 | 28 | scenario "searching isn't broken" do 29 | visit admin_root_path(search: "asdf") 30 | 31 | expect(page).to have_content("Interview") 32 | end 33 | 34 | scenario "viewing a pdf" do 35 | create(:interview, fee_agent_name: "Jessie Tester") 36 | 37 | visit admin_root_path 38 | 39 | click_on "Download" 40 | 41 | temp_file = write_raw_pdf_to_temp_file(source: page.source) 42 | pdf_values = filled_in_values(temp_file.path) 43 | 44 | # Minimal testing to make sure PDF isn't corrupted 45 | expect(pdf_values["fa_name"]).to include("Jessie Tester") 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/forms/convicted_drug_felony_details_form.rb: -------------------------------------------------------------------------------- 1 | class ConvictedDrugFelonyDetailsForm < Form 2 | set_attributes_for :interview, 3 | :convicted_drug_felony_name, 4 | :completed_probation_or_parole, 5 | :completed_treatment_program, 6 | :taken_action_towards_rehabilitation, 7 | :complied_with_reentry, 8 | :none 9 | 10 | validates_presence_of :convicted_drug_felony_name, message: "Make sure to include their name." 11 | validate :at_least_one_drug_felony_or_none_selected 12 | 13 | def save 14 | enum_keys = %i[ 15 | completed_probation_or_parole 16 | completed_treatment_program 17 | taken_action_towards_rehabilitation 18 | complied_with_reentry 19 | ] 20 | enum_values = attributes_for(:interview).slice(*enum_keys) 21 | enum_values.update(enum_values) { |_, val| val == "1" ? "yes" : "no" } 22 | interview.update(enum_values.merge(attributes_for(:interview).except(*enum_keys).except(:none))) 23 | end 24 | 25 | private 26 | 27 | def at_least_one_drug_felony_or_none_selected 28 | return true if attributes_for(:interview).except(:convicted_drug_felony_name).values.any? { |value| value == "1" } 29 | 30 | errors.add(:convicted_drug_felony_details, "Please select at least one option or 'none of the above.'") 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/forms/what_living_expenses_form.rb: -------------------------------------------------------------------------------- 1 | class WhatLivingExpensesForm < Form 2 | set_attributes_for :interview, 3 | :has_rent_mortgage_expense, 4 | :has_space_rent_expense, 5 | :has_property_tax_expense, 6 | :has_child_support_expense, 7 | :has_home_insurance_expense, 8 | :has_child_care_expense, 9 | :has_medical_care_medicine_expense, 10 | :has_wood_coal_expense, 11 | :has_telephone_expense, 12 | :has_water_sewage_expense, 13 | :has_electricity_expense, 14 | :has_propane_gas_expense, 15 | :has_oil_expense, 16 | :none 17 | 18 | validate :at_least_one_expense_or_none_selected 19 | 20 | def save 21 | interview.update(attributes_for(:interview).except(:none)) 22 | end 23 | 24 | def self.existing_attributes(interview) 25 | attributes_to_checkbox_values(interview, attribute_names.reject { |name| name == :none }) 26 | end 27 | 28 | private 29 | 30 | def at_least_one_expense_or_none_selected 31 | return true if attributes_for(:interview).values.any? { |value| value == "1" } 32 | 33 | errors.add(:living_expenses, "Please select at least one option or 'none of the above.'") 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /spec/controllers/verification_guidance_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe VerificationGuidanceController do 4 | it_behaves_like "form controller always shows" 5 | 6 | context "with session" do 7 | let(:current_interview) { create(:interview, :with_navigator) } 8 | 9 | before do 10 | session[:current_interview_id] = current_interview.id 11 | end 12 | 13 | describe "#current_interview" do 14 | it "returns the Interview from the id in the session" do 15 | expect(controller.current_interview).to eq current_interview 16 | end 17 | end 18 | 19 | describe "#edit" do 20 | it "sets the form and renders the template" do 21 | get :edit 22 | 23 | expect(response).to render_template(:edit) 24 | expect(assigns[:interview]).to be_a VerificationGuidanceInterviewDecorator 25 | end 26 | end 27 | 28 | describe "#current_path" do 29 | it "returns the path for this route" do 30 | expect(controller.current_path).to eq "/screens/#{controller.class.to_param}" 31 | end 32 | end 33 | 34 | describe "#next_path" do 35 | it "returns the next path from this controller" do 36 | form_navigation = FormNavigation.new(controller) 37 | 38 | expect(controller.next_path).to eq "/screens/#{form_navigation.next.to_param}" 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/generators/screen/screen_generator.rb: -------------------------------------------------------------------------------- 1 | class ScreenGenerator < Rails::Generators::NamedBase 2 | source_root File.expand_path("templates", __dir__) 3 | class_option :doc, type: :boolean, default: false, desc: "Include documentation." 4 | 5 | def generate_model 6 | generate_form_model 7 | generate_form_controller 8 | generate_form_view 9 | generate_form_model_spec 10 | generate_form_controller_spec 11 | 12 | puts "\nDone generating the #{model} screen!" 13 | puts "Be sure to add #{model}Controller in the desired application order in `form_navigation.rb`" 14 | end 15 | 16 | private 17 | 18 | alias_method :model, :name 19 | 20 | def generate_form_model 21 | template "form_model.template", "app/forms/#{model.underscore}_form.rb" 22 | end 23 | 24 | def generate_form_model_spec 25 | template "form_model_spec.template", 26 | "spec/forms/#{model.underscore}_form_spec.rb" 27 | end 28 | 29 | def generate_form_controller 30 | template "form_controller.template", 31 | "app/controllers/#{model.underscore}_controller.rb" 32 | end 33 | 34 | def generate_form_controller_spec 35 | template "form_controller_spec.template", 36 | "spec/controllers/#{model.underscore}_controller_spec.rb" 37 | end 38 | 39 | def generate_form_view 40 | template "form_view.template", 41 | "app/views/#{model.underscore}/edit.html.erb" 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /app/views/expenses_payment_details/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Explain how the household has been supporting itself before applying for assistance." %> 2 | 3 | <% content_for :card_body do %> 4 | <%= fields_for(:form, @form, builder: Cfa::Styleguide::CfaFormBuilder) do |f| %> 5 | <%= f.cfa_textarea :expenses_payment_details, 6 | "

If the #{applicant_or_client} claimed \"no income,\" explain how the expenses have been paid, or note that they are due or unpaid.

7 | 8 |
9 |
10 | 11 |
12 | 13 |
14 | The more details you can provide, the more likely the #{applicant_or_client} can be approved without issues. 15 |
16 |
", 17 | options: { 18 | rows: "4", 19 | placeholder: "E.g., lives with brother - doesn’t pay rent. Gets PFD of $1600, monthly SSA payments of $500, monthly food box from food bank, relies on subsistence fishing and hunting.", 20 | } %> 21 | <% end %> 22 | <% end %> 23 | -------------------------------------------------------------------------------- /spec/controllers/want_direct_deposit_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe WantDirectDepositController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller successful update", { 6 | want_direct_deposit: true, 7 | } 8 | it_behaves_like "yes no forms controller with boolean values" 9 | 10 | describe "#show?" do 11 | context "when applicant is applying for Alaska Temporary Assistance" do 12 | it "returns true" do 13 | application = create(:interview, :with_navigator, selected_atap: true) 14 | 15 | show = WantDirectDepositController.show?(application) 16 | expect(show).to eq(true) 17 | end 18 | end 19 | 20 | context "when applicant is applying for Adult Public Assistance" do 21 | it "returns true" do 22 | application = create(:interview, :with_navigator, selected_apa: true) 23 | 24 | show = WantDirectDepositController.show?(application) 25 | expect(show).to eq(true) 26 | end 27 | end 28 | 29 | context "when applicant is not applying for Adult Public Assistance or Alaska Temporary Assistance" do 30 | it "returns false" do 31 | application = create(:interview, selected_apa: false, selected_atap: false) 32 | 33 | skip_step = WantDirectDepositController.show?(application) 34 | expect(skip_step).to eq(false) 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/support/shared_examples/forms_controller_base_behavior.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.shared_examples_for "form controller base behavior" do |is_last_section| 4 | context "with session" do 5 | let(:current_interview) { create(:interview, :with_navigator) } 6 | 7 | before do 8 | session[:current_interview_id] = current_interview.id 9 | end 10 | 11 | describe "#current_interview" do 12 | it "returns the Interview from the id in the session" do 13 | expect(controller.current_interview).to eq current_interview 14 | end 15 | end 16 | 17 | describe "#edit" do 18 | it "sets the form and renders the template" do 19 | get :edit 20 | 21 | expect(response).to render_template(:edit) 22 | expect(assigns[:form]).to be_a Form 23 | end 24 | end 25 | 26 | describe "#current_path" do 27 | it "returns the path for this route" do 28 | expect(controller.current_path).to eq "/screens/#{controller.class.to_param}" 29 | end 30 | end 31 | 32 | describe "#next_path" do 33 | it "returns the next path from this controller" do 34 | form_navigation = FormNavigation.new(controller) 35 | 36 | if is_last_section 37 | expect(controller.next_path).to eq "/" 38 | else 39 | expect(controller.next_path).to eq "/screens/#{form_navigation.next.to_param}" 40 | end 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /spec/forms/other_information_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe OtherInformationForm do 4 | describe "validations" do 5 | context "when other_info is provided" do 6 | it "is valid" do 7 | form = OtherInformationForm.new( 8 | nil, 9 | other_info: "best attribute", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when other_info is not provided" do 17 | it "is still valid" do 18 | form = OtherInformationForm.new( 19 | nil, 20 | other_info: nil, 21 | ) 22 | 23 | expect(form).to be_valid 24 | end 25 | end 26 | end 27 | 28 | describe "#save" do 29 | let(:interview) { create :interview } 30 | 31 | let(:valid_params) do 32 | { 33 | other_info: "I'm hungry", 34 | } 35 | end 36 | 37 | it "persists the values to the correct models" do 38 | form = OtherInformationForm.new(interview, valid_params) 39 | form.valid? 40 | form.save 41 | 42 | interview.reload 43 | 44 | expect(interview.other_info).to eq "I'm hungry" 45 | end 46 | end 47 | 48 | describe ".from_interview" do 49 | it "assigns values from interview" do 50 | interview = create(:interview, other_info: "What up") 51 | 52 | form = OtherInformationForm.from_interview(interview) 53 | 54 | expect(form.other_info).to eq "What up" 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /spec/forms/cama_details_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe CamaDetailsForm do 4 | describe "validations" do 5 | context "when cama_details is provided" do 6 | it "is valid" do 7 | form = CamaDetailsForm.new( 8 | nil, 9 | cama_details: "best attribute", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when some_attribute is not provided" do 17 | it "is still valid" do 18 | form = CamaDetailsForm.new( 19 | nil, 20 | cama_details: nil, 21 | ) 22 | 23 | expect(form).to be_valid 24 | end 25 | end 26 | end 27 | 28 | describe "#save" do 29 | let(:interview) { create :interview } 30 | 31 | let(:valid_params) do 32 | { 33 | cama_details: "Lots of medical problems to report.", 34 | } 35 | end 36 | 37 | it "persists the values to the correct models" do 38 | form = CamaDetailsForm.new(interview, valid_params) 39 | form.valid? 40 | form.save 41 | 42 | interview.reload 43 | 44 | expect(interview.cama_details).to eq "Lots of medical problems to report." 45 | end 46 | end 47 | 48 | describe ".from_interview" do 49 | it "assigns values from interview" do 50 | interview = create(:interview, cama_details: "SOMETHING") 51 | 52 | form = CamaDetailsForm.from_interview(interview) 53 | 54 | expect(form.cama_details).to eq "SOMETHING" 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /config/puma.rb: -------------------------------------------------------------------------------- 1 | # Puma can serve each request in a thread from an internal thread pool. 2 | # The `threads` method setting takes two numbers: a minimum and maximum. 3 | # Any libraries that use thread pools should be configured to match 4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum 5 | # and maximum; this matches the default thread size of Active Record. 6 | # 7 | threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 8 | threads threads_count, threads_count 9 | 10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000. 11 | # 12 | port ENV.fetch("PORT") { 3000 } 13 | 14 | # Specifies the `environment` that Puma will run in. 15 | # 16 | environment ENV.fetch("RAILS_ENV") { "development" } 17 | 18 | # Specifies the number of `workers` to boot in clustered mode. 19 | # Workers are forked webserver processes. If using threads and workers together 20 | # the concurrency of the application would be max `threads` * `workers`. 21 | # Workers do not work on JRuby or Windows (both of which do not support 22 | # processes). 23 | # 24 | # workers ENV.fetch("WEB_CONCURRENCY") { 2 } 25 | 26 | # Use the `preload_app!` method when specifying a `workers` number. 27 | # This directive tells Puma to first boot the application and load code 28 | # before forking the application. This takes advantage of Copy On Write 29 | # process behavior so workers use less memory. 30 | # 31 | # preload_app! 32 | 33 | # Allow puma to be restarted by `rails restart` command. 34 | plugin :tmp_restart 35 | -------------------------------------------------------------------------------- /app/views/any_not_listed/edit.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :card_title, "Is there anyone who is living in the home but is not listed on the #{application_or_renewal}?".html_safe %> 2 | 3 | <% content_for :card_help, "The context helps DPA in case there are other people in the home who need to be included." %> 4 | 5 | <% content_for :card_body do %> 6 |
7 |

Who needs to be listed?

8 |
9 | 17 |
18 |
19 | <% end %> 20 | -------------------------------------------------------------------------------- /lib/generators/screen/templates/form_model.template: -------------------------------------------------------------------------------- 1 | class <%= model.camelcase %>Form < Form 2 | <%- if options.doc? -%> 3 | # Whitelist top-level parameter names for Interview, e.g. 4 | # 5 | # given params: { form: { living_situation: "stable_housing" } } 6 | # 7 | # set_attributes_for :interview, :living_situation 8 | # 9 | # Delete the method if you aren't updating the Interview. 10 | <%- end -%> 11 | set_attributes_for :interview, :foo 12 | 13 | <%- if options.doc? -%> 14 | # Whitelist top-level parameter names for InterviewNavigator, e.g. 15 | # 16 | # given params: { form: { anyone_requesting_food: "yes" } } 17 | # 18 | # set_attributes_for :navigator, :anyone_requesting_food 19 | # 20 | # These attributes should be used for application flow, and not to fill out 21 | # the application PDF. 22 | # 23 | # Delete the method if you aren't updating the InterviewNavigator. 24 | <%- end -%> 25 | set_attributes_for :navigator, :street_address, :city, :zip_code 26 | 27 | <%- if options.doc? -%> 28 | # Add any validations below. Be sure to include helpful error messages. 29 | <%- end -%> 30 | validates_presence_of :street_address, message: "Please add your street address" 31 | validates_presence_of :city, message: "Please add the city you live in" 32 | validates :zip_code, length: { is: 5, message: "Please add a five digit ZIP code" } 33 | 34 | def save 35 | interview.update(attributes_for(:interview)) 36 | interview.navigator.update(attributes_for(:navigator)) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/generators/screen/anyone/templates/details/form_model_spec.template: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe <%= details_class_name %>Form do 4 | describe "validations" do 5 | context "when some_attribute is provided" do 6 | it "is valid" do 7 | form = <%= details_class_name %>Form.new( 8 | nil, 9 | some_attribute: "best attribute", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when some_attribute is not provided" do 17 | it "is invalid" do 18 | form = <%= details_class_name %>Form.new( 19 | nil, 20 | some_attribute: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:some_attribute]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | # some attributes 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = <%= details_class_name %>Form.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | # expectations 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, :with_navigator) 52 | 53 | form = <%= details_class_name %>Form.from_interview(interview) 54 | 55 | # expectation 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/support/shared_examples/anyone_form.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.shared_examples_for "anyone form" do |method_name| 4 | describe "validations" do 5 | context "when #{method_name} is provided" do 6 | it "is valid" do 7 | form = described_class.new( 8 | nil, 9 | method_name => "yes", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when #{method_name} is not provided" do 17 | it "is invalid" do 18 | form = described_class.new( 19 | nil, 20 | method_name => "unfilled", 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[method_name.to_sym]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:valid_params) do 31 | { 32 | method_name => "yes", 33 | } 34 | end 35 | 36 | it "persists the values to the correct models" do 37 | interview = create(:interview) 38 | form = described_class.new(interview, valid_params) 39 | form.valid? 40 | form.save 41 | 42 | interview.reload 43 | 44 | expect(form.public_send(method_name)).to eq("yes") 45 | end 46 | end 47 | 48 | describe ".from_interview" do 49 | it "assigns values from interview" do 50 | interview = create(:interview, method_name => "no") 51 | 52 | form = described_class.from_interview(interview) 53 | 54 | expect(form.public_send(method_name)).to eq("no") 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /spec/forms/tribe_details_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe TribeDetailsForm do 4 | describe "validations" do 5 | context "when tribe_details is provided" do 6 | it "is valid" do 7 | form = TribeDetailsForm.new( 8 | nil, 9 | tribe_details: "best attribute", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when tribe_details is not provided" do 17 | it "is invalid" do 18 | form = TribeDetailsForm.new( 19 | nil, 20 | tribe_details: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:tribe_details]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | tribe_details: "WHATEVER THOUGH", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = TribeDetailsForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.tribe_details).to eq "WHATEVER THOUGH" 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, tribe_details: "SOMETHING SOMETHING") 52 | 53 | form = TribeDetailsForm.from_interview(interview) 54 | 55 | expect(form.tribe_details).to eq "SOMETHING SOMETHING" 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /app/assets/stylesheets/molecules/_show-more.scss: -------------------------------------------------------------------------------- 1 | // Original implementation (with specs): 2 | // https://github.com/codeforamerica/gcf-backend/commit/410a93ee58b69c88919a2a59d73a9320fc952004 3 | 4 | .show-more { 5 | text-align: left; 6 | margin-bottom: 3em; 7 | position: relative; 8 | 9 | &:after { 10 | content: ''; 11 | display: block; 12 | position: absolute; 13 | bottom: 0em; 14 | left: 0; 15 | right: 0; 16 | background-image: linear-gradient(-180deg, rgba(255,255,255,0.00) 0%, #FFFFFF 75%); 17 | height: 7em; 18 | border-bottom: 2px solid #EAEAE9; // $color-light-grey 19 | } 20 | 21 | &.is-open { 22 | border-bottom: 0; 23 | 24 | &:after { 25 | display: none; 26 | } 27 | .show-more__content { 28 | max-height: none; 29 | } 30 | .show-more__button { 31 | display: none; 32 | } 33 | } 34 | } 35 | 36 | .show-more--long { 37 | .show-more__content { 38 | max-height: 30rem; 39 | } 40 | } 41 | 42 | .show-more__button { 43 | font-size: 1.6rem; // $font-size-small 44 | display: inline-block; 45 | padding: .2em .4em; 46 | border-radius: 30px; 47 | border: 2px solid #EAEAE9; // $color-light-grey 48 | text-decoration: none; 49 | position: absolute; 50 | bottom: -1.3em; 51 | left: 50%; 52 | z-index: 2; 53 | width: 8em; 54 | margin-left: -4em; 55 | text-align: center; 56 | background-color: #FFF; 57 | &:hover { 58 | background-color: #FAFAF9; // $color-background 59 | } 60 | } 61 | 62 | .show-more__content { 63 | max-height: 15rem; 64 | overflow: hidden; 65 | } 66 | -------------------------------------------------------------------------------- /lib/generators/screen/templates/form_model_spec.template: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe <%= model.camelcase %>Form do 4 | describe "validations" do 5 | context "when some_attribute is provided" do 6 | it "is valid" do 7 | form = <%= "#{model.camelcase}Form".classify %>.new( 8 | nil, 9 | some_attribute: "best attribute", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when some_attribute is not provided" do 17 | it "is invalid" do 18 | form = <%= "#{model.camelcase}Form".classify %>.new( 19 | nil, 20 | some_attribute: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:some_attribute]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | # some attributes 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = <%= "#{model.camelcase}Form".classify %>.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | # expectations 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, :with_navigator) 52 | 53 | form = <%= "#{model.camelcase}Form".classify %>.from_interview(interview) 54 | 55 | # expectation 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /app/models/interview.rb: -------------------------------------------------------------------------------- 1 | class Interview < ApplicationRecord 2 | has_one :navigator, 3 | dependent: :destroy 4 | 5 | has_many_attached :id_verifications 6 | 7 | attr_encrypted :client_last_four_ssn, key: CredentialsHelper.secret_key_for_ssn_encryption 8 | 9 | enum any_not_listed: { unfilled: 0, yes: 1, no: 2 }, _prefix: :any_not_listed 10 | enum any_away_from_home: { unfilled: 0, yes: 1, no: 2 }, _prefix: :any_away_from_home 11 | enum anyone_convicted_drug_felony: { unfilled: 0, yes: 1, no: 2 }, _prefix: :anyone_convicted_drug_felony 12 | enum completed_probation_or_parole: { unfilled: 0, yes: 1, no: 2 }, _prefix: :completed_probation_or_parole 13 | enum completed_treatment_program: { unfilled: 0, yes: 1, no: 2 }, _prefix: :completed_treatment_program 14 | enum taken_action_towards_rehabilitation: { unfilled: 0, yes: 1, no: 2 }, 15 | _prefix: :taken_action_towards_rehabilitation 16 | enum complied_with_reentry: { unfilled: 0, yes: 1, no: 2 }, _prefix: :complied_with_reentry 17 | enum anyone_tribe: { unfilled: 0, yes: 1, no: 2 }, _prefix: :anyone_tribe 18 | enum anyone_stopped_work: { unfilled: 0, yes: 1, no: 2 }, _prefix: :anyone_stopped_work 19 | enum has_quest_card: { unfilled: 0, yes: 1, no: 2 }, _prefix: :has_quest_card 20 | enum anyone_filing_tax_return: { unfilled: 0, yes: 1, no: 2 }, _prefix: :anyone_filing_tax_return 21 | # Generated enums added above 22 | enum approved_for_disability: { unfilled: 0, yes: 1, no: 2 }, _prefix: :approved_for_disability 23 | enum intend_to_stay: { unfilled: 0, yes: 1, no: 2 }, _prefix: :intend_to_stay 24 | end 25 | -------------------------------------------------------------------------------- /spec/forms/rights_and_responsibilities_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe RightsAndResponsibilitiesForm do 4 | describe "validations" do 5 | context "when rights_and_responsibilities is provided" do 6 | it "is valid" do 7 | form = RightsAndResponsibilitiesForm.new( 8 | nil, 9 | explained_rights: "1", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when rights_and_responsibilities is false" do 17 | it "is invalid" do 18 | form = RightsAndResponsibilitiesForm.new( 19 | nil, 20 | explained_rights: "0", 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:explained_rights]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | explained_rights: "1", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = RightsAndResponsibilitiesForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.explained_rights).to be(true) 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, :with_navigator) 52 | 53 | form = RightsAndResponsibilitiesForm.from_interview(interview) 54 | 55 | expect(form.explained_rights).to eq("0") 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/forms/any_not_listed_names_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AnyNotListedNamesForm do 4 | describe "validations" do 5 | context "when any_not_listed_names is provided" do 6 | it "is valid" do 7 | form = AnyNotListedNamesForm.new( 8 | nil, 9 | any_not_listed_names: "yada yada", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when any_not_listed_names is not provided" do 17 | it "is invalid" do 18 | form = AnyNotListedNamesForm.new( 19 | nil, 20 | any_not_listed_names: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:any_not_listed_names]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | any_not_listed_names: "Sean Carter", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = AnyNotListedNamesForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.any_not_listed_names).to eq "Sean Carter" 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, any_not_listed_names: "Beyonce Knowles") 52 | 53 | form = AnyNotListedNamesForm.from_interview(interview) 54 | 55 | expect(form.any_not_listed_names).to eq "Beyonce Knowles" 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/forms/approved_for_disability_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe ApprovedForDisabilityForm do 4 | describe "validations" do 5 | context "when approved_for_disability is provided" do 6 | it "is valid" do 7 | form = ApprovedForDisabilityForm.new( 8 | nil, 9 | approved_for_disability: "yes", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when approved_for_disability is not provided" do 17 | it "is invalid" do 18 | form = ApprovedForDisabilityForm.new( 19 | nil, 20 | approved_for_disability: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:approved_for_disability]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | approved_for_disability: "yes", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = ApprovedForDisabilityForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.approved_for_disability).to eq("yes") 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, approved_for_disability: "yes") 52 | 53 | form = ApprovedForDisabilityForm.from_interview(interview) 54 | 55 | expect(form.approved_for_disability).to eq("yes") 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/forms/filing_tax_return_details_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe FilingTaxReturnDetailsForm do 4 | describe "validations" do 5 | context "when filing_tax_return_details is provided" do 6 | it "is valid" do 7 | form = FilingTaxReturnDetailsForm.new( 8 | nil, 9 | filing_tax_return_details: "a bunch of details", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when filing_tax_return_details is not provided" do 17 | it "is invalid" do 18 | form = FilingTaxReturnDetailsForm.new( 19 | nil, 20 | filing_tax_return_details: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:filing_tax_return_details]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | filing_tax_return_details: "YES YES YES", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = FilingTaxReturnDetailsForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.filing_tax_return_details).to eq "YES YES YES" 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, filing_tax_return_details: "OKAY OKAY OKAY") 52 | 53 | form = FilingTaxReturnDetailsForm.from_interview(interview) 54 | 55 | expect(form.filing_tax_return_details).to eq "OKAY OKAY OKAY" 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/forms/stopped_work_details_form_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe StoppedWorkDetailsForm do 4 | describe "validations" do 5 | context "when stopped_work_details is provided" do 6 | it "is valid" do 7 | form = StoppedWorkDetailsForm.new( 8 | nil, 9 | stopped_work_details: "Travelling circus act is closed for the winter.", 10 | ) 11 | 12 | expect(form).to be_valid 13 | end 14 | end 15 | 16 | context "when stopped_work_details is not provided" do 17 | it "is invalid" do 18 | form = StoppedWorkDetailsForm.new( 19 | nil, 20 | stopped_work_details: nil, 21 | ) 22 | 23 | expect(form).not_to be_valid 24 | expect(form.errors[:stopped_work_details]).to be_present 25 | end 26 | end 27 | end 28 | 29 | describe "#save" do 30 | let(:interview) { create :interview } 31 | 32 | let(:valid_params) do 33 | { 34 | stopped_work_details: "Laser tattoo removal only opened weekends now.", 35 | } 36 | end 37 | 38 | it "persists the values to the correct models" do 39 | form = StoppedWorkDetailsForm.new(interview, valid_params) 40 | form.valid? 41 | form.save 42 | 43 | interview.reload 44 | 45 | expect(interview.stopped_work_details).to eq "Laser tattoo removal only opened weekends now." 46 | end 47 | end 48 | 49 | describe ".from_interview" do 50 | it "assigns values from interview" do 51 | interview = create(:interview, stopped_work_details: "OKAY OKAY") 52 | 53 | form = StoppedWorkDetailsForm.from_interview(interview) 54 | 55 | expect(form.stopped_work_details).to eq "OKAY OKAY" 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /spec/controllers/add_id_verification_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe AddIdVerificationController do 4 | it_behaves_like "form controller base behavior" 5 | it_behaves_like "form controller always shows" 6 | 7 | describe "#update" do 8 | context "without interview" do 9 | it "redirects to homepage" do 10 | put :update, params: { form: {} } 11 | 12 | expect(response).to redirect_to(root_path) 13 | end 14 | end 15 | 16 | context "with interview" do 17 | let(:interview) do 18 | create(:interview, :with_navigator) 19 | end 20 | 21 | let(:active_storage_blob) do 22 | ActiveStorage::Blob.create_after_upload!( 23 | io: File.open(Rails.root.join("spec", "fixtures", "image.jpg")), 24 | filename: "image.jpg", 25 | content_type: "image/jpg", 26 | ) 27 | end 28 | 29 | before do 30 | session[:current_interview_id] = interview.id 31 | end 32 | 33 | context "with documents" do 34 | let(:valid_params) do 35 | { 36 | documents: ["", active_storage_blob.signed_id], 37 | } 38 | end 39 | 40 | it "redirects to next path" do 41 | put :update, params: { form: valid_params } 42 | 43 | expect(response).to redirect_to(subject.next_path) 44 | end 45 | end 46 | 47 | context "without documents (ie: Safari)" do 48 | let(:valid_params) do 49 | {} 50 | end 51 | 52 | it "redirects to next path" do 53 | put :update, params: { form: valid_params } 54 | 55 | expect(response).to redirect_to(subject.next_path) 56 | end 57 | end 58 | end 59 | end 60 | end 61 | --------------------------------------------------------------------------------