def setUp(self): super().setUp() self.org = self.create_organisation('My Org') self.root_project_facade = ProjectFixtureBuilder() \ .with_results( [{ 'title': 'Result #1', 'indicators': [ {'title': 'Indicator #1', 'periods': [{'period_start': '2020-01-01', 'period_end': '2020-01-31'}]}, {'title': 'Indicator #2', 'periods': [{'period_start': '2020-03-01', 'period_end': '2020-03-31'}]}, ] }] ) \ .with_contributors( [ {'title': 'Contrib #1'}, ] ) \ .build() self.program = self.create_project_hierarchy( self.org, self.root_project_facade.object, 2) self.root_project = self.root_project_facade.object self.contributor_project = self.root_project_facade.get_contributor( title="Contrib #1").object self.parent_period = IndicatorPeriod.objects.filter( indicator__result=self.root_project.results.first()).first() self.child_period = IndicatorPeriod.objects.filter( indicator__result=self.contributor_project.results.first()).first( )
def test_should_not_be_able_to_reorder_indicator(self): # Given self.create_user(self.email, self.password, is_superuser=True) self.c.login(username=self.email, password=self.password) lead = ProjectFixtureBuilder()\ .with_title('Lead Project')\ .with_results([ { 'title': 'Result #1', 'indicators': [ {'title': 'Indicator #1'}, {'title': 'Indicator #2'}, ] }, ])\ .with_contributors([ {'title': 'Contrib Project'} ])\ .build() contrib = lead.get_contributor(title='Contrib Project') indicators = contrib.indicators.all() # When url = '/rest/v1/project/{}/reorder_items/'.format(contrib.object.id) data = { 'item_type': 'indicator', 'item_id': indicators[0].id, 'item_direction': 'down', } response = self.c.post(url, data=data, follow=True) # Then self.assertEqual(response.status_code, 400)
def test_reordering_result_at_lead_reflected_to_contributor(self): # Given self.create_user(self.email, self.password, is_superuser=True) self.c.login(username=self.email, password=self.password) lead = ProjectFixtureBuilder()\ .with_title('Lead Project')\ .with_results([ {'title': 'Result #1'}, {'title': 'Result #2'}, ])\ .with_contributors([ {'title': 'Contrib Project'} ])\ .build() contrib = lead.get_contributor(title='Contrib Project') lead_result = lead.results.get(title='Result #2') # When url = '/rest/v1/project/{}/reorder_items/'.format(lead.object.id) data = { 'item_type': 'result', 'item_id': lead_result.id, 'item_direction': 'up', } self.c.post(url, data=data, follow=True) # Then self.assertEqual(lead.results.get(title='Result #1').order, 1) self.assertEqual(lead.results.get(title='Result #2').order, 0) self.assertEqual(contrib.results.get(title='Result #1').order, 1) self.assertEqual(contrib.results.get(title='Result #2').order, 0)
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_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_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_patch_to_change_photo_credit_and_caption(self): # Given org, user = self.create_org_user(self.username, self.password) project = ProjectFixtureBuilder()\ .with_partner(org)\ .build()\ .object update = ProjectUpdate.objects.create(project=project, user=user, title='Test') photo = ProjectUpdatePhoto.objects.create( update=update, photo=SimpleUploadedFile('test_image.jpg', get_mock_image()) ) # When self.c.login(username=self.username, password=self.password) url = '/rest/v1/project_update/{}/photos/{}/?format=json'.format(update.id, photo.id) data = {'credit': 'test credit', 'caption': 'test caption'} response = self.c.patch(url, json.dumps(data), content_type='application/json') # Then self.assertEqual(200, response.status_code) actual = ProjectUpdatePhoto.objects.get(id=photo.id) self.assertEqual('test credit', actual.credit) self.assertEqual('test caption', actual.caption)
def test_should_not_be_able_to_lock_without_correct_permission(self): self.create_user('*****@*****.**', 'password') project = ProjectFixtureBuilder()\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [{ 'period_start': date(2010, 1, 1), 'period_end': date(2010, 12, 31), 'locked': False, }] }] }])\ .build() period = project.periods.first() response = self.post_request(project.object, data={ 'periods': [period.id], 'locked': True }, username='******', password='******') period = project.periods.first() self.assertFalse(period.locked) self.assertEqual(403, response.status_code)
def test_should_not_be_able_to_add_periods_without_having_correct_permission( self): self.create_user('*****@*****.**', 'password') project = ProjectFixtureBuilder()\ .with_results([{ 'title': 'Result #1', 'indicators': [ {'title': 'Indicator #1', 'periods': []}, {'title': 'Indicator #2', 'periods': []}, ] }])\ .build() data = { 'periods': [{ 'period_start': '2020-01-01', 'period_end': '2020-01-31' }] } response = self.post_request(project.object, data=data, username='******', password='******') self.assertEqual(403, response.status_code) self.assertEqual(0, project.periods.count())
def test_should_be_able_to_unlock_periods_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(2010, 1, 1), 'period_end': date(2010, 12, 31), 'locked': True, }] }] }])\ .build() period = project.periods.first() response = self.post_request(project.object, data={ 'periods': [period.id], 'locked': False }, username='******', password='******') period = project.periods.first() self.assertFalse(period.locked) self.assertEqual(200, response.status_code)
def test_can_post_indicator_periods(self): username, password = '******', 'password' _, org = self.create_org_user(username, 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': [] }] }]).build() indicator = project.indicators[0] data = { 'period_start': '2010-1-1', 'period_end': '2010-12-31', 'target_value': 10, 'indicator': indicator.id, 'disaggregation_targets': [], } self.c.login(username=username, password=password) response = self.c.post('/rest/v1/indicator_period/', data=json.dumps(data), content_type='application/json') self.assertEqual(response.status_code, 201) for key, value in data.items(): self.assertEqual(data[key], value)
def test_patch_to_change_the_photo(self): # Given org, user = self.create_org_user(self.username, self.password) project = ProjectFixtureBuilder()\ .with_partner(org)\ .build()\ .object update = ProjectUpdate.objects.create(project=project, user=user, title='Test') photo = ProjectUpdatePhoto.objects.create( update=update, photo=SimpleUploadedFile('test_image.jpg', get_mock_image()) ) # When self.c.login(username=self.username, password=self.password) url = '/rest/v1/project_update/{}/photos/{}/?format=json'.format(update.id, photo.id) data = encode_multipart(BOUNDARY, { 'photo': SimpleUploadedFile('changed_image.jpg', get_mock_image()), }) response = self.c.patch(url, data, content_type=MULTIPART_CONTENT) # Then self.assertEqual(200, response.status_code) actual = ProjectUpdatePhoto.objects.get(id=photo.id) self.assertTrue('changed_image' in actual.photo.name)
def test_change_parent_to_sibling(self): # Given root = ProjectFixtureBuilder()\ .with_title('Parent project')\ .with_disaggregations({'Foo': ['Bar']})\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [{ 'period_start': date(2020, 1, 1), 'period_end': date(2020, 12, 31), }] }] }])\ .with_contributors([ {'title': 'Child project'}, {'title': 'New project'} ])\ .build() child_project = root.get_contributor(title='Child project') new_project = root.get_contributor(title='New project') # When command.change_parent(new_project.object, child_project.object) # Then self.assertIsNone( new_project.object.parents_all().filter(id=root.object.id).first()) self.assertIsNotNone(new_project.object.parents_all().filter( id=child_project.object.id).first()) self.assertEqual( new_project.results.get(title='Result #1').parent_result, child_project.results.get(title='Result #1')) self.assertEqual( new_project.indicators.get(title='Indicator #1').parent_indicator, child_project.indicators.get(title='Indicator #1')) self.assertEqual( new_project.periods.get( period_start=date(2020, 1, 1)).parent_period, child_project.periods.get(period_start=date(2020, 1, 1))) self.assertEqual( new_project.object.dimension_names.get( name='Foo').parent_dimension_name, child_project.object.dimension_names.get(name='Foo')) self.assertEqual( new_project.get_disaggregation('Foo', 'Bar').parent_dimension_value, child_project.get_disaggregation('Foo', 'Bar'))
def test_project_enumerators_get(self): org = self.create_organisation('Acme Org') user = self.create_user('*****@*****.**') 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' }, ], 'enumerators': [user], }, { 'title': 'Indicator #2', 'periods': [ { 'period_start': '2010-1-1', 'period_end': '2010-12-31' }, { 'period_start': '2011-1-1', 'period_end': '2011-12-31' }, ], 'enumerators': [user], } ] }, ])\ .build() response = self.c.get( "/rest/v1/project/{}/enumerators/?format=json".format( project.project.id)) self.assertEqual(response.status_code, 200) data = response.data self.assertEqual(len(data), 1) enumerator = data[0] self.assertEqual(enumerator['email'], user.email) self.assertEqual(set(enumerator['indicators']), {i.id for i in project.indicators})
def test_partner_site_for_program(self): org = self.create_organisation('Acme') single_project = ProjectFixtureBuilder()\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .build() root_project = ProjectFixtureBuilder()\ .with_partner(org, Partnership.IATI_REPORTING_ORGANISATION)\ .with_contributors([ {'title': 'Contrib #1', 'contributors': [{'title': 'Subcon #1.1'}]}, {'title': 'Contrib #2'} ])\ .build() program = self.create_project_hierarchy(org, root_project.object, 2) program_page = PartnerSite.objects.create(organisation=org, hostname="program", program=program) self.assertEqual(4, program_page.projects().count()) self.assertNotIn(single_project.object.id, program_page.projects().values_list('id', flat=True))
def test_cannot_find_orphans(self): ProjectFixtureBuilder() \ .with_results( [{ 'title': 'Result #1', 'indicators': [ {'title': 'Indicator #1', 'periods': [{'period_start': '2020-01-01', 'period_end': '2020-01-31'}]}, ] }] ) \ .build() self.assertEqual(Command.get_orphans().count(), 0)
def test_should_be_able_to_add_periods_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.1', 'periods': [] }, { 'title': 'Indicator #1.2', 'periods': [ {'period_start': '2020-01-01', 'period_end': '2020-01-31'} ] }, ] }, { 'title': 'Result #2', 'indicators': [ {'title': 'Indicator #2.1', 'periods': []}, ] } ])\ .build() data = { 'periods': [ { 'period_start': '2020-01-01', 'period_end': '2020-01-31' }, { 'period_start': '2020-02-01', 'period_end': '2020-02-29' }, ] } response = self.post_request(project.object, data=data, username='******', password='******') self.assertEqual(200, response.status_code) self.assertEqual(6, project.periods.count())
def test_aggregate_quantitative_unit(self): # Given root = ProjectFixtureBuilder()\ .with_results([{ 'title': 'Result #1', 'indicators': [{ 'title': 'Indicator #1', 'periods': [ { 'period_start': date(2010, 1, 1), 'period_end': date(2010, 12, 31), 'label': 'L1', }, { 'period_start': date(2011, 1, 1), 'period_end': date(2011, 12, 31), 'label': 'L2', }, { 'period_start': date(2012, 1, 1), 'period_end': date(2012, 12, 31), 'label': 'L3', }, ] }] }])\ .with_contributors([ {'title': 'Contrib #1', 'contributors': [{'title': 'Subcon #1.1'}]}, {'title': 'Contrib #2'} ])\ .build() l1 = root.get_label('L1') l2 = root.get_label('L2') l3 = root.get_label('L3') contrib2 = root.get_contributor(title='Contrib #2') subcon1_1 = root.get_contributor(title='Subcon #1.1') user = self.create_user('*****@*****.**', 'password', is_admin=True) contrib2.get_period(period_start=date(2010, 1, 1)).set_label(l1).add_update(user, value=1) contrib2.get_period(period_start=date(2011, 1, 1)).set_label(l2).add_update(user, value=2) contrib2.get_period(period_start=date(2012, 1, 1)).set_label(l3).add_update(user, value=3) subcon1_1.get_period(period_start=date(2010, 1, 1)).add_update(user, value=4) subcon1_1.get_period(period_start=date(2011, 1, 1)).set_label(l1).add_update(user, value=5) subcon1_1.get_period(period_start=date(2012, 1, 1)).set_label(l2).add_update(user, value=6) # When indicators = build_view_object(root.object) # Then self.assertEqual(1, len(indicators)) indicator = indicators[0] self.assertEqual(6, indicator.get_labeled_period('L1').actual_value) self.assertEqual(8, indicator.get_labeled_period('L2').actual_value) self.assertEqual(3, indicator.get_labeled_period('L3').actual_value)
def test_result_ordering(self): project = ProjectFixtureBuilder()\ .with_results([ {'title': 'Result #2'}, {'title': 'Result #3'}, {'title': 'Result #1'}, ])\ .build() project.results.filter(title='Result #1').update(order=1) project.results.filter(title='Result #2').update(order=2) project.results.filter(title='Result #3').update(order=3) vm = build_view_object(project.object) self.assertEqual(vm.results[0].title, 'Result #1') self.assertEqual(vm.results[1].title, 'Result #2') self.assertEqual(vm.results[2].title, 'Result #3')
def test_add_new_photos_to_an_update(self): # Given org, user = self.create_org_user(self.username, self.password) project = ProjectFixtureBuilder()\ .with_partner(org)\ .build()\ .object update = ProjectUpdate.objects.create(project=project, user=user, title='Test') # When self.c.login(username=self.username, password=self.password) url = '/rest/v1/project_update/{}/photos/?format=json'.format(update.id) data = { 'photo': SimpleUploadedFile('test_image.jpg', get_mock_image()), } response = self.c.post(url, data) # Then self.assertEqual(200, response.status_code) self.assertEqual(1, ProjectUpdatePhoto.objects.count())
def test_remove_photo_from_an_update(self): # Given org, user = self.create_org_user(self.username, self.password) project = ProjectFixtureBuilder()\ .with_partner(org)\ .build()\ .object update = ProjectUpdate.objects.create(project=project, user=user, title='Test') photo = ProjectUpdatePhoto.objects.create( update=update, photo=SimpleUploadedFile('test_image.jpg', get_mock_image()) ) # When self.c.login(username=self.username, password=self.password) url = '/rest/v1/project_update/{}/photos/{}/?format=json'.format(update.id, photo.id) response = self.c.delete(url) # Then self.assertEqual(204, response.status_code) self.assertEqual(0, ProjectUpdatePhoto.objects.count())
def test_indicator_ordering(self): project = ProjectFixtureBuilder()\ .with_results([ { 'title': 'Result', 'indicators': [ {'title': 'Indicator #3'}, {'title': 'Indicator #1'}, {'title': 'Indicator #2'}, ] } ])\ .build() project.indicators.filter(title='Indicator #1').update(order=1) project.indicators.filter(title='Indicator #2').update(order=2) project.indicators.filter(title='Indicator #3').update(order=3) vm = build_view_object(project.object) self.assertEqual(vm.results[0].indicators[0].title, 'Indicator #1') self.assertEqual(vm.results[0].indicators[1].title, 'Indicator #2') self.assertEqual(vm.results[0].indicators[2].title, 'Indicator #3')
def test_view_object_structure(self): project = ProjectFixtureBuilder()\ .with_title('Project #1')\ .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() vm = build_view_object(project.object) self.assertEqual(vm.title, 'Project #1') self.assertEqual(len(vm.results), 1) result = vm.results[0] self.assertEqual(result.title, 'Result #1') self.assertEqual(len(result.indicators), 1) indicator = result.indicators[0] self.assertEqual(indicator.title, 'Indicator #1') self.assertEqual(len(indicator.periods), 2) period = indicator.periods[0] self.assertEqual(period.period_start, date(2010, 1, 1))
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_date_filter(self): project = ProjectFixtureBuilder()\ .with_title('Project #1')\ .with_results([ { 'title': 'Result #1', 'indicators': [ { 'title': 'Indicator #1', 'periods': [ { 'period_start': date(2010, 1, 1), 'period_end': date(2010, 12, 31) }, ] } ] }, { 'title': 'Result #2', 'indicators': [ { 'title': 'Indicator #2', 'periods': [ { 'period_start': date(2011, 1, 1), 'period_end': date(2011, 12, 31) }, { 'period_start': date(2012, 1, 1), 'period_end': date(2012, 12, 31) }, ] } ] }, { 'title': 'Result #3', 'indicators': [ { 'title': 'Indicator #3', 'periods': [ { 'period_start': date(2012, 1, 1), 'period_end': date(2012, 12, 31) }, ] } ] }, ])\ .build() vm = build_view_object(project.object, date(2010, 6, 1), date(2012, 6, 30)) self.assertEqual(len(vm.results), 1) result = vm.results[0] self.assertEqual(result.title, 'Result #2') periods = result.indicators[0].periods self.assertEqual(len(periods), 1) self.assertEqual(periods[0].period_start, date(2011, 1, 1))
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())
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_project_results_framework_for_enumerator(self): org = self.create_organisation('Acme Org') email, password = '******', 'password' user = self.create_user(email, password) 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' }, ], 'enumerators': [user], }, { '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() self.c.login(username=email, password=password) 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'] self.assertEqual(len(results), 1) self.assertEqual(len(results[0]['indicators']), 1) indicator = results[0]['indicators'][0] self.assertEqual(indicator['title'], 'Indicator #1') # Assert M&E manager sees all the results self.make_employment(user, org, 'M&E Managers') self.c.login(username=email, password=password) 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'] self.assertEqual(len(results), 1) self.assertEqual(len(results[0]['indicators']), 2) indicator = results[0]['indicators'][0] self.assertEqual( {indicator['title'] for indicator in results[0]['indicators']}, {'Indicator #1', 'Indicator #2'})