def test_should_be_able_to_patch_disaggregation_targets_values(self): _, org = self.create_org_user('*****@*****.**', 'password') project = ProjectFixtureBuilder()\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .with_disaggregations({ 'Gender': ['Male', 'Female'], 'Age': ['Children', 'Adults'] })\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [{ 'period_start': date(2010, 1, 1), 'period_end': date(2010, 12, 31), 'target_value': 10, 'disaggregation_targets': { 'Gender': {'Male': 5, 'Female': 5}, 'Age': {'Adults': 10} } }] }] }]).build() period = project.get_period(period_start=date(2010, 1, 1)) gender_female_target = period.get_disaggregation_target( 'Gender', 'Female') age_adults_target = period.get_disaggregation_target('Age', 'Adults') data = { 'target_value': 12, 'disaggregation_targets': [ { 'dimension_value': gender_female_target.dimension_value.id, 'value': 7 }, { 'dimension_value': age_adults_target.dimension_value.id, 'value': 12 }, ] } response = self.send_request(period, data, username='******', password='******') self.assertEqual(response.status_code, 200) updated_period = project.get_period(period_start=date(2010, 1, 1)) self.assertEqual(ensure_decimal(updated_period.target_value), 12) self.assertEqual( updated_period.get_disaggregation_target('Gender', 'Female').value, 7) self.assertEqual( updated_period.get_disaggregation_target('Age', 'Adults').value, 12)
def test_should_be_able_to_change_status_without_having_correct_permission( self): user = self.create_user('*****@*****.**', 'password') org = self.create_organisation('Acme Org') self.make_employment(user, org, 'M&E Managers') project = ProjectFixtureBuilder()\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [{ 'period_start': date(2020, 1, 1), 'period_end': date(2020, 12, 31) }] }] }]).build() update = project.get_period(period_start=date(2020, 1, 1))\ .add_update(user, value=10, status=IndicatorPeriodData.STATUS_PENDING_CODE) response = self.post_request( project.object, data={ 'updates': [update.id], 'status': IndicatorPeriodData.STATUS_APPROVED_CODE }, username='******', password='******') update.refresh_from_db() self.assertEqual(IndicatorPeriodData.STATUS_APPROVED_CODE, update.status) self.assertEqual(200, response.status_code)
def test_should_not_be_able_to_change_status_without_having_correct_permission( self): user = self.create_user('*****@*****.**', 'password') project = ProjectFixtureBuilder()\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [{ 'period_start': date(2020, 1, 1), 'period_end': date(2020, 12, 31) }] }] }]).build() update = project.get_period(period_start=date(2020, 1, 1))\ .add_update(user, value=10, status=IndicatorPeriodData.STATUS_PENDING_CODE) response = self.post_request( project.object, data={ 'updates': [update.id], 'status': IndicatorPeriodData.STATUS_APPROVED_CODE }, username='******', password='******') update.refresh_from_db() self.assertEqual(IndicatorPeriodData.STATUS_PENDING_CODE, update.status) self.assertEqual(403, response.status_code)
def test_should_ignore_unrelated_dimension_values(self): org, _ = self.create_org_user('*****@*****.**', 'password') project = ProjectFixtureBuilder()\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .with_disaggregations({ 'Age': ['Adults'] })\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [{ 'period_start': date(2010, 1, 1), 'period_end': date(2010, 12, 31), 'target_value': 10, 'disaggregation_targets': { 'Age': {'Adults': 10} } }] }] }]).build() period = project.get_period(period_start=date(2010, 1, 1)) age_adults_target = period.get_disaggregation_target('Age', 'Adults') invalid_target_id = age_adults_target.dimension_value.id + 1 data = { 'disaggregation_targets': [ {'dimension_value': invalid_target_id, 'value': 1}, ] } response = self.send_patch(period, data, username='******', password='******') self.assertEqual(response.status_code, 400)
def test_can_create_disaggregation_targets(self): org, _ = self.create_org_user('*****@*****.**', 'password') project = ProjectFixtureBuilder()\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .with_disaggregations({ 'Gender': ['Male', 'Female'], 'Age': ['Children', 'Adults'] })\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [{ 'period_start': date(2010, 1, 1), 'period_end': date(2010, 12, 31), 'target_value': 10, }] }] }]).build() period = project.get_period(period_start=date(2010, 1, 1)) male = project.get_disaggregation('Gender', 'Male') female = project.get_disaggregation('Gender', 'Female') data = { 'target_value': 12, 'disaggregation_targets': [ {'value': 8, 'dimension_value': male.id}, {'value': 10, 'dimension_value': female.id}, ] } response = self.send_patch(period, data, username='******', password='******') self.assertEqual(response.status_code, 200) updated_period = project.get_period(period_start=date(2010, 1, 1)) self.assertEqual(ensure_decimal(updated_period.target_value), 12) self.assertEqual(updated_period.get_disaggregation_target('Gender', 'Male').value, 8) self.assertEqual(updated_period.get_disaggregation_target('Gender', 'Female').value, 10)
def test_indicator_disaggregations(self): user = self.create_user('*****@*****.**', 'password', is_admin=True) project = ProjectFixtureBuilder()\ .with_disaggregations({ 'Gender': ['Male', 'Female'], 'Age': ['Children', 'Adults'] })\ .with_results([ { 'title': 'Result #1', 'indicators': [ { 'title': 'Indicator #1', 'periods': [ { 'period_start': date(2010, 1, 1), 'period_end': date(2010, 12, 31) }, { 'period_start': date(2011, 1, 1), 'period_end': date(2011, 12, 31) }, ] } ] } ])\ .build() project.get_period(period_start=date(2010, 1, 1)).add_update( user, value=10, disaggregations={ 'Gender': { 'Male': { 'value': 3 }, 'Female': { 'value': 7 }, } }) project.get_period(period_start=date(2011, 1, 1)).add_update( user, value=5, disaggregations={ 'Gender': { 'Male': { 'value': 3 }, 'Female': { 'value': 2 }, } }) vm = build_view_object(project.object) disaggregations = vm.results[0].indicators[0].disaggregations self.assertEqual( disaggregations, { 'Gender': { 'Male': { 'value': 6, 'numerator': 0, 'denominator': 0 }, 'Female': { 'value': 9, 'numerator': 0, 'denominator': 0 }, } })
def test_indicator_updates_visibility(self): org = self.create_organisation('Acme Org') email1, email2, email3, password = ('*****@*****.**', '*****@*****.**', '*****@*****.**', 'password') user1 = self.create_user(email1, password) user2 = self.create_user(email2, password) user3 = self.create_user(email3, password) self.make_employment(user1, org, 'Enumerators') self.make_employment(user2, org, 'Enumerators') project = ProjectFixtureBuilder()\ .with_title('Project #1')\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .with_results([ { 'title': 'Result #1', 'indicators': [ { 'title': 'Indicator #1', 'periods': [ { 'period_start': '2010-1-1', 'period_end': '2010-12-31' }, { 'period_start': '2011-1-1', 'period_end': '2011-12-31' }, ], }, { 'title': 'Indicator #2', 'periods': [ { 'period_start': '2010-1-1', 'period_end': '2010-12-31' }, { 'period_start': '2011-1-1', 'period_end': '2011-12-31' }, ], } ] }, ])\ .build() period = project.get_period(indicator__title='Indicator #2', period_start='2010-01-01') # Add approved, draft and pending updates for both users period.add_update(user1, value=1, status='A') # Approved period.add_update(user1, value=1, status='P') # Pending period.add_update(user1, value=2, status='D') # Draft update period.add_update(user2, value=1, status='A') period.add_update(user2, value=1, status='P') period.add_update(user2, value=2, status='D') self.c.login(username=email1, password=password) with override_settings(NUFFIC_ROOT_PROJECT=project.object.id): response = self.c.get( "/rest/v1/project/{}/results_framework/?format=json".format( project.project.id)) self.assertEqual(response.status_code, 200) results = response.data['results'] updates = results[0]['indicators'][1]['periods'][0]['updates'] # Nuffic users can see drafts of other users too?! self.assertEqual(len(updates), 6) user1_status = set(u['status'] for u in updates if u['user_details']['id'] == user1.id) user2_status = set(u['status'] for u in updates if u['user_details']['id'] != user1.id) self.assertIn('D', user1_status) self.assertIn('D', user2_status) self.assertEqual(3, len(user1_status)) self.assertEqual(3, len(user2_status)) # Non employed user should only see approved updates self.c.login(username=user3.email, password=password) with override_settings(NUFFIC_ROOT_PROJECT=project.object.id): response = self.c.get( "/rest/v1/project/{}/results_framework/?format=json".format( project.project.id)) self.assertEqual(response.status_code, 200) results = response.data['results'] updates = results[0]['indicators'][1]['periods'][0]['updates'] self.assertEqual(len(updates), 2) self.assertEqual({'A'}, set(u['status'] for u in updates))
def test_should_skip_periods_with_updates(self): user = self.create_user('*****@*****.**', 'password') org = self.create_organisation('Acme Org') self.make_employment(user, org, 'M&E Managers') project = ProjectFixtureBuilder()\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .with_results([ { 'title': 'Result #1', 'indicators': [ { 'title': 'Indicator #1.1', 'periods': [ {'period_start': '2020-01-01', 'period_end': '2020-01-31'}, {'period_start': '2020-02-01', 'period_end': '2020-02-29'}, ] }, { 'title': 'Indicator #1.2', 'periods': [ {'period_start': '2020-01-01', 'period_end': '2020-01-31'}, {'period_start': '2020-02-01', 'period_end': '2020-02-29'}, ] }, ] }, { 'title': 'Result #2', 'indicators': [ { 'title': 'Indicator #2.1', 'periods': [ {'period_start': '2020-01-01', 'period_end': '2020-01-31'}, {'period_start': '2020-02-01', 'period_end': '2020-02-29'}, ] }, ] } ])\ .build() period = project.get_period(period_start='2020-01-01', indicator__title='Indicator #1.2') period.add_update(user, value=1) data = { 'periods': [ { 'period_start': '2020-02-01', 'period_end': '2020-02-29' }, { 'period_start': '2020-01-01', 'period_end': '2020-01-31' }, ] } response = self.post_request(project.object, data=data, username='******', password='******') self.assertEqual(204, response.status_code) self.assertEqual(1, project.periods.count())