def test_investment_project_syncs_when_team_member_adviser_changes( es_with_signals, team_member): """ Tests that when an adviser that is a team member of an investment project is updated, the related investment project is resynced. """ adviser = team_member.adviser adviser.dit_team = TeamFactory() adviser.save() es_with_signals.indices.refresh() result = get_search_by_entities_query( [InvestmentProject], term='', filter_data={ 'id': team_member.investment_project.pk }, ).execute() assert result.hits.total == 1 assert result.hits[0]['team_members'][0]['dit_team']['id'] == str( adviser.dit_team.id) assert result.hits[0]['team_members'][0]['dit_team'][ 'name'] == adviser.dit_team.name
def test_investment_project_interaction_updated_sync_to_opensearch( opensearch_with_signals): """Test investment project gets synced to OpenSearch when an interaction is updated.""" investment_project = InvestmentProjectFactory() interaction_date = '2018-05-05T00:00:00+00:00' interaction_subject = 'Did something interactive' new_interaction = InvestmentProjectInteractionFactory( investment_project=investment_project, date=datetime.fromisoformat(interaction_date), subject=interaction_subject, ) opensearch_with_signals.indices.refresh() assert_project_search_latest_interaction(has_interaction=True) results = get_search_by_entities_query( [InvestmentProject], term='', filter_data={}, ).execute() assert len(results) == 1 result = results[0] assert result['latest_interaction'] == { 'id': str(new_interaction.id), 'subject': interaction_subject, 'date': interaction_date, }
def get_base_query(self, request, validated_data): """Gets a filtered OpenSearch query for the provided search parameters.""" filter_data = self._get_filter_data(validated_data) entities = self.get_entities() permission_filters = self.search_app.get_permission_filters(request) ordering = _map_opensearch_ordering(validated_data['sortby'], self.es_sort_by_remappings) fields_to_exclude = ( *SHARED_FIELDS_TO_EXCLUDE, *(self.fields_to_exclude or ()), ) query = get_search_by_entities_query( entities=entities, term=validated_data['original_query'], filter_data=filter_data, composite_field_mapping=self.COMPOSITE_FILTERS, permission_filters=permission_filters, ordering=ordering, fields_to_include=self.fields_to_include, fields_to_exclude=fields_to_exclude, ) extra_filters = self.get_extra_filters(validated_data) if extra_filters: return query.filter(extra_filters) return query
def search_investment_project_by_id(pk): """Search for an investment project with the given id""" return get_search_by_entities_query( [InvestmentProject], term='', filter_data={ 'id': pk }, ).execute()
def test_investment_project_auto_sync_to_opensearch(opensearch_with_signals): """Tests if investment project gets synced to OpenSearch.""" test_name = 'very_hard_to_find_project' InvestmentProjectFactory(name=test_name, ) opensearch_with_signals.indices.refresh() result = get_search_by_entities_query( [InvestmentProject], term='', filter_data={ 'name': test_name }, ).execute() assert result.hits.total.value == 1
def test_investment_project_team_member_deleted_sync_to_es( es_with_signals, team_member): """Tests if investment project gets synced to Elasticsearch when a team member is deleted.""" team_member.delete() es_with_signals.indices.refresh() results = get_search_by_entities_query( [InvestmentProject], term='', filter_data={}, ).execute() assert len(results) == 1 result = results[0] assert len(result['team_members']) == 0
def test_investment_project_auto_updates_to_es(es_with_signals): """Tests if investment project gets synced to Elasticsearch.""" project = InvestmentProjectFactory() new_test_name = 'even_harder_to_find_investment_project' project.name = new_test_name project.save() es_with_signals.indices.refresh() result = get_search_by_entities_query( [InvestmentProject], term='', filter_data={ 'name': new_test_name }, ).execute() assert result.hits.total == 1
def test_investment_project_team_member_added_sync_to_opensearch( opensearch_with_signals, team_member, ): """Tests if investment project gets synced to OpenSearch when a team member is added.""" opensearch_with_signals.indices.refresh() results = get_search_by_entities_query( [InvestmentProject], term='', filter_data={}, ).execute() assert len(results) == 1 result = results[0] assert len(result['team_members']) == 1 assert result['team_members'][0]['id'] == str(team_member.adviser.id)
def assert_project_search_latest_interaction(has_interaction=True, name=''): """ Assert that a project on OpenSearch has or does not have a latest interaction. :param has_interaction: whether to expect the latest interaction to exist or not :param name: search term for OpenSearch """ filter_data = {'name': name} if name else {} results = get_search_by_entities_query( [InvestmentProject], term='', filter_data=filter_data, ).execute() assert len(results) == 1 result = results[0] if has_interaction: assert result['latest_interaction'] is not None else: assert result['latest_interaction'] is None
def test_investment_project_team_member_updated_sync_to_es( es_with_signals, team_member): """Tests if investment project gets synced to Elasticsearch when a team member is updated.""" new_adviser = AdviserFactory() team_member.adviser = new_adviser team_member.save() es_with_signals.indices.refresh() results = get_search_by_entities_query( [InvestmentProject], term='', filter_data={}, ).execute() assert len(results) == 1 result = results[0] assert len(result['team_members']) == 1 assert result['team_members'][0]['id'] == str(new_adviser.id)
def test_get_search_by_entities_query( term, filter_data, composite_field_mapping, permission_filters, ordering, fields_to_include, fields_to_exclude, expected_query, ): """Tests for the get_search_by_entities_query function.""" query = get_search_by_entities_query( [SimpleModelSearchApp.search_model], term=term, filter_data=filter_data, composite_field_mapping=composite_field_mapping, permission_filters=permission_filters, ordering=ordering, fields_to_include=fields_to_include, fields_to_exclude=fields_to_exclude, ) assert query.to_dict() == expected_query assert query._index == [SimpleModelSearchApp.search_model.get_read_alias()]
def test_investment_project_syncs_when_adviser_changes(es_with_signals, field): """ Tests that when an adviser is updated, investment projects related to that adviser are resynced. """ adviser = AdviserFactory() project = InvestmentProjectFactory(**{field: adviser}) adviser.dit_team = TeamFactory() adviser.save() es_with_signals.indices.refresh() result = get_search_by_entities_query( [InvestmentProject], term='', filter_data={ 'id': project.pk }, ).execute() assert result.hits.total == 1 assert result.hits[0][field]['dit_team']['id'] == str(adviser.dit_team.id) assert result.hits[0][field]['dit_team']['name'] == adviser.dit_team.name
def test_limited_get_search_by_entity_query(): """Tests search by entity.""" date = '2017-06-13T09:44:31.062870' filter_data = { 'name': 'Woodside', 'address.country.id': ['80756b9a-5d95-e211-a939-e4115bead28a'], 'archived_before': date, 'archived_after': date, } query = get_search_by_entities_query( [ESCompany], term='test', filter_data=filter_data, ) query = limit_search_query( query, offset=5, limit=5, ) assert query.to_dict() == { 'query': { 'bool': { 'must': [ { 'bool': { 'should': [ { 'match': { 'name.keyword': { 'query': 'test', 'boost': 2, }, }, }, { 'multi_match': { 'query': 'test', 'fields': ( 'id', 'name', 'name.trigram', 'company_number', 'trading_names', 'trading_names.trigram', 'reference_code', 'address.country.name.trigram', 'address.postcode.trigram', 'registered_address.country.name.trigram', 'registered_address.postcode.trigram', ), 'type': 'cross_fields', 'operator': 'and', }, }, ], }, }, ], 'filter': [ { 'bool': { 'must': [ { 'match': { 'name': { 'query': 'Woodside', 'operator': 'and', }, }, }, { 'bool': { 'should': [ { 'match': { 'address.country.id': { 'query': '80756b9a-5d95-e211-a939-e4115bead28a', 'operator': 'and', }, }, }, ], 'minimum_should_match': 1, }, }, { 'range': { 'archived': { 'lte': '2017-06-13T09:44:31.062870', 'gte': '2017-06-13T09:44:31.062870', }, }, }, ], }, }, ], }, }, 'sort': [ '_score', 'id', ], 'from': 5, 'size': 5, }
def test_limited_get_search_by_entity_query(): """Tests search by entity.""" date = '2017-06-13T09:44:31.062870' filter_data = { 'investor_company_country.id': ['80756b9a-5d95-e211-a939-e4115bead28a'], 'estimated_land_date_after': date, 'estimated_land_date_before': date, } query = get_search_by_entities_query( [ESInvestmentProject], term='test', filter_data=filter_data, ) query = limit_search_query( query, offset=5, limit=5, ) assert query.to_dict() == { 'query': { 'bool': { 'must': [ { 'bool': { 'should': [ { 'match': { 'name.keyword': { 'query': 'test', 'boost': 2, }, }, }, { 'multi_match': { 'query': 'test', 'fields': ( 'id', 'name', 'name.trigram', 'uk_company.name', 'uk_company.name.trigram', 'investor_company.name', 'investor_company.name.trigram', 'project_code.trigram', ), 'type': 'cross_fields', 'operator': 'and', }, }, ], }, }, ], 'filter': [ { 'bool': { 'must': [ { 'bool': { 'should': [ { 'match': { 'investor_company_country.id': { 'query': '80756b9a-5d95-e211-a939-e4115bead28a', 'operator': 'and', }, }, }, ], 'minimum_should_match': 1, }, }, { 'range': { 'estimated_land_date': { 'gte': '2017-06-13T09:44:31.062870', 'lte': '2017-06-13T09:44:31.062870', }, }, }, ], }, }, ], }, }, 'sort': [ '_score', 'id', ], 'from': 5, 'size': 5, }
def test_get_search_by_multiple_entities_query(): """Tests for the get_search_by_entities_query function.""" query = get_search_by_entities_query( [ SimpleModelSearchApp.search_model, RelatedModelSearchApp.search_model, ], term=None, filter_data=None, composite_field_mapping=None, permission_filters=None, ordering=None, fields_to_include=None, fields_to_exclude=None, ) expected_query = { 'query': { 'bool': { 'filter': [ { 'bool': {}, }, ], 'must': [ { 'bool': { 'should': [ { 'match': { 'name.keyword': { 'boost': 2, 'query': None, }, }, }, { 'multi_match': { 'fields': ( 'name', 'name.trigram', 'country.trigram', 'address.trigram', ), 'operator': 'and', 'query': None, 'type': 'cross_fields', }, }, ], }, }, { 'bool': { 'should': [ { 'match': { 'name.keyword': { 'boost': 2, 'query': None, }, }, }, { 'multi_match': { 'fields': ('simpleton.name',), 'operator': 'and', 'query': None, 'type': 'cross_fields', }, }, ], }, }, ], }, }, 'sort': [ '_score', 'id', ], 'track_total_hits': True, } assert query.to_dict() == expected_query assert query._index == [ SimpleModelSearchApp.search_model.get_read_alias(), RelatedModelSearchApp.search_model.get_read_alias(), ]
def test_get_limited_search_by_entity_query(): """Tests search by entity.""" date = '2017-06-13T09:44:31.062870' filter_data = { 'name': 'Woodside', 'address_country.id': ['80756b9a-5d95-e211-a939-e4115bead28a'], 'archived_before': date, 'archived_after': date, } query = get_search_by_entities_query( [SearchContact], term='test', filter_data=filter_data, ) query = limit_search_query( query, offset=5, limit=5, ) assert query.to_dict() == { 'query': { 'bool': { 'must': [ { 'bool': { 'should': [ { 'match': { 'name.keyword': { 'query': 'test', 'boost': 2, }, }, }, { 'multi_match': { 'query': 'test', 'fields': ( 'id', 'name', 'name.trigram', 'name_with_title', 'name_with_title.trigram', 'email', 'company.name', 'company.name.trigram', 'job_title', 'job_title.trigram', 'full_telephone_number', ), 'type': 'cross_fields', 'operator': 'and', }, }, ], }, }, ], 'filter': [ { 'bool': { 'must': [ { 'match': { 'name': { 'query': 'Woodside', 'operator': 'and', }, }, }, { 'bool': { 'should': [ { 'match': { 'address_country.id': { 'query': '80756b9a-5d95-e211-a939-e4115bead28a', 'operator': 'and', }, }, }, ], 'minimum_should_match': 1, }, }, { 'range': { 'archived': { 'gte': '2017-06-13T09:44:31.062870', 'lte': '2017-06-13T09:44:31.062870', }, }, }, ], }, }, ], }, }, 'sort': [ '_score', 'id', ], 'track_total_hits': True, 'from': 5, 'size': 5, }