def test_search_event(self, es_with_collector, setup_data): """Tests detailed event search.""" event_name = '012345catsinspace' EventFactory( name=event_name, ) es_with_collector.flush_and_refresh() url = reverse('api-v3:search:event') response = self.api_client.post( url, data={ 'original_query': event_name, }, ) assert response.status_code == status.HTTP_200_OK assert response.data['count'] == 1 assert len(response.data['results']) == 1 assert response.data['results'][0]['name'] == event_name
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_search_event_name(self, es_with_collector, setup_data): """Tests event_name filter.""" event_name = '0000000000' EventFactory( name=event_name, ) es_with_collector.flush_and_refresh() url = reverse('api-v3:search:event') response = self.api_client.post( url, data={ 'name': event_name[:5], }, ) assert response.status_code == status.HTTP_200_OK assert response.data['count'] == 1 assert len(response.data['results']) == 1 assert response.data['results'][0]['name'] == event_name
def test_search_event_address_country(self, es_with_collector, setup_data): """Tests address_country filter.""" country_id = constants.Country.united_states.value.id EventFactory( address_country_id=country_id, ) es_with_collector.flush_and_refresh() url = reverse('api-v3:search:event') response = self.api_client.post( url, data={ 'address_country': country_id, }, ) assert response.status_code == status.HTTP_200_OK assert response.data['count'] == 1 assert len(response.data['results']) == 1 assert response.data['results'][0]['address_country']['id'] == country_id
def test_search_event_organiser(self, es_with_collector, setup_data): """Tests organiser filter.""" organiser = AdviserFactory() EventFactory( organiser=organiser, ) es_with_collector.flush_and_refresh() url = reverse('api-v3:search:event') response = self.api_client.post( url, data={ 'organiser': organiser.id, }, ) assert response.status_code == status.HTTP_200_OK assert response.data['count'] == 1 assert len(response.data['results']) == 1 assert response.data['results'][0]['organiser']['id'] == str(organiser.id)
def test_enable_selected_events(self): """Tests enable selected action.""" events = [] for _ in range(5): events.append( EventFactory( disabled_on=now(), ), ) ids = [event.id for event in events] url = reverse('admin:event_event_changelist') data = { 'action': 'enable_selected', helpers.ACTION_CHECKBOX_NAME: ids, } response = self.client.post(url, data) assert response.status_code == status.HTTP_200_OK # Check if we get confirmation page in the response. assert 'Are you sure you want to enable the selected events?' in str(response.content) # Make sure none of selected events has been enabled. for event in events: event.refresh_from_db() assert event.disabled_on is not None # Confirm the action data['confirm'] = 'yes' response = self.client.post(url, data) assert response.status_code == status.HTTP_302_FOUND # Check if selected events have been enabled. for event in events: event.refresh_from_db() assert event.disabled_on is None
def test_search_event_date(self, es_with_collector, setup_data): """Tests start_date filter.""" start_date = datetime.date(2017, 7, 2) event = EventFactory( start_date=start_date, ) es_with_collector.flush_and_refresh() url = reverse('api-v3:search:event') response = self.api_client.post( url, data={ 'original_query': '', 'start_date_after': start_date, 'start_date_before': start_date, }, ) assert response.status_code == status.HTTP_200_OK assert response.data['count'] == 1 assert len(response.data['results']) == 1 assert response.data['results'][0]['id'] == str(event.id)
def test_search_event_organiser_name(self, opensearch_with_collector, setup_data): """Tests organiser_name filter.""" organiser_name = '00000000 000000000' EventFactory(organiser=AdviserFactory( first_name=organiser_name.split(' ', maxsplit=1)[0], last_name=organiser_name.split(' ', maxsplit=1)[1], ), ) opensearch_with_collector.flush_and_refresh() url = reverse('api-v3:search:event') response = self.api_client.post( url, data={ 'organiser_name': '00000', }, ) assert response.status_code == status.HTTP_200_OK assert response.data['count'] == 1 assert len(response.data['results']) == 1 assert response.data['results'][0]['organiser'][ 'name'] == organiser_name
def test_search_event_uk_region(self, es_with_collector): """Tests uk_region filter.""" country_id = constants.Country.united_kingdom.value.id uk_region_id = constants.UKRegion.jersey.value.id EventFactory( address_country_id=country_id, uk_region_id=uk_region_id, ) es_with_collector.flush_and_refresh() url = reverse('api-v3:search:event') response = self.api_client.post( url, data={ 'uk_region': uk_region_id, }, ) assert response.status_code == status.HTTP_200_OK assert response.data['count'] == 1 assert len(response.data['results']) == 1 assert response.data['results'][0]['address_country']['id'] == country_id assert response.data['results'][0]['uk_region']['id'] == uk_region_id
def test_permissions(self, es_with_collector, permission, permission_entity, entity): """ Tests model permissions enforcement in basic search. TODO: we should test permissions relevant to a specific search app in the tests for that search app, and remove this test. """ user = create_test_user(permission_codenames=[permission], dit_team=TeamFactory()) api_client = self.create_api_client(user=user) InvestmentProjectFactory(created_by=user) CompanyFactory() ContactFactory() EventFactory() CompanyInteractionFactory() OrderFactory() es_with_collector.flush_and_refresh() url = reverse('api-v3:search:basic') response = api_client.get( url, data={ 'term': '', 'entity': entity, }, ) assert response.status_code == status.HTTP_200_OK response_data = response.json() assert (response_data['count'] == 0) == (permission_entity != entity) assert len(response_data['aggregations']) == 1 assert response_data['aggregations'][0]['entity'] == permission_entity
def test_patch_all_fields(self): """Test updating an event.""" event = EventFactory() organiser = AdviserFactory() url = reverse('api-v3:event:item', kwargs={'pk': event.pk}) request_data = { 'name': 'Annual exhibition', 'event_type': EventType.exhibition.value.id, 'start_date': '2021-01-01', 'end_date': '2021-01-02', 'location_type': LocationType.post.value.id, 'notes': 'Updated notes', 'address_1': 'Annual Court Exhibition Centre', 'address_2': 'Annual Court Lane', 'address_town': 'Annual', 'address_county': 'County Annual', 'address_postcode': 'SW9 9AB', 'address_country': Country.isle_of_man.value.id, 'uk_region': None, 'organiser': str(organiser.pk), 'lead_team': Team.food_from_britain.value.id, 'teams': [Team.food_from_britain.value.id, Team.healthcare_uk.value.id], 'related_programmes': [Programme.great_challenge_fund.value.id], 'service': Service.account_management.value.id, } response = self.api_client.patch(url, request_data) assert response.status_code == status.HTTP_200_OK response_data = _get_canonical_response_data(response) assert response_data == { 'id': str(event.pk), 'name': 'Annual exhibition', 'event_type': { 'id': EventType.exhibition.value.id, 'name': EventType.exhibition.value.name, }, 'start_date': '2021-01-01', 'end_date': '2021-01-02', 'location_type': { 'id': LocationType.post.value.id, 'name': LocationType.post.value.name, }, 'notes': 'Updated notes', 'address_1': 'Annual Court Exhibition Centre', 'address_2': 'Annual Court Lane', 'address_town': 'Annual', 'address_county': 'County Annual', 'address_postcode': 'SW9 9AB', 'address_country': { 'id': Country.isle_of_man.value.id, 'name': Country.isle_of_man.value.name, }, 'disabled_on': None, 'uk_region': None, 'organiser': { 'id': str(organiser.pk), 'first_name': organiser.first_name, 'last_name': organiser.last_name, 'name': organiser.name, }, 'lead_team': { 'id': Team.food_from_britain.value.id, 'name': Team.food_from_britain.value.name, }, 'teams': [ { 'id': Team.healthcare_uk.value.id, 'name': Team.healthcare_uk.value.name, }, { 'id': Team.food_from_britain.value.id, 'name': Team.food_from_britain.value.name, }, ], 'related_programmes': [{ 'id': Programme.great_challenge_fund.value.id, 'name': Programme.great_challenge_fund.value.name, }], 'service': { 'id': Service.account_management.value.id, 'name': Service.account_management.value.name, }, 'archived_documents_url_path': event.archived_documents_url_path, }
def setup_data(): """Sets up data for the tests.""" EventFactory.create_batch(2)
def test_null_event_service(api_client): EventFactory(service_id=None) run_none_type_tests(api_client)
def test_null_event_location_type(api_client): EventFactory(location_type_id=None) run_none_type_tests(api_client)
def test_null_event_lead_team(api_client): EventFactory(lead_team_id=None) run_none_type_tests(api_client)
def test_null_event_organiser(api_client): EventFactory(organiser=None) run_none_type_tests(api_client)
def test_null_event_region(api_client): EventFactory(uk_region_id=None) run_none_type_tests(api_client)
def test_event_activity(api_client): """ Get a list of Events and test the returned JSON is valid """ start = datetime.datetime(year=2012, month=7, day=12, hour=15, minute=6, second=3) with freeze_time(start) as frozen_datetime: event = EventFactory() frozen_datetime.tick(datetime.timedelta(seconds=1, microseconds=1)) response = hawk.get(api_client, get_url('api-v3:activity-stream:events')) assert response.status_code == status.HTTP_200_OK assert response.json() == { '@context': 'https://www.w3.org/ns/activitystreams', 'summary': 'Event', 'type': 'OrderedCollectionPage', 'next': 'http://testserver/v3/activity-stream/event' + '?cursor=2012-07-12T15%3A06%3A03.000000%2B00%3A00' + f'&cursor={str(event.id)}', 'orderedItems': [ { 'id': f'dit:DataHubEvent:{event.id}:Announce', 'type': 'Announce', 'published': format_date_or_datetime(event.created_on), 'generator': { 'name': 'dit:dataHub', 'type': 'Application' }, 'object': { 'id': f'dit:DataHubEvent:{event.id}', 'type': [ 'dit:dataHub:Event', ], 'name': event.name, 'dit:eventType': { 'name': event.event_type.name }, 'content': event.notes, 'startTime': format_date_or_datetime(event.start_date), 'endTime': format_date_or_datetime(event.end_date), 'url': event.get_absolute_url(), 'dit:locationType': { 'name': event.location_type.name }, 'dit:address_1': event.address_1, 'dit:address_2': event.address_2, 'dit:address_town': event.address_town, 'dit:address_county': event.address_county, 'dit:address_postcode': event.address_postcode, 'dit:address_country': { 'name': event.address_country.name }, 'dit:leadTeam': { 'name': event.lead_team.name }, 'dit:organiser': { 'name': event.organiser.name }, 'dit:disabledOn': event.disabled_on, 'dit:service': { 'name': event.service.name }, 'dit:archivedDocumentsUrlPath': event.archived_documents_url_path, 'dit:ukRegion': { 'name': event.uk_region.name }, 'dit:teams': [ *[{ 'id': f'dit:DataHubTeam:{team.pk}', 'type': ['Group', 'dit:Team'], 'name': team.name, } for team in event.teams.order_by('pk')], ], 'dit:relatedProgrammes': [ *[{ 'id': f'dit:DataHubEventProgramme:{programme.pk}', 'name': programme.name, } for programme in event.related_programmes.order_by('pk')], ], 'dit:hasRelatedTradeAgreements': event.has_related_trade_agreements, 'dit:relatedTradeAgreements': [ *[{ 'id': f'dit:DataHubTradeAgreement:{trade_agreement.pk}', 'name': trade_agreement.name, } for trade_agreement in event.related_trade_agreements.order_by('pk')], ], }, }, ], }
def test_event_get_absolute_url(): """Test that Event.get_absolute_url() returns the correct URL.""" event = EventFactory.build() assert event.get_absolute_url() == ( f'{settings.DATAHUB_FRONTEND_URL_PREFIXES["event"]}/{event.pk}')
class TestInteractionCSVRowForm: """Tests for InteractionCSVRowForm.""" @pytest.mark.parametrize( 'data,errors', ( # kind blank ( { 'kind': '' }, { 'kind': ['This field is required.'] }, ), # kind invalid ( { 'kind': 'invalid' }, { 'kind': [ 'Select a valid choice. invalid is not one of the available choices.' ] }, ), # date blank ( { 'date': '' }, { 'date': ['This field is required.'] }, ), # invalid date ( { 'date': '08/31/2020' }, { 'date': ['Enter a valid date.'] }, ), # invalid contact_email ( { 'contact_email': 'invalid' }, { 'contact_email': ['Enter a valid email address.'] }, ), # blank adviser_1 ( { 'adviser_1': '' }, { 'adviser_1': ['This field is required.'] }, ), # adviser_1 doesn't exist ( { 'adviser_1': 'Non-existent adviser' }, { 'adviser_1': [ADVISER_NOT_FOUND_MESSAGE] }, ), # multiple matching values for adviser_1 ( { 'adviser_1': lambda: AdviserFactory.create_batch( 2, first_name='Pluto', last_name='Doris', )[0].name, }, { 'adviser_1': [MULTIPLE_ADVISERS_FOUND_MESSAGE] }, ), # adviser_1 and team_1 mismatch ( { 'adviser_1': lambda: AdviserFactory( first_name='Pluto', last_name='Doris', dit_team__name='Team Advantage', ).name, 'team_1': lambda: TeamFactory(name='Team Disadvantage', ).name, }, { 'adviser_1': [ADVISER_WITH_TEAM_NOT_FOUND_MESSAGE] }, ), # adviser_2 doesn't exist ( { 'adviser_2': 'Non-existent adviser' }, { 'adviser_2': [ADVISER_NOT_FOUND_MESSAGE] }, ), # multiple matching values for adviser_2 ( { 'adviser_2': lambda: AdviserFactory.create_batch( 2, first_name='Pluto', last_name='Doris', )[0].name, }, { 'adviser_2': [MULTIPLE_ADVISERS_FOUND_MESSAGE] }, ), # adviser_2 and team_2 mismatch ( { 'adviser_2': lambda: AdviserFactory( first_name='Pluto', last_name='Doris', dit_team__name='Team Advantage', ).name, 'team_2': lambda: TeamFactory(name='Team Disadvantage', ).name, }, { 'adviser_2': [ADVISER_WITH_TEAM_NOT_FOUND_MESSAGE] }, ), # service doesn't exist ( { 'service': 'Non-existent service' }, { 'service': [ 'Select a valid choice. That choice is not one of the available choices.', ], }, ), # service is disabled ( { 'service': lambda: _random_service(disabled=True).name, }, { 'service': [OBJECT_DISABLED_MESSAGE], }, ), # Multiple matching services ( { 'service': lambda: ServiceFactory.create_batch(2, name='Duplicate')[0] .name, }, { 'service': ['There is more than one matching service.'], }, ), # communication_channel doesn't exist ( { 'communication_channel': 'Non-existent communication channel' }, { 'communication_channel': [ 'Select a valid choice. That choice is not one of the available choices.', ], }, ), # Multiple matching communication channels ( { 'communication_channel': lambda: CommunicationChannelFactory.create_batch( 2, name='Duplicate', )[0].name, }, { 'communication_channel': [ 'There is more than one matching communication channel.', ], }, ), # communication_channel is disabled ( { 'communication_channel': lambda: _random_communication_channel(disabled=True, ). name, }, { 'communication_channel': [OBJECT_DISABLED_MESSAGE], }, ), # event_id invalid ( { 'event_id': 'non_existent_event_id' }, { 'event_id': [ "'non_existent_event_id' is not a valid UUID.", ], }, ), # event_id is for a disabled event ( { 'event_id': lambda: str(DisabledEventFactory().pk), }, { 'event_id': [OBJECT_DISABLED_MESSAGE], }, ), # event_id non-existent ( { 'event_id': '00000000-0000-0000-0000-000000000000' }, { 'event_id': [ 'Select a valid choice. That choice is not one of the available ' 'choices.', ], }, ), # cannot specify event_id for an interaction ( { 'kind': Interaction.KINDS.interaction, 'event_id': lambda: str(EventFactory().pk), }, { 'event_id': [INTERACTION_CANNOT_HAVE_AN_EVENT_MESSAGE], }, ), ), ) def test_validation_errors(self, data, errors): """Test validation for various fields.""" adviser = AdviserFactory(first_name='Neptune', last_name='Doris') service = _random_service() resolved_data = { 'kind': 'interaction', 'date': '01/01/2018', 'adviser_1': adviser.name, 'contact_email': '*****@*****.**', 'service': service.name, **_resolve_data(data), } form = InteractionCSVRowForm(data=resolved_data) assert form.errors == errors @pytest.mark.parametrize( 'field,input_value,expected_value', ( # UK date format without leading zeroes ( 'date', '1/2/2013', date(2013, 2, 1), ), # UK date format with leading zeroes ( 'date', '03/04/2015', date(2015, 4, 3), ), # ISO date format ( 'date', '2016-05-04', date(2016, 5, 4), ), # Subject ( 'subject', 'A subject', 'A subject', ), # Notes (trailing blank lines are stripped) ( 'notes', 'Notes with\nmultiple lines\n', 'Notes with\nmultiple lines', ), ), ) def test_simple_value_cleaning(self, field, input_value, expected_value): """Test the conversion and cleaning of various non-relationship fields.""" adviser = AdviserFactory(first_name='Neptune', last_name='Doris') service = _random_service() resolved_data = { 'kind': 'interaction', 'date': '01/01/2018', 'adviser_1': adviser.name, 'contact_email': '*****@*****.**', 'service': service.name, field: input_value, } form = InteractionCSVRowForm(data=resolved_data) assert not form.errors assert form.cleaned_data[field] == expected_value @pytest.mark.parametrize( 'kind', (Interaction.KINDS.interaction, Interaction.KINDS.service_delivery), ) @pytest.mark.parametrize( 'field,object_creator,input_transformer', ( # adviser_1 look-up (same case) ( 'adviser_1', lambda: AdviserFactory( first_name='Pluto', last_name='Doris', ), lambda obj: obj.name, ), # adviser_1 look-up (case-insensitive) ( 'adviser_1', lambda: AdviserFactory( first_name='Pluto', last_name='Doris', ), lambda obj: obj.name.upper(), ), # adviser_2 look-up (same case) ( 'adviser_1', lambda: AdviserFactory( first_name='Pluto', last_name='Doris', ), lambda obj: obj.name, ), # adviser_2 look-up (case-insensitive) ( 'adviser_1', lambda: AdviserFactory( first_name='Pluto', last_name='Doris', ), lambda obj: obj.name.upper(), ), # service look-up (same case) ( 'service', lambda: ServiceFactory(name='UNIQUE EXPORT DEAL'), lambda obj: obj.name, ), # service look-up (case-insensitive) ( 'service', lambda: ServiceFactory(name='UNIQUE EXPORT DEAL'), lambda obj: obj.name.lower(), ), ), ) def test_common_relation_fields(self, kind, field, object_creator, input_transformer): """ Test the looking up of values for relationship fields common to interactions and service deliveries. """ adviser = AdviserFactory(first_name='Neptune', last_name='Doris') service = _random_service() obj = object_creator() resolved_data = { 'kind': kind, 'date': '01/01/2018', 'adviser_1': adviser.name, 'contact_email': '*****@*****.**', 'service': service.name, field: input_transformer(obj), } form = InteractionCSVRowForm(data=resolved_data) assert not form.errors assert form.cleaned_data[field] == obj @pytest.mark.parametrize( 'field,object_creator,input_transformer', ( # communication channel look-up (same case) ( 'communication_channel', lambda: _random_communication_channel(), lambda obj: obj.name, ), # communication channel look-up (case-insensitive) ( 'communication_channel', lambda: _random_communication_channel(), lambda obj: obj.name.upper(), ), ), ) def test_interaction_relation_fields(self, field, object_creator, input_transformer): """Test the looking up of values for relationship fields specific to interactions.""" adviser = AdviserFactory(first_name='Neptune', last_name='Doris') service = _random_service() obj = object_creator() resolved_data = { 'kind': 'interaction', 'date': '01/01/2018', 'adviser_1': adviser.name, 'contact_email': '*****@*****.**', 'service': service.name, field: input_transformer(obj), } form = InteractionCSVRowForm(data=resolved_data) assert not form.errors assert form.cleaned_data[field] == obj @pytest.mark.parametrize( 'field,object_creator,input_transformer,expected_value_transformer', ( # communication channel should be ignored ( 'communication_channel', lambda: _random_communication_channel(), lambda obj: obj.name, lambda obj: None, ), # event look-up ( 'event_id', lambda: EventFactory(), lambda obj: str(obj.pk), lambda obj: obj, ), ), ) def test_service_delivery_relation_fields( self, field, object_creator, input_transformer, expected_value_transformer, ): """Test the looking up of values for relationship fields specific to service deliveries.""" adviser = AdviserFactory(first_name='Neptune', last_name='Doris') service = _random_service() obj = object_creator() resolved_data = { 'kind': 'service_delivery', 'date': '01/01/2018', 'adviser_1': adviser.name, 'contact_email': '*****@*****.**', 'service': service.name, field: input_transformer(obj), } form = InteractionCSVRowForm(data=resolved_data) assert not form.errors assert form.cleaned_data[field] == expected_value_transformer(obj) @pytest.mark.parametrize( 'kind', (Interaction.KINDS.interaction, Interaction.KINDS.service_delivery), ) def test_subject_falls_back_to_service(self, kind): """Test that if subject is not specified, the name of the service is used instead.""" adviser = AdviserFactory(first_name='Neptune', last_name='Doris') service = _random_service() data = { 'kind': kind, 'date': '01/01/2018', 'adviser_1': adviser.name, 'contact_email': '*****@*****.**', 'service': service.name, } form = InteractionCSVRowForm(data=data) assert not form.errors assert form.cleaned_data['subject'] == service.name