class CSVTestBase(test.TestCase): reporrtype = 'timeperiods' url = '/indicators/iptt_csv/{0}/{1}/' fields = ['id', 'number', 'name', 'level_name', 'unit_of_measure', 'unit_of_measure_type', 'sector', 'disaggregations', 'baseline', 'baseline_na', 'lop_target', 'target_frequency'] data_fields = ['lop_sum', 'lop_target', 'lop_met'] def setUp(self): self.client = test.Client() self.program = ProgramFactory(reporting_period_start=datetime.strptime('2017-01-01', '%Y-%m-%d'), reporting_period_end=datetime.strptime('2017-12-31', '%Y-%m-%d')) self.url = self.url.format(self.program.id, self.reporrtype) def tearDown(self): self.program.delete() def get_field(self, field, row): return row[ {v: c for c, v in enumerate(self.fields)}[field] ]
class TestIndicatorScenarios(test.TestCase): def setUp(self): self.program = ProgramFactory( reporting_period_start=get_date(dates['program_start']), reporting_period_end=get_date(dates['program_end'])) self.indicator = None self.targets = [] self.data = [] def tearDown(self): for data in self.data: data.delete() for target in self.targets: target.delete() if self.indicator is not None: self.indicator.delete() self.program.delete() def indicator_for_scenario(self, scenario): indicator = IndicatorFactory( target_frequency=Indicator.TRI_ANNUAL, is_cumulative=scenario['cumulative'], direction_of_change=(Indicator.DIRECTION_OF_CHANGE_POSITIVE if scenario['positive'] else Indicator.DIRECTION_OF_CHANGE_NEGATIVE), unit_of_measure_type=(Indicator.NUMBER if scenario['number'] else Indicator.PERCENTAGE), program=self.program) for target_number, period in zip(scenario['targets'], dates['targets']): self.targets.append( PeriodicTargetFactory(indicator=indicator, target=target_number, start_date=get_date(period[0]), end_date=get_date(period[1]))) for c, data_set in enumerate(scenario['data']): date_set = dates['collects'][c] for data, date in zip(data_set, date_set): self.data.append( CollectedDataFactory(periodic_target=self.targets[c], achieved=data, indicator=indicator, program=self.program, date_collected=get_date(date))) return indicator def get_scenarios(self): for scenario in scenarios: try: self.indicator = self.indicator_for_scenario(scenario) except ValidationError: exc_type, exc_value = sys.exc_info()[:2] self.fail("{0} in {1} scenario: {2}".format( exc_type.__name__, scenario['desc'], ",".join(exc_value))) self.assertEqual(self.indicator.program, self.program) yield scenario def test_scenario_totals_targetperiods(self): settings.DEBUG = True for scenario in self.get_scenarios(): created = len(connection.queries) iptt_indicator = IPTTIndicator.withtargets.get( pk=self.indicator.pk) expected_queries = 2 self.assertLessEqual( len(connection.queries) - created, expected_queries, "Expecting {0} query to fetch indicator, but it took {1}". format(expected_queries, len(connection.queries) - created)) # make sure iptt indicator proxy loaded correctly: self.assertEqual(iptt_indicator.pk, self.indicator.pk) if scenario['blank']: # no tests on a blank (unsupported for annotations) indicator: return self.assertEqual( iptt_indicator.lop_target_sum, scenario['lop_target'], "In scenario {desc}: calculated lop_target_sum should be {1}, got {0}" .format(iptt_indicator.lop_target_sum, scenario['lop_target'], desc=scenario['desc'])) self.assertEqual( iptt_indicator.lop_actual_sum, scenario['lop_sum'], "In scenario {desc}: calculated lop sum should be {0}, got {1}" .format(scenario['lop_sum'], iptt_indicator.lop_actual_sum, desc=scenario['desc'])) self.assertEqual( iptt_indicator.lop_met_target, scenario['lop_met'], "In scenarios {desc}: lop met_target should be {0}, got {1}". format(scenario['lop_met'], iptt_indicator.lop_met_target, desc=scenario['desc'])) settings.DEBUG = False def test_scenario_totals_timeperiods(self): settings.DEBUG = True for scenario in self.get_scenarios(): created = len(connection.queries) iptt_indicator = IPTTIndicator.notargets.get(pk=self.indicator.pk) expected_queries = 1 self.assertLessEqual( len(connection.queries) - created, expected_queries, "Expecting {0} query to fetch indicator, but it took {1}". format(expected_queries, len(connection.queries) - created)) # make sure iptt indicator proxy loaded correctly: self.assertEqual(iptt_indicator.pk, self.indicator.pk) if scenario['blank']: # no tests on a blank (unsupported for annotations) indicator: return self.assertEqual( iptt_indicator.lop_target_sum, scenario['lop_target'], "In scenario {desc}: calculated lop_target_sum should be {1}, got {0}" .format(iptt_indicator.lop_target_sum, scenario['lop_target'], desc=scenario['desc'])) self.assertEqual( iptt_indicator.lop_actual_sum, scenario['lop_sum'], "In scenario {desc}: calculated lop sum should be {0}, got {1}" .format(scenario['lop_sum'], iptt_indicator.lop_actual_sum, desc=scenario['desc'])) self.assertEqual( iptt_indicator.lop_met_target, scenario['lop_met'], "In scenarios {desc}: lop met_target should be {0}, got {1}". format(scenario['lop_met'], iptt_indicator.lop_met_target, desc=scenario['desc'])) settings.DEBUG = False def test_periodic_target_scenarios(self): settings.DEBUG = True for scenario in self.get_scenarios(): created = len(connection.queries) indicator = IPTTIndicator.withtargets.get(pk=self.indicator.pk) expected_queries = 2 #one for each target self.assertLessEqual( len(connection.queries) - created, expected_queries, "Expecting {0} queries to fetch indicator, but it took {1}". format(expected_queries, len(connection.queries) - created)) if scenario['blank']: return self.assertEqual( len(indicator.data_targets), len(scenario['targets']), "In {desc}: expecting {0} indicator targets, got {1}".format( len(scenario['targets']), len(indicator.data_targets), desc=scenario['desc'])) for c, target_actual in enumerate(indicator.data_targets): self.assertEqual( target_actual.target, scenario['targets'][c], "In {desc}: expected {0} for target {1}, but got {2}". format(scenario['targets'][c], c, target_actual.target, desc=scenario['desc'])) self.assertEqual( target_actual.data_sum, scenario['results'][c], "In {desc}: expected a sum of {0} for target {1}, but got {2}" .format(scenario['results'][c], c, target_actual.data_sum, desc=scenario['desc'])) self.assertEqual( target_actual.met, scenario['mets'][c], "In {desc}: expected a met of {0} for target {1}, but got {2}" .format(scenario['mets'][c], c, target_actual.met, desc=scenario['desc'])) self.assertEqual( target_actual.within_target_range, scenario['over_under'][c], "In {desc}: expected {0} within_target_range to be {1}, got {2}" .format(c, scenario['over_under'][c], target_actual.within_target_range, desc=scenario['desc'])) self.assertLessEqual( len(connection.queries) - created, expected_queries, "(after all tests): expecting {0} queries to fetch indicator, but it took {1}" .format(expected_queries, len(connection.queries) - created)) settings.DEBUG = False def test_timeperiod_scenarios(self): settings.DEBUG = True periods = [{ 'start_date': datetime(2016, 1, 1), 'end_date': datetime(2016, 6, 30), }, { 'start_date': datetime(2016, 7, 1), 'end_date': datetime(2016, 12, 31) }] for scenario in self.get_scenarios(): created = len(connection.queries) indicator = IPTTIndicator.notargets.periods(periods).get( pk=self.indicator.id) expected_queries = 1 self.assertLessEqual( len(connection.queries) - created, expected_queries, "Expecting {0} queries to fetch indicator, but it took {1}". format(expected_queries, len(connection.queries) - created)) expected_results = len(scenario['semi_annual_results'] ) if not scenario['blank'] else 0 self.assertEqual( len([p for p in indicator.timeperiods]), expected_results, "In {desc}, expected {0} timeperiods, got {1}".format( expected_results, len([p for p in indicator.timeperiods]), desc=scenario['desc'])) for c, period in enumerate(periods): if scenario['blank'] != True: period_sum = getattr( indicator, "{0}-{1}".format( period['start_date'].strftime('%Y-%m-%d'), period['end_date'].strftime('%Y-%m-%d'))) self.assertEqual( period_sum, scenario['semi_annual_results'][c], "{desc} expected {0} for sum of semi annual period {1}, got {2}" .format(scenario['semi_annual_results'][c], c, period_sum, desc=scenario['desc'])) settings.DEBUG = False