Пример #1
0
def _company_factory(num_interactions, num_contacts, num_orders):
    """Factory for a company that has companies, interactions and OMIS orders."""
    company = CompanyFactory()
    ContactFactory.create_batch(num_contacts, company=company)
    CompanyInteractionFactory.create_batch(num_interactions, company=company)
    OrderFactory.create_batch(num_orders, company=company)
    return company
Пример #2
0
    def test_filter_by_communication_channel(self, setup_es):
        """Tests filtering interaction by interaction type."""
        communication_channels = list(
            CommunicationChannel.objects.order_by('?')[:2])
        CompanyInteractionFactory.create_batch(
            5,
            communication_channel=communication_channels[0],
        )
        CompanyInteractionFactory.create_batch(
            5,
            communication_channel=communication_channels[1],
        )
        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'original_query': '',
            'communication_channel': communication_channels[1].pk,
        }
        response = self.api_client.post(url, request_data)

        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()

        assert response_data['count'] == 5

        results = response_data['results']
        result_ids = {
            result['communication_channel']['id']
            for result in results
        }
        assert result_ids == {str(communication_channels[1].pk)}
Пример #3
0
def test_interaction_ordering(api_client):
    """
    Test that the interactions are ordered by ('modified_on', 'pk')
    """
    interactions = []

    with freeze_time() as frozen_datetime:
        interactions += CompanyInteractionFactory.create_batch(2)

        frozen_datetime.tick(datetime.timedelta(microseconds=1))
        interactions += CompanyInteractionFactory.create_batch(8)

        frozen_datetime.tick(datetime.timedelta(seconds=1, microseconds=1))
        response = hawk.get(api_client, get_url('api-v3:activity-stream:interactions'))

    assert response.status_code == status.HTTP_200_OK

    sorted_interaction_ids = [
        f'dit:DataHubInteraction:{obj.pk}'
        for obj in sorted(interactions, key=lambda obj: (obj.modified_on, obj.pk))
    ]
    response_interaction_ids = [
        item['object']['id']
        for item in response.json()['orderedItems']
    ]
    assert sorted_interaction_ids == response_interaction_ids
Пример #4
0
    def test_filter_by_dit_adviser_name(self, setup_es):
        """Tests filtering interaction by dit adviser name."""
        advisers = AdviserFactory.create_batch(10)
        CompanyInteractionFactory.create_batch(
            len(advisers),
            dit_adviser=factory.Iterator(advisers),
        )

        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'dit_adviser_name': advisers[5].name,
        }
        response = self.api_client.post(url, request_data)

        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()

        assert response_data['count'] > 0

        results = response_data['results']
        # multiple records can match our filter, let's make sure at least one is exact match
        assert any(result['dit_adviser']['id'] == str(advisers[5].id)
                   for result in results)
        assert any(result['dit_adviser']['name'] == advisers[5].name
                   for result in results)
Пример #5
0
    def test_filter_by_service(self, setup_es):
        """Tests filtering interaction by service."""
        CompanyInteractionFactory.create_batch(
            5,
            service_id=constants.Service.trade_enquiry.value.id,
        )
        service_id = constants.Service.account_management.value.id
        CompanyInteractionFactory.create_batch(
            5,
            service_id=service_id,
        )
        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'service': service_id,
        }
        response = self.api_client.post(url, request_data)

        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()

        assert response_data['count'] == 5

        results = response_data['results']
        result_ids = {result['service']['id'] for result in results}
        assert result_ids == {str(service_id)}
Пример #6
0
def company_with_interactions_and_contacts_factory():
    """
    Factory for a company with interactions (and hence contacts, as interactions have contacts).
    """
    company = CompanyFactory()
    CompanyInteractionFactory.create_batch(3, company=company)
    return company
Пример #7
0
    def test_filter_by_dit_adviser_id(self, setup_es):
        """Tests filtering interaction by dit adviser id."""
        advisers = AdviserFactory.create_batch(10)
        CompanyInteractionFactory.create_batch(
            len(advisers),
            dit_adviser=factory.Iterator(advisers),
        )

        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'dit_adviser': advisers[5].id,
        }
        response = self.api_client.post(url, request_data)

        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()

        assert response_data['count'] == 1

        results = response_data['results']

        assert results[0]['dit_adviser']['id'] == str(advisers[5].id)
        assert results[0]['dit_adviser']['name'] == advisers[5].name
    def test_restricted_user_can_only_list_associated_interactions(self):
        """
        Test that a restricted user can only list interactions for associated investment
        projects.
        """
        creator = AdviserFactory()
        requester = create_test_user(
            permission_codenames=[InteractionPermission.view_associated_investmentproject],
            dit_team=creator.dit_team,
        )
        api_client = self.create_api_client(user=requester)

        company = CompanyFactory()
        non_associated_project = InvestmentProjectFactory()
        associated_project = InvestmentProjectFactory(created_by=creator)

        CompanyInteractionFactory.create_batch(3, company=company)
        CompanyInteractionFactory.create_batch(
            3, investment_project=non_associated_project,
        )
        associated_project_interactions = CompanyInteractionFactory.create_batch(
            2, investment_project=associated_project,
        )

        url = reverse('api-v3:interaction:collection')
        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert response_data['count'] == 2
        actual_ids = {i['id'] for i in response_data['results']}
        expected_ids = {str(i.id) for i in associated_project_interactions}
        assert actual_ids == expected_ids
Пример #9
0
    def test_filtered_by_investment_project(self):
        """List of interactions filtered by investment project"""
        contact = ContactFactory()
        project = InvestmentProjectFactory()
        company = CompanyFactory()

        CompanyInteractionFactory.create_batch(3, contacts=[contact])
        CompanyInteractionFactory.create_batch(3, company=company)
        project_interactions = CompanyInteractionFactory.create_batch(
            2, investment_project=project,
        )

        url = reverse('api-v3:interaction:collection')
        response = self.api_client.get(
            url,
            data={
                'investment_project_id': project.id,
            },
        )

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert response_data['count'] == 2
        actual_ids = {i['id'] for i in response_data['results']}
        expected_ids = {str(i.id) for i in project_interactions}
        assert actual_ids == expected_ids
Пример #10
0
    def test_filter_by_kind(self, setup_es):
        """Tests filtering interaction by kind."""
        CompanyInteractionFactory.create_batch(10)
        service_deliveries = ServiceDeliveryFactory.create_batch(10)

        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'kind': Interaction.KINDS.service_delivery,
        }
        response = self.api_client.post(url, request_data)

        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()

        assert response_data['count'] == 10

        results = response_data['results']
        service_delivery_ids = {
            str(interaction.id)
            for interaction in service_deliveries
        }
        assert {result['id'] for result in results} == service_delivery_ids
Пример #11
0
def company_with_interactions_factory(num_interactions, **interaction_kwargs):
    """Factory for a company with interactions."""
    company = CompanyFactory()
    CompanyInteractionFactory.create_batch(num_interactions,
                                           company=company,
                                           **interaction_kwargs)
    return company
Пример #12
0
    def test_default_sort(self, setup_es):
        """Tests default sorting of results by date (descending)."""
        url = reverse('api-v3:search:interaction')

        dates = (
            datetime(2017, 2, 4, 13, 15, 0, tzinfo=utc),
            datetime(2017, 1, 4, 11, 23, 10, tzinfo=utc),
            datetime(2017, 9, 29, 3, 25, 15, tzinfo=utc),
            datetime(2017, 7, 5, 11, 44, 33, tzinfo=utc),
            datetime(2017, 2, 1, 18, 15, 1, tzinfo=utc),
        )
        CompanyInteractionFactory.create_batch(
            len(dates),
            date=factory.Iterator(dates),
        )
        setup_es.indices.refresh()

        response = self.api_client.post(url, {})

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()

        sorted_dates = sorted(dates, reverse=True)
        expected_dates = [d.isoformat() for d in sorted_dates]
        assert response_data['count'] == len(dates)
        assert [item['date']
                for item in response_data['results']] == expected_dates
Пример #13
0
def _company_factory(
    num_interactions=0,
    num_contacts=0,
    num_investment_projects=0,
    num_orders=0,
    num_referrals=0,
    num_company_list_items=0,
    num_pipeline_items=0,
):
    """
    Factory for a company that has companies, interactions, investment projects and OMIS orders.
    """
    company = CompanyFactory()
    ContactFactory.create_batch(num_contacts, company=company)
    CompanyInteractionFactory.create_batch(num_interactions, company=company)
    CompanyReferralFactory.create_batch(num_referrals,
                                        company=company,
                                        contact=None)
    OrderFactory.create_batch(num_orders, company=company)
    CompanyListItemFactory.create_batch(num_company_list_items,
                                        company=company)
    PipelineItemFactory.create_batch(num_pipeline_items, company=company)

    fields_iter = cycle(INVESTMENT_PROJECT_COMPANY_FIELDS)
    fields = islice(fields_iter, 0, num_investment_projects)
    InvestmentProjectFactory.create_batch(
        num_investment_projects,
        **{field: company
           for field in fields},
    )
    return company
Пример #14
0
    def test_filter_by_policy_fields(self, es_with_collector, field,
                                     field_model):
        """
        Tests filtering interactions by:
        - policy area
        - policy issue type
        """
        values = list(field_model.objects.order_by('?')[:2])
        expected_field_value = values[0]
        other_field_value = values[1]

        factory_values = [
            [expected_field_value, other_field_value],
            [expected_field_value, other_field_value],
            [expected_field_value],
            [expected_field_value],
            [expected_field_value],
        ]

        expected_interactions = CompanyInteractionFactoryWithPolicyFeedback.create_batch(
            5,
            **{field: factory.Iterator(factory_values)},
        )

        # Unrelated interactions
        CompanyInteractionFactoryWithPolicyFeedback.create_batch(
            6,
            **{field: [other_field_value]},
        )
        CompanyInteractionFactory.create_batch(6)

        es_with_collector.flush_and_refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'original_query': '',
            field: expected_field_value.pk,
        }
        response = self.api_client.post(url, request_data)
        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()
        results = response_data['results']
        expected_ids = {
            str(interaction.pk)
            for interaction in expected_interactions
        }

        assert response_data['count'] == 5
        assert Counter(value['id'] for result in results
                       for value in result[field]) == {
                           str(expected_field_value.pk): 5,
                           # two interactions had both values
                           str(other_field_value.pk): 2,
                       }
        assert {result['id'] for result in results} == expected_ids
Пример #15
0
def unrelated_objects():
    """
    Create some objects not related to a known company.

    This is used in tests below to make sure objects unrelated to the company being merged
    do not affect the counts of objects that will be affected by the merge.
    """
    ContactFactory.create_batch(2)
    CompanyInteractionFactory.create_batch(2)
    OrderFactory.create_batch(2)
    InvestmentProjectFactory.create_batch(2)
Пример #16
0
    def test_filtered_by_company(self):
        """List of interactions filtered by company"""
        company1 = CompanyFactory()
        company2 = CompanyFactory()

        CompanyInteractionFactory.create_batch(3, company=company1)
        interactions = CompanyInteractionFactory.create_batch(2, company=company2)

        url = reverse('api-v3:interaction:collection')
        response = self.api_client.get(url, data={'company_id': company2.id})

        assert response.status_code == status.HTTP_200_OK
        assert response.data['count'] == 2
        assert {i['id'] for i in response.data['results']} == {str(i.id) for i in interactions}
Пример #17
0
    def test_sector_descends_filter_for_company_interaction(
        self,
        hierarchical_sectors,
        setup_es,
        sector_level,
    ):
        """Test the sector_descends filter with company interactions."""
        num_sectors = len(hierarchical_sectors)
        sectors_ids = [sector.pk for sector in hierarchical_sectors]

        companies = CompanyFactory.create_batch(
            num_sectors,
            sector_id=factory.Iterator(sectors_ids),
        )
        company_interactions = CompanyInteractionFactory.create_batch(
            3,
            company=factory.Iterator(companies),
        )

        other_companies = CompanyFactory.create_batch(
            3,
            sector=factory.LazyFunction(lambda: random_obj_for_queryset(
                Sector.objects.exclude(pk__in=sectors_ids), )),
        )
        CompanyInteractionFactory.create_batch(
            3,
            company=factory.Iterator(other_companies),
        )

        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        body = {
            'sector_descends': hierarchical_sectors[sector_level].pk,
        }
        response = self.api_client.post(url, body)
        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()
        assert response_data['count'] == num_sectors - sector_level

        actual_ids = {
            UUID(interaction['id'])
            for interaction in response_data['results']
        }
        expected_ids = {
            interaction.pk
            for interaction in company_interactions[sector_level:]
        }
        assert actual_ids == expected_ids
Пример #18
0
    def test_filter_by_contact(self):
        """Test filtering interactions by contact (using contacts__id)."""
        contact1 = ContactFactory()
        contact2 = ContactFactory()

        CompanyInteractionFactory.create_batch(3, contacts=[contact1])
        interactions = CompanyInteractionFactory.create_batch(2, contacts=[contact1, contact2])

        url = reverse('api-v3:interaction:collection')
        response = self.api_client.get(url, data={'contacts__id': contact2.id})

        assert response.status_code == status.HTTP_200_OK
        assert response.data['count'] == 2
        assert {i['id'] for i in response.data['results']} == {str(i.id) for i in interactions}
Пример #19
0
def _company_factory(
        num_interactions=0,
        num_contacts=0,
        num_orders=0,
        num_referrals=0,
        num_company_list_items=0,
):
    """Factory for a company that has companies, interactions and OMIS orders."""
    company = CompanyFactory()
    ContactFactory.create_batch(num_contacts, company=company)
    CompanyInteractionFactory.create_batch(num_interactions, company=company)
    CompanyReferralFactory.create_batch(num_referrals, company=company, contact=None)
    OrderFactory.create_batch(num_orders, company=company)
    CompanyListItemFactory.create_batch(num_company_list_items, company=company)
    return company
Пример #20
0
    def test_filter_by_dit_participant(self, setup_es, dit_participant_field):
        """Test filtering interaction by DIT participant adviser and team IDs."""
        interactions = CompanyInteractionFactory.create_batch(
            10, dit_participants=[])
        for interaction in interactions:
            InteractionDITParticipantFactory.create_batch(
                2, interaction=interaction)

        setup_es.indices.refresh()

        interaction = choice(interactions)
        dit_participant = interaction.dit_participants.order_by('?').first()

        url = reverse('api-v3:search:interaction')
        request_data = {
            f'dit_participants__{dit_participant_field}':
            getattr(dit_participant, dit_participant_field).id,
        }
        response = self.api_client.post(url, request_data)
        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()
        assert response_data['count'] == 1

        results = response_data['results']
        assert len(results) == 1
        assert results[0]['id'] == str(interaction.pk)
Пример #21
0
def _company_factory(num_interactions, num_contacts, num_investment_projects, num_orders):
    """
    Factory for a company that has companies, interactions, investment projects and OMIS orders.
    """
    company = CompanyFactory()
    ContactFactory.create_batch(num_contacts, company=company)
    CompanyInteractionFactory.create_batch(num_interactions, company=company)
    OrderFactory.create_batch(num_orders, company=company)

    fields_iter = cycle(INVESTMENT_PROJECT_COMPANY_FIELDS)
    fields = islice(fields_iter, 0, num_investment_projects)
    InvestmentProjectFactory.create_batch(
        num_investment_projects,
        **{field: company for field in fields},
    )
    return company
Пример #22
0
def test_interactions_to_es_documents(setup_es):
    """Test converting 2 orders to Elasticsearch documents."""
    interactions = CompanyInteractionFactory.create_batch(2)

    result = Interaction.db_objects_to_es_documents(interactions)

    assert {item['_id'] for item in result} == {str(item.pk) for item in interactions}
Пример #23
0
    def test_filter_by_was_policy_feedback_provided(
            self, setup_es, was_policy_feedback_provided):
        """Test filtering interactions by was_policy_feedback_provided."""
        interactions_without_policy_feedback = CompanyInteractionFactory.create_batch(
            5)
        interactions_with_policy_feedback = (
            CompanyInteractionFactoryWithPolicyFeedback.create_batch(5))

        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'was_policy_feedback_provided': was_policy_feedback_provided,
        }
        response = self.api_client.post(url, data=request_data)
        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()
        expected_interactions = (interactions_with_policy_feedback
                                 if was_policy_feedback_provided else
                                 interactions_without_policy_feedback)
        assert response_data['count'] == len(expected_interactions)

        results = response_data['results']
        result_ids = {result['id'] for result in results}
        assert result_ids == {
            str(interaction.pk)
            for interaction in expected_interactions
        }
Пример #24
0
    def test_ignores_interactions_without_adviser_and_team(
            self, monkeypatch, caplog):
        """Test that the task does not modify interactions without advisers and teams."""
        caplog.set_level('INFO', 'datahub')
        populate_interaction_dit_participant_mock = Mock(
            wraps=populate_interaction_dit_participant, )
        monkeypatch.setattr(
            'datahub.dbmaintenance.tasks.populate_interaction_dit_participant',
            populate_interaction_dit_participant_mock,
        )

        interactions = CompanyInteractionFactory.create_batch(
            10,
            dit_adviser=None,
            dit_team=None,
            dit_participants=[],
        )

        result = populate_interaction_dit_participant_mock.apply_async(
            kwargs={'batch_size': 100}, )

        assert result.successful()
        assert populate_interaction_dit_participant_mock.apply_async.call_count == 1

        for interaction in interactions:
            interaction.refresh_from_db()

        # These objects should not have been modified
        assert all([obj.dit_participants.count() == 0 for obj in interactions])
        assert len(caplog.records) == 1
        assert f'0 InteractionDITParticipant many-to-many objects created' in caplog.text
Пример #25
0
def test_interactions_to_documents(opensearch):
    """Test converting 2 orders to OpenSearch documents."""
    interactions = CompanyInteractionFactory.create_batch(2)

    result = Interaction.db_objects_to_documents(interactions)

    assert {item['_id']
            for item in result} == {item.pk
                                    for item in interactions}
Пример #26
0
    def test_intelligent_homepage_limit(self, setup_es):
        """Test the limit param."""
        CompanyInteractionFactory.create_batch(15, dit_adviser=self.user)
        ContactFactory.create_batch(15, created_by=self.user)

        setup_es.indices.refresh()

        url = reverse('dashboard:intelligent-homepage')
        response = self.api_client.get(
            url,
            data={
                'limit': 10,
            },
        )

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert len(response_data['contacts']) == 10
        assert len(response_data['interactions']) == 10
Пример #27
0
    def test_filtered_by_event(self):
        """List of interactions filtered by event"""
        contact = ContactFactory()
        event = EventFactory()

        CompanyInteractionFactory.create_batch(3, contacts=[contact])
        EventServiceDeliveryFactory.create_batch(3)
        service_deliveries = EventServiceDeliveryFactory.create_batch(3, event=event)

        url = reverse('api-v3:interaction:collection')
        response = self.api_client.get(url, data={'event_id': event.id})

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert response_data['count'] == 3

        actual_ids = {result['id'] for result in response_data['results']}
        expected_ids = {str(service_delivery.id) for service_delivery in service_deliveries}
        assert actual_ids == expected_ids
    def test_non_restricted_user_can_only_list_relevant_interactions(self, permissions):
        """Test that a non-restricted user can list all interactions"""
        requester = create_test_user(permission_codenames=permissions)
        api_client = self.create_api_client(user=requester)

        project = InvestmentProjectFactory()
        company = CompanyFactory()
        company_interactions = CompanyInteractionFactory.create_batch(3, company=company)
        project_interactions = CompanyInteractionFactory.create_batch(
            3, investment_project=project,
        )

        url = reverse('api-v3:interaction:collection')
        response = api_client.get(url)

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert response_data['count'] == 6
        actual_ids = {i['id'] for i in response_data['results']}
        expected_ids = {str(i.id) for i in chain(project_interactions, company_interactions)}
        assert actual_ids == expected_ids
Пример #29
0
    def test_interaction_permission(self, setup_es):
        """Test that the interaction view permission is enforced."""
        requester = create_test_user(permission_codenames=('view_contact', ), )
        CompanyInteractionFactory.create_batch(5, dit_adviser=requester)
        ContactFactory.create_batch(5, created_by=requester)

        setup_es.indices.refresh()

        api_client = self.create_api_client(user=requester)

        url = reverse('dashboard:intelligent-homepage')
        response = api_client.get(
            url,
            data={
                'limit': 10,
            },
        )

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert len(response_data['contacts']) == 5
        assert response_data['interactions'] == []
Пример #30
0
    def test_filter_by_created_on_exists(self, setup_es, created_on_exists):
        """Tests filtering interaction by created_on exists."""
        CompanyInteractionFactory.create_batch(3)
        no_created_on = CompanyInteractionFactory.create_batch(3)
        for interaction in no_created_on:
            interaction.created_on = None
            interaction.save()

        setup_es.indices.refresh()

        url = reverse('api-v3:search:interaction')
        request_data = {
            'created_on_exists': created_on_exists,
        }
        response = self.api_client.post(url, request_data)

        assert response.status_code == status.HTTP_200_OK

        response_data = response.json()
        results = response_data['results']
        assert response_data['count'] == 3
        assert all((not result['created_on'] is None) == created_on_exists
                   for result in results)