def test_non_restricted_user_can_see_all_projects(self, setup_es, permissions): """Test that normal users can see all projects.""" team = TeamFactory() team_others = TeamFactory() adviser_1 = AdviserFactory(dit_team_id=team.id) adviser_2 = AdviserFactory(dit_team_id=team_others.id) request_user = create_test_user( permission_codenames=permissions, dit_team=team, ) api_client = self.create_api_client(user=request_user) iproject_1 = InvestmentProjectFactory() iproject_2 = InvestmentProjectFactory() InvestmentProjectTeamMemberFactory(adviser=adviser_1, investment_project=iproject_1) InvestmentProjectTeamMemberFactory(adviser=adviser_2, investment_project=iproject_2) setup_es.indices.refresh() url = reverse('api-v3:search:investment_project') response = api_client.post(url, {}) assert response.status_code == status.HTTP_200_OK response_data = response.json() assert response_data['count'] == 2 assert {str(iproject_1.pk), str(iproject_2.pk)} == { result['id'] for result in response_data['results'] }
def test_search_adviser_filter(self, setup_es): """Tests the adviser filter.""" adviser = AdviserFactory() # Non-matching projects project_other_1 = InvestmentProjectFactory() InvestmentProjectTeamMemberFactory(investment_project=project_other_1) InvestmentProjectTeamMemberFactory(investment_project=project_other_1) InvestmentProjectFactory() # Matching projects project_1 = InvestmentProjectFactory() InvestmentProjectTeamMemberFactory(adviser=adviser, investment_project=project_1) InvestmentProjectTeamMemberFactory(investment_project=project_1) project_2 = InvestmentProjectFactory(created_by=adviser) project_3 = InvestmentProjectFactory(client_relationship_manager=adviser) project_4 = InvestmentProjectFactory(project_manager=adviser) project_5 = InvestmentProjectFactory(project_assurance_adviser=adviser) # Should only be returned once project_6 = InvestmentProjectFactory( created_by=adviser, client_relationship_manager=adviser, project_assurance_adviser=adviser, project_manager=adviser, ) InvestmentProjectTeamMemberFactory(adviser=adviser, investment_project=project_6) setup_es.indices.refresh() url = reverse('api-v3:search:investment_project') response = self.api_client.post( url, data={ 'adviser': adviser.pk, }, ) assert response.status_code == status.HTTP_200_OK response_data = response.json() assert response_data['count'] == 6 results = response_data['results'] expected_ids = { str(project_1.pk), str(project_2.pk), str(project_3.pk), str(project_4.pk), str(project_5.pk), str(project_6.pk), } assert {result['id'] for result in results} == expected_ids
def test_global_restricted_users_cannot_see_other_teams_projects(self, setup_es): """ Automatic filter to see only associated IP for a specific (leps) user """ team = TeamFactory() team_other = TeamFactory() adviser_other = AdviserFactory(dit_team_id=team_other.id) adviser_same_team = AdviserFactory(dit_team_id=team.id) request_user = create_test_user( permission_codenames=['view_associated_investmentproject'], dit_team=team, ) api_client = self.create_api_client(user=request_user) project_other = InvestmentProjectFactory() project_1 = InvestmentProjectFactory() project_2 = InvestmentProjectFactory(created_by=adviser_same_team) project_3 = InvestmentProjectFactory(client_relationship_manager=adviser_same_team) project_4 = InvestmentProjectFactory(project_manager=adviser_same_team) project_5 = InvestmentProjectFactory(project_assurance_adviser=adviser_same_team) InvestmentProjectTeamMemberFactory(adviser=adviser_other, investment_project=project_other) InvestmentProjectTeamMemberFactory(adviser=adviser_same_team, investment_project=project_1) setup_es.indices.refresh() url = reverse('api-v3:search:basic') response = api_client.get( url, data={ 'term': '', 'entity': 'investment_project', }, ) assert response.status_code == status.HTTP_200_OK response_data = response.json() assert response_data['count'] == 5 results = response_data['results'] expected_ids = { str(project_1.id), str(project_2.id), str(project_3.id), str(project_4.id), str(project_5.id), } assert {result['id'] for result in results} == expected_ids
def test_restricted_users_cannot_see_other_teams_projects(self, setup_es): """Test that restricted users cannot see other teams' projects in the export.""" team = TeamFactory() team_other = TeamFactory() adviser_other = AdviserFactory(dit_team_id=team_other.id) adviser_same_team = AdviserFactory(dit_team_id=team.id) request_user = create_test_user( permission_codenames=( InvestmentProjectPermission.view_associated, InvestmentProjectPermission.export, ), dit_team=team, ) api_client = self.create_api_client(user=request_user) project_other = InvestmentProjectFactory() team_projects = [ InvestmentProjectFactory(), InvestmentProjectFactory(created_by=adviser_same_team), InvestmentProjectFactory(client_relationship_manager=adviser_same_team), InvestmentProjectFactory(project_manager=adviser_same_team), InvestmentProjectFactory(project_assurance_adviser=adviser_same_team), ] InvestmentProjectTeamMemberFactory(adviser=adviser_other, investment_project=project_other) InvestmentProjectTeamMemberFactory( adviser=adviser_same_team, investment_project=team_projects[0], ) setup_es.indices.refresh() url = reverse('api-v3:search:investment_project-export') response = api_client.post(url, {}) assert response.status_code == status.HTTP_200_OK response_text = response.getvalue().decode('utf-8-sig') reader = DictReader(StringIO(response_text)) actual_rows = [dict(item) for item in reader] assert len(actual_rows) == 5 expected_names = {project.name for project in team_projects} assert {row['Project name'] for row in actual_rows} == expected_names
def test_restricted_users_cannot_see_other_teams_projects(self, setup_es): """Test that restricted users cannot see other teams' projects.""" url = reverse('api-v3:search:investment_project') team = TeamFactory() team_other = TeamFactory() adviser_other = AdviserFactory(dit_team_id=team_other.id) adviser_same_team = AdviserFactory(dit_team_id=team.id) request_user = create_test_user( permission_codenames=['view_associated_investmentproject'], dit_team=team, ) api_client = self.create_api_client(user=request_user) project_other = InvestmentProjectFactory() project_1 = InvestmentProjectFactory() project_2 = InvestmentProjectFactory(created_by=adviser_same_team) project_3 = InvestmentProjectFactory(client_relationship_manager=adviser_same_team) project_4 = InvestmentProjectFactory(project_manager=adviser_same_team) project_5 = InvestmentProjectFactory(project_assurance_adviser=adviser_same_team) InvestmentProjectTeamMemberFactory(adviser=adviser_other, investment_project=project_other) InvestmentProjectTeamMemberFactory(adviser=adviser_same_team, investment_project=project_1) setup_es.indices.refresh() response = api_client.post(url, {}) assert response.status_code == status.HTTP_200_OK response_data = response.json() assert response_data['count'] == 5 results = response_data['results'] expected_ids = { str(project_1.id), str(project_2.id), str(project_3.id), str(project_4.id), str(project_5.id), } assert {result['id'] for result in results} == expected_ids
def test_team_member_list_update_remove_all(): """Tests removing all team members.""" project = InvestmentProjectFactory() team_members = InvestmentProjectTeamMemberFactory.create_batch( 2, investment_project=project, ) child_serializer = IProjectTeamMemberSerializer() serializer = IProjectTeamMemberListSerializer(child=child_serializer) assert serializer.update(team_members, []) == [] assert project.team_members.count() == 0
def test_team_member_list_update_mixed_changes(): """Tests making mixed changes to team members.""" project = InvestmentProjectFactory() team_members = InvestmentProjectTeamMemberFactory.create_batch( 2, investment_project=project, role='old role', ) adviser = AdviserFactory() new_team_member_data = [ { 'investment_project': project, 'adviser': team_members[1].adviser, 'role': 'new role', }, { 'investment_project': project, 'adviser': adviser, 'role': 'new team member', }, ] child_serializer = IProjectTeamMemberSerializer() serializer = IProjectTeamMemberListSerializer(child=child_serializer) updated_team_members = serializer.update(team_members, new_team_member_data) assert len(updated_team_members) == 2 assert updated_team_members[0].adviser == new_team_member_data[0][ 'adviser'] assert updated_team_members[0].role == new_team_member_data[0]['role'] assert updated_team_members[1].adviser == new_team_member_data[1][ 'adviser'] assert updated_team_members[1].role == new_team_member_data[1]['role'] assert project.team_members.count() == 2
def team_member(): """Team member fixture""" yield InvestmentProjectTeamMemberFactory(role='Co-ordinator')
def test_export(self, setup_es, request_sortby, orm_ordering): """Test export of investment project search results.""" url = reverse('api-v3:search:investment_project-export') InvestmentProjectFactory() InvestmentProjectFactory(cdms_project_code='cdms-code') VerifyWinInvestmentProjectFactory() won_project = WonInvestmentProjectFactory() InvestmentProjectTeamMemberFactory.create_batch(3, investment_project=won_project) setup_es.indices.refresh() data = {} if request_sortby: data['sortby'] = request_sortby with freeze_time('2018-01-01 11:12:13'): response = self.api_client.post(url, data=data) assert response.status_code == status.HTTP_200_OK assert parse_header(response.get('Content-Disposition')) == ( 'attachment', {'filename': 'Data Hub - Investment projects - 2018-01-01-11-12-13.csv'}, ) sorted_projects = InvestmentProject.objects.order_by(orm_ordering, 'pk') response_text = response.getvalue().decode('utf-8-sig') reader = DictReader(StringIO(response_text)) assert reader.fieldnames == list(SearchInvestmentExportAPIView.field_titles.values()) expected_row_data = [ { 'Date created': project.created_on, 'Project reference': project.project_code, 'Project name': project.name, 'Investor company': project.investor_company.name, 'Country of origin': get_attr_or_none(project, 'investor_company.registered_address_country.name'), 'Investment type': get_attr_or_none(project, 'investment_type.name'), 'Status': project.get_status_display(), 'Stage': get_attr_or_none(project, 'stage.name'), 'Link': f'{settings.DATAHUB_FRONTEND_URL_PREFIXES["investment-project"]}' f'/{project.pk}', 'Actual land date': project.actual_land_date, 'Estimated land date': project.estimated_land_date, 'FDI value': get_attr_or_none(project, 'fdi_value.name'), 'Sector': get_attr_or_none(project, 'sector.name'), 'Date of latest interaction': None, 'Project manager': get_attr_or_none(project, 'project_manager.name'), 'Client relationship manager': get_attr_or_none(project, 'client_relationship_manager.name'), 'Global account manager': get_attr_or_none(project, 'investor_company.one_list_account_owner.name'), 'Project assurance adviser': get_attr_or_none(project, 'project_assurance_adviser.name'), 'Other team members': _join_values(project.team_members.all(), 'adviser.name'), 'Delivery partners': _join_values(project.delivery_partners.all()), 'Possible UK regions': _join_values(project.uk_region_locations.all()), 'Actual UK regions': _join_values(project.actual_uk_regions.all()), 'Specific investment programme': get_attr_or_none(project, 'specific_programme.name'), 'Referral source activity': get_attr_or_none(project, 'referral_source_activity.name'), 'Referral source activity website': get_attr_or_none(project, 'referral_source_activity_website.name'), 'Total investment': project.total_investment, 'New jobs': project.number_new_jobs, 'Average salary of new jobs': get_attr_or_none(project, 'average_salary.name'), 'Safeguarded jobs': project.number_safeguarded_jobs, 'Level of involvement': get_attr_or_none(project, 'level_of_involvement.name'), 'R&D budget': project.r_and_d_budget, 'Associated non-FDI R&D project': project.non_fdi_r_and_d_budget, 'New to world tech': project.new_tech_to_uk, } for project in sorted_projects ] expected_rows = format_csv_data(expected_row_data) actual_rows = [dict(item) for item in reader] # Support for ordering will be added to StringAgg in Django 2.2. In the meantime, # StringAgg fields are unordered and we use this workaround to compare them. unordered_fields = ( 'Other team members', 'Delivery partners', 'Possible UK regions', 'Actual UK regions', ) for row in chain(actual_rows, expected_rows): for field in unordered_fields: row[field] = frozenset(row[field].split(', ')) assert actual_rows == expected_rows
def test_associated_advisers_team_members(): """Tests that get_associated_advisers() includes team members.""" adviser = AdviserFactory() project = InvestmentProjectFactory() InvestmentProjectTeamMemberFactory(investment_project=project, adviser=adviser) assert adviser in tuple(project.get_associated_advisers())