diff --git a/app/controllers/intakes_controller.rb b/app/controllers/intakes_controller.rb index bb93838ea92..ca08b861167 100644 --- a/app/controllers/intakes_controller.rb +++ b/app/controllers/intakes_controller.rb @@ -144,7 +144,6 @@ def intake_ui_hash { unread_messages: unread_messages? } end - # rubocop:disable Metrics/AbcSize def feature_toggle_ui_hash { useAmaActivationDate: FeatureToggle.enabled?(:use_ama_activation_date, user: current_user), @@ -161,11 +160,9 @@ def feature_toggle_ui_hash updatedAppealForm: FeatureToggle.enabled?(:updated_appeal_form, user: current_user), hlrScUnrecognizedClaimants: FeatureToggle.enabled?(:hlr_sc_unrecognized_claimants, user: current_user), vhaClaimReviewEstablishment: FeatureToggle.enabled?(:vha_claim_review_establishment, user: current_user), - metricsBrowserError: FeatureToggle.enabled?(:metrics_browser_error, user: current_user), - removeCompAndPenIntake: FeatureToggle.enabled?(:remove_comp_and_pen_intake, user: current_user) + metricsBrowserError: FeatureToggle.enabled?(:metrics_browser_error, user: current_user) } end - # rubocop:enable Metrics/AbcSize def user_information_ui_hash { diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 34f4569dbf4..fa6d8052b65 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -17,6 +17,7 @@ class IssuesController < ApplicationController handle_non_critical_error("issues", e) end + # rubocop:disable Layout/LineLength def create return record_not_found unless appeal @@ -26,24 +27,21 @@ def create if convert_to_bool(create_params[:mst_status]) || convert_to_bool(create_params[:pact_status]) issue_in_caseflow = appeal.issues.find { |iss| iss.vacols_sequence_id == issue.issseq.to_i } - create_legacy_issue_update_task(issue_in_caseflow) if FeatureToggle.enabled?( - :legacy_mst_pact_identification, user: RequestStore[:current_user] - ) + create_legacy_issue_update_task(issue_in_caseflow) if FeatureToggle.enabled?(:legacy_mst_pact_identification, user: RequestStore[:current_user]) end render json: { issues: json_issues }, status: :created end + # rubocop:enable Layout/LineLength - # rubocop:disable Metrics/AbcSize + # rubocop:disable Layout/LineLength, Metrics/AbcSize def update return record_not_found unless appeal issue = appeal.issues.find { |iss| iss.vacols_sequence_id == params[:vacols_sequence_id].to_i } if issue.mst_status != convert_to_bool(params[:issues][:mst_status]) || issue.pact_status != convert_to_bool(params[:issues][:pact_status]) - create_legacy_issue_update_task(issue) if FeatureToggle.enabled?( - :legacy_mst_pact_identification, user: RequestStore[:current_user] - ) + create_legacy_issue_update_task(issue) if FeatureToggle.enabled?(:legacy_mst_pact_identification, user: RequestStore[:current_user]) end Issue.update_in_vacols!( @@ -57,7 +55,7 @@ def update render json: { issues: json_issues }, status: :ok end - # rubocop:enable Metrics/AbcSize + # rubocop:enable Layout/LineLength, Metrics/AbcSize def destroy return record_not_found unless appeal @@ -71,7 +69,10 @@ def destroy private + # rubocop:disable Layout/LineLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity def create_legacy_issue_update_task(issue) + user = current_user + # close out any tasks that might be open open_issue_task = Task.where( assigned_to: SpecialIssueEditTeam.singleton @@ -82,98 +83,63 @@ def create_legacy_issue_update_task(issue) appeal: appeal, parent: appeal.root_task, assigned_to: SpecialIssueEditTeam.singleton, - assigned_by: current_user, - completed_by: current_user + assigned_by: user, + completed_by: user ) - task_instructions_helper(issue, task) - end - # rubocop:disable Metrics/MethodLength - def task_instructions_helper(issue, task) # set up data for added or edited issue depending on the params action + disposition = issue.readable_disposition.nil? ? "N/A" : issue.readable_disposition change_category = (params[:action] == "create") ? "Added Issue" : "Edited Issue" updated_mst_status = convert_to_bool(params[:issues][:mst_status]) unless params[:action] == "create" updated_pact_status = convert_to_bool(params[:issues][:pact_status]) unless params[:action] == "create" - instruction_params = { - issue: issue, - task: task, - updated_mst_status: updated_mst_status, - updated_pact_status: updated_pact_status, - change_category: change_category - } - format_instructions(instruction_params) - - # create SpecialIssueChange record to log the changes - SpecialIssueChange.create!( - issue_id: issue.id, - appeal_id: appeal.id, - appeal_type: "LegacyAppeal", - task_id: task.id, - created_at: Time.zone.now.utc, - created_by_id: current_user.id, - created_by_css_id: current_user.css_id, - original_mst_status: issue.mst_status, - original_pact_status: issue.pact_status, - updated_mst_status: updated_mst_status, - updated_pact_status: updated_pact_status, - change_category: change_category - ) - end - # formats and saves task instructions - # rubocop:disable Metrics/AbcSize - # :reek:FeatureEnvy - def format_instructions(inst_params) note = params[:issues][:note].nil? ? "N/A" : params[:issues][:note] # use codes from params to get descriptions # opting to use params vs issue model to capture in-flight issue changes program_code = params[:issues][:program] issue_code = params[:issues][:issue] + level_1_code = params[:issues][:level_1] # line up param codes to their descriptions param_issue = Constants::ISSUE_INFO[program_code] iss = param_issue["levels"][issue_code]["description"] unless issue_code.nil? - - issue_code_message = build_issue_code_message(issue_code, param_issue) + level_1_description = level_1_code.nil? ? "N/A" : param_issue["levels"][issue_code]["levels"][level_1_code]["description"] # format the task instructions and close out set = CaseTimelineInstructionSet.new( - change_type: inst_params[:change_category], + change_type: change_category, issue_category: [ "Benefit Type: #{param_issue['description']}\n", "Issue: #{iss}\n", - "Code: #{issue_code_message}\n", - "Note: #{note}\n" + "Code: #{[level_1_code, level_1_description].join(' - ')}\n", + "Note: #{note}\n", + "Disposition: #{disposition}\n" ].compact.join("\r\n"), benefit_type: "", - original_mst: inst_params[:issue].mst_status, - original_pact: inst_params[:issue].pact_status, - edit_mst: inst_params[:updated_mst_status], - edit_pact: inst_params[:updated_pact_status] + original_mst: issue.mst_status, + original_pact: issue.pact_status, + edit_mst: updated_mst_status, + edit_pact: updated_pact_status + ) + task.format_instructions(set) + task.completed! + # create SpecialIssueChange record to log the changes + SpecialIssueChange.create!( + issue_id: issue.id, + appeal_id: appeal.id, + appeal_type: "LegacyAppeal", + task_id: task.id, + created_at: Time.zone.now.utc, + created_by_id: user.id, + created_by_css_id: user.css_id, + original_mst_status: issue.mst_status, + original_pact_status: issue.pact_status, + updated_mst_status: updated_mst_status, + updated_pact_status: updated_pact_status, + change_category: change_category ) - inst_params[:task].format_instructions(set) - inst_params[:task].completed! - end - # rubocop:enable Metrics/MethodLength, Metrics/AbcSize - - # builds issue code on IssuesUpdateTask for MST/PACT changes - def build_issue_code_message(issue_code, param_issue) - level_1_code = params[:issues][:level_1] - diagnostic_code = params[:issues][:level_2] - - # use diagnostic code message if it exists - if !diagnostic_code.blank? - diagnostic_description = Constants::DIAGNOSTIC_CODE_DESCRIPTIONS[diagnostic_code]["staff_description"] - [diagnostic_code, diagnostic_description].join(" - ") - # use level 1 message if it exists - elsif !level_1_code.blank? - level_1_description = param_issue["levels"][issue_code]["levels"][level_1_code]["description"] - [level_1_code, level_1_description].join(" - ") - # return N/A if none exist - else - "N/A" - end end + # rubocop:enable Layout/LineLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity def convert_to_bool(status) status == "Y" diff --git a/app/mailers/dispatch_mailer.rb b/app/mailers/dispatch_mailer.rb index 0c026bfca65..87da8af8e23 100644 --- a/app/mailers/dispatch_mailer.rb +++ b/app/mailers/dispatch_mailer.rb @@ -6,7 +6,7 @@ ## # rubocop:disable Rails/ApplicationMailer class DispatchMailer < ActionMailer::Base - default from: "Board of Veterans' Appeals " + default from: "Board of Veterans' Appeals " layout "dispatch_mailer" helper VirtualHearings::LinkHelper diff --git a/app/models/distribution.rb b/app/models/distribution.rb index 8c483b511ee..37045d03fbf 100644 --- a/app/models/distribution.rb +++ b/app/models/distribution.rb @@ -2,7 +2,11 @@ class Distribution < CaseflowRecord include ActiveModel::Serializers::JSON - include ByDocketDateDistribution + if FeatureToggle.enabled?(:acd_distribute_by_docket_date, user: RequestStore.store[:current_user]) + include ByDocketDateDistribution + else + include AutomaticCaseDistribution + end has_many :distributed_cases belongs_to :judge, class_name: "User" diff --git a/app/models/request_issues_update.rb b/app/models/request_issues_update.rb index 70ba1f7eede..622c347298e 100644 --- a/app/models/request_issues_update.rb +++ b/app/models/request_issues_update.rb @@ -237,6 +237,9 @@ def validate_before_perform if !changes? @error_code = :no_changes elsif RequestIssuesUpdate.where(review: review).where.not(id: id).processable.exists? + if @error_code == :no_changes + RequestIssuesUpdate.where(review: review).where.not(id: id).processable.last.destroy + end @error_code = :previous_update_not_done_processing end diff --git a/app/queries/appeals_ready_for_distribution.rb b/app/queries/appeals_ready_for_distribution.rb index 0406ab1834a..5f6ce4c7a99 100644 --- a/app/queries/appeals_ready_for_distribution.rb +++ b/app/queries/appeals_ready_for_distribution.rb @@ -44,53 +44,35 @@ def self.ready_appeals .flat_map do |sym, docket| appeals = docket.ready_to_distribute_appeals if sym == :legacy - legacy_rows(appeals, sym) + legacy_rows(appeals, docket, sym) else ama_rows(appeals, docket, sym) end end end - def self.legacy_rows(appeals, sym) + def self.legacy_rows(appeals, docket, sym) appeals.map do |appeal| - build_appeal_row(appeal, sym) - end - end - - def self.build_appeal_row(appeal, sym) - veteran_name = format_veteran_name(appeal["snamef"], appeal["snamel"]) - hearing_judge = format_vlj_name(appeal["vlj_namef"], appeal["vlj_namel"]) - appeal_affinity = fetch_affinity_start_date(appeal["bfkey"]) - - { - docket_number: appeal["tinum"], - docket: sym.to_s, - aod: appeal["aod"] == 1, - cavc: appeal["cavc"] == 1, - receipt_date: appeal["bfd19"], - ready_for_distribution_at: appeal["bfdloout"], - target_distro_date: target_distro_date(appeal["bfd19"], sym), - days_before_goal_date: days_before_goal_date(appeal["bfd19"], sym), - hearing_judge: hearing_judge, - original_judge: legacy_original_deciding_judge(appeal), - veteran_file_number: appeal["ssn"] || appeal["bfcorlid"], - veteran_name: veteran_name, - affinity_start_date: appeal_affinity - } - end - - def self.format_vlj_name(first_name, last_name) - name = FullName.new(first_name, nil, last_name).to_s - name.empty? ? nil : name - end + veteran_name = FullName.new(appeal["snamef"], nil, appeal["snamel"]).to_s + vlj_name = FullName.new(appeal["vlj_namef"], nil, appeal["vlj_namel"]).to_s + hearing_judge = vlj_name.empty? ? nil : vlj_name + appeal_affinity = AppealAffinity.find_by(case_id: appeal["bfkey"], case_type: "VACOLS::Case") - def self.format_veteran_name(first_name, last_name) - FullName.new(first_name, nil, last_name).to_s - end - - def self.fetch_affinity_start_date(case_id) - appeal_affinity = AppealAffinity.find_by(case_id: case_id, case_type: "VACOLS::Case") - appeal_affinity&.affinity_start_date + { + docket_number: appeal["tinum"], + docket: sym.to_s, + aod: appeal["aod"] == 1, + cavc: appeal["cavc"] == 1, + receipt_date: appeal["bfd19"], + ready_for_distribution_at: appeal["bfdloout"], + target_distro_date: target_distro_date(appeal["bfd19"], docket), + days_before_goal_date: days_before_goal_date(appeal["bfd19"], docket), + hearing_judge: hearing_judge, + veteran_file_number: appeal["ssn"] || appeal["bfcorlid"], + veteran_name: veteran_name, + affinity_start_date: appeal_affinity&.affinity_start_date + } + end end def self.ama_rows(appeals, docket, sym) @@ -99,7 +81,6 @@ def self.ama_rows(appeals, docket, sym) ready_for_distribution_at = distribution_task_query(appeal) # only look for hearings that were held hearing_judge = with_held_hearings(appeal) - priority_appeal = appeal.aod || appeal.cavc { docket_number: appeal.docket_number, docket: sym.to_s, @@ -107,8 +88,8 @@ def self.ama_rows(appeals, docket, sym) cavc: appeal.cavc, receipt_date: appeal.receipt_date, ready_for_distribution_at: ready_for_distribution_at, - target_distro_date: priority_appeal ? "N/A" : target_distro_date(appeal.receipt_date, docket), - days_before_goal_date: priority_appeal ? "N/A" : days_before_goal_date(appeal.receipt_date, docket), + target_distro_date: target_distro_date(appeal.receipt_date, docket), + days_before_goal_date: days_before_goal_date(appeal.receipt_date, docket), hearing_judge: hearing_judge, veteran_file_number: appeal.veteran_file_number, veteran_name: appeal.veteran&.name.to_s, diff --git a/client/COPY.json b/client/COPY.json index bbc5dc80ad9..e3b596368c3 100644 --- a/client/COPY.json +++ b/client/COPY.json @@ -965,7 +965,6 @@ "INTAKE_EDIT_ISSUE_BENEFIT_TYPE": "Benefit type: ", "INTAKE_EDIT_ISSUE_DECISION_DATE": "Decision date: ", "INTAKE_VHA_CLAIM_REVIEW_REQUIREMENT": "Only VHA team members can establish Higher Level Reviews and Supplemental Claims with VHA issues. If you have a VHA claim, please return the packet to the main “VHA” queue in the Centralized Mail Portal or send downloaded documents to %s.", - "INTAKE_REMOVE_COMP_AND_PEN": "Higher Level Reviews and Supplemental Claims with Compensation and Pension & Survivor's Benefits are now handled through VBMS and are no longer established through Caseflow", "VHA_BENEFIT_EMAIL_ADDRESS": "VHABENEFITAPPEALS@va.gov", "VHA_CAREGIVER_SUPPORT_EMAIL_ADDRESS": "VHA.CSPAppeals@va.gov", "VHA_PAYMENT_OPERATIONS_EMAIL_ADDRESS": "VHA10D1B3R2Appeals@va.gov", diff --git a/client/app/intake/components/BenefitType.jsx b/client/app/intake/components/BenefitType.jsx index ab04d9e09e8..e9cc8e80cc9 100644 --- a/client/app/intake/components/BenefitType.jsx +++ b/client/app/intake/components/BenefitType.jsx @@ -19,15 +19,13 @@ export default class BenefitType extends React.PureComponent { // If the feature toggle is off then all users should be able to select vha const canSelectVhaBenefit = featureToggles.vhaClaimReviewEstablishment ? userCanSelectVha : true; - const canSelectCompAndPen = !featureToggles.removeCompAndPenIntake; - return
{ + generateIssueActionOptions = (issue, userCanWithdrawIssues, userCanEditIntakeIssues, isDtaError, docketType) => { let options = []; if (issue.correctionType && issue.endProductCleared) { @@ -46,7 +38,7 @@ export default class IssuesList extends React.Component { { label: 'Remove issue', value: 'remove' } ); - if (userCanEditIntakeIssues && (formType === FORM_TYPES.APPEAL.key)) { + if (userCanEditIntakeIssues) { options.push( { label: 'Edit issue', value: 'edit' } @@ -68,7 +60,7 @@ export default class IssuesList extends React.Component { value: 'remove' } ); } - if (userCanEditIntakeIssues && (formType === FORM_TYPES.APPEAL.key)) { + if (userCanEditIntakeIssues) { options.push( { label: 'Edit issue', value: 'edit' } @@ -92,7 +84,6 @@ export default class IssuesList extends React.Component { value: 'requestWithdrawal' } ); } - /* eslint-enable max-params */ const isIssueWithdrawn = issue.withdrawalDate || issue.withdrawalPending; @@ -136,12 +127,7 @@ export default class IssuesList extends React.Component { editableIssueProperties); const issueActionOptions = this.generateIssueActionOptions( - issue, - userCanWithdrawIssues, - userCanEditIntakeIssues, - intakeData.isDtaError, - intakeData.docketType, - formType + issue, userCanWithdrawIssues, userCanEditIntakeIssues, intakeData.isDtaError, intakeData.docketType ); const isIssueWithdrawn = issue.withdrawalDate || issue.withdrawalPending; diff --git a/client/app/intake/components/NonratingRequestIssueModal.jsx b/client/app/intake/components/NonratingRequestIssueModal.jsx index 933c3f223fa..35967d8c804 100644 --- a/client/app/intake/components/NonratingRequestIssueModal.jsx +++ b/client/app/intake/components/NonratingRequestIssueModal.jsx @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import { css } from 'glamor'; import { COLORS } from 'app/constants/AppConstants'; -import { FORM_TYPES } from '../constants'; import BenefitType from '../components/BenefitType'; import PreDocketRadioField from '../components/PreDocketRadioField'; @@ -369,7 +368,7 @@ class NonratingRequestIssueModal extends React.Component { formType === 'appeal' ? : null; - const getSpecialIssues = (this.props.userCanEditIntakeIssues && (formType === FORM_TYPES.APPEAL.key)) ? + const getSpecialIssues = this.props.userCanEditIntakeIssues ? this.getSpecialIssues(mstIdentification, pactIdentification) : null; return ( diff --git a/client/app/intake/pages/formGenerator.jsx b/client/app/intake/pages/formGenerator.jsx index e359f3cf655..d20bbf29b0f 100644 --- a/client/app/intake/pages/formGenerator.jsx +++ b/client/app/intake/pages/formGenerator.jsx @@ -7,8 +7,7 @@ import { Redirect } from 'react-router-dom'; import { reject, map } from 'lodash'; import RadioField from '../../components/RadioField'; import ReceiptDateInput from './receiptDateInput'; -import { - setDocketType, setOriginalHearingRequestType, setHomelessnessType +import { setDocketType, setOriginalHearingRequestType, setHomelessnessType } from '../actions/appeal'; import { setReceiptDate, setOptionSelected } from '../actions/intake'; import { setAppealDocket, confirmIneligibleForm } from '../actions/rampRefiling'; @@ -118,14 +117,14 @@ const formFieldMapping = (props) => {
), 'original-hearing-request-type': - props.docketType === 'hearing' && props.featureToggles.updatedAppealForm ? hearingTypeDropdown : <>, + props.docketType === 'hearing' && props.featureToggles.updatedAppealForm ? hearingTypeDropdown : <>, 'legacy-opt-in': ( @@ -143,7 +142,7 @@ const formFieldMapping = (props) => { onChange={props.setBenefitType} errorMessage={ props.benefitTypeError || - props.errors?.['benefit-type-options']?.message + props.errors?.['benefit-type-options']?.message } register={props.register} formName={props.formName} @@ -163,7 +162,7 @@ const formFieldMapping = (props) => { }} errorMessage={ props.informalConferenceError || - props.errors?.['informal-conference']?.message + props.errors?.['informal-conference']?.message } value={renderBooleanValue('informalConference')} inputRef={props.register} @@ -222,7 +221,7 @@ const formFieldMapping = (props) => { onChange={props.setOptionSelected} errorMessage={ props.optionSelectedError || - props.errors?.['opt-in-election']?.message + props.errors?.['opt-in-election']?.message } value={props.optionSelected} inputRef={props.register} @@ -236,7 +235,7 @@ const formFieldMapping = (props) => { onChange={props.setAppealDocket} errorMessage={ props.appealDocketError || - props.errors?.['appeal-docket']?.message + props.errors?.['appeal-docket']?.message } value={props.appealDocket} inputRef={props.register} @@ -287,7 +286,6 @@ const FormGenerator = (props) => { )} - {props.reviewIntakeError && } {showInvalidVeteranError && ( { errorData={props.veteranInvalidFields} /> )} - - {isHlrOrScForm && !props.userIsVhaEmployee && props.featureToggles.vhaClaimReviewEstablishment && !props.featureToggles.removeCompAndPenIntake && ( + {!props.userIsVhaEmployee && isHlrOrScForm && props.featureToggles.vhaClaimReviewEstablishment && (
)} - - {isHlrOrScForm && !props.userIsVhaEmployee && props.featureToggles.vhaClaimReviewEstablishment && props.featureToggles.removeCompAndPenIntake && ( -
- -
    -
  • -
  • {COPY.INTAKE_REMOVE_COMP_AND_PEN}
  • -
-
-
- )} - - {isHlrOrScForm && props.featureToggles.removeCompAndPenIntake && ((props.featureToggles.vhaClaimReviewEstablishment && props.userIsVhaEmployee) || (!props.featureToggles.vhaClaimReviewEstablishment && !props.userIsVhaEmployee)) && ( -
- -
    -
  • {COPY.INTAKE_REMOVE_COMP_AND_PEN}
  • -
-
-
- )} - {Object.keys(props.schema.fields).map((field) => formFieldMapping(props)[field])} ); diff --git a/client/app/intake/reducers/featureToggles.js b/client/app/intake/reducers/featureToggles.js index e5705f0cc0c..3d1d73f5856 100644 --- a/client/app/intake/reducers/featureToggles.js +++ b/client/app/intake/reducers/featureToggles.js @@ -40,9 +40,6 @@ const updateFromServerFeatures = (state, featureToggles) => { }, vhaClaimReviewEstablishment: { $set: Boolean(featureToggles.vhaClaimReviewEstablishment) - }, - removeCompAndPenIntake: { - $set: Boolean(featureToggles.removeCompAndPenIntake) } }); }; @@ -61,8 +58,7 @@ export const mapDataToFeatureToggle = (data = { featureToggles: {} }) => justificationReason: false, updatedAppealForm: false, hlrScUnrecognizedClaimants: false, - vhaClaimReviewEstablishment: false, - removeCompAndPenIntake: false + vhaClaimReviewEstablishment: false }, data.featureToggles ); diff --git a/client/app/intake/util/index.js b/client/app/intake/util/index.js index 01b48cbdf48..97436c487ec 100644 --- a/client/app/intake/util/index.js +++ b/client/app/intake/util/index.js @@ -4,8 +4,7 @@ import { sprintf } from 'sprintf-js'; import { REVIEW_OPTIONS, REVIEW_DATA_FIELDS, CLAIMANT_ERRORS } from '../constants'; import { INTAKE_VHA_CLAIM_REVIEW_REQUIREMENT, - VHA_BENEFIT_EMAIL_ADDRESS, - INTAKE_REMOVE_COMP_AND_PEN + VHA_BENEFIT_EMAIL_ADDRESS } from '../../../COPY'; import DATES from '../../../constants/DATES'; import { formatDateStr } from '../../util/DateUtil'; @@ -92,7 +91,7 @@ export const getDefaultPayeeCode = (state, claimant) => { return null; }; -export const formatBenefitTypeRadioOptions = (options, userCanSelectVha, userCanSelectCompAndPen) => { +export const formatBenefitTypeRadioOptions = (options, userCanSelectVha) => { return _.map(options, (value, key) => { const radioData = { value: key, displayText: value }; @@ -102,12 +101,6 @@ export const formatBenefitTypeRadioOptions = (options, userCanSelectVha, userCan disabled: true, tooltipText: sprintf(INTAKE_VHA_CLAIM_REVIEW_REQUIREMENT, VHA_BENEFIT_EMAIL_ADDRESS) }; - } else if ((key === 'compensation' || key === 'pension') && !userCanSelectCompAndPen) { - return { - ...radioData, - disabled: true, - tooltipText: sprintf(INTAKE_REMOVE_COMP_AND_PEN) - }; } return radioData; diff --git a/client/test/app/intake/components/BenefitType.test.js b/client/test/app/intake/components/BenefitType.test.js index 4ce2794db33..a90ae4a1428 100644 --- a/client/test/app/intake/components/BenefitType.test.js +++ b/client/test/app/intake/components/BenefitType.test.js @@ -18,15 +18,12 @@ const defaultProps = { }; const vhaTooltipText = sprintf(COPY.INTAKE_VHA_CLAIM_REVIEW_REQUIREMENT, COPY.VHA_BENEFIT_EMAIL_ADDRESS); -const penAndCompTooltipText = sprintf(COPY.INTAKE_REMOVE_COMP_AND_PEN); const renderBenefitType = (props) => { return render(); }; const getVhaRadioOption = () => screen.getByRole('radio', { name: BENEFIT_TYPES.vha }); -const getCompRadioOption = () => screen.getByRole('radio', { name: BENEFIT_TYPES.compensation }); -const getPenRadioOption = () => screen.getByRole('radio', { name: BENEFIT_TYPES.pension }); const getVhaOptionTooltip = () => { return screen.getByRole( @@ -76,70 +73,6 @@ describe('BenefitType', () => { }); }); - describe('when remove comp and pen intake is disabled', () => { - const props = { - ...defaultProps, - featureToggles: { removeCompAndPenIntake: false } - - }; - - beforeEach(() => { - renderBenefitType(props); - }); - - it('The "Veterans Health Administration" option is enabled', () => { - expect(getCompRadioOption()).not.toBeDisabled(); - expect(getPenRadioOption()).not.toBeDisabled(); - }); - - it('Tooltip does not appear whenever Compensation option is hovered over', () => { - hoverOverRadioOption(getCompRadioOption()); - - expect( - screen.queryByText(vhaTooltipText) - ).not.toBeInTheDocument(); - }); - - it('Tooltip does not appear whenever Pension option is hovered over', () => { - hoverOverRadioOption(getPenRadioOption()); - - expect( - screen.queryByText(vhaTooltipText) - ).not.toBeInTheDocument(); - }); - }); - - describe('when remove comp and pen intake is enabled', () => { - const props = { - ...defaultProps, - featureToggles: { removeCompAndPenIntake: true } - - }; - - beforeEach(() => { - renderBenefitType(props); - }); - - it('The "Veterans Health Administration" option is enabled', () => { - expect(getCompRadioOption()).toBeDisabled(); - expect(getPenRadioOption()).toBeDisabled(); - }); - - it('Tooltip appear whenever Comp and Pen option is hovered over', async () => { - - await waitFor(() => { - const toolTipElements = screen.getAllByRole('tooltip'); - - toolTipElements.forEach((toolTipElement) => { - if (toolTipElement.id === 'tooltip-pension' || toolTipElement.id === 'tooltip-compensation') { - expect(toolTipElement).toBeInTheDocument(); - expect(toolTipElement).toHaveTextContent(penAndCompTooltipText); - } - }); - }); - }); - }); - describe('when the user is a VHA staff member with feature toggle disabled on Higher Level Review Form', () => { const props = { ...defaultProps, diff --git a/client/test/app/testSeeds/components/CustomSeeds.test.js b/client/test/app/testSeeds/components/CustomSeeds.test.js index 2e4077dc48d..8ac682d198e 100644 --- a/client/test/app/testSeeds/components/CustomSeeds.test.js +++ b/client/test/app/testSeeds/components/CustomSeeds.test.js @@ -1,22 +1,16 @@ import React from 'react'; -import { render, fireEvent, screen, waitFor } from '@testing-library/react'; +import { render, fireEvent, screen } from '@testing-library/react'; import CustomSeeds from 'app/testSeeds/components/CustomSeeds'; import CUSTOM_SEEDS from '../../../../constants/CUSTOM_SEEDS'; import { Provider } from 'react-redux'; import { createStore, applyMiddleware } from 'redux'; import rootReducer from 'app/testSeeds/reducers/root'; -import { addCustomSeed, resetCustomSeeds, removeCustomSeed, saveCustomSeeds } from 'app/testSeeds/reducers/seeds/seedsActions'; +import { addCustomSeed } from 'app/testSeeds/reducers/seeds/seedsActions'; import thunk from 'redux-thunk'; import ApiUtil from 'app/util/ApiUtil'; jest.mock('app/util/ApiUtil', () => ({ - get: jest.fn(), - post: jest.fn(), -})); - -jest.mock('app/testSeeds/reducers/seeds/seedsActions', () => ({ - ...jest.requireActual('app/testSeeds/reducers/seeds/seedsActions'), // Use actual implementation for other functions - saveCustomSeeds: jest.fn(), // Mock the saveCustomSeeds function + get: jest.fn() })); describe('Custom Seeds', () => { @@ -26,19 +20,6 @@ describe('Custom Seeds', () => { applyMiddleware(thunk) ); - beforeAll(() => { - // Mock window.location.assign - Object.defineProperty(window, 'location', { - writable: true, - value: { assign: jest.fn() } - }); - }); - - afterAll(() => { - jest.restoreAllMocks(); // Restore original window.location.assign after all tests - }); - - afterEach(() => { jest.clearAllMocks(); }); @@ -178,180 +159,6 @@ describe('Custom Seeds', () => { ApiUtil.get.mockResolvedValueOnce({ data: 'Success' }); fireEvent.click(button); - expect(ApiUtil.get).toHaveBeenCalledWith('/seeds/reset_all_appeals'); - }); - - it('downloads the template', () => { - const store = getStore(); - - render( - - - - ); - - const downloadButton = screen.getByText('Download Template'); - fireEvent.click(downloadButton); - - expect(window.location.href).toContain('sample_custom_seeds.csv'); - }); - - it('handles file upload and parses CSV correctly', () => { - const store = getStore(); - - const { container } = render( - - - - ); - - const fileInput = container.querySelector('#seed_file_upload'); - const file = new File( - ['Case(s) Type,Amount,Days Ago,Associated Judge\nType1,10,5,Judge1'], - 'test.csv', - { type: 'text/csv' } - ); - - fireEvent.change(fileInput, { - target: { files: [file] } - }); - - const reader = new FileReader(); - reader.onload = jest.fn((e) => { - const result = e.target.result; - fireEvent.load(fileInput, { target: { result } }); - }); - - const base64 = btoa('Case(s) Type,Amount,Days Ago,Associated Judge\nType1,10,5,Judge1\nType2,20,15,Judge2'); - const mockFile = { - split: () => ['data:text/csv;base64', base64], - }; - - fireEvent.load(fileInput, { target: { result: mockFile } }); - - waitFor(() => { - expect(screen.getByText('Create 2 test cases')).toBeInTheDocument(); - }); - }); - - it('handles file upload and parses invalid CSV', () => { - const store = getStore(); - - const { container } = render( - - - - ); - - const fileInput = container.querySelector('#seed_file_upload'); - const file = new File( - ['Type,Price,Days,Judge\nType1,10,5,Judge1'], - 'test.csv', - { type: 'text/csv' } - ); - - fireEvent.change(fileInput, { - target: { files: [file] } - }); - - const reader = new FileReader(); - reader.onload = jest.fn((e) => { - const result = e.target.result; - fireEvent.load(fileInput, { target: { result } }); - }); - - const base64 = btoa('Type,Price,Days,Judge\nType1,10,5,Judge1'); - const mockFile = { - split: () => ['data:text/csv;base64', base64], - }; - - fireEvent.load(fileInput, { target: { result: mockFile } }); - - waitFor(() => { - expect(screen.getByText('Create 0 test cases')).toBeInTheDocument(); - }); - }); - - it('saves seeds correctly', async () => { - const store = getStore(); - - const { container } = render( - - - - ); - - const firstSeed = seedTypes[0]; - const caseCountInput = screen.getByLabelText(`seed-count-${firstSeed}`); - const daysAgoInput = screen.getByLabelText(`days-ago-${firstSeed}`); - const cssIdInput = screen.getByLabelText(`css-id-${firstSeed}`); - fireEvent.change(caseCountInput, { target: { value: '10' } }); - fireEvent.change(daysAgoInput, { target: { value: '5' } }); - fireEvent.change(cssIdInput, { target: { value: '12345' } }); - const button = container.querySelector(`#btn-${firstSeed}`); - fireEvent.click(button); - - waitFor(() => { - expect(screen.getByText('Create 1 test cases')).toBeInTheDocument(); - }); - - waitFor(() => { - const saveButton = container.querySelector('.cf-btn-link.lever-right.test-seed-button-style.cf-right-side Button'); - expect(saveButton.innerText).toBe('Create 1 test cases'); - fireEvent.click(saveButton); - }); - - // const saveButton = screen.getByRole('button', { name: 'Create 1 test cases' }); - // fireEvent.click(saveButton); - - // const saveButton = container.querySelector('#button-Create-1-test-cases'); - // fireEvent.click(saveButton); - - waitFor(() => { - expect(saveCustomSeeds).toHaveBeenCalledTimes(1); - const actions = store.getActions(); - const expectedAction = saveCustomSeeds(store.getState().testSeeds.seeds); - expect(actions).toContainEqual(expectedAction); - }); - - waitFor(() => { - expect(ApiUtil.post).toHaveBeenCalledWith('/seeds/save', expect.any(Object)); - }); - - waitFor(() => { - expect(screen.getByText('Test seeds have been saved')).toBeInTheDocument(); - }); - }); - - it('handles empty CSV file gracefully', () => { - const store = getStore(); - - const { container } = render( - - - - ); - - const fileInput = container.querySelector('#seed_file_upload'); - const file = new File([''], 'empty.csv', { type: 'text/csv' }); - - fireEvent.change(fileInput, { - target: { files: [file] } - }); - - const reader = new FileReader(); - reader.onload = jest.fn((e) => { - const result = e.target.result; - fireEvent.load(fileInput, { target: { result } }); - }); - - const base64 = btoa(''); - const mockFile = { - split: () => ['data:text/csv;base64', base64], - }; - - fireEvent.load(fileInput, { target: { result: mockFile } }); - - expect(screen.queryByText('Create 1 test cases')).not.toBeInTheDocument(); + expect(ApiUtil.get).toHaveBeenCalledWith(`/seeds/reset_all_appeals`); }); }); diff --git a/client/test/app/testSeeds/reducers/seeds/seedsReducer.test.js b/client/test/app/testSeeds/reducers/seeds/seedsReducer.test.js index df422f7e0a2..72ea77467cd 100644 --- a/client/test/app/testSeeds/reducers/seeds/seedsReducer.test.js +++ b/client/test/app/testSeeds/reducers/seeds/seedsReducer.test.js @@ -2,21 +2,13 @@ import seedsReducer from 'app/testSeeds/reducers/seeds/seedsReducer'; import { ACTIONS } from 'app/testSeeds/reducers/seeds/seedsActionTypes'; -describe('seedsReducer function declaration', () => { +describe('Seed reducer', () => { let initialState = { seeds: [], displayBanner: false }; - it('should initialize the reducer with initialState', () => { - const state = seedsReducer(undefined, {}); - expect(state).toEqual(initialState); - }); -}); - -describe('Seed reducer', () => { - let seed = { "seed_count": 1, "days_ago": 12, @@ -24,32 +16,6 @@ describe('Seed reducer', () => { "seed_type": "ama-aod-hearing-seeds" }; - let seed1 = { - "seed_count": 1, - "days_ago": 12, - "judge_css_id": "keeling", - "seed_type": "ama-aod-hearing-seeds" - }; - - let seed2 = { - "seed_count": 1, - "days_ago": 20, - "judge_css_id": "keeling1", - "seed_type": "ama-aod-hearing-seeds" - }; - - let seed3 = { - "seed_count": 1, - "days_ago": 25, - "judge_css_id": "keeling2", - "seed_type": "ama-aod-hearing-seeds" - }; - - let initialState = { - seeds: [seed1, seed2, seed3], - displayBanner: false - }; - afterEach(() => { jest.clearAllMocks(); }); @@ -62,52 +28,45 @@ describe('Seed reducer', () => { } }; - const newState = seedsReducer(initialState, action); - expect(newState.seeds).toContain(seed); - }); - - it('Should handle RESET_CUSTOM_SEEDS action', () => { - const action = { - type: ACTIONS.RESET_CUSTOM_SEEDS, - }; - const expectedState = { ...initialState, - seeds: [] + seeds: [action.payload.seed] }; const newState = seedsReducer(initialState, action); expect(newState).toEqual(expectedState); - }); - it('Should set displayBanner to true when dispatched SAVE_CUSTOM_SEEDS action', () => { - const action = { - type: ACTIONS.SAVE_CUSTOM_SEEDS + const removeAction = { + type: ACTIONS.REMOVE_CUSTOM_SEED, + payload: { + seed: seed, + index: 0 + } }; - const newState = seedsReducer(initialState, action); - expect(newState.displayBanner).toBe(true); - }); + const expectedRemoveState = { + ...initialState, + seeds: [] + }; - it('should not modify the state for unknown action', () => { - const action = { type: 'UNKNOWN_ACTION' }; + const newStateFixed = seedsReducer(initialState, removeAction); - const newState = seedsReducer(initialState, action); - expect(newState).toEqual(initialState); + expect(newStateFixed).toEqual(expectedRemoveState); }); - it('should remove a custom seed when dispatche REMOVE_CUSTOM_SEED action', () => { - const indexToRemove = 1; + it('Should handle RESET_CUSTOM_SEEDS action', () => { const action = { - type: ACTIONS.REMOVE_CUSTOM_SEED, - payload: { - index: indexToRemove - } + type: ACTIONS.RESET_CUSTOM_SEEDS, + }; + + const expectedState = { + ...initialState, + seeds: [] }; const newState = seedsReducer(initialState, action); - expect(newState.seeds).toHaveLength(initialState.seeds.length - 1); - expect(newState.seeds).not.toContain(initialState.seeds[indexToRemove]); + + expect(newState).toEqual(expectedState); }); }); diff --git a/spec/controllers/legacy_tasks_controller_spec.rb b/spec/controllers/legacy_tasks_controller_spec.rb index 54b8e2570a3..e34027b2859 100644 --- a/spec/controllers/legacy_tasks_controller_spec.rb +++ b/spec/controllers/legacy_tasks_controller_spec.rb @@ -72,19 +72,6 @@ expect(response.status).to eq 200 end end - - context "when rendering json format" do - it "records metric with MetricsService" do - allow(LegacyWorkQueue).to receive(:tasks_for_user).and_return([]) - expect(MetricsService).to receive(:record).with( - "VACOLS: Get all tasks with appeals for #{user.css_id}", - name: "LegacyTasksController.index" - ).and_call_original - get :index, format: :json, params: { user_id: user.css_id, rest: "/assign" } - expect(response.status).to eq 200 - end - end - context "CSS_ID in URL is invalid" do it "returns 404" do [-1, "BAD_CSS_ID", ""].each do |user_id_path| diff --git a/spec/controllers/test_docket_seeds_controller_spec.rb b/spec/controllers/test_docket_seeds_controller_spec.rb index 98d269992e3..91847bc3fe3 100644 --- a/spec/controllers/test_docket_seeds_controller_spec.rb +++ b/spec/controllers/test_docket_seeds_controller_spec.rb @@ -8,22 +8,6 @@ end let!(:authenticated_user) { User.authenticate!(css_id: "RSPEC", roles: ["System Admin"]) } - let(:root_task) { create(:root_task) } - let(:distribution_task) do - DistributionTask.create!( - appeal: root_task.appeal, - assigned_to: Bva.singleton, - status: "assigned" - ) - end - - let(:bfcurloc_keys) { %w[77 81 83] } - let!(:cases) do - bfcurloc_keys.map do |bfcurloc_key| - create(:case, bfcurloc: bfcurloc_key) - end - end - describe "POST run-demo?seed_type=ii?seed_count=x&days_ago=y&judge_css_id=zzz" do before(:all) do Rake::Task.define_task(:environment) @@ -612,34 +596,5 @@ end end end - - it "should reset all appeals" do - expect(distribution_task.status).to eq("assigned") - expect(VACOLS::Case.where(bfcurloc: %w[81 83]).count).to eq(2) - expect(VACOLS::Case.where(bfcurloc: "testing").count).to eq(0) - get :reset_all_appeals - expect(response.status).to eq 200 - expect(distribution_task.reload.status).to eq("on_hold") - expect(VACOLS::Case.where(bfcurloc: %w[81 83]).count).to eq(0) - expect(VACOLS::Case.where(bfcurloc: "testing").count).to eq(2) - end - - context "check environment when non prod environments is true" do - before { allow(Rails).to receive(:deploy_env?).with(:demo).and_return(true) } - - it "allows access without redirecting" do - get :reset_all_appeals - expect(response.status).to eq 200 - end - end - - context "check environment when in other environments" do - before { allow(Rails).to receive(:deploy_env?).and_return(false) } - - it "redirects to /unauthorized" do - get :reset_all_appeals - expect(response).to redirect_to("/unauthorized") - end - end end end diff --git a/spec/factories/case_distribution_lever.rb b/spec/factories/case_distribution_lever.rb index 30789851b51..a216d6e6716 100644 --- a/spec/factories/case_distribution_lever.rb +++ b/spec/factories/case_distribution_lever.rb @@ -83,6 +83,30 @@ lever_group_order { 101 } end + trait :disable_legacy_priority do + item { "disable_legacy_priority" } + title { "ACD Disable Legacy Priority" } + description { "" } + data_type { "boolean" } + value { false } + unit { "" } + algorithms_used { %w[docket proportion] } + lever_group { "docket_levers" } + lever_group_order { 105 } + end + + trait :disable_ama_non_priority_direct_review do + item { "disable_ama_non_priority_direct_review" } + title { "ACD Disable AMA Non-Priority Direct Review" } + description { "" } + data_type { "boolean" } + value { false } + unit { "" } + algorithms_used { %w[docket proportion] } + lever_group { "docket_levers" } + lever_group_order { 103 } + end + trait :ama_hearings_start_distribution_prior_to_goals do item { "ama_hearings_start_distribution_prior_to_goals" } title { "AMA Hearings Start Distribution Prior to Goals" } @@ -388,117 +412,5 @@ lever_group_order { 103 } control_group { "non_priority" } end - - trait :disable_legacy_priority do - item { "disable_legacy_priority" } - title { "ACD Disable Legacy Priority" } - data_type { "boolean" } - options do - [ - { - displayText: "On", - name: Constants.DISTRIBUTION.disable_legacy_priority, - value: "true", - disabled: false - }, - { - displayText: "Off", - name: Constants.DISTRIBUTION.disable_legacy_priority, - value: "false", - disabled: false - } - ] - end - value { false } - unit { "days" } - algorithms_used { %w(proportion docket) } - lever_group { "docket_levers" } - lever_group_order { 103 } - control_group { "priority" } - end - - trait :disable_ama_priority_hearing do - item { "disable_ama_priority_hearing" } - title { "ACD Disable AMA Priority Hearing" } - data_type { "boolean" } - options do - [ - { - displayText: "On", - name: Constants.DISTRIBUTION.disable_ama_priority_hearing, - value: "true", - disabled: false - }, - { - displayText: "Off", - name: Constants.DISTRIBUTION.disable_ama_priority_hearing, - value: "false", - disabled: false - } - ] - end - value { false } - unit { "days" } - algorithms_used { %w(proportion docket) } - lever_group { "docket_levers" } - lever_group_order { 103 } - control_group { "priority" } - end - - trait :disable_ama_priority_direct_review do - item { "disable_ama_priority_direct_review" } - title { "ACD Disable AMA Priority Direct Review" } - data_type { "boolean" } - options do - [ - { - displayText: "On", - name: Constants.DISTRIBUTION.disable_ama_priority_direct_review, - value: "true", - disabled: false - }, - { - displayText: "Off", - name: Constants.DISTRIBUTION.disable_ama_priority_direct_review, - value: "false", - disabled: false - } - ] - end - value { false } - unit { "days" } - algorithms_used { %w(proportion docket) } - lever_group { "docket_levers" } - lever_group_order { 103 } - control_group { "priority" } - end - - trait :disable_ama_priority_evidence_submission do - item { "disable_ama_priority_direct_review" } - title { "ACD Disable AMA Priority Evidence Submission" } - data_type { "boolean" } - options do - [ - { - displayText: "On", - name: Constants.DISTRIBUTION.disable_ama_priority_evidence_submission, - value: "true", - disabled: false - }, - { - displayText: "Off", - name: Constants.DISTRIBUTION.disable_ama_priority_evidence_submission, - value: "false", - disabled: false - } - ] - end - value { false } - unit { "days" } - algorithms_used { %w(proportion docket) } - lever_group { "docket_levers" } - lever_group_order { 103 } - control_group { "priority" } - end end end diff --git a/spec/feature/intake/review_page_spec.rb b/spec/feature/intake/review_page_spec.rb index 0d7a80316ff..f4c4cff8285 100644 --- a/spec/feature/intake/review_page_spec.rb +++ b/spec/feature/intake/review_page_spec.rb @@ -486,8 +486,6 @@ def select_claimant(index = 0) shared_examples "Claim review intake with VHA benefit type" do let(:benefit_type_label) { Constants::BENEFIT_TYPES["vha"] } - let(:compensation_type_label) { Constants::BENEFIT_TYPES["compensation"] } - let(:pension_type_label) { Constants::BENEFIT_TYPES["pension"] } let(:email_href) do "mailto:VHABENEFITAPPEALS@va.gov?subject=Potential%20VHA%20Higher-Level%20Review%20or%20Supplemental%20Claim" end @@ -549,79 +547,6 @@ def select_claimant(index = 0) end end - context "Correct banner shows when user is NOT a member of the VHA business line" do - let(:vha_business_line) { create(:business_line, name: benefit_type_label, url: "vha") } - let(:current_user) { create(:user, roles: ["Admin Intake"]) } - - before do - User.authenticate!(user: current_user) - end - - it "display both REMOVE_INTAKE_COMP_AND_PEN and VHA messages" do - FeatureToggle.enable!(:remove_comp_and_pen_intake) - FeatureToggle.enable!(:vha_claim_review_establishment) - navigate_to_review_page(form_type) - - expect(page).to have_content(COPY::INTAKE_REMOVE_COMP_AND_PEN) - expect(page).to have_link(COPY::VHA_BENEFIT_EMAIL_ADDRESS, href: email_href) - end - - it "display REMOVE_INTAKE_COMP_AND_PEN message and doesn't display VHA message" do - FeatureToggle.enable!(:remove_comp_and_pen_intake) - FeatureToggle.disable!(:vha_claim_review_establishment) - navigate_to_review_page(form_type) - - expect(page).to have_content(COPY::INTAKE_REMOVE_COMP_AND_PEN) - expect(page).to_not have_link(COPY::VHA_BENEFIT_EMAIL_ADDRESS, href: email_href) - end - - it "Display VHA message and doesn't display REMOVE_INTAKE_COMP_AND_PEN message" do - FeatureToggle.disable!(:remove_comp_and_pen_intake) - FeatureToggle.enable!(:vha_claim_review_establishment) - navigate_to_review_page(form_type) - - expect(page).to_not have_content(COPY::INTAKE_REMOVE_COMP_AND_PEN) - expect(page).to have_link(COPY::VHA_BENEFIT_EMAIL_ADDRESS, href: email_href) - end - - it "Doesn't display VHA message nor REMOVE_INTAKE_COMP_AND_PEN message if these features are disabled" do - FeatureToggle.disable!(:remove_comp_and_pen_intake) - FeatureToggle.disable!(:vha_claim_review_establishment) - navigate_to_review_page(form_type) - - expect(page).to_not have_content(COPY::INTAKE_REMOVE_COMP_AND_PEN) - expect(page).to_not have_link(COPY::VHA_BENEFIT_EMAIL_ADDRESS, href: email_href) - end - end - - context "Correct banner shows when user IS a member of the VHA business line" do - let(:vha_business_line) { VhaBusinessLine.singleton } - let(:current_user) { create(:user, roles: ["Admin Intake"]) } - - before do - vha_business_line.add_user(current_user) - User.authenticate!(user: current_user) - end - - it "display REMOVE_INTAKE_COMP_AND_PEN message and doesn't display VHA message" do - FeatureToggle.enable!(:remove_comp_and_pen_intake) - FeatureToggle.enable!(:vha_claim_review_establishment) - navigate_to_review_page(form_type) - - expect(page).to have_content(COPY::INTAKE_REMOVE_COMP_AND_PEN) - expect(page).to_not have_link(COPY::VHA_BENEFIT_EMAIL_ADDRESS, href: email_href) - end - - it "Doesn't display VHA message nor REMOVE_INTAKE_COMP_AND_PEN message if these features are disabled" do - FeatureToggle.disable!(:remove_comp_and_pen_intake) - FeatureToggle.disable!(:vha_claim_review_establishment) - navigate_to_review_page(form_type) - - expect(page).to_not have_content(COPY::INTAKE_REMOVE_COMP_AND_PEN) - expect(page).to_not have_link(COPY::VHA_BENEFIT_EMAIL_ADDRESS, href: email_href) - end - end - context "Current user is not a member of the VHA business line with feature toggle disabled" do let(:vha_business_line) { create(:business_line, name: benefit_type_label, url: "vha") } let(:current_user) { create(:user, roles: ["Admin Intake"]) } @@ -641,46 +566,6 @@ def select_claimant(index = 0) expect(page).to have_field benefit_type_label, disabled: false, visible: false end end - - context "Current user has Compensation and Pension form selections disabled" do - let(:current_user) { create(:user, roles: ["Admin Intake"]) } - - before do - FeatureToggle.enable!(:remove_comp_and_pen_intake) - User.authenticate!(user: current_user) - navigate_to_review_page(form_type) - end - - after do - FeatureToggle.disable!(:remove_comp_and_pen_intake) - end - - it "Compensation benefit type radio option is disabled" do - expect(page).to have_field compensation_type_label, disabled: true, visible: false - end - - it "Pension benefit type radio option is disabled" do - expect(page).to have_field pension_type_label, disabled: true, visible: false - end - - it "The tooltip appears whenenver Compensation radio field is hovered over" do - find("label", text: compensation_type_label).hover - - # Checks for tooltip text - expect(page).to have_content( - format(COPY::INTAKE_REMOVE_COMP_AND_PEN) - ) - end - - it "The tooltip appears whenenver Pension radio field is hovered over" do - find("label", text: pension_type_label).hover - - # Checks for tooltip text - expect(page).to have_content( - format(COPY::INTAKE_REMOVE_COMP_AND_PEN) - ) - end - end end describe "Intaking a claim review" do diff --git a/spec/feature/queue/ama_queue_workflow_spec.rb b/spec/feature/queue/ama_queue_workflow_spec.rb index 898e2bcf0ba..cc9b675238c 100644 --- a/spec/feature/queue/ama_queue_workflow_spec.rb +++ b/spec/feature/queue/ama_queue_workflow_spec.rb @@ -164,14 +164,12 @@ # joins the user with the organization to grant access to role and org permissions FeatureToggle.enable!(:mst_identification) FeatureToggle.enable!(:pact_identification) - FeatureToggle.enable!(:legacy_mst_pact_identification) FeatureToggle.enable!(:acd_distribute_by_docket_date) end after do FeatureToggle.disable!(:mst_identification) FeatureToggle.disable!(:pact_identification) - FeatureToggle.enable!(:legacy_mst_pact_identification) FeatureToggle.disable!(:acd_distribute_by_docket_date) end diff --git a/spec/jobs/push_priority_appeals_to_judges_job_spec.rb b/spec/jobs/push_priority_appeals_to_judges_job_spec.rb index 9d52ecaabed..f46cb7d0826 100644 --- a/spec/jobs/push_priority_appeals_to_judges_job_spec.rb +++ b/spec/jobs/push_priority_appeals_to_judges_job_spec.rb @@ -13,6 +13,7 @@ create(:case_distribution_lever, :ama_hearing_case_aod_affinity_days) create(:case_distribution_lever, :ama_direct_review_start_distribution_prior_to_goals) create(:case_distribution_lever, :disable_legacy_non_priority) + create(:case_distribution_lever, :disable_legacy_priority) end def to_judge_hash(arr) @@ -221,11 +222,10 @@ def to_judge_hash(arr) context "using Automatic Case Distribution module" do before do - create(:case_distribution_lever, :disable_legacy_priority) allow_any_instance_of(PushPriorityAppealsToJudgesJob).to receive(:eligible_judges).and_return(eligible_judges) end - xit "should only distribute the ready priority cases tied to a judge" do + it "should only distribute the ready priority cases tied to a judge" do expect(subject.count).to eq eligible_judges.count expect(subject.map { |dist| dist.statistics["batch_size"] }).to match_array [2, 2, 0, 0] @@ -252,78 +252,27 @@ def to_judge_hash(arr) FeatureToggle.disable!(:acd_distribute_by_docket_date) FeatureToggle.enable!(:acd_exclude_from_affinity) end - context "without using Docket Levers" do - before do - create(:case_distribution_lever, :disable_legacy_priority, value: "false") - end - - xit "should only distribute the ready priority cases tied to a judge" do - expect(subject.count).to eq eligible_judges.count - expect(subject.map { |dist| dist.statistics["batch_size"] }).to match_array [2, 2, 0, 0] - - # Ensure we only distributed the 2 ready legacy and hearing priority cases that are tied to a judge - distributed_cases = DistributedCase.where(distribution: subject) - expect(distributed_cases.count).to eq 4 - expected_array = [ready_priority_bfkey, ready_priority_bfkey2, ready_priority_uuid, ready_priority_uuid2] - expect(distributed_cases.map(&:case_id)).to match_array expected_array - # Ensure all docket types cases are distributed, including the 5 cavc evidence submission cases - expected_array2 = %w[hearing hearing legacy legacy] - expect(distributed_cases.map(&:docket)).to match_array expected_array2 - expect(distributed_cases.map(&:priority).uniq).to match_array [true] - expect(distributed_cases.map(&:genpop).uniq).to match_array [false, true] - end - end - - context "using Excluding Appeals by Docket Type and Priority from Automatic Case Distribution levers" do - context "all Exluding levers turned to Include" do - before do - create(:case_distribution_lever, :disable_legacy_priority, value: "false") - create(:case_distribution_lever, :disable_ama_priority_hearing, value: "false") - create(:case_distribution_lever, :disable_ama_priority_direct_review, value: "false") - create(:case_distribution_lever, :disable_ama_priority_evidence_submission, value: "false") - end - - xit "should distribute the ready priority cases" do - expect(subject.count).to eq eligible_judges.count - expect(subject.map { |dist| dist.statistics["batch_size"] }).to match_array [2, 2, 0, 0] - - distributed_cases = DistributedCase.where(distribution: subject) - expect(distributed_cases.count).to eq 4 - expected_array = [ready_priority_bfkey, ready_priority_bfkey2, ready_priority_uuid, ready_priority_uuid2] - expect(distributed_cases.map(&:case_id)).to match_array expected_array - # Ensure all docket types cases are distributed, including the 5 cavc evidence submission cases - expected_array2 = %w[hearing hearing legacy legacy] - expect(distributed_cases.map(&:docket)).to match_array expected_array2 - expect(distributed_cases.map(&:priority).uniq).to match_array [true] - expect(distributed_cases.map(&:genpop).uniq).to match_array [false, true] - end - end - - context "all Exluding levers turned to Exclude" do - before do - create(:case_distribution_lever, :disable_legacy_priority, value: "true") - create(:case_distribution_lever, :disable_ama_priority_hearing, value: "true") - create(:case_distribution_lever, :disable_ama_priority_direct_review, value: "true") - create(:case_distribution_lever, :disable_ama_priority_evidence_submission, value: "true") - end - xit "should not distribute the ready priority cases" do - expect(subject.count).to eq eligible_judges.count - expect(subject.map { |dist| dist.statistics["batch_size"] }).to match_array [0, 0, 0, 0] + it "should only distribute the ready priority cases tied to a judge" do + expect(subject.count).to eq eligible_judges.count + expect(subject.map { |dist| dist.statistics["batch_size"] }).to match_array [2, 2, 0, 0] - distributed_cases = DistributedCase.where(distribution: subject) - expect(distributed_cases.count).to eq 0 - expected_array = [] - expect(distributed_cases).to match_array expected_array - end - end + # Ensure we only distributed the 2 ready legacy and hearing priority cases that are tied to a judge + distributed_cases = DistributedCase.where(distribution: subject) + expect(distributed_cases.count).to eq 4 + expected_array = [ready_priority_bfkey, ready_priority_bfkey2, ready_priority_uuid, ready_priority_uuid2] + expect(distributed_cases.map(&:case_id)).to match_array expected_array + # Ensure all docket types cases are distributed, including the 5 cavc evidence submission cases + expected_array2 = %w[hearing hearing legacy legacy] + expect(distributed_cases.map(&:docket)).to match_array expected_array2 + expect(distributed_cases.map(&:priority).uniq).to match_array [true] + expect(distributed_cases.map(&:genpop).uniq).to match_array [false, true] end end end context ".distribute_genpop_priority_appeals" do before do - create(:case_distribution_lever, :disable_legacy_priority) allow_any_instance_of(DirectReviewDocket) .to receive(:nonpriority_receipts_per_year) .and_return(100) diff --git a/spec/mailers/dispatch_mailer_spec.rb b/spec/mailers/dispatch_mailer_spec.rb index 4e6cf0cb1ed..74422e993b8 100644 --- a/spec/mailers/dispatch_mailer_spec.rb +++ b/spec/mailers/dispatch_mailer_spec.rb @@ -14,7 +14,7 @@ subject { DispatchMailer.dispatch(email_address: email_address, appeal: appeal) } describe "#dispatch" do it "has the correct from" do - expect(subject.from).to include("BoardofVeteransAppealsDecisions@messages.va.gov") + expect(subject.from).to include("BoardofVeteransAppealsHearings@messages.va.gov") end it "has the correct subject line" do diff --git a/spec/models/distribution_spec.rb b/spec/models/distribution_spec.rb index 3e3b2e5124d..66aebd9302d 100644 --- a/spec/models/distribution_spec.rb +++ b/spec/models/distribution_spec.rb @@ -186,7 +186,7 @@ end it "updates status to error if an error is thrown and sends slack notification" do - allow(new_distribution).to receive(:num_oldest_priority_appeals_for_judge_by_docket).and_raise(StandardError) + allow_any_instance_of(LegacyDocket).to receive(:distribute_appeals).and_raise(StandardError) expect_any_instance_of(SlackService).to receive(:send_notification).exactly(1).times expect { new_distribution.distribute! }.to raise_error(StandardError) @@ -224,4 +224,103 @@ end end end + + # The following are specifically testing the priority push code in the AutomaticCaseDistribution module + # ByDocketDateDistribution tests are in their own file, by_docket_date_distribution_spec.rb + context "priority push distributions" do + let(:priority_push) { true } + + context "when there is no limit" do + let(:limit) { nil } + + it "distributes priority appeals on the legacy and hearing dockets" do + expect_any_instance_of(LegacyDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: nil, priority: true, genpop: "not_genpop", style: "push") + .and_return([]) + + expect_any_instance_of(HearingRequestDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: nil, priority: true, genpop: "not_genpop", style: "push") + .and_return([]) + + new_distribution.distribute!(limit) + end + end + + context "when there is a limit set" do + let(:limit) { 10 } + + let(:stubbed_appeals) do + { + legacy: 5, + direct_review: 3, + evidence_submission: 1, + hearing: 1 + } + end + + it "distributes only up to the limit" do + expect(new_distribution).to receive(:num_oldest_priority_appeals_by_docket) + .with(limit) + .and_return stubbed_appeals + + expect_any_instance_of(LegacyDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: 5, priority: true, style: "push") + .and_return(create_list(:appeal, 5)) + + expect_any_instance_of(DirectReviewDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: 3, priority: true, style: "push") + .and_return(create_list(:appeal, 3)) + + expect_any_instance_of(EvidenceSubmissionDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: 1, priority: true, style: "push") + .and_return(create_list(:appeal, 1)) + + expect_any_instance_of(HearingRequestDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: 1, priority: true, style: "push") + .and_return(create_list(:appeal, 1)) + + new_distribution.distribute!(limit) + end + end + end + + context "requested distributions" do + context "when priority_acd is enabled" do + let(:limit) { 10 } + let(:batch_size) { CaseDistributionLever.alternative_batch_size } + + before { FeatureToggle.enable!(:priority_acd) } + + it "calls distribute_appeals with bust_backlog set along with the other calls" do + expect_any_instance_of(LegacyDocket).to receive(:distribute_nonpriority_appeals) + .with(new_distribution, limit: batch_size, genpop: "not_genpop", bust_backlog: true, style: "request") + .and_return([]) + + expect_any_instance_of(LegacyDocket).to receive(:distribute_priority_appeals) + .with(new_distribution, limit: batch_size, genpop: "not_genpop", style: "request") + .and_return([]) + + expect_any_instance_of(HearingRequestDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: batch_size, priority: true, genpop: "not_genpop", style: "request") + .and_return([]) + + expect_any_instance_of(LegacyDocket).to receive(:distribute_nonpriority_appeals) + .with(new_distribution, limit: batch_size, genpop: "not_genpop", range: 0, style: "request") + .and_return([]) + + expect_any_instance_of(HearingRequestDocket).to receive(:distribute_appeals) + .with(new_distribution, limit: batch_size, priority: false, genpop: "not_genpop", style: "request") + .and_return([]) + + expect(new_distribution).to receive(:distribute_limited_priority_appeals_from_all_dockets) + .with(15, style: "request") + .and_return([]) + + expect(new_distribution).to receive(:deduct_distributed_actuals_from_remaining_docket_proportions) + .with(:legacy, :hearing) + + new_distribution.distribute!(limit) + end + end + end end