def test_settings(self): self.index.save_object(F.obj()).wait() self.index.set_settings({'searchableAttributes': ['name']}).wait() self.assertEqual( self.index.get_settings()['searchableAttributes'], ['name'] ) self.index.set_settings({'typoTolerance': 'min'}).wait() self.assertEqual( self.index.get_settings()['typoTolerance'], 'min' ) self.index.set_settings(self.index.get_settings()).wait() self.assertEqual( self.index.get_settings()['typoTolerance'], 'min' ) self.assertEqual( self.index.get_settings()['searchableAttributes'], ['name'] )
def test_settings(self): self.index.save_object(F.obj()).wait() self.index.set_settings({'searchableAttributes': ['name']}).wait() self.assertEqual( self.index.get_settings()['searchableAttributes'], ['name'] ) self.index.set_settings({'typoTolerance': 'min'}).wait() self.assertEqual( self.index.get_settings()['typoTolerance'], 'min' ) self.index.set_settings(self.index.get_settings()).wait() self.assertEqual( self.index.get_settings()['typoTolerance'], 'min' ) self.assertEqual( self.index.get_settings()['searchableAttributes'], ['name'] ) self.index.set_settings({'indexLanguages': ['ja']}).wait() self.assertEqual( self.index.get_settings()['indexLanguages'], ['ja'] )
def test_replace_all_objects(self): self.index._create_temporary_name = mock.Mock( name="_create_temporary_name") tmp_index_name = "index-name_tmp_bar" self.index._create_temporary_name.return_value = tmp_index_name # noqa: E501 obj = F.obj() self.index.replace_all_objects([obj]) # Asserts the operations of the replace all objects. self.transporter.write.assert_has_calls([ mock.call( "POST", "1/indexes/index-name/operation", { "operation": "copy", "destination": "index-name_tmp_bar" }, {"scope": ["settings", "synonyms", "rules"]}, ), mock.call( "POST", "1/indexes/index-name_tmp_bar/batch", {"requests": [{ "action": "updateObject", "body": obj }]}, None, ), mock.call( "POST", "1/indexes/index-name_tmp_bar/operation", { "operation": "move", "destination": "index-name" }, None, ), ]) self.index._transporter.read = mock.Mock(name="read") self.index._transporter.read.return_value = {"status": "published"} self.index._transporter.write = mock.Mock(name="write") self.index._transporter.write.return_value = {"taskID": 1} self.index.replace_all_objects([obj]) self.assertEqual(self.index._transporter.write.call_count, 3) self.index.replace_all_objects([obj], {"safe": True}) self.assertEqual(self.index._transporter.write.call_count, 6) # 3+3 self.assertEqual(self.index._transporter.read.call_count, 3) # 3 waits
def test_replace_all_objects(self): self.index._create_temporary_name = mock.Mock( name="_create_temporary_name") tmp_index_name = 'index-name_tmp_bar' self.index._create_temporary_name.return_value = tmp_index_name # noqa: E501 obj = F.obj() self.index.replace_all_objects([obj]) # Asserts the operations of the replace all objects. self.transporter.write.assert_has_calls( [mock.call('POST', '1/indexes/index-name/operation', {'operation': 'copy', 'destination': 'index-name_tmp_bar'}, {'scope': ['settings', 'synonyms', 'rules']}), mock.call('POST', '1/indexes/index-name_tmp_bar/batch', {'requests': [ {'action': 'updateObject', 'body': obj}]}, None), mock.call('POST', '1/indexes/index-name_tmp_bar/operation', {'operation': 'move', 'destination': 'index-name'}, None)] ) response = NullResponse() response.wait = mock.Mock(name="wait") self.index.copy_to = mock.Mock( name="copy_to") self.index.copy_to.return_value = response self.index.move_to = mock.Mock( name="move_to") self.index.move_to.return_value = response self.index.save_objects = mock.Mock( name="save_objects") self.index.save_objects.return_value = response self.index.replace_all_objects([obj]) self.assertEqual(response.wait.call_count, 0) result = self.index.replace_all_objects([obj], {'safe': True}) self.assertEqual(response.wait.call_count, 3) self.assertEqual(len(result.responses), 3) self.assertEqual(len(result._waitable), 0)
def test_replace_all_objects(self): self.index._create_temporary_name = mock.Mock( name="_create_temporary_name") tmp_index_name = 'index-name_tmp_bar' self.index._create_temporary_name.return_value = tmp_index_name # noqa: E501 obj = F.obj() self.index.replace_all_objects([obj]) # Asserts the operations of the replace all objects. self.transporter.write.assert_has_calls( [mock.call('POST', '1/indexes/index-name/operation', {'operation': 'copy', 'destination': 'index-name_tmp_bar'}, {'scope': ['settings', 'synonyms', 'rules']}), mock.call('POST', '1/indexes/index-name_tmp_bar/batch', {'requests': [ {'action': 'updateObject', 'body': obj}]}, None), mock.call('POST', '1/indexes/index-name_tmp_bar/operation', {'operation': 'move', 'destination': 'index-name'}, None)] ) response = NullResponse() response.wait = mock.Mock(name="wait") self.index.copy_to = mock.Mock( name="copy_to") self.index.copy_to.return_value = response self.index.move_to = mock.Mock( name="move_to") self.index.move_to.return_value = response self.index.save_objects = mock.Mock( name="save_objects") self.index.save_objects.return_value = response self.index.replace_all_objects([obj]) self.assertEqual(response.wait.call_count, 0) result = self.index.replace_all_objects([obj], {'safe': True}) self.assertEqual(response.wait.call_count, 3) self.assertEqual(len(result.responses), 3) self.assertEqual(len(result._waitable), 0)
def test_safe_replacing(self): # Adds dummy object self.index.save_object(F.obj()).wait() # Calls replace all objects with an object without # object id, and with the safe parameter self.index.replace_all_objects([{ 'name': 'two' }], { 'autoGenerateObjectIDIfNotExist': True, 'safe': True }) response = self.index.search('') self.assertEqual(response['nbHits'], 1) hit = response['hits'][0] self.assertEqual(hit['name'], 'two') self.assertIn('objectID', hit) self.assertIn('_highlightResult', hit)
def test_safe_replacing(self): # Adds dummy object self.index.save_object(F.obj()).wait() # Calls replace all objects with an object without # object id, and with the safe parameter self.index.replace_all_objects([{ "name": "two" }], { "autoGenerateObjectIDIfNotExist": True, "safe": True }) response = self.index.search("") self.assertEqual(response["nbHits"], 1) hit = response["hits"][0] self.assertEqual(hit["name"], "two") self.assertIn("objectID", hit) self.assertIn("_highlightResult", hit)
def test_replace_all_objects(self): self.index._create_temporary_name = mock.Mock( name='_create_temporary_name') tmp_index_name = 'index-name_tmp_bar' self.index._create_temporary_name.return_value = tmp_index_name # noqa: E501 obj = F.obj() self.index.replace_all_objects([obj]) # Asserts the operations of the replace all objects. self.transporter.write.assert_has_calls([ mock.call('POST', '1/indexes/index-name/operation', { 'operation': 'copy', 'destination': 'index-name_tmp_bar' }, {'scope': ['settings', 'synonyms', 'rules']}), mock.call('POST', '1/indexes/index-name_tmp_bar/batch', {'requests': [{ 'action': 'updateObject', 'body': obj }]}, None), mock.call('POST', '1/indexes/index-name_tmp_bar/operation', { 'operation': 'move', 'destination': 'index-name' }, None) ]) self.index._transporter.read = mock.Mock(name='read') self.index._transporter.read.return_value = {'status': 'published'} self.index._transporter.write = mock.Mock(name='write') self.index._transporter.write.return_value = {'taskID': 1} self.index.replace_all_objects([obj]) self.assertEqual(self.index._transporter.write.call_count, 3) self.index.replace_all_objects([obj], {'safe': True}) self.assertEqual(self.index._transporter.write.call_count, 6) # 3+3 self.assertEqual(self.index._transporter.read.call_count, 3) # 3 waits
def test_tasks(self): task_id = self.index.save_object(F.obj()).raw_responses[0]['taskID'] task = self.index.get_task(task_id + 1000000) self.assertEqual(task['status'], 'notPublished')
def test_settings(self): self.index.save_object(F.obj()).wait() settings = { 'searchableAttributes': [ 'attribute1', 'attribute2', 'attribute3', 'ordered(attribute4)', 'unordered(attribute5)', ], 'attributesForFaceting': [ 'attribute1', 'filterOnly(attribute2)', 'searchable(attribute3)', ], 'unretrievableAttributes': [ 'attribute1', 'attribute2', ], 'attributesToRetrieve': [ 'attribute3', 'attribute4', ], 'ranking': [ 'asc(attribute1)', 'desc(attribute2)', 'attribute', 'custom', 'exact', 'filters', 'geo', 'proximity', 'typo', 'words', ], 'customRanking': [ 'asc(attribute1)', 'desc(attribute1)', ], 'replicas': [ self.index.name + '_replica1', self.index.name + '_replica2', ], 'maxValuesPerFacet': 100, 'sortFacetValuesBy': 'count', 'attributesToHighlight': ['attribute1', 'attribute2'], 'attributesToSnippet': [ 'attribute1:10', 'attribute2:8', ], 'highlightPreTag': '<strong>', 'highlightPostTag': '</strong>', 'snippetEllipsisText': ' and so on.', 'restrictHighlightAndSnippetArrays': True, 'hitsPerPage': 42, 'paginationLimitedTo': 43, 'minWordSizefor1Typo': 2, 'minWordSizefor2Typos': 6, 'typoTolerance': 'false', 'allowTyposOnNumericTokens': False, 'ignorePlurals': True, 'disableTypoToleranceOnAttributes': [ 'attribute1', 'attribute2', ], 'disableTypoToleranceOnWords': [ 'word1', 'word2', ], 'separatorsToIndex': '()[]', 'queryType': 'prefixNone', 'removeWordsIfNoResults': 'allOptional', 'advancedSyntax': True, 'optionalWords': [ 'word1', 'word2', ], 'removeStopWords': True, 'disablePrefixOnAttributes': [ 'attribute1', 'attribute2', ], 'disableExactOnAttributes': ['attribute1', 'attribute2'], 'exactOnSingleWordQuery': 'word', 'enableRules': False, 'numericAttributesForFiltering': [ 'attribute1', 'attribute2', ], 'allowCompressionOfIntegerArray': True, 'attributeForDistinct': 'attribute1', 'distinct': 2, 'replaceSynonymsInHighlight': False, 'minProximity': 7, 'responseFields': ['hits', 'hitsPerPage'], 'maxFacetHits': 100, 'camelCaseAttributes': [ 'attribute1', 'attribute2', ], 'decompoundedAttributes': { 'de': ['attribute1', 'attribute2'], 'fi': ['attribute3'], }, 'keepDiacriticsOnCharacters': 'øé', 'queryLanguages': [ 'en', 'fr', ], 'alternativesAsExact': ['ignorePlurals'], 'advancedSyntaxFeatures': ['exactPhrase'], 'userData': { 'customUserData': 42.0, }, 'indexLanguages': ['ja'], } self.index.set_settings(settings).wait() # Because the response settings dict contains the extra version key, we # also add it to the expected settings dict to prevent the test to fail # for a missing key. settings['version'] = 2 # In case something is wrong, we disable the maximum diff length to be # able to see which setting is incorrect. self.maxDiff = None found = self.index.get_settings() self.assertEqual( self.index.get_settings(), Unicode.convert_dict_to_unicode(settings), ) settings['typoTolerance'] = 'min' settings['ignorePlurals'] = ["en", "fr"] settings['removeStopWords'] = ["en", "fr"] settings['distinct'] = True self.index.set_settings(settings).wait() self.assertEqual( self.index.get_settings(), Unicode.convert_dict_to_unicode(settings), ) # To prevent issues in other test, we reset the maximum diff length to # its default value self.maxDiff = 80 * 8
def test_tasks(self): task_id = self.index.save_object(F.obj()).raw_responses[0]['taskID'] task = self.index.get_task(task_id + 1000000) self.assertEqual(task['status'], 'notPublished')
def setUp(self): self.index = Factory.index(self._testMethodName) self.obj = Factory.obj()
def test_tasks(self): task_id = self.index.save_object(F.obj()).raw_responses[0]["taskID"] task = self.index.get_task(task_id + 1000000) self.assertEqual(task["status"], "notPublished")
def test_settings(self): self.index.save_object(F.obj()).wait() settings = { "searchableAttributes": [ "attribute1", "attribute2", "attribute3", "ordered(attribute4)", "unordered(attribute5)", ], "attributesForFaceting": [ "attribute1", "filterOnly(attribute2)", "searchable(attribute3)", ], "unretrievableAttributes": ["attribute1", "attribute2"], "attributesToRetrieve": ["attribute3", "attribute4"], "ranking": [ "asc(attribute1)", "desc(attribute2)", "attribute", "custom", "exact", "filters", "geo", "proximity", "typo", "words", ], "customRanking": ["asc(attribute1)", "desc(attribute1)"], "replicas": [self.index.name + "_replica1", self.index.name + "_replica2"], "maxValuesPerFacet": 100, "sortFacetValuesBy": "count", "attributesToHighlight": ["attribute1", "attribute2"], "attributesToSnippet": ["attribute1:10", "attribute2:8"], "highlightPreTag": "<strong>", "highlightPostTag": "</strong>", "snippetEllipsisText": " and so on.", "restrictHighlightAndSnippetArrays": True, "hitsPerPage": 42, "paginationLimitedTo": 43, "minWordSizefor1Typo": 2, "minWordSizefor2Typos": 6, "typoTolerance": "false", "allowTyposOnNumericTokens": False, "ignorePlurals": True, "disableTypoToleranceOnAttributes": ["attribute1", "attribute2"], "disableTypoToleranceOnWords": ["word1", "word2"], "separatorsToIndex": "()[]", "queryType": "prefixNone", "removeWordsIfNoResults": "allOptional", "advancedSyntax": True, "optionalWords": ["word1", "word2"], "removeStopWords": True, "disablePrefixOnAttributes": ["attribute1", "attribute2"], "disableExactOnAttributes": ["attribute1", "attribute2"], "exactOnSingleWordQuery": "word", "enableRules": False, "numericAttributesForFiltering": ["attribute1", "attribute2"], "allowCompressionOfIntegerArray": True, "attributeForDistinct": "attribute1", "distinct": 2, "replaceSynonymsInHighlight": False, "minProximity": 7, "responseFields": ["hits", "hitsPerPage"], "maxFacetHits": 100, "camelCaseAttributes": ["attribute1", "attribute2"], "decompoundedAttributes": { "de": ["attribute1", "attribute2"], "fi": ["attribute3"], }, "keepDiacriticsOnCharacters": "øé", "queryLanguages": ["en", "fr"], "alternativesAsExact": ["ignorePlurals"], "advancedSyntaxFeatures": ["exactPhrase"], "userData": { "customUserData": 42.0 }, "indexLanguages": ["ja"], } self.index.set_settings(settings).wait() # Because the response settings dict contains the extra version key, we # also add it to the expected settings dict to prevent the test to fail # for a missing key. settings["version"] = 2 # In case something is wrong, we disable the maximum diff length to be # able to see which setting is incorrect. self.maxDiff = None found = self.index.get_settings() self.assertEqual( self.index.get_settings(), Unicode.convert_dict_to_unicode(settings), ) settings["typoTolerance"] = "min" settings["ignorePlurals"] = ["en", "fr"] settings["removeStopWords"] = ["en", "fr"] settings["distinct"] = True self.index.set_settings(settings).wait() self.assertEqual( self.index.get_settings(), Unicode.convert_dict_to_unicode(settings), ) # To prevent issues in other test, we reset the maximum diff length to # its default value self.maxDiff = 80 * 8
def test_indexing(self): responses = [] # adding a object with object id obj1 = F.obj() responses.append(self.index.save_object(obj1)) # adding a object w/o object id obj2 = F.obj(object_id=False) opts = {'autoGenerateObjectIDIfNotExist': True} responses.append(self.index.save_object(obj2, opts)) # adding two objects with object id obj3 = F.obj({'_tags': ['algolia']}) obj4 = F.obj({'_tags': ['algolia']}) responses.append(self.index.save_objects([obj3, obj4])) # adding two objects w/o object id obj5 = F.obj(object_id=False) obj6 = F.obj(object_id=False) opts = {'autoGenerateObjectIDIfNotExist': True} responses.append(self.index.save_objects([obj5, obj6], opts)) object1_id = self.get_object_id(responses[0]) object2_id = self.get_object_id(responses[1]) object3_id = self.get_object_id(responses[2]) object4_id = self.get_object_id(responses[2], 1) object5_id = self.get_object_id(responses[3]) object6_id = self.get_object_id(responses[3], 1) # adding 1000 objects with object id objects = [] for i in range(1000): object_id = i objects.append({ 'objectID': str(object_id), 'name': object_id, }) self.index._config.batch_size = 100 responses.append(self.index.save_objects(objects)) # waiting for all responses MultipleResponse(responses).wait() # Check 6 first records with get_object self.assertEqual(obj1['name'], self.index.get_object(object1_id)['name']) self.assertEqual(obj2['name'], self.index.get_object(object2_id)['name']) self.assertEqual(obj3['name'], self.index.get_object(object3_id)['name']) self.assertEqual(obj4['name'], self.index.get_object(object4_id)['name']) self.assertEqual(obj5['name'], self.index.get_object(object5_id)['name']) self.assertEqual(obj6['name'], self.index.get_object(object6_id)['name']) # Check 1000 remaining records with get_objects results = self.index.get_objects(range(1000))['results'] for obj in results: self.assertIn(obj, objects) self.assertEqual(len(results), len(objects)) # Browse all records with browse_objects results = [] for obj in self.index.browse_objects(): results.append(obj) for obj in objects: self.assertIn(obj, results) for obj in [obj1, obj3, obj4]: self.assertIn(obj, results) self.assertEqual(len(results), 1006) responses = [] # Alter 1 record with partial_update_object obj1['name'] = 'This is an altered name' responses.append(self.index.partial_update_object(obj1)) # Alter 2 records with partial_update_objects obj3['bar'] = 40 obj4['foo'] = 30 responses.append(self.index.partial_update_objects([obj3, obj4])) MultipleResponse(responses).wait() self.assertEqual(self.index.get_object(object1_id), obj1) self.assertEqual(self.index.get_object(object3_id), obj3) self.assertEqual(self.index.get_object(object4_id), obj4) responses = [] # Delete the 6 first records with delete_object responses.append(self.index.delete_object(object1_id)) responses.append(self.index.delete_object(object2_id)) responses.append(self.index.delete_by({'tagFilters': ['algolia']})) responses.append(self.index.delete_objects([ object5_id, object6_id ])) # Delete the 1000 remaining records with delete_objects responses.append(self.index.clear_objects()) MultipleResponse(responses).wait() objects = [obj for obj in self.index.browse_objects()] self.assertEqual(len(objects), 0)
def test_indexing(self): responses = [] # adding a object with object id obj1 = F.obj() responses.append(self.index.save_object(obj1)) # adding a object w/o object id obj2 = F.obj(object_id=False) opts = {'autoGenerateObjectIDIfNotExist': True} responses.append(self.index.save_object(obj2, opts)) # adding two objects with object id obj3 = F.obj({'_tags': ['algolia']}) obj4 = F.obj({'_tags': ['algolia']}) responses.append(self.index.save_objects([obj3, obj4])) # adding two objects w/o object id obj5 = F.obj(object_id=False) obj6 = F.obj(object_id=False) opts = {'autoGenerateObjectIDIfNotExist': True} responses.append(self.index.save_objects([obj5, obj6], opts)) object1_id = self.get_object_id(responses[0]) object2_id = self.get_object_id(responses[1]) object3_id = self.get_object_id(responses[2]) object4_id = self.get_object_id(responses[2], 1) object5_id = self.get_object_id(responses[3]) object6_id = self.get_object_id(responses[3], 1) # adding 1000 objects with object id objects = [] for i in range(1000): object_id = i objects.append({ 'objectID': str(object_id), 'name': object_id, }) self.index._config.batch_size = 100 responses.append(self.index.save_objects(objects)) # waiting for all responses MultipleResponse(responses).wait() # Check 6 first records with get_object self.assertEqual(obj1['name'], self.index.get_object(object1_id)['name']) self.assertEqual(obj2['name'], self.index.get_object(object2_id)['name']) self.assertEqual(obj3['name'], self.index.get_object(object3_id)['name']) self.assertEqual(obj4['name'], self.index.get_object(object4_id)['name']) self.assertEqual(obj5['name'], self.index.get_object(object5_id)['name']) self.assertEqual(obj6['name'], self.index.get_object(object6_id)['name']) # Check 1000 remaining records with get_objects results = self.index.get_objects(range(1000))['results'] for obj in results: self.assertIn(obj, objects) self.assertEqual(len(results), len(objects)) # Browse all records with browse_objects results = [] for obj in self.index.browse_objects(): results.append(obj) for obj in objects: self.assertIn(obj, results) for obj in [obj1, obj3, obj4]: self.assertIn(obj, results) self.assertEqual(len(results), 1006) responses = [] # Alter 1 record with partial_update_object obj1['name'] = 'This is an altered name' responses.append(self.index.partial_update_object(obj1)) # Alter 2 records with partial_update_objects obj3['bar'] = 40 obj4['foo'] = 30 responses.append(self.index.partial_update_objects([obj3, obj4])) MultipleResponse(responses).wait() self.assertEqual(self.index.get_object(object1_id), obj1) self.assertEqual(self.index.get_object(object3_id), obj3) self.assertEqual(self.index.get_object(object4_id), obj4) responses = [] # Delete the 6 first records with delete_object responses.append(self.index.delete_object(object1_id)) responses.append(self.index.delete_object(object2_id)) responses.append(self.index.delete_by({'tagFilters': ['algolia']})) responses.append(self.index.delete_objects([ object5_id, object6_id ])) # Delete the 1000 remaining records with delete_objects responses.append(self.index.clear_objects()) MultipleResponse(responses).wait() objects = [obj for obj in self.index.browse_objects()] self.assertEqual(len(objects), 0)
def test_exists(self): self.assertFalse(self.index.exists()) self.index.save_object(F.obj()).wait() self.assertTrue(self.index.exists())
def setUp(self): self.client = F.search_client() self.index = F.index(self.client, self._testMethodName) self.obj = F.obj()