def test_entry_dropped_excerpt_migrations(self): def _get_excerpt_snapshot(): return list(Entry.objects.order_by('id').values_list('excerpt', 'dropped_excerpt', 'excerpt_modified')) migration_file = importlib.import_module('entry.migrations.0036_entry_excerpt_modified') af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=af) lead = LeadFactory.create(project=project) # Create entry before data migrate EntryFactory.create(lead=lead, excerpt='', dropped_excerpt='') EntryFactory.create(lead=lead, excerpt='sample-1', dropped_excerpt='') EntryFactory.create(lead=lead, excerpt='sample-2', dropped_excerpt='sample-2-updated') EntryFactory.create(lead=lead, excerpt='sample-3', dropped_excerpt='sample-3') old_excerpt_snaphost = _get_excerpt_snapshot() # Apply the migration logic migration_file._update_entry_excerpt(Entry) new_excerpt_snaphost = _get_excerpt_snapshot() assert Entry.objects.count() == 4 assert Entry.objects.filter(dropped_excerpt='').count() == 1 assert Entry.objects.filter(excerpt_modified=True).count() == 1 assert Entry.objects.filter(dropped_excerpt=models.F('excerpt')).count() == 3 assert Entry.objects.exclude(dropped_excerpt=models.F('excerpt')).count() == 1 assert new_excerpt_snaphost != old_excerpt_snaphost assert new_excerpt_snaphost == [ ('', '', False), ('sample-1', 'sample-1', False), ('sample-2', 'sample-2-updated', True), ('sample-3', 'sample-3', False), ]
def test_entry_delete(self): """ This test makes sure only valid users can update entry """ entry = EntryFactory.create( project=self.project, lead=self.lead, analysis_framework=self.project.analysis_framework) def _query_check(**kwargs): return self.query_check(self.DELETE_ENTRY_QUERY, variables={ 'projectId': self.project.id, 'entryId': entry.id }, **kwargs) # -- Without login _query_check(assert_for_error=True) # -- With login (non-member) self.force_login(self.non_member_user) _query_check(assert_for_error=True) # --- member user (read-only) self.force_login(self.readonly_member_user) _query_check(assert_for_error=True) # --- member user # Invalid input self.force_login(self.member_user) content = _query_check( okay=False)['data']['project']['entryDelete']['result'] self.assertIdEqual(content['id'], entry.id)
def test_project_stat_recent(self): query = ''' query MyQuery { recentProjects { id status title isPrivate description currentUserRole } } ''' user = UserFactory.create() analysis_framework = AnalysisFrameworkFactory.create() public_project1, public_project2, public_project3, public_project4 = ProjectFactory.create_batch( 4) public_project1.add_member(user) public_project2.add_member(user) public_project3.add_member(user) lead1 = LeadFactory.create(project=public_project1, created_by=user) LeadFactory.create(project=public_project2, created_by=user) EntryFactory.create(lead=lead1, controlled=False, created_by=user, project=public_project1, analysis_framework=analysis_framework) LeadFactory.create(project=public_project3, created_by=user) LeadFactory.create(project=public_project4, created_by=user) # -- Without login self.query_check(query, assert_for_error=True) # -- With login self.force_login(user) content = self.query_check(query) self.assertEqual(len(content['data']['recentProjects']), 3, content) self.assertEqual(content['data']['recentProjects'][0]['id'], str(public_project3.pk), content) self.assertEqual(content['data']['recentProjects'][1]['id'], str(public_project1.pk), content) self.assertEqual(content['data']['recentProjects'][2]['id'], str(public_project2.pk), content)
def test_leads_status(self): query = ''' query MyQuery ($id: ID!) { project(id: $id) { leads(ordering: ASC_ID) { results { id title status } } } } ''' user = UserFactory.create() project = ProjectFactory.create( analysis_framework=AnalysisFrameworkFactory.create()) project.add_member(user) lead1, _ = LeadFactory.create_batch(2, project=project) def _query_check(): return self.query_check(query, variables={'id': project.id}) self.force_login(user) content = _query_check()['data']['project']['leads']['results'] self.assertEqual(len(content), 2, content) self.assertEqual( set([lead['status'] for lead in content]), {self.genum(Lead.Status.NOT_TAGGED)}, content, ) # Add entry to lead1 entry1 = EntryFactory.create(lead=lead1) content = _query_check()['data']['project']['leads']['results'] self.assertEqual(len(content), 2, content) self.assertEqual(content[0]['status'], self.genum(Lead.Status.IN_PROGRESS), content) self.assertEqual(content[1]['status'], self.genum(Lead.Status.NOT_TAGGED), content) # Update lead1 status to TAGGED lead1.status = Lead.Status.TAGGED lead1.save(update_fields=['status']) content = _query_check()['data']['project']['leads']['results'] self.assertEqual(len(content), 2, content) self.assertEqual(content[0]['status'], self.genum(Lead.Status.TAGGED), content) self.assertEqual(content[1]['status'], self.genum(Lead.Status.NOT_TAGGED), content) # Now update entry1 entry1.save() content = _query_check()['data']['project']['leads']['results'] self.assertEqual(len(content), 2, content) self.assertEqual(content[0]['status'], self.genum(Lead.Status.IN_PROGRESS), content) self.assertEqual(content[1]['status'], self.genum(Lead.Status.NOT_TAGGED), content)
def test_lead_entries_query(self): # Includes permissions checks query = ''' query MyQuery ($projectId: ID! $leadId: ID!) { project(id: $projectId) { lead(id: $leadId) { entries { id order entryType excerpt attributes { widgetType widget data clientId widgetVersion id } clientId droppedExcerpt highlightHidden informationDate image { id metadata mimeType title file { url name } } controlled } } } } ''' lead = LeadFactory.create(project=self.project) entry = EntryFactory.create(project=self.project, analysis_framework=self.af, lead=lead) def _query_check(**kwargs): return self.query_check(query, variables={'projectId': self.project.pk, 'leadId': lead.id}, **kwargs) # Without login _query_check(assert_for_error=True) # With login self.force_login(self.user) content = _query_check() results = content['data']['project']['lead']['entries'] self.assertEqual(len(content['data']['project']['lead']['entries']), 1, content) self.assertIdEqual(results[0]['id'], entry.pk, results)
def test_test_entry_review_verify_control_migrations(self): migration_file = importlib.import_module('entry.migrations.0031_entry-migrate-verify-to-review-comment') # 3 normal users + Additional non-active user user1, user2, user3, _ = UserFactory.create_batch(4) af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=af) lead = LeadFactory.create(project=project) # Create entry before data migrate EntryFactory.create(lead=lead, controlled=True, controlled_changed_by=user1) EntryFactory.create(lead=lead, controlled=True, controlled_changed_by=user2) EntryFactory.create(lead=lead, controlled=False, controlled_changed_by=user3) EntryFactory.create(lead=lead, controlled=True, controlled_changed_by=None) EntryFactory.create(lead=lead, controlled=False, controlled_changed_by=None) # Apply the migration logic migration_file.migrate_entry_controlled_to_review_comment_(Entry, EntryReviewComment) assert Entry.objects.count() == 5 # 2 verified review comment are created and 1 unverified review comment is created assert EntryReviewComment.objects.count() == 3 # Related review comment are created by user last action on entry. assert set(EntryReviewComment.objects.values_list('created_by_id', flat=True)) == set([user1.pk, user2.pk, user3.pk]) assert EntryReviewComment.objects.filter(comment_type=EntryReviewComment.CommentType.VERIFY).count() == 2 assert EntryReviewComment.objects.filter(comment_type=EntryReviewComment.CommentType.UNVERIFY).count() == 1 assert set( EntryReviewComment.objects.filter( comment_type=EntryReviewComment.CommentType.VERIFY, ).values_list('created_by_id', flat=True) ) == set([user1.pk, user2.pk]) assert set( EntryReviewComment.objects.filter( comment_type=EntryReviewComment.CommentType.UNVERIFY, ).values_list('created_by_id', flat=True) ) == set([user3.pk]) # All controlled, controlled_changed_by should be reset. assert Entry.objects.filter(controlled=True).count() == 0 assert Entry.objects.filter(controlled_changed_by__isnull=False).count() == 0
def setUp(self): super().setUp() self.qa_member_user = UserFactory.create() self.member_user = UserFactory.create() self.readonly_member_user = UserFactory.create() self.non_member_user = UserFactory.create() self.af = AnalysisFrameworkFactory.create() self.project = ProjectFactory.create(analysis_framework=self.af) self.lead = LeadFactory.create(project=self.project) self.entry = EntryFactory.create(lead=self.lead) # Add member to project self.project.add_member(self.readonly_member_user, role=self.project_role_reader_non_confidential) self.project.add_member(self.member_user, role=self.project_role_member) self.project.add_member(self.qa_member_user, role=self.project_role_member, badges=[ProjectMembership.BadgeType.QA])
def set_project_viz_configuration(project): w_data = entry_stats_data.WIDGET_DATA a_data = entry_stats_data.ATTRIBUTE_DATA lead = LeadFactory.create(project=project) entry = EntryFactory.create(lead=lead) af = project.analysis_framework # Create widgets, attributes and configs invalid_stat_config = {} valid_stat_config = {} for index, (title, widget_identifier, data_identifier, config_kwargs) in enumerate([ ('widget 1d', 'widget_1d', 'matrix1dWidget', {}), ('widget 2d', 'widget_2d', 'matrix2dWidget', {}), ('geo widget', 'geo_widget', 'geoWidget', {}), ('reliability widget', 'reliability_widget', 'scaleWidget', {}), ('affected groups widget', 'affected_groups_widget', 'multiselectWidget', {}), ('specific needs groups widget', 'specific_needs_groups_widget', 'multiselectWidget', {}), ]): widget = WidgetFactory.create( analysis_framework=af, section=None, title=title, widget_id=data_identifier, key=f'{data_identifier}-{index}', properties={'data': w_data[data_identifier]}, ) EntryAttributeFactory.create(entry=entry, widget=widget, data=a_data[data_identifier]) valid_stat_config[widget_identifier] = { 'pk': widget.pk, **config_kwargs, } invalid_stat_config[widget_identifier] = {'pk': 0} af.properties = {'stats_config': invalid_stat_config} af.save(update_fields=('properties',)) project.is_visualization_enabled = True project.save(update_fields=('is_visualization_enabled',))
def test_create_assignment_create_on_entry_review_comment( self, get_user_mocked_func): af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=af) user1, user2 = UserFactory.create_batch(2) get_user_mocked_func.return_value = user2 entry = EntryFactory.create(lead=LeadFactory.create(project=project)) old_assignment_count = Assignment.objects.count() entry_review_comment = EntryReviewCommentFactory.create( entry=entry, entry_comment=None, created_by=user1) new_assignment_count = Assignment.objects.count() self.assertEqual(old_assignment_count, new_assignment_count) entry_review_comment.mentioned_users.add(user1) new_assignment_count = Assignment.objects.count() self.assertEqual(old_assignment_count + 1, new_assignment_count) # try to change the assigne for the entry_review_comment and test for the change in assignment entry_review_comment.mentioned_users.remove(user1) entry_review_comment.mentioned_users.add(user2) self.assertEqual(old_assignment_count + 1, new_assignment_count) assignment = Assignment.objects.get( entry_review_comment__id=entry_review_comment.id) self.assertEqual(assignment.created_for, user2) # should represent the new user2 # try to add another user and remove both from assignee entry_review_comment.mentioned_users.add(user1) new_assignment_count = Assignment.objects.count() self.assertEqual(old_assignment_count + 2, new_assignment_count) # try to get the assignment for user entry_review_comment.mentioned_users.add(user1, user2) assignment = Assignment.get_for(user1) assert assignment.count() == 1 # for only the user assert get_user_mocked_func.called
def test(self): entry1_1 = EntryFactory.create(**self.entry_create_kwargs, lead=self.lead1) entry2_1 = EntryFactory.create(**self.entry_create_kwargs, lead=self.lead2) entry3_1 = EntryFactory.create(**self.entry_create_kwargs, lead=self.lead3) entry3_2 = EntryFactory.create(**self.entry_create_kwargs, lead=self.lead3) # Create attributes for multiselect (LIST Filter) EntryAttributeFactory.create(entry=entry1_1, widget=self.widget_multiselect, data={'value': ['key-101', 'key-102']}) EntryAttributeFactory.create(entry=entry2_1, widget=self.widget_multiselect, data={'value': ['key-102', 'key-103']}) # Create attributes for time (NUMBER Filter) EntryAttributeFactory.create(entry=entry1_1, widget=self.widget_number, data={'value': 10001}) EntryAttributeFactory.create(entry=entry3_1, widget=self.widget_number, data={'value': 10002}) # Create attributes for date range (INTERSECTS Filter) EntryAttributeFactory.create( entry=entry2_1, widget=self.widget_date_range, data={'value': {'startDate': '2020-01-10', 'endDate': '2020-01-20'}}, ) EntryAttributeFactory.create( entry=entry3_1, widget=self.widget_date_range, data={'value': {'startDate': '2020-01-10', 'endDate': '2020-02-20'}}, ) EntryAttributeFactory.create( entry=entry3_2, widget=self.widget_date_range, data={'value': {'startDate': '2020-01-15', 'endDate': '2020-01-25'}}, ) # Create attributes for text (TEXT Filter) EntryAttributeFactory.create(entry=entry1_1, widget=self.widget_text, data={'value': 'This is a test 1'}) EntryAttributeFactory.create(entry=entry3_1, widget=self.widget_text, data={'value': 'This is a test 2'}) # Create attributes for GEO (LIST Filter) EntryAttributeFactory.create( entry=entry1_1, widget=self.widget_geo, data={'value': [self.geo_area_3_2.pk]} # Leaf tagged ) EntryAttributeFactory.create( entry=entry2_1, widget=self.widget_geo, data={'value': [self.geo_area_1.pk]} # Root tagged ) EntryAttributeFactory.create( entry=entry3_1, widget=self.widget_geo, data={'value': [self.geo_area_2_1.pk]} # Middle child tagged ) EntryAttributeFactory.create( entry=entry3_2, widget=self.widget_geo, data={'value': [self.geo_area_1.pk, self.geo_area_3_2.pk]} # Middle child tagged + leaf node ) # Some entries with different AF other_entry = EntryFactory.create(lead=self.lead1, analysis_framework=AnalysisFrameworkFactory.create(title='Other')) EntryAttributeFactory.create( entry=other_entry, widget=self.widget_multiselect, data={'value': ['key-101', 'key-102']}) EntryAttributeFactory.create(entry=other_entry, widget=self.widget_number, data={'value': 10002}) EntryAttributeFactory.create( entry=other_entry, widget=self.widget_geo, data={'value': [self.geo_area_3_2.pk]} # Leaf tagged ) # Some leads/entries in other projects other_leads = LeadFactory.create_batch(3, project=ProjectFactory.create(analysis_framework=self.af)) [EntryFactory.create_batch(3, lead=lead) for lead in other_leads] # -- With login self.force_login(self.user) for filter_name, filter_data, expected_entries in [ # NUMBER Filter Cases ( 'number-filter-1', [ { 'filterKey': self.widget_number.key, 'value': '10001', 'valueGte': '10002', # This is ignored when value is provided 'valueLte': '10005', # This is ignored when value is provided }, ], [entry1_1], ), ( 'number-filter-2', [ { 'filterKey': self.widget_number.key, 'valueGte': '10001', 'valueLte': '10005', }, ], [entry1_1, entry3_1], ), ( 'number-filter-3', [ { 'filterKey': self.widget_number.key, 'valueLte': '10001', }, ], [entry1_1], ), ( 'number-filter-4', [ { 'filterKey': self.widget_number.key, 'valueGte': '10002', }, ], [entry3_1], ), # TEXT Filter Cases ( 'text-filter-1', [ { 'filterKey': self.widget_text.key, 'value': 'This is a test', 'valueGte': '10002', # This is ignored }, ], [entry1_1, entry3_1], ), ( 'text-filter-2', [ { 'filterKey': self.widget_text.key, 'value': 'This is a test 1', 'valueLte': '10002', # This is ignored }, ], [entry1_1], ), # INTERSECTS TODO: May need more test cases ( 'intersect-filter-1', [ { 'filterKey': self.widget_date_range.key, 'value': '2020-01-10', # 'valueLte': '2020-01-01', # TODO: # 'valueGte': '2020-01-30', # TODO: }, ], [entry2_1, entry3_1], ), ( 'intersect-filter-2', [ { 'filterKey': self.widget_date_range.key, 'valueGte': '2020-01-01', 'valueLte': '2020-01-30', }, ], [entry2_1, entry3_1, entry3_2], ), ( 'intersect-filter-3', [ { 'filterKey': self.widget_date_range.key, 'valueGte': '2020-01-30', # Only one is ignored }, ], [entry1_1, entry2_1, entry3_1, entry3_2], ), # LIST Filter ( 'list-filter-1', [ { 'filterKey': self.widget_multiselect.key, 'value': '13', # This is ignored }, ], [entry1_1, entry2_1, entry3_1, entry3_2], ), ( 'list-filter-2', [ { 'filterKey': self.widget_multiselect.key, 'valueList': ['key-101', 'key-102'], }, ], [entry1_1, entry2_1], ), ( 'list-filter-3', [ { 'filterKey': self.widget_multiselect.key, 'valueList': ['key-101', 'key-102'], 'useAndOperator': True, }, ], [entry1_1], ), ( 'list-filter-4', [ { 'filterKey': self.widget_multiselect.key, 'valueList': ['key-101', 'key-102'], 'useAndOperator': True, 'useExclude': True, }, ], [entry2_1, entry3_1, entry3_2], ), ( 'list-filter-5', [ { 'filterKey': self.widget_multiselect.key, 'valueList': ['key-101', 'key-102'], 'useExclude': True, }, ], [entry3_1, entry3_2], ), # GEO (LIST) Filter ( 'geo-filter-1', [ { 'filterKey': self.widget_geo.key, 'valueList': [self.geo_area_1.pk], }, ], [entry2_1, entry3_2], ), ( 'geo-filter-2', [ { 'filterKey': self.widget_geo.key, 'valueList': [self.geo_area_1.pk], 'includeSubRegions': True, }, ], [entry1_1, entry2_1, entry3_1, entry3_2], ), ( 'geo-filter-3', [ { 'filterKey': self.widget_geo.key, 'valueList': [self.geo_area_1.pk], 'includeSubRegions': True, 'useExclude': True, }, ], [], ), ( 'geo-filter-4', [ { 'filterKey': self.widget_geo.key, 'valueList': [self.geo_area_2_2.pk], 'includeSubRegions': True, }, ], [entry1_1, entry3_2], ), ( 'geo-filter-5', [ { 'filterKey': self.widget_geo.key, 'valueList': [self.geo_area_2_2.pk], 'includeSubRegions': True, 'useExclude': True, }, ], [entry2_1, entry3_1], ) ]: # Lead filter test content = self.query_check( self.entries_query, variables={'projectId': self.project.id, 'filterableData': filter_data}, ) self.assertListIds( content['data']['project']['entries']['results'], expected_entries, {'response': content, 'filter': filter_data, 'filter_name': filter_name} ) # Lead filter test expected_leads = set([entry.lead for entry in expected_entries]) content = self.query_check( TestLeadQuerySchema.lead_filter_query, variables={ 'projectId': self.project.id, 'hasEntries': True, 'entriesFilterData': { 'filterableData': filter_data, } } ) self.assertListIds( content['data']['project']['leads']['results'], expected_leads, {'response': content, 'filter': filter_data, 'filter_name': filter_name} )
def test_entry_update(self): """ This test makes sure only valid users can update entry """ entry = EntryFactory.create( project=self.project, lead=self.lead, analysis_framework=self.project.analysis_framework) minput = dict( attributes=[ dict(widget=self.widget1.pk, data=self.dummy_data, clientId='client-id-attribute-1', widgetVersion=1), dict(widget=self.widget2.pk, data=self.dummy_data, clientId='client-id-attribute-2', widgetVersion=1), dict(widget=self.widget1.pk, data=self.dummy_data, clientId='client-id-attribute-3', widgetVersion=1), ], order=1, lead=self.lead.pk, informationDate=self.get_date_str(timezone.now()), image=self.other_file.pk, # leadImage='', highlightHidden=False, excerpt='This is a text', entryType=self.genum(Entry.TagType.EXCERPT), droppedExcerpt='This is a dropped text', clientId='entry-101', ) def _query_check(**kwargs): return self.query_check(self.UPDATE_ENTRY_QUERY, minput=minput, variables={ 'projectId': self.project.id, 'entryId': entry.id }, **kwargs) # -- Without login _query_check(assert_for_error=True) # -- With login (non-member) self.force_login(self.non_member_user) _query_check(assert_for_error=True) # --- member user (read-only) self.force_login(self.readonly_member_user) _query_check(assert_for_error=True) # --- member user # Invalid input self.force_login(self.member_user) response = _query_check(okay=False) self.assertMatchSnapshot(response, 'error') # Valid input minput['image'] = self.our_file.pk response = _query_check() self.assertMatchSnapshot(response, 'success')
def test_entries_query(self): # Includes permissions checks query = ''' query MyQuery ($projectId: ID!) { project(id: $projectId) { entries (ordering: "-id") { totalCount results { id order entryType excerpt attributes { widgetType widget data clientId widgetVersion id } clientId droppedExcerpt highlightHidden informationDate image { id metadata mimeType title file { url name } } controlled } } } } ''' user = UserFactory.create() lead = LeadFactory.create(project=self.project) conf_lead = LeadFactory.create(project=self.project, confidentiality=Lead.Confidentiality.CONFIDENTIAL) entry = EntryFactory.create(project=self.project, analysis_framework=self.af, lead=lead) conf_entry = EntryFactory.create(project=self.project, analysis_framework=self.af, lead=conf_lead) def _query_check(**kwargs): return self.query_check(query, variables={'projectId': self.project.pk}, **kwargs) # Without login _query_check(assert_for_error=True) # With login self.force_login(user) # -- Without membership content = _query_check() results = content['data']['project']['entries']['results'] self.assertEqual(content['data']['project']['entries']['totalCount'], 0, content) self.assertEqual(len(results), 0, results) # -- Without membership (confidential only) current_membership = self.project.add_member(user, role=self.project_role_reader_non_confidential) content = _query_check() results = content['data']['project']['entries']['results'] self.assertEqual(content['data']['project']['entries']['totalCount'], 1, content) self.assertIdEqual(results[0]['id'], entry.pk, results) # -- With membership (non-confidential only) current_membership.delete() self.project.add_member(user, role=self.project_role_reader) content = _query_check() results = content['data']['project']['entries']['results'] self.assertEqual(content['data']['project']['entries']['totalCount'], 2, content) self.assertIdEqual(results[0]['id'], conf_entry.pk, results) self.assertIdEqual(results[1]['id'], entry.pk, results)
def test_lead_query_filter(self): af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=af) org_type1, org_type2 = OrganizationTypeFactory.create_batch(2) org1 = OrganizationFactory.create(organization_type=org_type1) org2 = OrganizationFactory.create(organization_type=org_type2) org3 = OrganizationFactory.create(organization_type=org_type2) org1_child = OrganizationFactory.create(organization_type=org_type2, parent=org1) # User with role user = UserFactory.create() member1 = UserFactory.create() member2 = UserFactory.create() project.add_member(user, role=self.project_role_reader) project.add_member(member1, role=self.project_role_reader) project.add_member(member2, role=self.project_role_reader) lead1 = LeadFactory.create( project=project, title='Test 1', source_type=Lead.SourceType.TEXT, confidentiality=Lead.Confidentiality.CONFIDENTIAL, source=org1_child, authors=[org1, org2], assignee=[member1], priority=Lead.Priority.HIGH, status=Lead.Status.IN_PROGRESS, ) lead2 = LeadFactory.create( project=project, source_type=Lead.SourceType.TEXT, title='Test 2', assignee=[member2], authors=[org2, org3], priority=Lead.Priority.HIGH, ) lead3 = LeadFactory.create( project=project, source_type=Lead.SourceType.WEBSITE, url='https://wwwexample.com/sample-1', title='Sample 1', confidentiality=Lead.Confidentiality.CONFIDENTIAL, source=org2, authors=[org1, org3], priority=Lead.Priority.LOW, ) lead4 = LeadFactory.create( project=project, title='Sample 2', source=org3, authors=[org1], priority=Lead.Priority.MEDIUM, ) lead5 = LeadFactory.create( project=project, title='Sample 3', status=Lead.Status.TAGGED, assignee=[member2], source=org3, ) EntryFactory.create(project=project, analysis_framework=af, lead=lead4, controlled=False) EntryFactory.create(project=project, analysis_framework=af, lead=lead4, controlled=False) EntryFactory.create(project=project, analysis_framework=af, lead=lead5, controlled=True) AssessmentFactory.create(project=project, lead=lead1) AssessmentFactory.create(project=project, lead=lead2) # -- With login self.force_login(user) # TODO: Add direct test for filter_set as well (is used within export) for filter_data, expected_leads in [ ({ 'search': 'test' }, [lead1, lead2]), ({ 'confidentiality': self.genum(Lead.Confidentiality.CONFIDENTIAL) }, [lead1, lead3]), ({ 'assignees': [member2.pk] }, [lead2, lead5]), ({ 'assignees': [member1.pk, member2.pk] }, [lead1, lead2, lead5]), ({ 'authoringOrganizationTypes': [org_type2.pk] }, [lead1, lead2, lead3]), ({ 'authoringOrganizationTypes': [org_type1.pk, org_type2.pk] }, [lead1, lead2, lead3, lead4]), ({ 'authorOrganizations': [org1.pk, org2.pk] }, [lead1, lead2, lead3, lead4]), ({ 'authorOrganizations': [org3.pk] }, [lead2, lead3]), ({ 'sourceOrganizations': [org1.pk, org2.pk] }, [lead1, lead3]), ({ 'sourceOrganizations': [org3.pk] }, [lead4, lead5]), ({ 'priorities': [self.genum(Lead.Priority.HIGH)] }, [lead1, lead2]), ({ 'priorities': [ self.genum(Lead.Priority.LOW), self.genum(Lead.Priority.HIGH) ] }, [lead1, lead2, lead3, lead5]), ({ 'sourceTypes': [self.genum(Lead.SourceType.WEBSITE)] }, [lead3]), ({ 'sourceTypes': [ self.genum(Lead.SourceType.TEXT), self.genum(Lead.SourceType.WEBSITE) ] }, [lead1, lead2, lead3]), ({ 'statuses': [self.genum(Lead.Status.NOT_TAGGED)] }, [lead2, lead3]), ({ 'statuses': [ self.genum(Lead.Status.IN_PROGRESS), self.genum(Lead.Status.TAGGED) ] }, [lead1, lead4, lead5]), ({ 'hasEntries': True }, [lead4, lead5]), ({ 'hasEntries': False }, [lead1, lead2, lead3]), ({ 'hasEntries': True, 'ordering': [ self.genum(LeadOrderingEnum.DESC_ENTRIES_COUNT), self.genum(LeadOrderingEnum.ASC_ID) ], }, [lead5, lead4]), ({ 'hasEntries': True, 'entriesFilterData': {}, 'ordering': [ self.genum(LeadOrderingEnum.DESC_ENTRIES_COUNT), self.genum(LeadOrderingEnum.ASC_ID) ], }, [lead5, lead4]), ({ 'entriesFilterData': { 'controlled': True }, 'ordering': [ self.genum(LeadOrderingEnum.DESC_ENTRIES_COUNT), self.genum(LeadOrderingEnum.ASC_ID) ], }, [lead5]), ({ 'hasAssessment': True }, [lead1, lead2]), ({ 'hasAssessment': False }, [lead3, lead4, lead5]), # TODO: # ({'emmEntities': []}, []), # ({'emmKeywords': []}, []), # ({'emmRiskFactors': []}, []), # TODO: Common filters # ({'publishedOn': []}, []), # ({'publishedOnGte': []}, []), # ({'publishedOnLte': []}, []), # ({'text': []}, []), # ({'url': []}, []), # ({'createdAt': []}, []), # ({'createdAtGte': []}, []), # ({'createdAtLte': []}, []), ]: content = self.query_check(self.lead_filter_query, variables={ 'projectId': project.id, **filter_data }) self.assertListIds(content['data']['project']['leads']['results'], expected_leads, { 'response': content, 'filter': filter_data })
def test_project_query(self): """ Test private + non-private project behaviour """ query = ''' query MyQuery ($id: ID!) { project(id: $id) { id title currentUserRole startDate status isVisualizationEnabled isPrivate endDate description data stats { entriesActivity { count date } numberOfLeads numberOfLeadsNotTagged numberOfLeadsInProgress numberOfLeadsTagged numberOfEntries numberOfEntriesVerified numberOfEntriesControlled numberOfUsers leadsActivity { count date } } membershipPending isRejected regions { id title } } } ''' user = UserFactory.create() analysis_framework = AnalysisFrameworkFactory.create() public_project, public_project2, public_project3, public_project4 = ProjectFactory.create_batch( 4, analysis_framework=analysis_framework) now = timezone.now() lead1_1 = self.update_obj(LeadFactory.create(project=public_project), created_at=now + relativedelta(months=-1)) lead1_2 = self.update_obj(LeadFactory.create(project=public_project), created_at=now + relativedelta(months=-2)) lead1_3 = self.update_obj(LeadFactory.create(project=public_project), created_at=now + relativedelta(months=-2)) lead1_4 = self.update_obj(LeadFactory.create(project=public_project), created_at=now + relativedelta(months=-1)) self.update_obj(LeadFactory.create(project=public_project), created_at=now + relativedelta(months=-1)) data = [ { "lead": lead1_1, "controlled": False, "months": -1, }, { "lead": lead1_1, "controlled": False, "months": -3, }, { "lead": lead1_2, "controlled": True, "months": -3, }, { "lead": lead1_2, "controlled": False, "months": -2, }, { "lead": lead1_2, "controlled": True, "months": -2, }, { "lead": lead1_3, "controlled": True, "months": -3, }, { "lead": lead1_3, "controlled": True, "months": -3, }, ] now = timezone.now() for item in data: self.update_obj( EntryFactory.create(lead=item['lead'], controlled=item['controlled'], project=public_project, analysis_framework=analysis_framework), created_at=now + relativedelta(months=item['months'])) EntryFactory.create(lead=lead1_3, project=public_project, controlled=True, analysis_framework=analysis_framework) EntryFactory.create(lead=lead1_4, project=public_project, controlled=True, analysis_framework=analysis_framework) lead2 = LeadFactory.create(project=public_project2) lead3 = LeadFactory.create(project=public_project3) EntryFactory.create(lead=lead2, project=public_project2, controlled=False, analysis_framework=analysis_framework) EntryFactory.create(lead=lead3, project=public_project3, controlled=False, analysis_framework=analysis_framework) user2, user3, request_user, non_member_user = UserFactory.create_batch( 4) public_project = ProjectFactory.create( analysis_framework=analysis_framework) private_project = ProjectFactory.create( is_private=True, analysis_framework=analysis_framework) ProjectJoinRequestFactory.create(project=public_project, requested_by=request_user, status='pending', role=self.project_role_admin) # create projectJoinRequest(status='rejected') ProjectJoinRequestFactory.create(project=public_project4, requested_by=request_user, status='rejected', role=self.project_role_admin) # add some project member public_project.add_member(user) public_project.add_member(user2) public_project.add_member(user3) # add some lead for the project lead = LeadFactory.create(project=public_project) lead2 = LeadFactory.create(project=public_project) LeadFactory.create_batch(3, project=public_project) LeadFactory.create(project=private_project) # add some entry for the project EntryFactory.create_batch(4, project=public_project, analysis_framework=analysis_framework, lead=lead) entry2_1 = EntryFactory.create(project=public_project, analysis_framework=analysis_framework, lead=lead2, controlled=True) entry2_2 = EntryFactory.create(project=public_project, analysis_framework=analysis_framework, lead=lead2) EntryFactory.create(project=private_project, analysis_framework=analysis_framework, lead=lead) # Verify entries entry2_1.verified_by.add(user) entry2_1.verified_by.add(user3) entry2_2.verified_by.add(user) # NOTE: Right noe only IN_PROGRESS status is set automatically # Control one lead lead2.status = Lead.Status.TAGGED lead2.save(update_fields=('status', )) # lets add some regions to project region1, region2, region3 = RegionFactory.create_batch(3) public_project.regions.add(region1) public_project.regions.add(region2) private_project.regions.add(region3) # Generate project cache _generate_project_stats_cache() # -- Without login self.query_check(query, assert_for_error=True, variables={'id': public_project.id}) self.query_check(query, assert_for_error=True, variables={'id': private_project.id}) # -- With login self.force_login(user) # --- non-member user content = self.query_check(query, variables={'id': public_project.id}) self.assertNotEqual(content['data']['project'], None, content) content = self.query_check(query, variables={'id': private_project.id}) self.assertEqual(content['data']['project'], None, content) # login with non_member self.force_login(non_member_user) content = self.query_check(query, variables={'id': public_project.id}) self.assertNotEqual(content['data']['project'], None, content) self.assertEqual(content['data']['project']['membershipPending'], False) # login with request_user self.force_login(request_user) content = self.query_check(query, variables={'id': public_project4.id}) self.assertNotEqual(content['data']['project'], None, content) self.assertEqual(content['data']['project']['isRejected'], True) # --- member user # ---- (public-project) self.force_login(user) content = self.query_check(query, variables={'id': public_project.id}) self.assertNotEqual(content['data']['project'], None, content) self.assertEqual(content['data']['project']['stats']['numberOfLeads'], 5, content) self.assertEqual( content['data']['project']['stats']['numberOfLeadsNotTagged'], 3, content) self.assertEqual( content['data']['project']['stats']['numberOfLeadsInProgress'], 1, content) self.assertEqual( content['data']['project']['stats']['numberOfLeadsTagged'], 1, content) self.assertEqual( content['data']['project']['stats']['numberOfEntries'], 6, content) self.assertEqual( content['data']['project']['stats']['numberOfEntriesVerified'], 2, content) self.assertEqual( content['data']['project']['stats']['numberOfEntriesControlled'], 1, content) self.assertEqual(content['data']['project']['stats']['numberOfUsers'], 3, content) self.assertEqual( len(content['data']['project']['stats']['leadsActivity']), 1, content) self.assertEqual( len(content['data']['project']['stats']['entriesActivity']), 1, content) self.assertEqual(len(content['data']['project']['regions']), 2, content) self.assertListIds(content['data']['project']['regions'], [region1, region2], content) # login with request user self.force_login(request_user) content = self.query_check(query, variables={'id': public_project.id}) self.assertNotEqual(content['data']['project'], None, content) self.assertEqual(content['data']['project']['membershipPending'], True) # ---- (private-project) self.force_login(user) private_project.add_member(user) content = self.query_check(query, variables={'id': private_project.id}) self.assertNotEqual(content['data']['project'], None, content) self.assertEqual(len(content['data']['project']['regions']), 1, content) self.assertListIds(content['data']['project']['regions'], [region3], content)
def test_snapshot(self): query = ''' query MyQuery { projectExploreStats { totalProjects totalUsers leadsAddedWeekly dailyAverageLeadsTaggedPerProject generatedExportsMonthly topActiveProjects { projectId projectTitle analysisFrameworkId analysisFrameworkTitle } calculatedAt } } ''' def _cache_clear(): cache.delete( CacheKey.PROJECT_EXPLORE_STATS_LOADER_KEY) # Delete cache user = UserFactory.create() # -- With login self.force_login(user) _cache_clear() previous_content = content = self.query_check(query) self.assertMatchSnapshot(content, 'no-data') UserFactory.create_batch(3, is_active=False) # Some Inactive users analysis_framework = AnalysisFrameworkFactory.create() projects = ProjectFactory.create_batch(3) projects_with_af = ProjectFactory.create_batch( 3, analysis_framework=analysis_framework) # This shouldn't show in top projects but leads/entries count should private_project = ProjectFactory.create( title='Private Project', is_private=True, analysis_framework=analysis_framework) now = timezone.now() # Generate project cache _generate_project_stats_cache() content = self.query_check(query) self.assertEqual(content, previous_content) # Test for cache _cache_clear() previous_content = content = self.query_check( query) # Pull latest data self.assertMatchSnapshot(content, 'only-project') self.update_obj(LeadFactory.create(project=projects[0]), created_at=now + relativedelta(weeks=-1)) self.update_obj(LeadFactory.create(project=projects[0]), created_at=now + relativedelta(weeks=-1)) self.update_obj(LeadFactory.create(project=projects[1]), created_at=now + relativedelta(weeks=-2)) self.update_obj(LeadFactory.create(project=projects[1]), created_at=now + relativedelta(weeks=-1)) self.update_obj(LeadFactory.create(project=projects[1]), created_at=now + relativedelta(weeks=-1)) self.update_obj(LeadFactory.create(project=projects[2]), created_at=now + relativedelta(weeks=-2)) lead0_1 = self.update_obj( LeadFactory.create(project=projects_with_af[0]), created_at=now + relativedelta(weeks=-1)) lead1_1 = self.update_obj( LeadFactory.create(project=projects_with_af[1]), created_at=now + relativedelta(weeks=-2)) lead1_2 = self.update_obj( LeadFactory.create(project=projects_with_af[1]), created_at=now + relativedelta(weeks=-1)) plead1_1 = self.update_obj(LeadFactory.create(project=private_project), created_at=now + relativedelta(weeks=-2)) plead1_2 = self.update_obj(LeadFactory.create(project=private_project), created_at=now + relativedelta(weeks=-1)) self.update_obj(LeadFactory.create(project=projects_with_af[1]), created_at=now + relativedelta(weeks=-1)) self.update_obj(LeadFactory.create(project=projects_with_af[2]), created_at=now + relativedelta(weeks=-3)) self.update_obj(EntryFactory.create(lead=lead0_1), created_at=now + relativedelta(weeks=-1)) self.update_obj(EntryFactory.create(lead=lead1_1), created_at=now + relativedelta(weeks=-1)) self.update_obj(EntryFactory.create(lead=lead1_2), created_at=now + relativedelta(weeks=-1)) self.update_obj(EntryFactory.create(lead=plead1_1), created_at=now + relativedelta(weeks=-1)) self.update_obj(EntryFactory.create(lead=plead1_2), created_at=now + relativedelta(weeks=-1)) # Generate project cache _generate_project_stats_cache() self.update_obj(ExportFactory.create(project=projects_with_af[0], exported_by=user), exported_at=now + relativedelta(months=-1)) self.update_obj(ExportFactory.create(project=projects_with_af[0], exported_by=user), exported_at=now + relativedelta(months=-1)) self.update_obj(ExportFactory.create(project=projects_with_af[0], exported_by=user), exported_at=now + relativedelta(months=-2)) self.update_obj(ExportFactory.create(project=projects_with_af[1], exported_by=user), exported_at=now + relativedelta(months=-2)) self.update_obj(ExportFactory.create(project=projects_with_af[2], exported_by=user), exported_at=now + relativedelta(months=-3)) self.update_obj(ExportFactory.create(project=private_project, exported_by=user), exported_at=now + relativedelta(months=-1)) content = self.query_check(query) self.assertEqual(content, previous_content) # Test for cache _cache_clear() previous_content = content = self.query_check( query) # Pull latest data self.assertMatchSnapshot(content, 'with-data')
def test_entry_query_filter(self): query = ''' query MyQuery ( $projectId: ID! $leadAuthoringOrganizationTypes: [ID!] $commentStatus: EntryFilterCommentStatusEnum $controlled: Boolean $createdAt: DateTime $createdAtGte: DateTime $createdAtLte: DateTime $createdBy: [ID!] $entriesId: [ID!] $entryTypes: [EntryTagTypeEnum!] $excerpt: String $filterableData: [EntryFilterDataType!] $geoCustomShape: String $leadAssignees: [ID!] $leadConfidentialities: [LeadConfidentialityEnum!] $leadGroupLabel: String $leadPriorities: [LeadPriorityEnum!] $leadPublishedOn: Date $leadPublishedOnGte: Date $leadPublishedOnLte: Date $leads: [ID!] $leadStatuses: [LeadStatusEnum!] $leadTitle: String $modifiedAt: DateTime $modifiedBy: [ID!] $projectEntryLabels: [ID!] ) { project(id: $projectId) { entries ( commentStatus: $commentStatus controlled: $controlled createdAt: $createdAt createdAtGte: $createdAtGte createdAtLte: $createdAtLte createdBy: $createdBy entriesId: $entriesId entryTypes: $entryTypes excerpt: $excerpt filterableData: $filterableData geoCustomShape: $geoCustomShape modifiedAt: $modifiedAt modifiedBy: $modifiedBy projectEntryLabels: $projectEntryLabels # Lead filters leadAuthoringOrganizationTypes: $leadAuthoringOrganizationTypes leadAssignees: $leadAssignees leadConfidentialities: $leadConfidentialities leadGroupLabel: $leadGroupLabel leadPriorities: $leadPriorities leadPublishedOn: $leadPublishedOn leadPublishedOnGte: $leadPublishedOnGte leadPublishedOnLte: $leadPublishedOnLte leads: $leads leadStatuses: $leadStatuses leadTitle: $leadTitle ) { results { id } } } } ''' af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=af) org_type1, org_type2 = OrganizationTypeFactory.create_batch(2) org1 = OrganizationFactory.create(organization_type=org_type1) org2 = OrganizationFactory.create(organization_type=org_type2) org3 = OrganizationFactory.create(organization_type=org_type2) # User with role user = UserFactory.create() member1 = UserFactory.create() member2 = UserFactory.create() project.add_member(user, role=self.project_role_reader) project.add_member(member1, role=self.project_role_reader) project.add_member(member2, role=self.project_role_reader) lead1 = LeadFactory.create( project=project, title='Test 1', source_type=Lead.SourceType.TEXT, confidentiality=Lead.Confidentiality.CONFIDENTIAL, authors=[org1, org2], assignee=[member1], priority=Lead.Priority.HIGH, status=Lead.Status.IN_PROGRESS, ) lead2 = LeadFactory.create( project=project, source_type=Lead.SourceType.TEXT, title='Test 2', assignee=[member2], authors=[org2, org3], priority=Lead.Priority.HIGH, ) lead3 = LeadFactory.create( project=project, source_type=Lead.SourceType.WEBSITE, url='https://wwwexample.com/sample-1', title='Sample 1', confidentiality=Lead.Confidentiality.CONFIDENTIAL, authors=[org1, org3], priority=Lead.Priority.LOW, ) lead4 = LeadFactory.create( project=project, title='Sample 2', authors=[org1], priority=Lead.Priority.MEDIUM, ) other_project = ProjectFactory.create(analysis_framework=af) other_lead = LeadFactory.create(project=other_project) outside_entry = EntryFactory.create(project=other_project, analysis_framework=af, lead=other_lead) entry1_1 = EntryFactory.create( project=project, analysis_framework=af, lead=lead1, entry_type=Entry.TagType.EXCERPT, controlled=False) entry2_1 = EntryFactory.create( project=project, analysis_framework=af, lead=lead2, entry_type=Entry.TagType.IMAGE, controlled=True) entry3_1 = EntryFactory.create( project=project, analysis_framework=af, lead=lead3, entry_type=Entry.TagType.EXCERPT, controlled=False) entry4_1 = EntryFactory.create( project=project, analysis_framework=af, lead=lead4, entry_type=Entry.TagType.EXCERPT, controlled=False) # Change lead1 status to TAGGED lead1.status = Lead.Status.TAGGED lead1.save(update_fields=['status']) # Some leads/entries in other projects other_leads = LeadFactory.create_batch(3, project=ProjectFactory.create(analysis_framework=af)) [EntryFactory.create_batch(3, lead=lead) for lead in other_leads] # -- With login self.force_login(user) # TODO: Add direct test for filter_set as well (is used within export) for filter_data, expected_entries in [ ({'controlled': True}, [entry2_1]), ({'controlled': False}, [entry1_1, entry3_1, entry4_1]), ({'entriesId': [entry1_1.id, entry2_1.id, outside_entry.id]}, [entry1_1, entry2_1]), ({'entryTypes': [self.genum(Entry.TagType.EXCERPT)]}, [entry1_1, entry3_1, entry4_1]), ( {'entryTypes': [self.genum(Entry.TagType.EXCERPT), self.genum(Entry.TagType.IMAGE)]}, [entry1_1, entry2_1, entry3_1, entry4_1], ), # TODO: ({'projectEntryLabels': []}, []), # TODO: ({'geoCustomShape': []}, []), # TODO: After adding comment({'commentStatus': self.genum(EntryFilterMixin.CommentStatus.RESOLVED)}, []), # Lead filters ({'leadAuthoringOrganizationTypes': [org_type2.pk]}, [entry1_1, entry2_1, entry3_1]), ({'leadAuthoringOrganizationTypes': [org_type1.pk, org_type2.pk]}, [entry1_1, entry2_1, entry3_1, entry4_1]), ({'leads': [lead1.pk, lead2.pk]}, [entry1_1, entry2_1]), ({'leadTitle': 'test'}, [entry1_1, entry2_1]), ({'leadAssignees': [member2.pk]}, [entry2_1]), ({'leadAssignees': [member1.pk, member2.pk]}, [entry1_1, entry2_1]), ({'leadConfidentialities': self.genum(Lead.Confidentiality.CONFIDENTIAL)}, [entry1_1, entry3_1]), ({'leadPriorities': [self.genum(Lead.Priority.HIGH)]}, [entry1_1, entry2_1]), ( {'leadPriorities': [self.genum(Lead.Priority.LOW), self.genum(Lead.Priority.HIGH)]}, [entry1_1, entry2_1, entry3_1] ), ({'leadStatuses': [self.genum(Lead.Status.NOT_TAGGED)]}, []), ({'leadStatuses': [self.genum(Lead.Status.IN_PROGRESS)]}, [entry2_1, entry3_1, entry4_1]), ({'leadStatuses': [self.genum(Lead.Status.TAGGED)]}, [entry1_1]), ( {'leadStatuses': [self.genum(Lead.Status.IN_PROGRESS), self.genum(Lead.Status.TAGGED)]}, [entry1_1, entry2_1, entry3_1, entry4_1] ), # TODO: Common filters # ({'excerpt': []}, []), # ({'modifiedAt': []}, []), # ({'modifiedBy': []}, []), # ({'createdAt': []}, []), # ({'createdAtGte': []}, []), # ({'createdAtLte': []}, []), # ({'createdBy': []}, []), # ({'leadGroupLabel': []}, []), # ({'leadPublishedOn': []}, []), # ({'leadPublishedOnGte': []}, []), # ({'leadPublishedOnLte': []}, []), ]: # Entry filter test content = self.query_check(query, variables={'projectId': project.id, **filter_data}) self.assertListIds( content['data']['project']['entries']['results'], expected_entries, {'response': content, 'filter': filter_data} ) # Lead filter test expected_leads = set([entry.lead for entry in expected_entries]) content = self.query_check( TestLeadQuerySchema.lead_filter_query, variables={ 'projectId': project.id, 'hasEntries': True, 'entriesFilterData': filter_data, } ) self.assertListIds( content['data']['project']['leads']['results'], expected_leads, {'response': content, 'filter': filter_data}, )
def test_review_comments_query(self): query = ''' query MyQuery ($projectId: ID! $entryId: ID!) { project(id: $projectId) { entry (id: $entryId) { id verifiedBy { displayName id } controlled controlledChangedBy { id displayName } reviewCommentsCount } reviewComments (entry: $entryId, ordering: DESC_ID) { totalCount results { id text commentType createdAt mentionedUsers { displayName id } } } } } ''' user = UserFactory.create() user2, user3 = UserFactory.create_batch(2) analysis_framework = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=analysis_framework) lead = LeadFactory.create(project=project) entry = EntryFactory.create(project=project, analysis_framework=analysis_framework, lead=lead, controlled=True, controlled_changed_by=user2, verified_by=[user2, user3]) entry1 = EntryFactory.create( project=project, analysis_framework=analysis_framework, lead=lead, ) review_comment1, review_comment2 = EntryReviewCommentFactory.create_batch( 2, entry=entry, created_by=user) EntryReviewCommentFactory.create(entry=entry1, created_by=user) review_text1 = EntryReviewCommentTextFactory.create( comment=review_comment1) # -- Without login self.query_check(query, assert_for_error=True, variables={ 'projectId': project.id, 'entryId': entry.id }) # -- With login self.force_login(user) # --- non-member user content = self.query_check(query, variables={ 'projectId': project.id, 'entryId': entry.id }) self.assertEqual(content['data']['project']['entry'], None, content) # --- add-member in project project.add_member(user) content = self.query_check(query, variables={ 'projectId': project.id, 'entryId': entry.id }) self.assertEqual( content['data']['project']['entry']['reviewCommentsCount'], 2, content) self.assertEqual( content['data']['project']['reviewComments']['totalCount'], 2, content) self.assertListIds( content['data']['project']['reviewComments']['results'], [review_comment1, review_comment2], content) self.assertEqual( content['data']['project']['reviewComments']['results'][1]['text'], review_text1.text, content) # add another review_text for same review_comment review_text2 = EntryReviewCommentTextFactory.create( comment=review_comment1) content = self.query_check(query, variables={ 'projectId': project.id, 'entryId': entry.id }) self.assertEqual( content['data']['project']['entry']['reviewCommentsCount'], 2, content) self.assertEqual( content['data']['project']['reviewComments']['results'][1]['text'], review_text2.text, # here latest text should be present content) # lets check for the contolled in entry self.assertEqual(content['data']['project']['entry']['controlled'], True, content) self.assertEqual( content['data']['project']['entry']['controlledChangedBy']['id'], str(user2.id), content) self.assertEqual( len(content['data']['project']['entry']['verifiedBy']), 2, content) # lets query for another entry content = self.query_check(query, variables={ 'projectId': project.id, 'entryId': entry1.id }) self.assertEqual( content['data']['project']['entry']['reviewCommentsCount'], 1, content) self.assertEqual( content['data']['project']['reviewComments']['totalCount'], 1, content)
def test_review_comments_project_scope_query(self): """ Include permission check """ query = ''' query MyQuery ($projectId: ID! $reviewId: ID!) { project(id: $projectId) { reviewComment(id: $reviewId) { commentType createdAt createdBy { id firstName } id mentionedUsers { displayName displayPictureUrl } textHistory { createdAt id text } } } } ''' user = UserFactory.create() analysis_framework = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=analysis_framework) lead = LeadFactory.create(project=project) conf_lead = LeadFactory.create( project=project, confidentiality=Lead.Confidentiality.CONFIDENTIAL) entry = EntryFactory.create(project=project, analysis_framework=analysis_framework, lead=lead) conf_entry = EntryFactory.create(project=project, analysis_framework=analysis_framework, lead=conf_lead) review_comment = EntryReviewCommentFactory.create(entry=entry, created_by=user) conf_review_comment = EntryReviewCommentFactory.create( entry=conf_entry, created_by=user) review_text1, review_text2 = EntryReviewCommentTextFactory.create_batch( 2, comment=review_comment) review_text_conf1, review_text_conf2 = EntryReviewCommentTextFactory.create_batch( 2, comment=conf_review_comment) def _query_check(review_comment, **kwargs): return self.query_check(query, variables={ 'projectId': project.id, 'reviewId': review_comment.id }, **kwargs) # Without login _query_check(review_comment, assert_for_error=True) _query_check(conf_review_comment, assert_for_error=True) # With login self.force_login(user) # -- Without membership content = _query_check(review_comment) self.assertEqual(content['data']['project']['reviewComment'], None, content) # -- Without membership (confidential only) current_membership = project.add_member( user, role=self.project_role_reader_non_confidential) content = _query_check(review_comment) self.assertNotEqual(content['data']['project']['reviewComment'], None, content) self.assertEqual( len(content['data']['project']['reviewComment']['textHistory']), 2, content) self.assertListIds( content['data']['project']['reviewComment']['textHistory'], [review_text1, review_text2], content) content = _query_check(conf_review_comment) self.assertEqual(content['data']['project']['reviewComment'], None, content) # -- With membership (non-confidential only) current_membership.delete() project.add_member(user, role=self.project_role_reader) content = _query_check(review_comment) self.assertNotEqual(content['data']['project']['reviewComment'], None, content) content = _query_check(conf_review_comment) self.assertNotEqual(content['data']['project']['reviewComment'], None, content) self.assertEqual( len(content['data']['project']['reviewComment']['textHistory']), 2, content) self.assertListIds( content['data']['project']['reviewComment']['textHistory'], [review_text_conf1, review_text_conf2], content)
def test_entry_query(self): # Includes permissions checks query = ''' query MyQuery ($projectId: ID! $entryId: ID!) { project(id: $projectId) { entry (id: $entryId) { id order entryType excerpt attributes { widgetType widget data clientId widgetVersion id } clientId droppedExcerpt highlightHidden informationDate image { id metadata mimeType title file { url name } } controlled } } } ''' user = UserFactory.create() lead = LeadFactory.create(project=self.project) conf_lead = LeadFactory.create(project=self.project, confidentiality=Lead.Confidentiality.CONFIDENTIAL) entry = EntryFactory.create(project=self.project, analysis_framework=self.af, lead=lead) conf_entry = EntryFactory.create(project=self.project, analysis_framework=self.af, lead=conf_lead) def _query_check(entry, **kwargs): return self.query_check(query, variables={'projectId': self.project.pk, 'entryId': entry.id}, **kwargs) # Without login _query_check(entry, assert_for_error=True) _query_check(conf_entry, assert_for_error=True) # With login self.force_login(user) # -- Without membership content = _query_check(entry) # Normal entry self.assertEqual(content['data']['project']['entry'], None, content) content = _query_check(conf_entry) # Confidential entry self.assertEqual(content['data']['project']['entry'], None, content) # -- Without membership (confidential only) current_membership = self.project.add_member(user, role=self.project_role_reader_non_confidential) content = _query_check(entry) # Normal entry self.assertNotEqual(content['data']['project']['entry'], None, content) content = _query_check(conf_entry) # Confidential entry self.assertEqual(content['data']['project']['entry'], None, content) # -- With membership (non-confidential only) current_membership.delete() self.project.add_member(user, role=self.project_role_reader) content = _query_check(entry) # Normal entry self.assertNotEqual(content['data']['project']['entry'], None, content) content = _query_check(conf_entry) # Confidential entry self.assertNotEqual(content['data']['project']['entry'], None, content)