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 test_service_delivery_to_dict(setup_es): """Test converting an interaction to a dict.""" interaction = ServiceDeliveryFactory() result = Interaction.db_object_to_dict(interaction) assert result == { 'id': str(interaction.pk), 'kind': interaction.kind, 'date': interaction.date, 'company': { 'id': str(interaction.company.pk), 'name': interaction.company.name, 'trading_name': interaction.company.alias, }, 'company_sector': { 'id': str(interaction.company.sector.pk), 'name': interaction.company.sector.name, 'ancestors': [{ 'id': str(ancestor.pk), } for ancestor in interaction.company.sector.get_ancestors()], }, 'contact': { 'id': str(interaction.contact.pk), 'first_name': interaction.contact.first_name, 'name': interaction.contact.name, 'last_name': interaction.contact.last_name, }, 'is_event': interaction.is_event, 'event': None, 'service': { 'id': str(interaction.service.pk), 'name': interaction.service.name, }, 'subject': interaction.subject, 'dit_adviser': { 'id': str(interaction.dit_adviser.pk), 'first_name': interaction.dit_adviser.first_name, 'name': interaction.dit_adviser.name, 'last_name': interaction.dit_adviser.last_name, }, 'notes': interaction.notes, 'dit_team': { 'id': str(interaction.dit_team.pk), 'name': interaction.dit_team.name, }, 'communication_channel': None, 'investment_project': None, 'investment_project_sector': None, 'service_delivery_status': { 'id': str(interaction.service_delivery_status.pk), 'name': interaction.service_delivery_status.name, }, 'grant_amount_offered': interaction.grant_amount_offered, 'net_company_receipt': interaction.net_company_receipt, 'created_on': interaction.created_on, 'modified_on': interaction.modified_on, }
def test_fails_with_negative_net_company_receipt(self): """Test validation when an a negative net company receipt is entered.""" interaction = ServiceDeliveryFactory() url = reverse('api-v3:interaction:item', kwargs={'pk': interaction.pk}) response = self.api_client.patch( url, data={ 'net_company_receipt': '-100.00', }, ) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = response.json() assert response_data['net_company_receipt'] == [ 'Ensure this value is greater than or equal to 0.', ]
def test_change_non_event_service_delivery_to_event(self): """Test making a non-event service delivery an event service delivery.""" service_delivery = ServiceDeliveryFactory() event = EventFactory() url = reverse('api-v3:interaction:item', kwargs={'pk': service_delivery.pk}) response = self.api_client.patch( url, data={ 'is_event': True, 'event': event.pk, }, ) assert response.status_code == status.HTTP_200_OK response_data = response.json() assert response_data['is_event'] is True assert response_data['event'] == { 'id': str(event.pk), 'name': event.name, }
def test_service_delivery_to_dict(setup_es): """Test converting an interaction to a dict.""" interaction = ServiceDeliveryFactory() result = Interaction.db_object_to_dict(interaction) result['contacts'].sort(key=itemgetter('id')) result['dit_participants'].sort( key=lambda dit_participant: dit_participant['adviser']['id']) assert result == { 'id': interaction.pk, 'kind': interaction.kind, 'date': interaction.date, 'company': { 'id': str(interaction.company.pk), 'name': interaction.company.name, 'trading_names': interaction.company.trading_names, }, 'company_sector': { 'id': str(interaction.company.sector.pk), 'name': interaction.company.sector.name, 'ancestors': [{ 'id': str(ancestor.pk), } for ancestor in interaction.company.sector.get_ancestors()], }, 'contacts': [{ 'id': str(obj.pk), 'first_name': obj.first_name, 'name': obj.name, 'last_name': obj.last_name, } for obj in sorted(interaction.contacts.all(), key=attrgetter('id'))], 'is_event': interaction.is_event, 'event': None, 'service': { 'id': str(interaction.service.pk), 'name': interaction.service.name, }, 'subject': interaction.subject, 'dit_adviser': { 'id': str(interaction.dit_adviser.pk), 'first_name': interaction.dit_adviser.first_name, 'name': interaction.dit_adviser.name, 'last_name': interaction.dit_adviser.last_name, }, 'dit_participants': [{ 'adviser': { 'id': str(dit_participant.adviser.pk), 'first_name': dit_participant.adviser.first_name, 'name': dit_participant.adviser.name, 'last_name': dit_participant.adviser.last_name, }, 'team': { 'id': str(dit_participant.team.pk), 'name': dit_participant.team.name, }, } for dit_participant in interaction.dit_participants.order_by( 'adviser__pk')], 'notes': interaction.notes, 'dit_team': { 'id': str(interaction.dit_team.pk), 'name': interaction.dit_team.name, }, 'communication_channel': None, 'investment_project': None, 'investment_project_sector': None, 'policy_areas': [], 'policy_issue_types': [], 'service_delivery_status': { 'id': str(interaction.service_delivery_status.pk), 'name': interaction.service_delivery_status.name, }, 'grant_amount_offered': interaction.grant_amount_offered, 'net_company_receipt': interaction.net_company_receipt, 'was_policy_feedback_provided': interaction.was_policy_feedback_provided, 'created_on': interaction.created_on, 'modified_on': interaction.modified_on, }
def test_service_delivery_activity(api_client): """ Get a list of interactions and test the returned JSON is valid as per: https://www.w3.org/TR/activitystreams-core/ """ interaction = ServiceDeliveryFactory() response = hawk.get(api_client, get_url('api-v3:activity-stream:interactions')) assert response.status_code == status.HTTP_200_OK assert response.json() == { '@context': 'https://www.w3.org/ns/activitystreams', 'summary': 'Interaction Activities', 'type': 'OrderedCollectionPage', 'id': 'http://testserver/v3/activity-stream/interaction', 'partOf': 'http://testserver/v3/activity-stream/interaction', 'previous': None, 'next': None, 'orderedItems': [ { 'id': f'dit:DataHubInteraction:{interaction.id}:Announce', 'type': 'Announce', 'published': format_date_or_datetime(interaction.created_on), 'generator': {'name': 'dit:dataHub', 'type': 'Application'}, 'object': { 'id': f'dit:DataHubInteraction:{interaction.id}', 'type': ['dit:Event', 'dit:ServiceDelivery'], 'startTime': format_date_or_datetime(interaction.date), 'dit:status': interaction.status, 'dit:archived': interaction.archived, 'dit:subject': interaction.subject, 'dit:service': {'name': interaction.service.name}, 'attributedTo': [ { 'id': f'dit:DataHubCompany:{interaction.company.pk}', 'dit:dunsNumber': interaction.company.duns_number, 'dit:companiesHouseNumber': interaction.company.company_number, 'type': ['Organization', 'dit:Company'], 'name': interaction.company.name, }, *[ { 'id': f'dit:DataHubAdviser:{participant.adviser.pk}', 'type': ['Person', 'dit:Adviser'], 'dit:emailAddress': participant.adviser.contact_email or participant.adviser.email, 'name': participant.adviser.name, 'dit:team': { 'id': f'dit:DataHubTeam:{participant.team.pk}', 'type': ['Group', 'dit:Team'], 'name': participant.team.name, }, } for participant in interaction.dit_participants.order_by('pk') ], *[ { 'id': f'dit:DataHubContact:{contact.pk}', 'type': ['Person', 'dit:Contact'], 'url': contact.get_absolute_url(), 'dit:emailAddress': contact.email, 'dit:jobTitle': contact.job_title, 'name': contact.name, } for contact in interaction.contacts.order_by('pk') ], ], 'url': interaction.get_absolute_url(), }, }, ], }
def test_interaction_export( self, setup_es, request_sortby, orm_ordering, ): """ Test export of interaction search results with a policy feedback user. Checks that all interaction kinds except for policy feedback are included in the export. """ # Faker generates job titles containing commas which complicates comparisons, # so all contact job titles are explicitly set company = CompanyFactory() CompanyInteractionFactory( company=company, contacts=[ ContactFactory(company=company, job_title='Engineer'), ContactFactory(company=company, job_title=None), ContactFactory(company=company, job_title=''), ], ) EventServiceDeliveryFactory( company=company, contacts=[ ContactFactory(company=company, job_title='Managing director'), ], ) InvestmentProjectInteractionFactory( company=company, contacts=[ ContactFactory(company=company, job_title='Exports manager'), ], ) ServiceDeliveryFactory( company=company, contacts=[ ContactFactory(company=company, job_title='Sales director'), ], ) CompanyInteractionFactoryWithPolicyFeedback( company=company, contacts=[ ContactFactory(company=company, job_title='Business development manager'), ], policy_areas=PolicyArea.objects.order_by('?')[:2], policy_issue_types=PolicyIssueType.objects.order_by('?')[:2], ) setup_es.indices.refresh() data = {} if request_sortby: data['sortby'] = request_sortby url = reverse('api-v3:search:interaction-export') 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-Type')) == ('text/csv', { 'charset': 'utf-8' }) assert parse_header(response.get('Content-Disposition')) == ( 'attachment', { 'filename': 'Data Hub - Interactions - 2018-01-01-11-12-13.csv' }, ) sorted_interactions = Interaction.objects.all().order_by( orm_ordering, 'pk', ) reader = DictReader(StringIO(response.getvalue().decode('utf-8-sig'))) assert reader.fieldnames == list( SearchInteractionExportAPIView.field_titles.values()) expected_row_data = [{ 'Date': interaction.date, 'Type': interaction.get_kind_display(), 'Service': get_attr_or_none(interaction, 'service.name'), 'Subject': interaction.subject, 'Link': f'{settings.DATAHUB_FRONTEND_URL_PREFIXES["interaction"]}' f'/{interaction.pk}', 'Company': get_attr_or_none(interaction, 'company.name'), 'Company link': f'{settings.DATAHUB_FRONTEND_URL_PREFIXES["company"]}' f'/{interaction.company.pk}', 'Company country': get_attr_or_none( interaction, 'company.address_country.name', ), 'Company UK region': get_attr_or_none(interaction, 'company.uk_region.name'), 'Company sector': get_attr_or_none(interaction, 'company.sector.name'), 'Contacts': _format_expected_contacts(interaction), 'Adviser': get_attr_or_none(interaction, 'dit_adviser.name'), 'Service provider': get_attr_or_none(interaction, 'dit_team.name'), 'Event': get_attr_or_none(interaction, 'event.name'), 'Communication channel': get_attr_or_none(interaction, 'communication_channel.name'), 'Service delivery status': get_attr_or_none( interaction, 'service_delivery_status.name', ), 'Net company receipt': interaction.net_company_receipt, 'Policy issue types': join_attr_values(interaction.policy_issue_types.all()), 'Policy areas': join_attr_values(interaction.policy_areas.all(), separator='; '), 'Policy feedback notes': interaction.policy_feedback_notes, } for interaction in sorted_interactions] actual_row_data = [_format_actual_csv_row(row) for row in reader] assert actual_row_data == format_csv_data(expected_row_data)
def test_service_delivery_activity(api_client): """ Get a list of interactions and test the returned JSON is valid as per: https://www.w3.org/TR/activitystreams-core/ """ start = datetime.datetime(year=2012, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(start) as frozen_datetime: interaction = ServiceDeliveryFactory() 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 assert response.json() == { '@context': 'https://www.w3.org/ns/activitystreams', 'summary': 'Interaction Activities', 'type': 'OrderedCollectionPage', 'next': 'http://testserver/v3/activity-stream/interaction' + '?cursor=2012-07-12T15%3A06%3A03.000000%2B00%3A00' + f'&cursor={str(interaction.id)}', 'orderedItems': [ { 'id': f'dit:DataHubInteraction:{interaction.id}:Announce', 'type': 'Announce', 'published': format_date_or_datetime(interaction.created_on), 'generator': {'name': 'dit:dataHub', 'type': 'Application'}, 'object': { 'id': f'dit:DataHubInteraction:{interaction.id}', 'type': [ 'dit:Event', 'dit:ServiceDelivery', f'dit:datahub:theme:{interaction.theme}', ], 'content': interaction.notes, 'startTime': format_date_or_datetime(interaction.date), 'dit:status': interaction.status, 'dit:archived': interaction.archived, 'dit:subject': interaction.subject, 'dit:service': {'name': interaction.service.name}, 'attributedTo': [ *[ { 'id': f'dit:DataHubCompany:{company.pk}', 'dit:dunsNumber': company.duns_number, 'dit:companiesHouseNumber': company.company_number, 'type': ['Organization', 'dit:Company'], 'name': company.name, } for company in interaction.companies.order_by('pk') ], *[ { 'id': f'dit:DataHubAdviser:{participant.adviser.pk}', 'type': ['Person', 'dit:Adviser'], 'dit:emailAddress': participant.adviser.contact_email or participant.adviser.email, 'name': participant.adviser.name, 'dit:team': { 'id': f'dit:DataHubTeam:{participant.team.pk}', 'type': ['Group', 'dit:Team'], 'name': participant.team.name, }, } for participant in interaction.dit_participants.order_by('pk') ], *[ { 'id': f'dit:DataHubContact:{contact.pk}', 'type': ['Person', 'dit:Contact'], 'url': contact.get_absolute_url(), 'dit:emailAddress': contact.email, 'dit:jobTitle': contact.job_title, 'name': contact.name, } for contact in interaction.contacts.order_by('pk') ], ], 'url': interaction.get_absolute_url(), }, }, ], }