diff --git a/backend/app/models/concerns/dgfip_validation_methods.rb b/backend/app/models/concerns/dgfip_validation_methods.rb index 5ed78ef45..6ceb29b77 100644 --- a/backend/app/models/concerns/dgfip_validation_methods.rb +++ b/backend/app/models/concerns/dgfip_validation_methods.rb @@ -8,9 +8,9 @@ def no_need_to_select_scopes? end def rgpd_general_agreement_validation - unless additional_content&.fetch("rgpd_general_agreement", false) - errors.add(:additional_content, :invalid, message: "Vous devez attester que votre organisation déclarera à la DGFiP l'accomplissement des formalités en terme de protection des données") - end + return if additional_content&.fetch("rgpd_general_agreement", false) + + errors.add(:additional_content, :invalid, message: "Vous devez attester que votre organisation déclarera à la DGFiP l'accomplissement des formalités en terme de protection des données") end def api_impot_particulier_scope_validation @@ -23,19 +23,15 @@ def api_impot_particulier_scope_validation dgfip_PaDeduc_EnfMaj dgfip_PaDeduc_Autres dgfip_EpargRetrDeduc dgfip_IndLep ] - if (scopes & %w[dgfip_annee_n_moins_1 dgfip_annee_n_moins_2 dgfip_annee_n_moins_3 dgfip_annee_n_moins_2_si_indispo_n_moins_1]).empty? - errors.add(:scopes, :invalid, message: "Vous devez cocher au moins une année de revenus souhaitée avant de continuer") - end - - if (scopes & %w[dgfip_annee_n_moins_2_si_indispo_n_moins_1 dgfip_annee_df_au_3112_si_deces_ctb_mp]).present? && (scopes & incompatible_scopes).present? - errors.add(:scopes, :invalid, message: "Des données incompatibles entre elles ont été cochées. Pour connaître les modalités d’appel et de réponse de l’API Impôt particulier ainsi que les données proposées, vous pouvez consulter le guide de présentation de cette API dans la rubrique « Les données nécessaires > Comment choisir les données »") - end + validate_revenue_years_selection + validate_incompatible_scopes(incompatible_scopes) + validate_exclusive_years_scope_combination end def api_impot_particulier_acces_validation - unless additional_content.any? { |k, v| v && %w[acces_spi acces_etat_civil].include?(k) } - errors.add(:scopes, :invalid, message: "Vous devez cocher au moins une modalité d’accès avant de continuer") - end + return if additional_content.any? { |k, v| v && %w[acces_spi acces_etat_civil].include?(k) } + + errors.add(:scopes, :invalid, message: "Vous devez cocher au moins une modalité d’accès avant de continuer") end def production_form_validation @@ -57,4 +53,34 @@ def production_form_validation errors.add(:cgu_approved, :invalid, message: "Vous devez valider les modalités d’utilisation avant de continuer") unless cgu_approved? errors.add(:dpo_is_informed, :invalid, message: "Vous devez confirmer avoir informé le DPD de votre organisation avant de continuer") unless dpo_is_informed? end + + private + + def validate_revenue_years_selection + selected_years = %w[ + dgfip_annee_n_moins_1 dgfip_annee_n_moins_2 dgfip_annee_n_moins_3 + dgfip_annee_n_moins_2_si_indispo_n_moins_1 + ] + + return unless (scopes & selected_years).empty? + + errors.add(:scopes, :invalid, message: "Vous devez cocher au moins une année de revenus souhaitée avant de continuer") + end + + def validate_incompatible_scopes(incompatible_scopes) + special_scopes = %w[ + dgfip_annee_n_moins_2_si_indispo_n_moins_1 dgfip_annee_df_au_3112_si_deces_ctb_mp + ] + + return unless (scopes & special_scopes).present? && (scopes & incompatible_scopes).present? + + errors.add(:scopes, :invalid, message: "Des données incompatibles entre elles ont été cochées. Pour connaître les modalités d’appel et de réponse de l’API Impôt particulier ainsi que les données proposées, vous pouvez consulter le guide de présentation de cette API dans la rubrique « Les données nécessaires > Comment choisir les données »") + end + + def validate_exclusive_years_scope_combination + if (scopes & %w[dgfip_annee_n_moins_2_si_indispo_n_moins_1]).present? && + (scopes & %w[dgfip_annee_n_moins_1 dgfip_annee_n_moins_2 dgfip_annee_n_moins_3]).present? + errors.add(:scopes, :invalid, message: "Vous ne pouvez pas sélectionner la donnée 'avant dernière année de revenu, si la dernière année de revenu est indisponible' avec d'autres années de revenus") + end + end end diff --git a/backend/spec/models/enrollment/api_impot_particulier_sandbox_spec.rb b/backend/spec/models/enrollment/api_impot_particulier_sandbox_spec.rb index fd4ca257d..9d477390f 100644 --- a/backend/spec/models/enrollment/api_impot_particulier_sandbox_spec.rb +++ b/backend/spec/models/enrollment/api_impot_particulier_sandbox_spec.rb @@ -12,6 +12,24 @@ end end + context "when incompatible years combination years are selected" do + before { enrollment.update(scopes: ["dgfip_annee_n_moins_2_si_indispo_n_moins_1", "dgfip_annee_n_moins_1"]) } + + it "is not valid" do + enrollment.send(:submit_validation) + expect(enrollment.errors[:scopes]).to include("Vous ne pouvez pas sélectionner la donnée 'avant dernière année de revenu, si la dernière année de revenu est indisponible' avec d'autres années de revenus") + end + end + + context "when exclusive years combination years are selected" do + before { enrollment.update(scopes: ["dgfip_annee_n_moins_1", "dgfip_annee_n_moins_2"]) } + + it "is valid" do + enrollment.send(:submit_validation) + expect(enrollment).to be_valid + end + end + context "when no scope is selected but a specific requirement is expressed" do before { enrollment.update(additional_content: {"specific_requirements" => true}) } @@ -20,5 +38,14 @@ expect(enrollment.errors[:scopes]).not_to include("Vous devez cocher au moins une année de revenus souhaitée avant de continuer") end end + + context "when incompatible scopes are selected with special scopes" do + before { enrollment.update(scopes: ["dgfip_IndLep", "dgfip_annee_df_au_3112_si_deces_ctb_mp"]) } + + it "is not valid" do + enrollment.send(:submit_validation) + expect(enrollment.errors[:scopes]).to include("Des données incompatibles entre elles ont été cochées. Pour connaître les modalités d’appel et de réponse de l’API Impôt particulier ainsi que les données proposées, vous pouvez consulter le guide de présentation de cette API dans la rubrique « Les données nécessaires > Comment choisir les données »") + end + end end end