def test_search_filter(self): AnalysisFrameworkFactory.create(title='one') af2 = AnalysisFrameworkFactory.create(title='two') af3 = AnalysisFrameworkFactory.create(title='twoo') obtained = self.filter_class(data=dict(search='tw')).qs expected = [af2, af3] self.assertQuerySetIdEqual(expected, obtained)
def test_analysis_framework_list(self): query = ''' query MyQuery { analysisFrameworks (ordering: "id") { page pageSize totalCount results { id title description isPrivate } } } ''' user = UserFactory.create() private_af = AnalysisFrameworkFactory.create(is_private=True) normal_af = AnalysisFrameworkFactory.create() member_af = AnalysisFrameworkFactory.create() member_af.add_member(user) # Without login self.query_check(query, assert_for_error=True) # With login self.force_login(user) content = self.query_check(query) results = content['data']['analysisFrameworks']['results'] self.assertEqual(content['data']['analysisFrameworks']['totalCount'], 2) self.assertIdEqual(results[0]['id'], normal_af.id) self.assertIdEqual(results[1]['id'], member_af.id) self.assertNotIn(str(private_af.id), [d['id'] for d in results]) # Can't see private project. project = ProjectFactory.create(analysis_framework=private_af) # It shouldn't list private AF after adding to a project. content = self.query_check(query) results = content['data']['analysisFrameworks']['results'] self.assertEqual(content['data']['analysisFrameworks']['totalCount'], 2) self.assertNotIn(str(private_af.id), [d['id'] for d in results]) # Can't see private project. project.add_member(user) # It should list private AF after user is member of the project. content = self.query_check(query) results = content['data']['analysisFrameworks']['results'] self.assertEqual(content['data']['analysisFrameworks']['totalCount'], 3) self.assertIn(str(private_af.id), [d['id'] for d in results]) # Can see private project now.
def test_analysis_framework(self): query = ''' query MyQuery ($id: ID!) { analysisFramework(id: $id) { id currentUserRole description isPrivate title } } ''' user = UserFactory.create() private_af = AnalysisFrameworkFactory.create(is_private=True) normal_af = AnalysisFrameworkFactory.create() member_af = AnalysisFrameworkFactory.create() member_af.add_member(user) # Without login self.query_check(query, assert_for_error=True, variables={'id': normal_af.pk}) # With login self.force_login(user) # Should work for normal AF response = self.query_check(query, variables={'id': normal_af.pk })['data']['analysisFramework'] self.assertIdEqual(response['id'], normal_af.id, response) self.assertEqual(response['isPrivate'], False, response) # Should work for member AF response = self.query_check(query, variables={'id': member_af.pk })['data']['analysisFramework'] self.assertIdEqual(response['id'], member_af.id, response) self.assertEqual(response['isPrivate'], False, response) # Shouldn't work for non-member private AF response = self.query_check(query, variables={'id': private_af.pk })['data']['analysisFramework'] self.assertEqual(response, None, response) # Shouldn't work for non-member private AF even if there is a project attached project = ProjectFactory.create(analysis_framework=private_af) response = self.query_check(query, variables={'id': private_af.pk })['data']['analysisFramework'] self.assertEqual(response, None, response) # Should work for member private AF project.add_member(user) response = self.query_check(query, variables={'id': private_af.pk })['data']['analysisFramework'] self.assertIdEqual(response['id'], private_af.id, response) self.assertEqual(response['isPrivate'], True, response)
def test_change_other_fields(self): private_framework = AnalysisFrameworkFactory.create(is_private=True) public_framework = AnalysisFrameworkFactory.create(is_private=False) user = self.user private_framework.add_member( user, private_framework.get_or_create_owner_role()) public_framework.add_member( user, public_framework.get_or_create_owner_role()) self.force_login(user) # private framework update self.input = dict( title='new title updated', isPrivate=private_framework.is_private, ) response = self.query( self.update_mutation, input_data=self.input, variables={'id': private_framework.id}, ) private_framework.refresh_from_db() content = response.json() self.assertNotEqual( content['data']['analysisFramework']['analysisFrameworkUpdate'], None, content) self.assertTrue( content['data']['analysisFramework']['analysisFrameworkUpdate'] ['ok'], content) self.assertEqual(private_framework.title, self.input['title']) # public framework update self.input = dict( title='public title updated', isPrivate=public_framework.is_private, ) response = self.query( self.update_mutation, input_data=self.input, variables={'id': public_framework.id}, ) public_framework.refresh_from_db() content = response.json() self.assertNotEqual( content['data']['analysisFramework']['analysisFrameworkUpdate'], None, content) self.assertTrue( content['data']['analysisFramework']['analysisFrameworkUpdate'] ['ok'], content) self.assertEqual(public_framework.title, self.input['title'])
def test_change_is_private_field(self): """Even the owner should be unable to change privacy""" private_framework = AnalysisFrameworkFactory.create(is_private=True) public_framework = AnalysisFrameworkFactory.create(is_private=False) user = self.user private_framework.add_member( user, private_framework.get_or_create_owner_role()) public_framework.add_member( user, public_framework.get_or_create_owner_role()) content = self._change_framework_privacy(public_framework, user) self.assertIsNotNone(content['errors'][0]['message']) self.assertIn('permission', content['errors'][0]['message']) content = self._change_framework_privacy(private_framework, user) self.assertIsNotNone(content['errors'][0]['message']) self.assertIn('permission', content['errors'][0]['message'])
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_project_query_has_assesment_af(self): query = ''' query MyQuery { projects(ordering: "id") { results { id hasAnalysisFramework hasAssessmentTemplate } } } ''' user = UserFactory.create() analysis_framework = AnalysisFrameworkFactory.create() assessment_template = AssessmentTemplateFactory.create() project1 = ProjectFactory.create( analysis_framework=analysis_framework, assessment_template=assessment_template) project2 = ProjectFactory.create( analysis_framework=analysis_framework, ) project3 = ProjectFactory.create( assessment_template=assessment_template) self.force_login(user) projects = self.query_check(query)['data']['projects']['results'] for index, (_id, has_af, has_ary_template) in enumerate([ (project1.pk, True, True), (project2.pk, True, False), (project3.pk, False, True), ]): self.assertIdEqual(projects[index]['id'], _id, projects) self.assertEqual(projects[index]['hasAnalysisFramework'], has_af, projects) self.assertEqual(projects[index]['hasAssessmentTemplate'], has_ary_template, projects)
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_analysis_pillars_entries_query(self): query = ''' query MyQuery ($projectId: ID!, $analysisPillarId: ID!) { project(id: $projectId) { analysisPillar (id: $analysisPillarId) { id title entries { totalCount results { id } } } } } ''' now = datetime.datetime.now() member_user = UserFactory.create() non_member_user = UserFactory.create() af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=af) another_project = ProjectFactory.create(analysis_framework=af) project.add_member(member_user, role=self.project_role_reader_non_confidential) analysis = AnalysisFactory.create(project=project, team_lead=member_user, end_date=now) analysis_pillar = AnalysisPillarFactory.create(analysis=analysis, assignee=member_user) def _query_check(**kwargs): return self.query_check( query, variables={'projectId': project.id, 'analysisPillarId': analysis_pillar.pk}, **kwargs, ) # -- Without login _query_check(assert_for_error=True) # --- With login self.force_login(non_member_user) content = _query_check() self.assertEqual(content['data']['project']['analysisPillar'], None, content) self.force_login(member_user) content = _query_check() self.assertEqual(content['data']['project']['analysisPillar']['entries']['totalCount'], 0, content) self.assertEqual(len(content['data']['project']['analysisPillar']['entries']['results']), 0, content) # Let's add some entries lead_published_on = now - datetime.timedelta(days=1) # To fit within analysis end_date EntryFactory.create_batch(10, lead=LeadFactory.create(project=project, published_on=lead_published_on)) EntryFactory.create_batch(8, lead=LeadFactory.create(project=another_project, published_on=lead_published_on)) content = _query_check() self.assertEqual(content['data']['project']['analysisPillar']['entries']['totalCount'], 10, content) self.assertEqual(len(content['data']['project']['analysisPillar']['entries']['results']), 10, content)
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 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 setUp(self): super().setUp() self.af = AnalysisFrameworkFactory.create() self.project = ProjectFactory.create(analysis_framework=self.af) # User with role self.non_member_user = UserFactory.create() self.readonly_member_user = UserFactory.create() self.member_user = UserFactory.create() 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.lead = LeadFactory.create(project=self.project) self.widget1 = WidgetFactory.create(analysis_framework=self.af) self.widget2 = WidgetFactory.create(analysis_framework=self.af) self.widget3 = WidgetFactory.create(analysis_framework=self.af) # Files self.other_file = FileFactory.create() self.our_file = FileFactory.create(created_by=self.member_user) self.dummy_data = dict({})
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 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_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_project_create_mutation(self): query = ''' mutation MyMutation($input: ProjectCreateInputType!) { __typename projectCreate(data: $input) { ok errors result { id title analysisFramework { id isPrivate } description startDate endDate isPrivate hasPubliclyViewableLeads isVisualizationEnabled organizations { id organization { id title } organizationType organizationTypeDisplay } status } } } ''' user = UserFactory.create() af = AnalysisFrameworkFactory.create() private_project_feature = FeatureFactory.create(key=Feature.FeatureKey.PRIVATE_PROJECT) private_af = AnalysisFrameworkFactory.create(is_private=True) private_af_w_membership = AnalysisFrameworkFactory.create(is_private=True) private_af_w_membership.add_member(user) org1 = OrganizationFactory.create() minput = dict( title='Project 1', analysisFramework=str(private_af.id), description='Project description 101', startDate='2020-01-01', endDate='2021-01-01', status=self.genum(Project.Status.ACTIVE), isPrivate=True, hasPubliclyViewableLeads=False, isVisualizationEnabled=False, organizations=[ dict( organization=str(org1.pk), organizationType=self.genum(ProjectOrganization.Type.LEAD_ORGANIZATION), ), ], ) def _query_check(**kwargs): return self.query_check( query, minput=minput, **kwargs, ) # ---------- Without login _query_check(assert_for_error=True) # ---------- With login self.force_login(user) # ----------------- Some Invalid input response = _query_check(okay=False) # invalid [private AF with memership] + public project minput['analysisFramework'] = str(private_af_w_membership.pk) minput['isPrivate'] = False response = _query_check(okay=False) # invalid [private AF with memership] + private project + without feature permission minput['isPrivate'] = True response = _query_check(okay=False) # invalid [private AF with memership] + private project + with feature permission private_project_feature.users.add(user) response = _query_check(okay=True)['data']['projectCreate'] self.assertMatchSnapshot(response, 'private-af-private-project-success') # Valid [public AF] + private project minput['analysisFramework'] = str(af.pk) minput['isPrivate'] = True response = _query_check(okay=True)['data']['projectCreate'] self.assertMatchSnapshot(response, 'public-af-private-project-success') # Valid [public AF] + private project minput['analysisFramework'] = str(af.pk) minput['isPrivate'] = False response = _query_check(okay=True)['data']['projectCreate'] self.assertMatchSnapshot(response, 'public-af-public-project-success')
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_projects_viz_node(self): query = ''' query MyQuery ($id: ID!) { project(id: $id) { vizData { dataUrl modifiedAt publicShare publicUrl status } title isVisualizationAvailable isVisualizationEnabled } } ''' af = AnalysisFrameworkFactory.create() member_user = UserFactory.create() # with confidential access non_confidential_user = UserFactory.create() non_member_user = UserFactory.create() project = ProjectFactory.create(analysis_framework=af) project.add_member(member_user, role=self.project_role_member) project.add_member(non_confidential_user, role=self.project_role_reader_non_confidential) def _query_check(**kwargs): return self.query_check(query, variables={'id': project.pk}, **kwargs) # -- Without login _query_check(assert_for_error=True) # -- With login # Before enabling viz. # --- non-member user self.force_login(non_member_user) content = _query_check() self.assertEqual(content['data']['project']['vizData'], None, content) self.assertEqual(content['data']['project']['isVisualizationEnabled'], False, content) self.assertEqual( content['data']['project']['isVisualizationAvailable'], False, content) # --- member user self.force_login(member_user) content = _query_check() self.assertEqual(content['data']['project']['vizData'], None, content) self.assertEqual(content['data']['project']['isVisualizationEnabled'], False, content) self.assertEqual( content['data']['project']['isVisualizationAvailable'], False, content) # Only enabling project viz settings (not configuring AF). project.is_visualization_enabled = True project.save(update_fields=('is_visualization_enabled', )) # --- non-member user self.force_login(non_member_user) content = _query_check() self.assertEqual(content['data']['project']['vizData'], None, content) self.assertEqual(content['data']['project']['isVisualizationEnabled'], True, content) self.assertEqual( content['data']['project']['isVisualizationAvailable'], False, content) # --- member user self.force_login(member_user) content = _query_check() self.assertEqual(content['data']['project']['vizData'], None, content) self.assertEqual(content['data']['project']['isVisualizationEnabled'], True, content) self.assertEqual( content['data']['project']['isVisualizationAvailable'], False, content) # Configure/Enable viz. TestProjectGeneralMutation.set_project_viz_configuration(project) # --- non-member project self.force_login(non_member_user) content = _query_check() self.assertEqual(content['data']['project']['vizData'], None, content) self.assertEqual(content['data']['project']['isVisualizationEnabled'], True, content) self.assertEqual( content['data']['project']['isVisualizationAvailable'], True, content) # --- member project self.force_login(member_user) content = _query_check() self.assertNotEqual(content['data']['project']['vizData'], None, content) self.assertEqual(content['data']['project']['isVisualizationEnabled'], True, content) self.assertEqual( content['data']['project']['isVisualizationAvailable'], True, content) self.assertEqual( content['data']['project']['vizData'], { 'dataUrl': '', 'modifiedAt': self.now_datetime_str, 'publicShare': False, 'publicUrl': None, 'status': self.genum(ProjectStats.Status.PENDING), }, content, ) # Enable public share/url project_stats = project.project_stats.update_public_share_configuration( ProjectStats.Action.ON) content = _query_check() self.assertNotEqual(content['data']['project']['vizData'], None, content) self.assertEqual(content['data']['project']['isVisualizationEnabled'], True, content) self.assertEqual( content['data']['project']['isVisualizationAvailable'], True, content) self.assertEqual( content['data']['project']['vizData'], { 'dataUrl': '', 'modifiedAt': self.now_datetime_str, 'publicShare': True, 'publicUrl': 'http://testserver' + project_stats.get_public_url(), 'status': self.genum(ProjectStats.Status.PENDING), }, content, )
def test_project_update_mutation(self): query = ''' mutation MyMutation($projectId: ID!, $input: ProjectUpdateInputType!) { __typename project(id: $projectId) { projectUpdate(data: $input) { ok errors result { id title analysisFramework { id isPrivate } description startDate endDate isPrivate hasPubliclyViewableLeads isVisualizationEnabled organizations { id organization { id title } organizationType organizationTypeDisplay } status } } } } ''' user = UserFactory.create() normal_user = UserFactory.create() another_user = UserFactory.create() af = AnalysisFrameworkFactory.create() private_af = AnalysisFrameworkFactory.create(is_private=True) private_af_2 = AnalysisFrameworkFactory.create(is_private=True) private_af_w_membership = AnalysisFrameworkFactory.create(is_private=True) private_af_w_membership.add_member(user) public_project = ProjectFactory.create(title='Public Project 101', analysis_framework=af) private_project = ProjectFactory.create(title='Private Project 101', analysis_framework=private_af, is_private=True) public_project.add_member(user, role=self.project_role_owner) private_project.add_member(user, role=self.project_role_owner) public_project.add_member(normal_user) org1 = OrganizationFactory.create() public_minput = dict( title=public_project.title, analysisFramework=str(public_project.analysis_framework.id), isPrivate=False, organizations=[ dict( organization=str(org1.pk), organizationType=self.genum(ProjectOrganization.Type.LEAD_ORGANIZATION), ), ], ) private_minput = dict( title=private_project.title, analysisFramework=str(private_project.analysis_framework.id), isPrivate=True, organizations=[ dict( organization=str(org1.pk), organizationType=self.genum(ProjectOrganization.Type.LEAD_ORGANIZATION), ), ], ) def _query_check(project, minput, **kwargs): return self.query_check( query, minput=minput, mnested=['project'], variables={'projectId': str(project.pk)}, **kwargs, ) def _public_query_check(**kwargs): return _query_check(public_project, public_minput, **kwargs) def _private_query_check(**kwargs): return _query_check(private_project, private_minput, **kwargs) # ---------- Without login _public_query_check(assert_for_error=True) _private_query_check(assert_for_error=True) # ---------- With login (non member) self.force_login(another_user) _public_query_check(assert_for_error=True) _private_query_check(assert_for_error=True) # ---------- With login (member with low access) self.force_login(normal_user) _public_query_check(assert_for_error=True) _private_query_check(assert_for_error=True) # ---------- With login (member with high access) self.force_login(user) _public_query_check(okay=True) _private_query_check(okay=True) # WITH ACCESS # ----- isPrivate attribute # [changing private status) [public project] public_minput['isPrivate'] = True self.assertMatchSnapshot(_public_query_check(okay=False), 'public-project:is-private-change-error') public_minput['isPrivate'] = False # [changing private status) [public project] private_minput['isPrivate'] = False self.assertMatchSnapshot(_private_query_check(okay=False), 'private-project:is-private-change-error') private_minput['isPrivate'] = True # ----- AF attribute # [changing private status) [public project] public_minput['analysisFramework'] = str(private_af.id) self.assertMatchSnapshot(_public_query_check(okay=False), 'public-project:private-af') public_minput['analysisFramework'] = str(private_af_w_membership.id) self.assertMatchSnapshot(_public_query_check(okay=False), 'public-project:private-af-with-membership') public_minput['analysisFramework'] = str(public_project.analysis_framework_id) # [changing private status) [private project] private_minput['analysisFramework'] = str(private_af_2.id) self.assertMatchSnapshot(_private_query_check(okay=False), 'private-project:private-af') private_minput['analysisFramework'] = str(private_af_w_membership.id) _private_query_check(okay=True) private_minput['analysisFramework'] = str(private_project.analysis_framework_id)
def test_project_region_action_mutation(self): query = ''' mutation MyMutation ($projectId: ID!, $regionsToAdd: [ID!], $regionsToRemove: [ID!]) { project(id: $projectId) { projectRegionBulk(regionsToAdd: $regionsToAdd, regionsToRemove: $regionsToRemove) { result { id title } deletedResult { id title } } } } ''' user = UserFactory.create() normal_user = UserFactory.create() another_user = UserFactory.create() af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(title='Project 101', analysis_framework=af) project.add_member(user, role=self.project_role_owner) project.add_member(normal_user) region_public = RegionFactory.create(title='public-region') region_private = RegionFactory.create(title='private-region', public=False) region_private_owner = RegionFactory.create(title='private-region-owner', public=False, created_by=user) # Region with project membership # -- Normal region_private_with_membership = RegionFactory.create(title='private-region-with-membership', public=False) another_project_for_membership = ProjectFactory.create() another_project_for_membership.regions.add(region_private_with_membership) another_project_for_membership.add_member(user, role=self.project_role_admin) # -- Admin region_private_with_membership_admin = RegionFactory.create(title='private-region-with-membership', public=False) another_project_for_membership_admin = ProjectFactory.create() another_project_for_membership_admin.regions.add(region_private_with_membership_admin) another_project_for_membership_admin.add_member(user, role=self.project_role_admin) def _query_check(add, remove, **kwargs): return self.query_check( query, mnested=['project'], variables={ 'projectId': str(project.pk), 'regionsToAdd': add, 'regionsToRemove': remove, }, **kwargs, ) # ---------- Without login _query_check([], [], assert_for_error=True) # ---------- With login (non member) self.force_login(another_user) _query_check([], [], assert_for_error=True) # ---------- With login (member + low access) self.force_login(normal_user) _query_check([], [], assert_for_error=True) # ---------- With login (member with high access) self.force_login(user) # Simple checkup response = _query_check([], []) self.assertEqual(response['data']['project']['projectRegionBulk'], { 'deletedResult': [], 'result': [], }) # Add response = _query_check( [ str(region_public.pk), str(region_private.pk), str(region_private_owner.pk), str(region_private_with_membership.pk), ], [], ) self.assertEqual(response['data']['project']['projectRegionBulk'], { 'deletedResult': [], 'result': [ dict(id=str(region_public.pk), title=region_public.title), dict(id=str(region_private_owner.pk), title=region_private_owner.title), dict(id=str(region_private_with_membership.pk), title=region_private_with_membership.title), ], }) self.assertEqual( list(project.regions.values_list('id', flat=True).order_by('id')), [ region_public.pk, region_private_owner.pk, region_private_with_membership.pk, ] ) # Delete response = _query_check( [], [ str(region_public.pk), str(region_private.pk), str(region_private_owner.pk), str(region_private_with_membership.pk), ], ) self.assertEqual(response['data']['project']['projectRegionBulk'], { 'deletedResult': [ dict(id=str(region_public.pk), title=region_public.title), dict(id=str(region_private_owner.pk), title=region_private_owner.title), dict(id=str(region_private_with_membership.pk), title=region_private_with_membership.title), ], 'result': [], }) self.assertEqual(list(project.regions.values_list('id', flat=True).order_by('id')), [])
def test_public_projects(self): query = ''' query MyQuery { publicProjects (ordering: "id") { page pageSize totalCount results { id title description createdAt analysisFrameworkTitle organizationsTitle regionsTitle numberOfEntries numberOfLeads numberOfUsers } } } ''' # Lets create some analysis_framework(private + publice) public_analysis_framework = AnalysisFrameworkFactory.create( is_private=False, title='Public Analysis Framework Title') private_analysis_framework = AnalysisFrameworkFactory.create( title='Private Analysis Framework Title', is_private=True) # lets create some regions(private + public) public_region = RegionFactory.create(public=True, title='Public Region') private_region = RegionFactory.create(public=False, title='Private Region') public_project1 = ProjectFactory.create( analysis_framework=public_analysis_framework, regions=[public_region]) public_project2 = ProjectFactory.create( analysis_framework=public_analysis_framework, regions=[private_region]) public_project3 = ProjectFactory.create( analysis_framework=private_analysis_framework, regions=[public_region]) public_project4 = ProjectFactory.create( analysis_framework=private_analysis_framework, regions=[public_region]) private_project = ProjectFactory.create(is_private=True) content = self.query_check(query) self.assertEqual(content['data']['publicProjects']['totalCount'], 4, content) self.assertListIds(content['data']['publicProjects']['results'], [ public_project1, public_project2, public_project3, public_project4 ], content) # some checks for analysis_framework private and public self.assertEqual( content['data']['publicProjects']['results'][0] ['analysisFrameworkTitle'], 'Public Analysis Framework Title', content) self.assertEqual( content['data']['publicProjects']['results'][2] ['analysisFrameworkTitle'], None, content) # some check for regions private and public self.assertEqual( content['data']['publicProjects']['results'][2]['regionsTitle'], 'Public Region', content) self.assertEqual( content['data']['publicProjects']['results'][1]['regionsTitle'], None, content) # make sure private projects are not visible here self.assertNotListIds(content['data']['publicProjects']['results'], [private_project], content)
def test_projects_viz_configuration_update(self): query = ''' mutation MyMutation($id: ID!, $input: ProjectVizConfigurationInputType!) { project(id: $id) { projectVizConfigurationUpdate(data: $input) { ok errors result { dataUrl modifiedAt publicShare publicUrl status } } } } ''' normal_user = UserFactory.create() admin_user = UserFactory.create() member_user = UserFactory.create() af = AnalysisFrameworkFactory.create() project = ProjectFactory.create(analysis_framework=af) self.set_project_viz_configuration(project) project.add_member(admin_user, role=self.project_role_admin) project.add_member(member_user, role=self.project_role_member) minput = dict(action=None) def _query_check(**kwargs): return self.query_check( query, minput=minput, mnested=['project'], variables={'id': project.id}, **kwargs, ) Action = ProjectStats.Action _generate_project_viz_stats(project.pk) # Check permission for token generation for action in [Action.NEW, Action.OFF, Action.NEW, Action.ON]: for user, assertLogic in [ (normal_user, self.assert_403), (member_user, self.assert_403), (admin_user, self.assert_200), ]: self.force_login(user) current_stats = project.project_stats minput['action'] = self.genum(action) if assertLogic == self.assert_200: content = _query_check(okay=True) else: _query_check(assert_for_error=True) continue response = content['data']['project']['projectVizConfigurationUpdate']['result'] if assertLogic == self.assert_200: if action == 'new': assert response['publicUrl'] != current_stats.token # Logout and check if response is okay self.client.logout() rest_response = self.client.get(f"{response['publicUrl']}?format=json") self.assert_200(rest_response) elif action == 'on': assert ( response['publicUrl'] is not None ) or ( response['publicUrl'] == current_stats.token ) # Logout and check if response is not okay self.client.logout() rest_response = self.client.get(f"{response['publicUrl']}?format=json") self.assert_200(rest_response) elif action == 'off': assert ( response['publicUrl'] is not None ) or ( response['publicUrl'] == current_stats.token ) # Logout and check if response is not okay self.client.logout() rest_response = self.client.get(f"{response['publicUrl']}?format=json") self.assert_403(rest_response)
def test_analysis_framework_detail_query(self): query = ''' query MyQuery ($id: ID!) { analysisFramework(id: $id) { id currentUserRole description isPrivate title allowedPermissions secondaryTagging { id key title widgetId order properties version } primaryTagging { id title order tooltip widgets { id key title version widgetId order properties } } members { id joinedAt addedBy { id displayName } member { id displayName } role { id title } } visibleProjects { id title } } } ''' user = UserFactory.create() another_user = UserFactory.create() af = AnalysisFrameworkFactory.create() af.add_member(another_user) project = ProjectFactory.create(analysis_framework=af, is_private=False) private_project = ProjectFactory.create(analysis_framework=af, is_private=True) def _query_check(**kwargs): return self.query_check(query, variables={'id': af.pk}, **kwargs) # Without login _query_check(assert_for_error=True) # With login self.force_login(user) # Should work for normal AF response = _query_check()['data']['analysisFramework'] self.assertEqual(len(response['secondaryTagging']), 0, response) self.assertEqual(len(response['primaryTagging']), 0, response) self.assertEqual(len(response['visibleProjects']), 1, response) self.assertListIds(response['visibleProjects'], [project], response) # lets add member to the private_project private_project.add_member(user) response = _query_check()['data']['analysisFramework'] self.assertEqual(len(response['visibleProjects']), 2, response) self.assertListIds(response['visibleProjects'], [project, private_project], response) # Let's add some widgets and sections sequence = factory.Sequence(lambda n: n) rsequence = factory.Sequence(lambda n: 20 - n) # Primary Tagging for order, widget_count, tooltip, _sequence in ( (3, 2, 'Some tooltip info 101', sequence), (1, 3, 'Some tooltip info 102', rsequence), (2, 4, 'Some tooltip info 103', sequence), ): section = SectionFactory.create(analysis_framework=af, order=order, tooltip=tooltip) WidgetFactory.create_batch(widget_count, analysis_framework=af, section=section, order=_sequence) WidgetFactory.reset_sequence() # Secondary Tagging WidgetFactory.create_batch(4, analysis_framework=af, order=rsequence) # Let's save/compare snapshot (without membership) response = _query_check() self.assertMatchSnapshot(response, 'without-membership') # Let's save/compare snapshot (with membership) af.add_member(user) response = _query_check() self.assertMatchSnapshot(response, 'with-membership')
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_recent_analysis_framework(self): # NOTE: This test includes the recent_analysis_framework based on project and source query = ''' query MyQuery { projectExploreStats { topActiveFrameworks { analysisFrameworkId analysisFrameworkTitle projectCount sourceCount } } } ''' # lets create some analysis_framework analysis_framework1 = AnalysisFrameworkFactory.create() analysis_framework2 = AnalysisFrameworkFactory.create() analysis_framework3 = AnalysisFrameworkFactory.create() analysis_framework4 = AnalysisFrameworkFactory.create() analysis_framework5 = AnalysisFrameworkFactory.create() analysis_framework6 = AnalysisFrameworkFactory.create() project1 = ProjectFactory.create( analysis_framework=analysis_framework1) project2 = ProjectFactory.create( analysis_framework=analysis_framework2) project3 = ProjectFactory.create( analysis_framework=analysis_framework1) project4 = ProjectFactory.create( analysis_framework=analysis_framework3) project5 = ProjectFactory.create( analysis_framework=analysis_framework4) project6 = ProjectFactory.create( analysis_framework=analysis_framework3) project7 = ProjectFactory.create( analysis_framework=analysis_framework1) project8 = ProjectFactory.create( analysis_framework=analysis_framework5) project9 = ProjectFactory.create( analysis_framework=analysis_framework6) # some lead for the project LeadFactory.create_batch(15, project=project1) LeadFactory.create_batch(13, project=project2) LeadFactory.create_batch(20, project=project3) LeadFactory.create_batch(20, project=project4) LeadFactory.create_batch(20, project=project5) LeadFactory.create_batch(30, project=project6) LeadFactory.create_batch(30, project=project7) LeadFactory.create_batch(30, project=project8) LeadFactory.create_batch(30, project=project9) content = self.query_check(query) self.assertEqual( len(content['data']['projectExploreStats']['topActiveFrameworks']), 5, content) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][0] ['analysisFrameworkId'], str(analysis_framework1.id)) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][0] ['projectCount'], 3) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][0] ['sourceCount'], 65) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][1] ['analysisFrameworkId'], str(analysis_framework3.id)) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][1] ['projectCount'], 2) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][2] ['analysisFrameworkId'], str(analysis_framework5.id)) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][3] ['analysisFrameworkId'], str(analysis_framework6.id)) self.assertEqual( content['data']['projectExploreStats']['topActiveFrameworks'][4] ['analysisFrameworkId'], str(analysis_framework4.id))
def setUp(self): super().setUp() self.entries_query = ''' query MyQuery ($projectId: ID! $filterableData: [EntryFilterDataType!]) { project(id: $projectId) { entries (filterableData: $filterableData) { results { id } } } } ''' # AnalysisFramework setup self.af = AnalysisFrameworkFactory.create() region = RegionFactory.create() # -- Admin levels admin_level1 = AdminLevelFactory.create(region=region, level=1) admin_level2 = AdminLevelFactory.create(region=region, level=2) admin_level3 = AdminLevelFactory.create(region=region, level=3) # -- GeoAreas (with parent relations) self.geo_area_1 = GeoAreaFactory.create(admin_level=admin_level1) self.geo_area_2_1 = GeoAreaFactory.create(admin_level=admin_level2, parent=self.geo_area_1) self.geo_area_2_2 = GeoAreaFactory.create(admin_level=admin_level2, parent=self.geo_area_1) self.geo_area_2_3 = GeoAreaFactory.create(admin_level=admin_level2, parent=self.geo_area_1) self.geo_area_3_1 = GeoAreaFactory.create(admin_level=admin_level3, parent=self.geo_area_2_1) self.geo_area_3_2 = GeoAreaFactory.create(admin_level=admin_level3, parent=self.geo_area_2_2) self.geo_area_3_3 = GeoAreaFactory.create(admin_level=admin_level3, parent=self.geo_area_2_3) # For LIST Filter self.widget_multiselect = WidgetFactory.create( analysis_framework=self.af, key='multiselect-widget-101', title='Multiselect Widget', widget_id=Widget.WidgetType.MULTISELECT, properties={ 'data': { 'options': [ { 'key': 'key-101', 'label': 'Key label 101' }, { 'key': 'key-102', 'label': 'Key label 102' }, { 'key': 'key-103', 'label': 'Key label 103' }, { 'key': 'key-104', 'label': 'Key label 104' }, ] }, }, ) # For Number Filter self.widget_number = WidgetFactory.create( analysis_framework=self.af, key='number-widget-101', title='Number Widget', widget_id=Widget.WidgetType.NUMBER, ) # For INTERSECTS Filter self.widget_date_range = WidgetFactory.create( analysis_framework=self.af, key='date-range-widget-101', title='DateRange Widget', widget_id=Widget.WidgetType.DATE_RANGE, ) # For TEXT Filter self.widget_text = WidgetFactory.create( analysis_framework=self.af, key='text-widget-101', title='Text Widget', widget_id=Widget.WidgetType.TEXT, ) self.widget_geo = WidgetFactory.create( analysis_framework=self.af, key='geo-widget-101', title='GEO Widget', widget_id=Widget.WidgetType.GEO, ) self.project = ProjectFactory.create(analysis_framework=self.af) self.project.regions.add(region) # User with role self.user = UserFactory.create() self.project.add_member(self.user, role=self.project_role_reader) self.lead1 = LeadFactory.create(project=self.project) self.lead2 = LeadFactory.create(project=self.project) self.lead3 = LeadFactory.create(project=self.project) self.entry_create_kwargs = dict(project=self.project, analysis_framework=self.af)
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_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_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}, )