Exemple #1
0
    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']
        }
Exemple #2
0
    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
Exemple #3
0
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())
Exemple #4
0
    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
Exemple #5
0
    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
Exemple #6
0
 def test_with_team_members(self, data_flow_api_client):
     """Test that endpoint returns with expected data for a single project with team members"""
     project = InvestmentProjectTeamMemberFactory().investment_project
     response = data_flow_api_client.get(self.view_url)
     assert response.status_code == status.HTTP_200_OK
     response_results = response.json()['results']
     assert len(response_results) == 1
     result = response_results[0]
     expected_result = get_expected_data_from_project(project)
     assert result == expected_result
Exemple #7
0
    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(self):
        """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(self):
        """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
Exemple #10
0
def team_member():
    """Team member fixture"""
    yield InvestmentProjectTeamMemberFactory(role='Co-ordinator')
Exemple #11
0
    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)

        InvestmentProjectFactory(
            name='project for subsidiary',
            investor_company=CompanyFactory(
                global_headquarters=CompanyFactory(
                    one_list_tier_id=OneListTier.objects.first().id,
                    one_list_account_owner=AdviserFactory(),
                ),
            ),
        )

        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,
                'Investor company town or city': project.investor_company.address_town,
                'Country of origin':
                    get_attr_or_none(project, 'investor_company.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["investmentproject"]}'
                    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': self._get_global_account_manager_name(project),
                'Project assurance adviser':
                    get_attr_or_none(project, 'project_assurance_adviser.name'),
                'Other team members': join_attr_values(project.team_members.all(), 'adviser.name'),
                'Delivery partners': join_attr_values(project.delivery_partners.all()),
                'Possible UK regions': join_attr_values(project.uk_region_locations.all()),
                'Actual UK regions': join_attr_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'),
                'Likelihood to land': get_attr_or_none(project, 'likelihood_to_land.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,
                'FDI type': project.fdi_type,
                'Foreign equity investment': project.foreign_equity_investment,
                'GVA multiplier': get_attr_or_none(project, 'gva_multiplier.multiplier'),
                'GVA': project.gross_value_added,
            }
            for project in sorted_projects
        ]

        expected_rows = format_csv_data(expected_row_data)

        # item is an ordered dict so is cast to a dict to make the comparison easier to
        # interpret in the event of the assert actual_rows == expected_rows failing.
        actual_rows = [dict(item) for item in reader]

        # Support for ordering was added to StringAgg in Django 2.2. However, it is not
        # currently used due to https://code.djangoproject.com/ticket/30315. While that
        # remains the case, our 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