Esempio n. 1
0
    def test_sort_by_first_and_last_name_of_first_contact(self, primary_field, secondary_field):
        """Test sorting interactions by the first and last names of the first contact."""
        contacts = [
            ContactFactory(**{primary_field: 'Alfred', secondary_field: 'Jones'}),
            ContactFactory(**{primary_field: 'Alfred', secondary_field: 'Terry'}),
            ContactFactory(**{primary_field: 'Thomas', secondary_field: 'Richards'}),
            ContactFactory(**{primary_field: 'Thomas', secondary_field: 'West'}),
        ]
        interactions = [
            EventServiceDeliveryFactory(contacts=[contact])
            for contact in sample(contacts, len(contacts))
        ]

        url = reverse('api-v3:interaction:collection')
        response = self.api_client.get(
            url,
            data={
                'sortby': f'{primary_field}_of_first_contact,{secondary_field}_of_first_contact',
            },
        )

        assert response.status_code == status.HTTP_200_OK

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

        actual_ids = [
            interaction['contacts'][0]['id'] for interaction in response_data['results']
        ]
        expected_ids = [str(person.pk) for person in contacts]
        assert actual_ids == expected_ids
Esempio n. 2
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
Esempio n. 3
0
def test_null_team(api_client):
    """
    Test that we can handle dit_participant.team being None
    """
    interaction = EventServiceDeliveryFactory(dit_participants=[])
    InteractionDITParticipantFactory(
        interaction=interaction,
        team=None,
    )
    response = hawk.get(api_client, get_url('api-v3:activity-stream:interactions'))
    assert response.status_code == status.HTTP_200_OK
Esempio n. 4
0
    def test_sorting(self, field):
        """Test sorting interactions by various fields."""
        data_list = [
            {
                'created_on': datetime(2015, 1, 1),
                'company__name': 'Black Group',
                'subject': 'lorem',
            },
            {
                'created_on': datetime(2005, 4, 1),
                'company__name': 'Hicks Ltd',
                'subject': 'ipsum',
            },
            {
                'created_on': datetime(2019, 1, 1),
                'company__name': 'Sheppard LLC',
                'subject': 'dolor',
            },
        ]

        interactions = []
        for data in data_list:
            creation_time = data.pop('created_on')
            with freeze_time(creation_time):
                interactions.append(
                    EventServiceDeliveryFactory(**data),
                )

        url = reverse('api-v3:interaction:collection')
        response = self.api_client.get(
            url,
            data={
                'sortby': field.replace('.', '__'),
            },
        )

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

        expected = sorted(map(attrgetter(field), interactions))
        if isinstance(expected[0], datetime):
            expected = [format_date_or_datetime(item) for item in expected]

        actual = [
            reduce(  # get nested items if needed
                lambda data, key: data.get(key),
                field.split('.'),
                result,
            )
            for result in response_data['results']
        ]
        assert expected == actual
Esempio n. 5
0
    def test_update_400_doesnt_create_a_new_version(self):
        """Test that if the endpoint returns 400, no version is created."""
        service_delivery = EventServiceDeliveryFactory()

        assert Version.objects.get_for_object(service_delivery).count() == 0

        response = self.api_client.patch(
            reverse('api-v3:interaction:item', kwargs={'pk': service_delivery.pk}),
            data={'kind': 'invalid'},
        )

        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert Version.objects.get_for_object(service_delivery).count() == 0
    def test_cannot_add_more_contacts_to_event_service_delivery(self):
        """Test that an event service delivery cannot be updated to have multiple contacts."""
        service_delivery = EventServiceDeliveryFactory()
        new_contacts = ContactFactory.create_batch(2, company=service_delivery.company)

        url = reverse('api-v3:interaction:item', kwargs={'pk': service_delivery.pk})
        request_data = {
            'contacts': [{'id': contact.pk} for contact in new_contacts],
        }
        response = self.api_client.patch(url, data=request_data)

        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert response.json() == {
            'contacts': ['Only one contact can be provided for event service deliveries.'],
        }
    def test_change_event_service_delivery_to_non_event(self):
        """Test making an event service delivery a non-event service delivery."""
        service_delivery = EventServiceDeliveryFactory()

        url = reverse('api-v3:interaction:item', kwargs={'pk': service_delivery.pk})
        response = self.api_client.patch(
            url,
            data={
                'is_event': False,
                'event': None,
            },
        )

        assert response.status_code == status.HTTP_200_OK
        response_data = response.json()
        assert response_data['is_event'] is False
        assert response_data['event'] is None
Esempio n. 8
0
    def test_update_creates_a_new_version(self):
        """Test that updating an interaction creates a new version."""
        service_delivery = EventServiceDeliveryFactory()

        assert Version.objects.get_for_object(service_delivery).count() == 0

        response = self.api_client.patch(
            reverse('api-v3:interaction:item', kwargs={'pk': service_delivery.pk}),
            data={'subject': 'new subject'},
        )

        assert response.status_code == status.HTTP_200_OK
        assert response.data['subject'] == 'new subject'

        # check version created
        assert Version.objects.get_for_object(service_delivery).count() == 1
        version = Version.objects.get_for_object(service_delivery).first()
        assert version.revision.user == self.user
        assert version.field_dict['subject'] == 'new subject'
Esempio n. 9
0
def test_service_delivery_event_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 = EventServiceDeliveryFactory()
    event = interaction.event
    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(),
                    'context': [
                        {
                            'id': f'dit:DataHubEvent:{event.pk}',
                            'type': 'dit:Event',
                            'dit:eventType': {'name': event.event_type.name},
                            'name': interaction.event.name,
                            'startTime': format_date_or_datetime(event.start_date),
                            'endTime': format_date_or_datetime(event.end_date),
                            'dit:team': {
                                'id': f'dit:DataHubTeam:{interaction.event.lead_team.pk}',
                                'type': ['Group', 'dit:Team'],
                                'name': interaction.event.lead_team.name,
                            },
                            'url': interaction.event.get_absolute_url(),
                        },
                    ],
                },
            },
        ],
    }
Esempio n. 10
0
    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)
Esempio n. 11
0
def test_service_delivery_event_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 = EventServiceDeliveryFactory()
        event = interaction.event
        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(),
                    'context': [
                        {
                            'id': f'dit:DataHubEvent:{event.pk}',
                            'type': 'dit:Event',
                            'dit:eventType': {'name': event.event_type.name},
                            'name': interaction.event.name,
                            'startTime': format_date_or_datetime(event.start_date),
                            'endTime': format_date_or_datetime(event.end_date),
                            'dit:team': {
                                'id': f'dit:DataHubTeam:{interaction.event.lead_team.pk}',
                                'type': ['Group', 'dit:Team'],
                                'name': interaction.event.lead_team.name,
                            },
                            'url': interaction.event.get_absolute_url(),
                        },
                    ],
                },
            },
        ],
    }