def test_intervention_locations_in_use(self): self.client.force_login(self.unicef_staff) url = reverse("locations-gis-in-use") # test with missing country, expect error response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) response = self.client.get("{}?country_id={}".format( reverse("locations-gis-in-use"), self.country.id), user=self.unicef_staff) self.assertEqual(response.status_code, status.HTTP_200_OK) # see if no location are in use yet self.assertEqual(len(response.json()), 0) # add intervention locations and test the response intervention = InterventionFactory(status=Intervention.SIGNED) intervention.flat_locations.add(self.location_no_geom, self.location_with_geom) intervention.save() response = self.client.get("{}?country_id={}".format( reverse("locations-gis-in-use"), self.country.id), user=self.unicef_staff) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(response.data[0].keys()), ["gateway_id", "id", "level", "name", "p_code", "parent_id"])
def test_remap_in_use_validation_failed(self): self.mock_sql.return_value = {"rows": []} intervention = InterventionFactory(status=Intervention.SIGNED) intervention.flat_locations.add(self.remapped_location) intervention.save() with self.assertRaises(tasks.NoRemapInUseException): self._run_validation(self.carto_table.pk)
def test_send(self): intervention = InterventionFactory(status=Intervention.DRAFT) tz = timezone.get_default_timezone() intervention.created = datetime.datetime(2018, 1, 1, 12, 55, 12, 12345, tzinfo=tz) intervention.save() mock_send = Mock() with patch(self.send_path, mock_send): utils.send_intervention_draft_notification() self.assertEqual(mock_send.call_count, 1)
def test_command(self): send_path = "etools.applications.partners.utils.send_notification_with_template" intervention = InterventionFactory(status=Intervention.DRAFT) tz = timezone.get_default_timezone() intervention.created = datetime.datetime(2018, 1, 1, 12, 55, 12, 12345, tzinfo=tz) intervention.save() mock_send = Mock() with patch(send_path, mock_send): call_command("send_intervention_draft_notification") self.assertEqual(mock_send.call_count, 1)
class TestGetInterventionContext(BaseTenantTestCase): '''Exercise the tasks' helper function get_intervention_context()''' def setUp(self): super(TestGetInterventionContext, self).setUp() self.intervention = InterventionFactory() self.focal_point_user = UserFactory() def test_simple_intervention(self): '''Exercise get_intervention_context() with a very simple intervention''' result = etools.applications.partners.tasks.get_intervention_context( self.intervention) self.assertIsInstance(result, dict) self.assertEqual( sorted(result.keys()), sorted([ 'number', 'partner', 'start_date', 'url', 'unicef_focal_points' ])) self.assertEqual(result['number'], str(self.intervention)) self.assertEqual(result['partner'], self.intervention.agreement.partner.name) self.assertEqual(result['start_date'], 'None') self.assertEqual( result['url'], 'https://{}/pmp/interventions/{}/details'.format( settings.HOST, self.intervention.id)) self.assertEqual(result['unicef_focal_points'], []) def test_non_trivial_intervention(self): '''Exercise get_intervention_context() with an intervention that has some interesting detail''' self.focal_point_user = get_user_model().objects.first() self.intervention.unicef_focal_points.add(self.focal_point_user) self.intervention.start = datetime.date(2017, 8, 1) self.intervention.save() result = etools.applications.partners.tasks.get_intervention_context( self.intervention) self.assertIsInstance(result, dict) self.assertEqual( sorted(result.keys()), sorted([ 'number', 'partner', 'start_date', 'url', 'unicef_focal_points' ])) self.assertEqual(result['number'], str(self.intervention)) self.assertEqual(result['partner'], self.intervention.agreement.partner.name) self.assertEqual(result['start_date'], '2017-08-01') self.assertEqual( result['url'], 'https://{}/pmp/interventions/{}/details'.format( settings.HOST, self.intervention.id)) self.assertEqual(result['unicef_focal_points'], [self.focal_point_user.email])
def test_remap_in_use_validation_success(self): self.mock_sql.return_value = { "rows": [{ "old_pcode": self.remapped_location.p_code, "new_pcode": self.new_location.p_code }] } intervention = InterventionFactory(status=Intervention.SIGNED) intervention.flat_locations.add(self.remapped_location) intervention.save() response = self._run_validation(self.carto_table.pk) self.assertTrue(response)
def test_remap_in_use_cleanup(self): self.mock_sql.return_value = { "rows": [{ "old_pcode": self.remapped_location.p_code, "new_pcode": self.new_location.p_code }] } intervention = InterventionFactory(status=Intervention.SIGNED) intervention.flat_locations.add(self.remapped_location) intervention.save() self.assertEqual(len(Location.objects.all_locations()), 5) self._run_cleanup(self.carto_table.pk) self.assertEqual(len(Location.objects.all_locations()), 2)
def test_intervention_locations_in_use(self): # add intervention locations and test the response intervention = InterventionFactory(status=Intervention.SIGNED) intervention.flat_locations.add(self.location_no_geom, self.location_with_geom) intervention.save() response = self.forced_auth_req( "get", reverse("management_gis:locations-gis-in-use"), user=self.unicef_staff, data={"country_id": self.country.id, "geo_format": "whatever"}, ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(sorted(response.data[0].keys()), ["gateway_id", "id", "level", "name", "p_code", "parent_id"])
def test_intervention_locations_in_use(self): # add intervention locations and test the response intervention = InterventionFactory(status=Intervention.SIGNED) intervention.flat_locations.add(self.location_no_geom, self.location_with_geom) intervention.save() response = self.forced_auth_req( "get", reverse("management_gis:locations-gis-in-use"), user=self.unicef_staff, data={ "country_id": self.country.id, "geo_format": "whatever" }, ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( sorted(response.data[0].keys()), ["gateway_id", "id", "level", "name", "p_code", "parent_id"])
def test_remap_in_use_reassignment_success(self): self.mock_remap_data.return_value = ( True, [{ "old_pcode": self.remapped_location.p_code, "new_pcode": self.new_location.p_code }], [self.remapped_location.p_code], [self.new_location.p_code], ) self.mock_carto_data.return_value = True, [{ self.carto_table.pcode_col: self.new_location.p_code, "name": self.new_location.name + "_remapped", "the_geom": self.geom }] intervention = InterventionFactory(status=Intervention.SIGNED) intervention.flat_locations.add(self.remapped_location) intervention.save() with self.assertRaises(Location.DoesNotExist): intervention.flat_locations.get(id=self.new_location.id) self.assertIsNotNone( intervention.flat_locations.get(id=self.remapped_location.id)) self._run_update(self.carto_table.pk) with self.assertRaises(Location.DoesNotExist): intervention.flat_locations.get(id=self.remapped_location.id) new_flat_location = intervention.flat_locations.get( p_code=self.new_location.p_code) self.assertIsNotNone(new_flat_location) self.assertEqual(new_flat_location.name, self.new_location.name + "_remapped")
def test_update_intervention(self): """Ensure agreement update fails if intervention dates aren't appropriate. I don't think it's possible to supply interventions when creating via the serializer, so this only tests update. """ agreement = AgreementFactory( agreement_type=Agreement.SSFA, partner=self.partner, status=Agreement.DRAFT, start=self.today - datetime.timedelta(days=5), end=self.today + datetime.timedelta(days=5), signed_by_unicef_date=None, signed_by_partner_date=None, reference_number_year=datetime.date.today().year) intervention = InterventionFactory(agreement=agreement) # Start w/an invalid intervention. data = { "agreement": agreement, "intervention": intervention, } serializer = AgreementCreateUpdateSerializer() # If I don't set serializer.instance, the validator gets confused. I guess (?) this is ordinarily set by DRF # during an update? serializer.instance = agreement serializer.context['request'] = self.fake_request with self.assertRaises(serializers.ValidationError) as context_manager: serializer.validate(data=data) self.assertSimpleExceptionFundamentals( context_manager, "Start and end dates don't match the Document's start and end") # Set start date and save again; it should still fail because end date isn't set. intervention.start = agreement.start intervention.save() with self.assertRaises(serializers.ValidationError) as context_manager: serializer.validate(data=data) self.assertSimpleExceptionFundamentals( context_manager, "Start and end dates don't match the Document's start and end") # Set start date and save again; it should still fail because end date doesn't match agreement end date. intervention.end = agreement.end + datetime.timedelta(days=100) intervention.save() with self.assertRaises(serializers.ValidationError) as context_manager: serializer.validate(data=data) self.assertSimpleExceptionFundamentals( context_manager, "Start and end dates don't match the Document's start and end") # Set start date and save again; it should now succeed. intervention.end = agreement.end intervention.save() # Should not raise an exception serializer.validate(data=data)
def test_update_intervention(self): """Ensure agreement update fails if intervention dates aren't appropriate. I don't think it's possible to supply interventions when creating via the serializer, so this only tests update. """ agreement = AgreementFactory(agreement_type=Agreement.SSFA, partner=self.partner, status=Agreement.DRAFT, start=self.today - datetime.timedelta(days=5), end=self.today + datetime.timedelta(days=5), signed_by_unicef_date=None, signed_by_partner_date=None, reference_number_year=datetime.date.today().year) intervention = InterventionFactory(agreement=agreement) # Start w/an invalid intervention. data = { "agreement": agreement, "intervention": intervention, } serializer = AgreementCreateUpdateSerializer() # If I don't set serializer.instance, the validator gets confused. I guess (?) this is ordinarily set by DRF # during an update? serializer.instance = agreement serializer.context['request'] = self.fake_request with self.assertRaises(serializers.ValidationError) as context_manager: serializer.validate(data=data) self.assertSimpleExceptionFundamentals( context_manager, "Start and end dates don't match the Document's start and end" ) # Set start date and save again; it should still fail because end date isn't set. intervention.start = agreement.start intervention.save() with self.assertRaises(serializers.ValidationError) as context_manager: serializer.validate(data=data) self.assertSimpleExceptionFundamentals( context_manager, "Start and end dates don't match the Document's start and end" ) # Set start date and save again; it should still fail because end date doesn't match agreement end date. intervention.end = agreement.end + datetime.timedelta(days=100) intervention.save() with self.assertRaises(serializers.ValidationError) as context_manager: serializer.validate(data=data) self.assertSimpleExceptionFundamentals( context_manager, "Start and end dates don't match the Document's start and end" ) # Set start date and save again; it should now succeed. intervention.end = agreement.end intervention.save() # Should not raise an exception serializer.validate(data=data)
class TestAppliedIndicatorSerializer(BaseTenantTestCase): @classmethod def setUpTestData(cls): cls.section = SectionFactory() cls.location = LocationFactory() def setUp(self): self.indicator = IndicatorBlueprintFactory() self.intervention = InterventionFactory(status=Intervention.ACTIVE) self.result_link = InterventionResultLinkFactory( intervention=self.intervention, ) self.lower_result = LowerResultFactory(result_link=self.result_link, ) self.applied_indicator = AppliedIndicatorFactory( lower_result=self.lower_result, target={ "d": 3, "v": 4 }, ) self.intervention.flat_locations.add(self.location) self.intervention.sections.add(self.section) self.data = { "indicator": { "title": self.indicator.title }, "lower_result": self.lower_result.pk, "locations": [self.location.pk], "section": self.section.pk, } def test_validate_invalid_location(self): """If location is not related to intervention, then fail validation""" self.intervention.flat_locations.remove(self.location) serializer = AppliedIndicatorSerializer(data=self.data) self.assertFalse(serializer.is_valid()) self.assertEqual( serializer.errors, { "non_field_errors": [ 'This indicator can only have locations that were ' 'previously saved on the intervention' ] }) def test_validate_no_section(self): """If no section provided on indicator creation, then fail validation""" del self.data["section"] request = RequestFactory().post( reverse('partners_api:intervention-indicators-update', args=[self.intervention.id])) serializer = AppliedIndicatorSerializer(data=self.data, context={"request": request}) self.assertFalse(serializer.is_valid()) self.assertEqual(serializer.errors, {"non_field_errors": ['Section is required']}) # PATCHing an indicator should not require to have sections in the request request = RequestFactory().patch( reverse('partners_api:intervention-indicators-update', args=[self.intervention.id])) serializer = AppliedIndicatorSerializer(data=self.data, context={"request": request}) self.assertTrue(serializer.is_valid()) def test_validate_invalid_section(self): """If sector already set on applied indicator then fail validation""" self.data["section"] = SectionFactory().pk serializer = AppliedIndicatorSerializer(data=self.data) self.assertFalse(serializer.is_valid()) self.assertEqual( serializer.errors, { "non_field_errors": [ 'This indicator can only have a section that was ' 'previously saved on the intervention' ] }) def test_validate_no_cluster_indicator(self): """Check that validation passes when given no cluster indicator id""" self.intervention.flat_locations.add(self.location) serializer = AppliedIndicatorSerializer(data=self.data) self.assertTrue(serializer.is_valid()) def test_validate_indicator_used(self): """CHeck that is indicator already used we fail validation""" self.applied_indicator.indicator = self.indicator self.applied_indicator.save() serializer = AppliedIndicatorSerializer(data=self.data) self.assertFalse(serializer.is_valid()) self.assertEqual( serializer.errors, { "non_field_errors": ['This indicator is already being monitored for this Result'] }) def test_validate_partial_exception(self): """If partial validation, and indicator is not blueprint indicator instance then fail""" self.data["indicator"] = {"title": "wrong"} serializer = AppliedIndicatorSerializer(data=self.data, partial=True) self.assertFalse(serializer.is_valid()) self.assertEqual( serializer.errors, { "non_field_errors": [ 'Indicator blueprint cannot be updated after first use, ' 'please remove this indicator and add another or contact the eTools Focal Point in ' 'your office for assistance' ] }) def test_validate(self): """If cluster indicator provided, no check is happening that value""" self.data["cluster_indicator_id"] = "404" self.intervention.flat_locations.add(self.location) serializer = AppliedIndicatorSerializer(data=self.data) self.assertTrue(serializer.is_valid()) def test_validate_value_numbers(self): self.data["target"] = {"d": 123, "v": "$321"} self.data["baseline"] = {"d": "wrong", "v": 321} self.intervention.flat_locations.add(self.location) serializer = AppliedIndicatorSerializer(data=self.data) self.assertFalse(serializer.is_valid()) self.assertIn("target", serializer.errors) self.assertIn("baseline", serializer.errors) def test_create(self): applied_qs = AppliedIndicator.objects.filter( lower_result__pk=self.lower_result.pk) count = applied_qs.count() serializer = AppliedIndicatorSerializer(data=self.data) self.assertTrue(serializer.is_valid()) indicator = serializer.create(serializer.validated_data) self.assertIsInstance(indicator, AppliedIndicator) self.assertEqual(applied_qs.count(), count + 1) def test_validate_changed_denominator_status_active(self): """Not allowed to change denominator if draft status active and not in amendment mode""" self.applied_indicator.indicator = self.indicator self.applied_indicator.save() self.data["cluster_indicator_id"] = "404" self.data["target"] = {'d': 1, 'v': 2} self.intervention.flat_locations.add(self.location) self.assertEqual(self.intervention.status, Intervention.ACTIVE) self.assertFalse(self.intervention.in_amendment) serializer = AppliedIndicatorSerializer( data=self.data, instance=self.applied_indicator) self.assertFalse(serializer.is_valid()) self.assertEqual( serializer.errors, { "non_field_errors": [ 'You cannot change the Indicator Target Denominator if PD/SSFA is not in status Draft or Signed' ] }) def test_validate_changed_denominator_status_draft(self): """Allowed to change denominator if in draft status""" self.intervention.status = Intervention.DRAFT self.intervention.save() self.applied_indicator.indicator = self.indicator self.applied_indicator.save() self.data["cluster_indicator_id"] = "404" self.data["target"] = {'d': 1, 'v': 2} self.intervention.flat_locations.add(self.location) self.assertEqual(self.intervention.status, Intervention.DRAFT) serializer = AppliedIndicatorSerializer( data=self.data, instance=self.applied_indicator) self.assertTrue(serializer.is_valid()) def test_validate_changed_denominator_status_signed(self): """Allowed to change denominator if in signed status""" self.intervention.status = Intervention.SIGNED self.intervention.save() self.applied_indicator.indicator = self.indicator self.applied_indicator.save() self.data["cluster_indicator_id"] = "404" self.data["target"] = {'d': 1, 'v': 2} self.intervention.flat_locations.add(self.location) self.assertEqual(self.intervention.status, Intervention.SIGNED) serializer = AppliedIndicatorSerializer( data=self.data, instance=self.applied_indicator) self.assertTrue(serializer.is_valid()) def test_validate_changed_denominator_in_amendment(self): """Allowed to change denominator if in amendment mode""" self.intervention.in_amendment = True self.intervention.save() self.applied_indicator.indicator = self.indicator self.applied_indicator.save() self.data["cluster_indicator_id"] = "404" self.data["target"] = {'d': 1, 'v': 2} self.intervention.flat_locations.add(self.location) self.assertTrue(self.intervention.in_amendment) self.assertEqual(self.intervention.status, Intervention.ACTIVE) serializer = AppliedIndicatorSerializer( data=self.data, instance=self.applied_indicator) self.assertTrue(serializer.is_valid()) def test_validate_changed_denominator_ratio_in_amendment(self): """Not allowed to change denominator if in amendment mode and display_type is ratio """ self.intervention.in_amendment = True self.intervention.save() self.indicator.display_type = IndicatorBlueprint.RATIO self.indicator.save() self.applied_indicator.indicator = self.indicator self.applied_indicator.save() self.data["cluster_indicator_id"] = "404" self.data["target"] = {'d': 1, 'v': 2} self.intervention.flat_locations.add(self.location) self.assertTrue(self.intervention.in_amendment) self.assertEqual(self.intervention.status, Intervention.ACTIVE) self.assertEqual(self.applied_indicator.indicator.display_type, IndicatorBlueprint.RATIO) serializer = AppliedIndicatorSerializer( data=self.data, instance=self.applied_indicator) self.assertFalse(serializer.is_valid()) self.assertEqual( serializer.errors, { "non_field_errors": [ 'You cannot change the Indicator Target Denominator if PD/SSFA is not in status Draft or Signed' ] })