def single_file_errors(self):
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(APPROP_FILE, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 10)
    assert (error_count == 0)
    assert (report_headers == self.validator.report_headers)
    assert (len(report_content) == 0)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(HEADER_ERROR, 'appropriations', warning=False, ignore_error=True)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 0)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 0)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (self.validator.job.number_of_rows is None)
    assert (self.validator.job.number_of_rows_valid == 0)
    assert (error_count == 0)
    assert (report_headers == ['Error type', 'Header name'])
    expected_values = [{'Error type': 'Duplicated header', 'Header name': 'AllocationTransferAgencyIdentifier'}, {'Error type': 'Missing header', 'Header name': 'AdjustmentsToUnobligatedBalanceBroughtForward_CPE'}, {'Error type': 'Missing header', 'Header name': 'AgencyIdentifier'}, {'Error type': 'Missing header', 'Header name': 'BudgetAuthorityUnobligatedBalanceBroughtForward_FYB'}, {'Error type': 'Missing header', 'Header name': 'DeobligationsRecoveriesRefundsByTAS_CPE'}, {'Error type': 'Missing header', 'Header name': 'GrossOutlayAmountByTAS_CPE'}, {'Error type': 'Missing header', 'Header name': 'ObligationsIncurredTotalByTAS_CPE'}, {'Error type': 'Missing header', 'Header name': 'StatusOfBudgetaryResourcesTotal_CPE'}]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(READ_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 6)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 12)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 6)
    format_errors = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).one()
    format_error_count = format_errors.occurrences
    assert (format_error_count == 4)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': '', 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': '', 'Expected Value': '', 'Difference': '', 'Flex Field': '', 'Row Number': '2', 'Rule Label': ''}, {'Unique ID': '', 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': '', 'Expected Value': '', 'Difference': '', 'Flex Field': '', 'Row Number': '3', 'Rule Label': ''}, {'Unique ID': '', 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': '', 'Expected Value': '', 'Difference': '', 'Flex Field': '', 'Row Number': '5', 'Rule Label': ''}, {'Unique ID': '', 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': '', 'Expected Value': '', 'Difference': '', 'Flex Field': '', 'Row Number': '7', 'Rule Label': ''}]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(TYPE_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 9)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 18)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 9)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 1)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': 'TAS: 069-013-X-2050-005', 'Field Name': 'statusofbudgetaryresourcestotal_cpe', 'Rule Message': 'The value provided was of the wrong type. Note that all type errors in a line must be fixed before the rest of the validation logic is applied to that line.', 'Value Provided': 'statusofbudgetaryresourcestotal_cpe: A', 'Expected Value': 'This field must be a decimal', 'Difference': '', 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '6', 'Rule Label': ''}]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(LENGTH_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 9)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 1)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': 'TAS: 069-013-X-2050-005', 'Field Name': 'grossoutlayamountbytas_cpe', 'Rule Message': 'Value was longer than maximum length for this field.', 'Value Provided': 'grossoutlayamountbytas_cpe: 35000000000000000000000000', 'Expected Value': 'Max length: 21', 'Difference': '', 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '6', 'Rule Label': ''}]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(REQUIRED_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 9)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 3)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': 'TAS: 019-2016/2016-0113-000', 'Field Name': 'statusofbudgetaryresourcestotal_cpe', 'Rule Message': 'This field is required for all submissions but was not provided in this row.', 'Value Provided': '', 'Expected Value': '(not blank)', 'Difference': '', 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '3', 'Rule Label': ''}, {'Unique ID': 'TAS: 019-2016/2016-0113-000', 'Field Name': 'statusofbudgetaryresourcestotal_cpe, obligationsincurredtotalbytas_cpe, unobligatedbalance_cpe', 'Rule Message': 'StatusOfBudgetaryResourcesTotal_CPE= ObligationsIncurredTotalByTAS_CPE + UnobligatedBalance_CPE', 'Value Provided': 'statusofbudgetaryresourcestotal_cpe: , obligationsincurredtotalbytas_cpe: 8.08, unobligatedbalance_cpe: 2.02', 'Expected Value': 'StatusOfBudgetaryResourcesTotal_CPE must equal the sum of these elements: ObligationsIncurredTotalByTAS_CPE + UnobligatedBalance_CPE. The Broker cannot distinguish which item is incorrect for this rule. Refer to related rule errors and warnings in this report (rules A15, A22, A23) to distinguish which elements may be incorrect.', 'Difference': '-10.10', 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '3', 'Rule Label': 'A4'}, {'Unique ID': 'TAS: 019-2016/2016-0113-000', 'Field Name': 'statusofbudgetaryresourcestotal_cpe, totalbudgetaryresources_cpe', 'Rule Message': 'StatusOfBudgetaryResourcesTotal_CPE = TotalBudgetaryResources_CPE', 'Value Provided': 'statusofbudgetaryresourcestotal_cpe: , totalbudgetaryresources_cpe: 10.1', 'Expected Value': 'StatusOfBudgetaryResourcesTotal_CPE must equal TotalBudgetaryResources_CPE. The Broker cannot distinguish which side of the equation is correct for this rule. Refer to related rule errors and warnings in this report (rules A6, A23) to distinguish which elements may be incorrect.', 'Difference': '-10.1', 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '3', 'Rule Label': 'A24'}]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(RULE_FAILED_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 10)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 0)
    assert (report_headers == self.validator.report_headers)
    self.cleanup()
    self.generate_file_report(AFINANCIAL_FILE, 'award_financial', warning=False)
    totals = self.session.query(TotalObligations).filter_by(submission_id=self.submission_id).one()
    assert (totals.total_obligations == 12000.0)
    assert (totals.total_proc_obligations == 8000.0)
    assert (totals.total_asst_obligations == 4000.0)
    self.cleanup()
def single_file_errors(self):
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(APPROP_FILE, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 10)
    assert (error_count == 0)
    assert (report_headers == self.validator.report_headers)
    assert (len(report_content) == 0)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(HEADER_ERROR, 'appropriations', warning=False, ignore_error=True)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 0)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 0)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (self.validator.job.number_of_rows is None)
    assert (self.validator.job.number_of_rows_valid == 0)
    assert (error_count == 0)
    assert (report_headers == ['Error type', 'Header name'])
    expected_values = [{'Error type': 'Duplicated header', 'Header name': 'AllocationTransferAgencyIdentifier'}, {'Error type': 'Missing header', 'Header name': 'AdjustmentsToUnobligatedBalanceBroughtForward_CPE'}, {'Error type': 'Missing header', 'Header name': 'AgencyIdentifier'}, {'Error type': 'Missing header', 'Header name': 'BudgetAuthorityUnobligatedBalanceBroughtForward_FYB'}, {'Error type': 'Missing header', 'Header name': 'DeobligationsRecoveriesRefundsByTAS_CPE'}, {'Error type': 'Missing header', 'Header name': 'GrossOutlayAmountByTAS_CPE'}, {'Error type': 'Missing header', 'Header name': 'ObligationsIncurredTotalByTAS_CPE'}, {'Error type': 'Missing header', 'Header name': 'StatusOfBudgetaryResourcesTotal_CPE'}]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(READ_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 6)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 12)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 6)
    format_errors = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).one()
    format_error_count = format_errors.occurrences
    assert (format_error_count == 4)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': , 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': , 'Expected Value': , 'Difference': , 'Flex Field': , 'Row Number': '2', 'Rule Label': }, {'Unique ID': , 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': , 'Expected Value': , 'Difference': , 'Flex Field': , 'Row Number': '3', 'Rule Label': }, {'Unique ID': , 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': , 'Expected Value': , 'Difference': , 'Flex Field': , 'Row Number': '5', 'Rule Label': }, {'Unique ID': , 'Field Name': 'Formatting Error', 'Rule Message': 'Could not parse this record correctly.', 'Value Provided': , 'Expected Value': , 'Difference': , 'Flex Field': , 'Row Number': '7', 'Rule Label': }]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(TYPE_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 9)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 18)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 9)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 1)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': 'TAS: 069-013-X-2050-005', 'Field Name': 'statusofbudgetaryresourcestotal_cpe', 'Rule Message': 'The value provided was of the wrong type. Note that all type errors in a line must be fixed before the rest of the validation logic is applied to that line.', 'Value Provided': 'statusofbudgetaryresourcestotal_cpe: A', 'Expected Value': 'This field must be a decimal', 'Difference': , 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '6', 'Rule Label': }]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(LENGTH_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 9)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 1)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': 'TAS: 069-013-X-2050-005', 'Field Name': 'grossoutlayamountbytas_cpe', 'Rule Message': 'Value was longer than maximum length for this field.', 'Value Provided': 'grossoutlayamountbytas_cpe: 35000000000000000000000000', 'Expected Value': 'Max length: 21', 'Difference': , 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '6', 'Rule Label': }]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(REQUIRED_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 9)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 3)
    assert (report_headers == self.validator.report_headers)
    expected_values = [{'Unique ID': 'TAS: 019-2016/2016-0113-000', 'Field Name': 'statusofbudgetaryresourcestotal_cpe', 'Rule Message': 'This field is required for all submissions but was not provided in this row.', 'Value Provided': , 'Expected Value': '(not blank)', 'Difference': , 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '3', 'Rule Label': }, {'Unique ID': 'TAS: 019-2016/2016-0113-000', 'Field Name': 'statusofbudgetaryresourcestotal_cpe, obligationsincurredtotalbytas_cpe, unobligatedbalance_cpe', 'Rule Message': 'StatusOfBudgetaryResourcesTotal_CPE= ObligationsIncurredTotalByTAS_CPE + UnobligatedBalance_CPE', 'Value Provided': 'statusofbudgetaryresourcestotal_cpe: , obligationsincurredtotalbytas_cpe: 8.08, unobligatedbalance_cpe: 2.02', 'Expected Value': 'StatusOfBudgetaryResourcesTotal_CPE must equal the sum of these elements: ObligationsIncurredTotalByTAS_CPE + UnobligatedBalance_CPE. The Broker cannot distinguish which item is incorrect for this rule. Refer to related rule errors and warnings in this report (rules A15, A22, A23) to distinguish which elements may be incorrect.', 'Difference': '-10.10', 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '3', 'Rule Label': 'A4'}, {'Unique ID': 'TAS: 019-2016/2016-0113-000', 'Field Name': 'statusofbudgetaryresourcestotal_cpe, totalbudgetaryresources_cpe', 'Rule Message': 'StatusOfBudgetaryResourcesTotal_CPE = TotalBudgetaryResources_CPE', 'Value Provided': 'statusofbudgetaryresourcestotal_cpe: , totalbudgetaryresources_cpe: 10.1', 'Expected Value': 'StatusOfBudgetaryResourcesTotal_CPE must equal TotalBudgetaryResources_CPE. The Broker cannot distinguish which side of the equation is correct for this rule. Refer to related rule errors and warnings in this report (rules A6, A23) to distinguish which elements may be incorrect.', 'Difference': '-10.1', 'Flex Field': 'flex_field_a: FLEX_A, flex_field_b: FLEX_B', 'Row Number': '3', 'Rule Label': 'A24'}]
    assert (report_content == expected_values)
    self.cleanup()
    (report_headers, report_content) = self.generate_file_report(RULE_FAILED_ERROR, 'appropriations', warning=False)
    appro_count = self.session.query(Appropriation).filter_by(submission_id=self.submission_id).count()
    assert (appro_count == 10)
    flex_count = self.session.query(FlexField).filter_by(submission_id=self.submission_id).count()
    assert (flex_count == 20)
    assert (self.validator.job.number_of_rows == 11)
    assert (self.validator.job.number_of_rows_valid == 10)
    error_count = self.session.query(ErrorMetadata).filter_by(job_id=self.val_job.job_id, severity_id=RULE_SEVERITY_DICT['fatal']).count()
    assert (error_count == 0)
    assert (report_headers == self.validator.report_headers)
    self.cleanup()
    self.generate_file_report(AFINANCIAL_FILE, 'award_financial', warning=False)
    totals = self.session.query(TotalObligations).filter_by(submission_id=self.submission_id).one()
    assert (totals.total_obligations == 12000.0)
    assert (totals.total_proc_obligations == 8000.0)
    assert (totals.total_asst_obligations == 4000.0)
    self.cleanup()