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
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)}
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
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)
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)}
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
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
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
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
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
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
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
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
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)
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}
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
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}
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
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)
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
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}
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 }
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
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}
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
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
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'] == []
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)