class IndicatorAliasedMatchTestCase(AutocompleterTestCase): fixtures = ['indicator_test_data_small.json'] def setUp(self): self.autocomp = Autocompleter("indicator_aliased") self.autocomp.store_all() super(IndicatorAliasedMatchTestCase, self).setUp() def tearDown(self): self.autocomp.remove_all() def test_aliasing(self): """ Various permutations of aliased matching work """ matches = self.autocomp.suggest('us consumer price index') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('united states consumer price index') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('us cpi') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('united states consumer price index') self.assertNotEqual(len(matches), 0)
def test_store_and_remove_all_basic_with_caching(self): """ Storing and removing items all at once works with caching turned on """ # Let's turn on caching because that will store things in Redis and we want to make # sure we clean them up. setattr(auto_settings, 'CACHE_TIMEOUT', 3600) autocomp = Autocompleter("stock") autocomp.store_all() keys = self.redis.hkeys('djac.test.stock') self.assertEqual(len(keys), 101) autocomp = Autocompleter("stock") for i in range(0, 3): autocomp.suggest('a') autocomp.suggest('z') autocomp.exact_suggest('aapl') autocomp.exact_suggest('xyz') autocomp.remove_all() keys = self.redis.keys('djac.test.stock*') self.assertEqual(len(keys), 0) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0)
class MultiMatchingPerfTestCase(AutocompleterTestCase): fixtures = ['stock_test_data.json', 'indicator_test_data.json'] num_iterations = 1000 def setUp(self): self.autocomp = Autocompleter("mixed") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_repeated_matches(self): """ Matching is fast """ setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', True) setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) for i in range(1, self.num_iterations): self.autocomp.suggest('ma') for i in range(1, self.num_iterations): self.autocomp.suggest('price consumer') for i in range(1, self.num_iterations): self.autocomp.suggest('a') for i in range(1, self.num_iterations): self.autocomp.suggest('non revolving') # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', False) setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
def test_dict_store_and_remove_all_basic_with_caching(self): """ Storing and removing items all at once works with caching turned on on dict ac """ # Let's turn on caching because that will store things in Redis and we want to make # sure we clean them up. setattr(auto_settings, 'CACHE_TIMEOUT', 3600) autocomp = Autocompleter("metric") autocomp.store_all() keys = self.redis.hkeys('djac.test.metric') self.assertEqual(len(keys), 8) autocomp = Autocompleter("metric") for i in range(0, 3): autocomp.suggest('m') autocomp.suggest('e') autocomp.exact_suggest('PE Ratio TTM') autocomp.exact_suggest('Market Cap') autocomp.remove_all() keys = self.redis.keys('djac.test.metric*') self.assertEqual(len(keys), 0) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0)
class MultiExactMatchTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json'] def setUp(self): super(MultiExactMatchTestCase, self).setUp() setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) self.autocomp = Autocompleter("mixed") self.autocomp.store_all() def tearDown(self): setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0) self.autocomp.remove_all() def test_exact_suggest(self): """ Exact matching works in multi-provider autocompleters """ matches = self.autocomp.exact_suggest('ma') self.assertEqual(len(matches['stock']), 1) matches = self.autocomp.exact_suggest('US Unemployment Rate') self.assertEqual(len(matches['ind']), 1) def test_move_exact_matches_to_top(self): """ MOVE_EXACT_MATCHES_TO_TOP works in multi-provider autocompleters """ matches = self.autocomp.suggest('Ma') setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches2 = self.autocomp.suggest('Ma') self.assertNotEqual(matches['stock'][0]['search_name'], matches2['stock'][0]['search_name']) setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False)
def test_facet_match_with_move_exact_matches(self): """ Exact matching still works with facet suggest """ setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) temp_autocomp = Autocompleter('faceted_stock') temp_autocomp.store_all() facets = [ { 'type': 'or', 'facets': [ {'key': 'sector', 'value': 'Technology'}, {'key': 'industry', 'value': 'Software'} ] } ] matches = temp_autocomp.suggest('Ma', facets=facets) setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches2 = temp_autocomp.suggest('Ma', facets=facets) self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name']) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False) temp_autocomp.remove_all()
def handle(self, *args, **options): # Configure loggingin level = { 0: logging.WARN, 1: logging.INFO, 2: logging.DEBUG }[options.get('verbosity', 0)] logging.basicConfig(level=level, format="%(name)s: %(levelname)s: %(message)s") self.log = logging.getLogger('commands.autocompleter_init') autocomp = Autocompleter(options["name"]) if options['remove']: self.log.info("Removing all objects for autocompleter: %s" % (options['name'])) autocomp.remove_all() if options['store']: delete_old = options['delete_old'] self.log.info("Storing all objects for autocompleter: %s" % (options['name'])) autocomp.store_all(delete_old=delete_old) if options['clear_cache']: self.log.info("Clearing cache for autocompleter: %s" % (options['name'])) autocomp.clear_cache()
class MultiMatchingPerfTestCase(AutocompleterTestCase): fixtures = ['stock_test_data.json', 'indicator_test_data.json'] num_iterations = 1000 def setUp(self): super(MultiMatchingPerfTestCase, self).setUp() self.autocomp = Autocompleter("mixed") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_repeated_matches(self): """ Matching is fast """ setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', True) setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) for i in range(1, self.num_iterations): self.autocomp.suggest('ma') for i in range(1, self.num_iterations): self.autocomp.suggest('price consumer') for i in range(1, self.num_iterations): self.autocomp.suggest('a') for i in range(1, self.num_iterations): self.autocomp.suggest('non revolving') # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MATCH_OUT_OF_ORDER_WORDS', False) setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True)
def test_store_and_remove_all_basic_with_caching(self): """ Storing and removing items all the once works with caching turned on """ # Let's turn on caching because that will store things in Redis and we want to make # sure we clean them up. setattr(auto_settings, 'CACHE_TIMEOUT', 3600) autocomp = Autocompleter("stock") autocomp.store_all() keys = self.redis.hkeys('djac.stock') self.assertEqual(len(keys), 101) autocomp = Autocompleter("stock") for i in range(0, 3): autocomp.suggest('a') autocomp.suggest('z') autocomp.exact_suggest('aapl') autocomp.exact_suggest('xyz') autocomp.remove_all() keys = self.redis.keys('djac.stock*') self.assertEqual(len(keys), 0) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0)
class IndicatorAliasedMatchTestCase(AutocompleterTestCase): fixtures = ['indicator_test_data_small.json'] def setUp(self): super(IndicatorAliasedMatchTestCase, self).setUp() self.autocomp = Autocompleter("indicator_aliased") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_basic_aliasing(self): """ Various permutations of aliased matching work """ matches = self.autocomp.suggest('us consumer price index') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('united states consumer price index') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('us cpi') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('united states consumer price index') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('u s a consumer price index') self.assertNotEqual(len(matches), 0) def test_alias_list_creation(self): """ Alias lists have replacement char variations """ provider = registry._providers_by_ac["indicator_aliased"][0] aliases = provider.get_norm_phrase_aliases() usa_aliases = aliases['usa'] self.assertTrue('u sa' in usa_aliases) self.assertTrue('us a' in usa_aliases) self.assertTrue('u s a' in usa_aliases) self.assertFalse('usa' in usa_aliases) def test_multi_term_aliasing(self): matches = self.autocomp.suggest('us consumer price index') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('usa consumer price index') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('america consumer price index') self.assertNotEqual(len(matches), 0) def test_double_aliasing(self): """ Double aliasing does not happen. California -> CA -> Canada """ matches = self.autocomp.suggest('california unemployment') self.assertEqual(len(matches), 1)
class MultiMatchingTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json'] def setUp(self): super(MultiMatchingTestCase, self).setUp() self.autocomp = Autocompleter("mixed") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_basic_match(self): """ A single autocompleter can return results from multiple models. """ matches = self.autocomp.suggest('Aapl') self.assertEqual(len(matches['stock']), 1) matches = self.autocomp.suggest('US Initial Claims') self.assertEqual(len(matches['ind']), 1) matches = self.autocomp.suggest('m') self.assertEqual(len(matches), 3) matches = self.autocomp.suggest('a') self.assertEqual(len(matches['stock']), 10) self.assertEqual(len(matches['ind']), 10) def test_min_letters_setting(self): """ MIN_LETTERS is respected in multi-type search case. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches['stock']), 10) self.assertEqual(len(matches['ind']), 10) setattr(auto_settings, 'MIN_LETTERS', 2) matches = self.autocomp.suggest('a') self.assertEqual(matches, {}) setattr(auto_settings, 'MIN_LETTERS', 1) def test_ac_provider_specific_min_letters_setting(self): """ Autocompleter/Provider specific MIN_LETTERS is respected in multi-type search case. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches['stock']), 10) self.assertEqual(len(matches['ind']), 10) registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS', 2) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS', 2) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) self.assertEqual('ind' not in matches, True) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS')
class MultiMatchingTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json'] def setUp(self): super(MultiMatchingTestCase, self).setUp() self.autocomp = Autocompleter("mixed") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_basic_match(self): """ A single autocompleter can return results from multiple models. """ matches = self.autocomp.suggest('Aapl') self.assertEqual(len(matches['stock']), 1) matches = self.autocomp.suggest('US Initial Claims') self.assertEqual(len(matches['ind']), 1) matches = self.autocomp.suggest('m') self.assertEqual(len(matches), 3) matches = self.autocomp.suggest('a') self.assertEqual(len(matches['stock']), 6) self.assertEqual(len(matches['ind']), 4) def test_min_letters_setting(self): """ MIN_LETTERS is respected in multi-type search case. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches['stock']), 6) self.assertEqual(len(matches['ind']), 4) setattr(auto_settings, 'MIN_LETTERS', 2) matches = self.autocomp.suggest('a') self.assertEqual(matches, {}) setattr(auto_settings, 'MIN_LETTERS', 1) def test_ac_provider_specific_min_letters_setting(self): """ Autocompleter/Provider specific MIN_LETTERS is respected in multi-type search case. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches['stock']), 6) self.assertEqual(len(matches['ind']), 4) registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS', 2) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS', 2) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) self.assertEqual('ind' not in matches, True) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MIN_LETTERS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MIN_LETTERS')
class StockExactMatchTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json'] def setUp(self): super(StockExactMatchTestCase, self).setUp() setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) self.autocomp = Autocompleter("stock") self.autocomp.store_all() def tearDown(self): setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0) self.autocomp.remove_all() def test_exact_suggest(self): """ Exact matching works """ matches_symbol = self.autocomp.exact_suggest('ma') self.assertEqual(len(matches_symbol), 1) def test_move_exact_matches_to_top_setting(self): """ MOVE_EXACT_MATCHES_TO_TOP works """ matches = self.autocomp.suggest('Ma') setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches2 = self.autocomp.suggest('Ma') self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name']) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False) def test_move_exact_matches_overridable_at_ac_level(self): """ MOVE_EXACT_MATCHES_TO_TOP can be set at the autocompleter level """ matches = self.autocomp.suggest('Ma') registry.set_autocompleter_setting(self.autocomp.name, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches2 = self.autocomp.suggest('Ma') registry.del_autocompleter_setting(self.autocomp.name, 'MOVE_EXACT_MATCHES_TO_TOP') self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name']) def test_exact_caching(self): """ Exact caching works """ matches = self.autocomp.exact_suggest('aapl') setattr(auto_settings, 'CACHE_TIMEOUT', 3600) for i in range(0, 10): matches2 = self.autocomp.exact_suggest('aapl') self.assertEqual(len(matches), len(matches2)) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0)
def test_exact_matches_not_stored_by_default(self): """ Exact matches are not stored by default """ autocomp = Autocompleter("stock") autocomp.store_all() keys = self.redis.keys('djac.test.stock.e.*') self.assertEqual(len(keys), 0) self.assertFalse(self.redis.exists('djac.test.stock.es')) autocomp.remove_all()
class DictProviderMatchingTestCase(AutocompleterTestCase): def setUp(self): super(DictProviderMatchingTestCase, self).setUp() self.autocomp = Autocompleter("metric") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_basic_match(self): matches = self.autocomp.suggest('m') self.assertEqual(len(matches), 1)
def test_store_and_remove_all_basic(self): """ Storing and removing items all at once works for a dictionary obj autocompleter. """ autocomp = Autocompleter("stock") autocomp.store_all() keys = self.redis.hkeys('djac.test.stock') self.assertEqual(len(keys), 104) autocomp.remove_all() keys = self.redis.keys('djac.test.stock*') self.assertEqual(len(keys), 0)
def test_dict_store_and_remove_all_basic(self): """ Storing and removing items all at once works for a single-model autocompleter. """ autocomp = Autocompleter("metric") autocomp.store_all() keys = self.redis.hkeys('djac.test.metric') self.assertEqual(len(keys), 8) autocomp.remove_all() keys = self.redis.keys('djac.test.metric') self.assertEqual(len(keys), 0)
def test_store_and_remove_all_basic(self): """ Storing and removing items all at once works for a dictionary obj autocompleter. """ autocomp = Autocompleter("stock") autocomp.store_all() keys = self.redis.hkeys('djac.test.stock') self.assertEqual(len(keys), 101) autocomp.remove_all() keys = self.redis.keys('djac.test.stock*') self.assertEqual(len(keys), 0)
def test_store_and_remove_all_basic(self): """ Storing and removing items all the once works for a single-model autocompleter. """ autocomp = Autocompleter("stock") autocomp.store_all() keys = self.redis.hkeys('djac.stock') self.assertEqual(len(keys), 101) autocomp.remove_all() keys = self.redis.keys('djac.stock*') self.assertEqual(len(keys), 0)
class CalcAutocompleteProviderTestCase(AutocompleterTestCase): fixtures = ['indicator_test_data_small.json'] def setUp(self): super(CalcAutocompleteProviderTestCase, self).setUp() self.autocomp = Autocompleter("metric_aliased") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_one_way_alias_list_creation(self): """ Test that oneway alias lists are created properly """ provider = registry._providers_by_ac["metric_aliased"][0] aliases = provider.get_norm_phrase_aliases() self.assertTrue('revenue' in aliases) self.assertFalse('turnover' in aliases) def test_one_way_aliasing(self): """ Aliases in get_one_way_phrase_aliases are not aliased both ways. """ matches = self.autocomp.suggest('revenue') self.assertEqual(len(matches), 1) matches = self.autocomp.suggest('Turnover') self.assertEqual(len(matches), 2) def test_one_way_with_two_way_alias_list_creation(self): """ Two way and one way aliases are both included/treated properly """ provider = registry._providers_by_ac["metric_aliased"][0] aliases = provider.get_norm_phrase_aliases() self.assertTrue('ev' in aliases) self.assertTrue('enterprise value' in aliases) self.assertTrue('revenue' in aliases) self.assertFalse('turnover' in aliases) def test_one_way_with_two_way_aliasing(self): """ Aliases in get_one_way_phrase_aliases are not aliased both ways. """ rev_matches = self.autocomp.suggest('revenue') turn_matches = self.autocomp.suggest('Turnover') self.assertFalse(rev_matches == turn_matches) ev_matches = self.autocomp.suggest('EV') ent_val_matches = self.autocomp.suggest('Enterprise Value') self.assertEqual(ev_matches, ent_val_matches)
class StockExactMatchTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json'] def setUp(self): super(StockExactMatchTestCase, self).setUp() setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) self.autocomp = Autocompleter("stock") self.autocomp.store_all() def tearDown(self): setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0) self.autocomp.remove_all() def test_exact_suggest(self): """ Exact matching works """ matches_symbol = self.autocomp.exact_suggest('ma') self.assertEqual(len(matches_symbol), 1) def test_move_exact_matches_to_top_setting(self): """ MOVE_EXACT_MATCHES_TO_TOP works """ matches = self.autocomp.suggest('Ma') setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches2 = self.autocomp.suggest('Ma') self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name']) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False) def test_exact_caching(self): """ Exact caching works """ matches = self.autocomp.exact_suggest('aapl') setattr(auto_settings, 'CACHE_TIMEOUT', 3600) for i in range(0, 10): matches2 = self.autocomp.exact_suggest('aapl') self.assertEqual(len(matches), len(matches2)) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0)
def test_exact_matches_stored_when_turned_on(self): """ We store exact matches when MAX_EXACT_MATCH_WORDS is turned on """ setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) autocomp = Autocompleter("stock") autocomp.store_all() keys = self.redis.keys('djac.test.stock.e.*') self.assertNotEqual(len(keys), 0) self.assertTrue(self.redis.exists('djac.test.stock.es')) autocomp.remove_all() # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
def test_selective_add_and_remove(self): """ We can exclude certain objects from the autocompleter selectively. """ autocomp = Autocompleter("indicator") autocomp.store_all() matches = autocomp.suggest('us unemployment rate') self.assertEqual(len(matches), 1) autocomp.remove_all() autocomp = Autocompleter("indicator_selective") autocomp.store_all() matches = autocomp.suggest('us unemployment rate') self.assertEqual(len(matches), 0) autocomp.remove_all()
def test_remove_all_facet_data(self): """ Calling remove_all clears all facet data """ autocomp = Autocompleter("faceted_stock") autocomp.store_all() facet_set_name = base.FACET_SET_BASE_NAME % ('faceted_stock', 'sector', 'Technology',) set_length = self.redis.zcard(facet_set_name) self.assertEqual(set_length, 12) facet_map_name = base.FACET_MAP_BASE_NAME % ('faceted_stock',) keys = self.redis.hkeys(facet_map_name) self.assertEqual(len(keys), 104) autocomp.remove_all() set_length = self.redis.zcard(facet_set_name) self.assertEqual(set_length, 0) keys = self.redis.hkeys(facet_map_name) self.assertEqual(len(keys), 0)
def test_orphan_removal(self): """ test orphan removal """ signal_registry.register(Indicator) autocomp = Autocompleter("indicator") autocomp.store_all() unemployment = Indicator.objects.get(internal_name='unemployment_rate') unemployment.name = 'free parking' unemployment.save() self.assertTrue(autocomp.suggest('free parking')[0]['id'] == 1) self.assertTrue(len(autocomp.suggest('US Unemployment Rate')) == 0) autocomp.remove_all() signal_registry.unregister(Indicator)
def test_provider_specific_max_exact_match_words_setting(self): """ We can store exact matches for 1 individual provider, and not others """ setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) registry.set_provider_setting(IndicatorAutocompleteProvider, 'MAX_EXACT_MATCH_WORDS', 0) autocomp = Autocompleter("mixed") autocomp.store_all() keys = self.redis.keys('djac.test.stock.e.*') self.assertNotEqual(len(keys), 0) self.assertTrue(self.redis.exists('djac.test.stock.es')) keys = self.redis.keys('djac.test.ind.e.*') self.assertEqual(len(keys), 0) self.assertFalse(self.redis.exists('djac.test.ind.es')) autocomp.remove_all() registry.del_provider_setting(IndicatorAutocompleteProvider, 'MAX_EXACT_MATCH_WORDS') setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
def test_store_and_remove_all_multi(self): """ Storing and removing items all the once works for a multi-model autocompleter. """ autocomp = Autocompleter("mixed") autocomp.store_all() keys = self.redis.hkeys('djac.stock') self.assertEqual(len(keys), 101) keys = self.redis.hkeys('djac.ind') self.assertEqual(len(keys), 100) autocomp.remove_all() keys = self.redis.keys('djac.stock*') self.assertEqual(len(keys), 0) keys = self.redis.keys('djac.ind*') self.assertEqual(len(keys), 0) keys = self.redis.keys('djac.mixed*') self.assertEqual(len(keys), 0)
def test_facet_mismatch_with_move_exact_matches(self): """ Exact matching shouldn't move an object that doesn't have a matching facet value """ # This test case depends on very specific data, which is why this test # issues multiple asserts to check our assumptions setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) temp_autocomp = Autocompleter('faceted_stock') temp_autocomp.store_all() facets = [ { 'type': 'and', 'facets': [ {'key': 'sector', 'value': 'Healthcare'}, {'key': 'industry', 'value': 'Healthcare Plans'}, ] } ] # When gathering suggestions for 'Un', based on the stock_data_small.json fixture, # the only match should be UnitedHealth Group Inc. when using the Healthcare sector facet matches = temp_autocomp.suggest('Un', facets=facets) self.assertEqual(len(matches), 1) self.assertEqual(matches[0]['search_name'], "UNH") # When MOVE_EXACT_MATCHES_TO_TOP is set to True and not using facets, # we are expecting Unilever to be moved to the top. setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches = temp_autocomp.suggest('Un') self.assertEqual(matches[0]['search_name'], "UN") # When MOVE_EXACT_MATCHES_TO_TOP is set to True and we are using the # Healthcare sector facet, we are expecting to see UnitedHealth group # since Unilever belongs to the Consumer Defensive sector matches = temp_autocomp.suggest('Un', facets=facets) self.assertEqual(matches[0]['search_name'], "UNH") # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False) temp_autocomp.remove_all()
def test_exact_matches_respect_max_words(self): """ We don't store exact matches greater than the number of words in MAX_EXACT_MATCH_WORDS """ setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) autocomp = Autocompleter("stock") autocomp.store_all() matches = autocomp.exact_suggest('International Business Machines Corporation') self.assertEqual(len(matches), 1) autocomp.remove_all() setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 2) autocomp = Autocompleter("stock") autocomp.store_all() matches = autocomp.exact_suggest('International Business Machines Corporation') self.assertEqual(len(matches), 0) autocomp.remove_all() # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
def handle(self, *args, **options): # Configure loggingin level = { '0': logging.WARN, '1': logging.INFO, '2': logging.DEBUG }[options.get('verbosity', '0')] logging.basicConfig(level=level, format="%(name)s: %(levelname)s: %(message)s") self.log = logging.getLogger('commands.autocompleter_init') autocomp = Autocompleter(options["name"]) if options['remove']: self.log.info("Removing all objects for autocompleter: %s" % (options['name'])) autocomp.remove_all() if options['store']: self.log.info("Storing all objects for autocompleter: %s" % (options['name'])) autocomp.store_all() if options['clear_cache']: self.log.info("Clearing cache for autocompleter: %s" % (options['name'])) autocomp.clear_cache()
def test_exact_matches_respect_max_words(self): """ We don't store exact matches greater than the number of words in MAX_EXACT_MATCH_WORDS """ setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) autocomp = Autocompleter("stock") autocomp.store_all() matches = autocomp.exact_suggest( 'International Business Machines Corporation') self.assertEqual(len(matches), 1) autocomp.remove_all() setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 2) autocomp = Autocompleter("stock") autocomp.store_all() matches = autocomp.exact_suggest( 'International Business Machines Corporation') self.assertEqual(len(matches), 0) autocomp.remove_all() # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0)
def test_store_and_remove_all_multi(self): """ Storing and removing items all at once works for a multi-model autocompleter. """ autocomp = Autocompleter("mixed") autocomp.store_all() keys = self.redis.hkeys('djac.test.stock') self.assertEqual(len(keys), 101) keys = self.redis.hkeys('djac.test.ind') self.assertEqual(len(keys), 100) keys = self.redis.hkeys('djac.test.metric') self.assertEqual(len(keys), 8) autocomp.remove_all() keys = self.redis.keys('djac.test.stock*') self.assertEqual(len(keys), 0) keys = self.redis.keys('djac.test.ind*') self.assertEqual(len(keys), 0) keys = self.redis.keys('djac.test.mixed*') self.assertEqual(len(keys), 0) keys = self.redis.keys('djac.test.metric*') self.assertEqual(len(keys), 0)
class TestExactSuggestView(AutocompleterTestCase): fixtures = ['stock_test_data_small.json'] def setUp(self): super(TestExactSuggestView, self).setUp() setattr(settings, 'MAX_EXACT_MATCH_WORDS', 10) self.autocomp = Autocompleter('stock') self.autocomp.store_all() def tearDown(self): setattr(settings, 'MAX_EXACT_MATCH_WORDS', 0) self.autocomp.remove_all() def test_simple_exact_suggest_match(self): """ ExactSuggestView returns 200 status code and correct number of results on match """ exact_suggest_url = reverse('exact_suggest', kwargs={'name': 'stock'}) matches_symbol = self.autocomp.exact_suggest('ma') response = self.client.get(exact_suggest_url, data={settings.SUGGEST_PARAMETER_NAME: 'ma'}) self.assertEqual(response.status_code, 200) json_response = json.loads(response.content.decode('utf-8')) self.assertGreaterEqual(len(json_response), 1) self.assertEqual(len(json_response), len(matches_symbol)) def test_no_exact_suggest_match(self): """ ExactSuggestView returns 200 status code when there is no match """ url = reverse('exact_suggest', kwargs={'name': 'stock'}) matches_symbol = self.autocomp.exact_suggest('gobblygook') response = self.client.get(url, data={settings.SUGGEST_PARAMETER_NAME: 'gobblygook'}) self.assertEqual(response.status_code, 200) json_response = json.loads(response.content.decode('utf-8')) self.assertEqual(len(json_response), len(matches_symbol))
def test_exact_match_low_score_still_at_top(self): """ Exact matching when using facets should push low scoring object to top if exact match """ # The setup for this test case is that we have three stocks that begin with the letter Z # but limit our MAX_RESULTS setting to just 2. # With MOVE_EXACT_MATCHES_TO_TOP initially set to False, we do not expect to see the # stock with symbol 'Z' in the suggest results since it has the lowest market cap of the 3 which is # what we base the score off of. # Once we set MOVE_EXACT_MATCHES_TO_TOP to True we expect Z to be right at the top even though # it didn't even show up in the previous suggest call since it is an exact match. setattr(auto_settings, 'MAX_RESULTS', 2) setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 10) temp_autocomp = Autocompleter('faceted_stock') temp_autocomp.store_all() facets = [ { 'type': 'and', 'facets': [ {'key': 'sector', 'value': 'Technology'}, {'key': 'industry', 'value': 'Software'}, ] } ] matches = temp_autocomp.suggest('Z', facets=facets) search_names = [match['search_name'] for match in matches] self.assertTrue('Z' not in search_names) setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches = temp_autocomp.suggest('Z', facets=facets) self.assertTrue(matches[0]['search_name'] == 'Z') setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False) setattr(auto_settings, 'MAX_RESULTS', 10) setattr(auto_settings, 'MAX_EXACT_MATCH_WORDS', 0) temp_autocomp.remove_all()
class ElasticMatchingTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json'] def setUp(self): super(ElasticMatchingTestCase, self).setUp() self.autocomp = Autocompleter("mixed") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_basic_match(self): """ Test basic multiple matching works """ matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 10) self.assertEqual(len(matches['metric']), 1) def test_matching_with_max_results_cap(self): """ Test that basic matching with results limit works """ registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 5) matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 5) self.assertEqual(len(matches['metric']), 1) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS') def test_matching_with_max_results_cap_and_elasticity(self): """ Test that simple elastic results """ registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 5) setattr(auto_settings, 'ELASTIC_RESULTS', True) matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 9) self.assertEqual(len(matches['metric']), 1) setattr(auto_settings, 'ELASTIC_RESULTS', False) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS') def test_matching_with_uneven_max_results_cap_and_elasticity(self): """ Test uneven redistribution of surplus result slots """ registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 4) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 6) setattr(auto_settings, 'ELASTIC_RESULTS', True) matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 9) self.assertEqual(len(matches['metric']), 1) setattr(auto_settings, 'ELASTIC_RESULTS', False) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS')
class StockMatchTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json'] def setUp(self): super(StockMatchTestCase, self).setUp() self.autocomp = Autocompleter("stock") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_simple_match(self): """ Basic matching works """ matches_symbol = self.autocomp.suggest('a') self.assertEqual(len(matches_symbol), 10) def test_no_match(self): """ Phrases that match nothing work """ matches_symbol = self.autocomp.suggest('gobblygook') self.assertEqual(len(matches_symbol), 0) def test_dual_term_matches(self): """ Items in autocompleter can match against multiple unique terms """ matches_symbol = self.autocomp.suggest('AAPL') self.assertEqual(len(matches_symbol), 1) matches_name = self.autocomp.suggest('Apple') self.assertEqual(len(matches_name), 1) def test_accented_matches(self): """ Accented phrases match against both their orignal accented form, and their non-accented basic form. """ matches = self.autocomp.suggest('estee lauder') self.assertEqual(len(matches), 1) self.assertEqual(matches[0]['search_name'], 'EL') matches = self.autocomp.suggest(u'estée lauder') self.assertEqual(len(matches), 1) self.assertEqual(matches[0]['search_name'], 'EL') def test_max_results_setting(self): """ MAX_RESULTS is respected. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) setattr(auto_settings, 'MAX_RESULTS', 2) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 2) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MAX_RESULTS', 10) def test_ac_specific_max_results_setting(self): """ Autocompleter specific MAX_RESULTS is respected """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) registry.set_autocompleter_setting('stock', 'MAX_RESULTS', 5) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 5) # Must set the setting back to where it was as it will persist registry.del_autocompleter_setting('stock', 'MAX_RESULTS') def test_caching(self): """ Caching works """ matches = self.autocomp.suggest('a') setattr(auto_settings, 'CACHE_TIMEOUT', 3600) for i in range(0, 3): matches2 = self.autocomp.suggest('a') self.assertEqual(len(matches), len(matches2)) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0) def test_dropped_character_matching(self): """ Searching for things that would be normalized to ' ' do not result in redis errors. """ matches = self.autocomp.suggest('+') self.assertEqual(len(matches), 0) matches = self.autocomp.suggest('NBBC vs Regional - Mid-Atlantic Banks vs Financial') self.assertEqual(len(matches), 0)
class IndicatorMatchTestCase(AutocompleterTestCase): fixtures = ['indicator_test_data_small.json'] def setUp(self): super(IndicatorMatchTestCase, self).setUp() self.autocomp = Autocompleter("indicator") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_same_score_word_based_id_ordering(self): """ Two results with the same score are returned in lexographic order of object ID """ matches = self.autocomp.suggest('us') self.assertEqual(matches[1]['display_name'], 'US Dollar to Australian Dollar Exchange Rate') self.assertEqual(matches[9]['display_name'], 'US Dollar to Chinese Yuan Exchange Rate') return matches def test_join_char_replacement(self): """ Dashes are handled correctly """ # Testing that both '3-month' and '3 month' match matches = self.autocomp.suggest('3-month') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('3 month') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('mortgage-backed') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('mortgagebacked') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('mortgage backed') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('backed mortgage') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('U S A') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('U SA') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('USA') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('U-S-A') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('U/S/A') self.assertNotEqual(len(matches), 0) matches = self.autocomp.suggest('U-S/A') self.assertNotEqual(len(matches), 0) def test_min_letters_setting(self): """ MIN_LETTERS is respected. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) setattr(auto_settings, 'MIN_LETTERS', 2) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 0) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MIN_LETTERS', 1) def test_ac_provider_specific_min_letters_setting(self): """ Autocompleter/Provider specific MIN_LETTERS is respected. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) setattr(auto_settings, 'MIN_LETTERS', 2) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 0) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MIN_LETTERS', 1)
class StockMatchTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json'] def setUp(self): super(StockMatchTestCase, self).setUp() self.autocomp = Autocompleter("stock") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_simple_match(self): """ Basic matching works """ matches_symbol = self.autocomp.suggest('a') self.assertEqual(len(matches_symbol), 10) def test_no_match(self): """ Phrases that match nothing work """ matches_symbol = self.autocomp.suggest('gobblygook') self.assertEqual(len(matches_symbol), 0) def test_dual_term_matches(self): """ Items in autocompleter can match against multiple unique terms """ matches_symbol = self.autocomp.suggest('AAPL') self.assertEqual(len(matches_symbol), 1) matches_name = self.autocomp.suggest('Apple') self.assertEqual(len(matches_name), 1) def test_accented_matches(self): """ Accented phrases match against both their orignal accented form, and their non-accented basic form. """ matches = self.autocomp.suggest('estee lauder') self.assertEqual(len(matches), 1) self.assertEqual(matches[0]['search_name'], 'EL') matches = self.autocomp.suggest(u'estée lauder') self.assertEqual(len(matches), 1) self.assertEqual(matches[0]['search_name'], 'EL') def test_max_results_setting(self): """ MAX_RESULTS is respected. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) setattr(auto_settings, 'MAX_RESULTS', 2) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 2) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MAX_RESULTS', 10) def test_ac_provider_specific_max_results_setting(self): """ Autocompleter/Provider specific MAX_RESULTS is respected """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) registry.set_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS', 5) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 5) # Must set the setting back to where it was as it will persist registry.del_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS') def test_caching(self): """ Caching works """ matches = self.autocomp.suggest('a') setattr(auto_settings, 'CACHE_TIMEOUT', 3600) for i in range(0, 3): matches2 = self.autocomp.suggest('a') self.assertEqual(len(matches), len(matches2)) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0) def test_dropped_character_matching(self): """ Searching for things that would be normalized to ' ' do not result in redis errors. """ matches = self.autocomp.suggest('+') self.assertEqual(len(matches), 0) matches = self.autocomp.suggest('NBBC vs Regional - Mid-Atlantic Banks vs Financial') self.assertEqual(len(matches), 0)
class ElasticMatchingTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json', 'indicator_test_data_small.json'] def setUp(self): super(ElasticMatchingTestCase, self).setUp() self.autocomp = Autocompleter("mixed") self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_basic_match(self): """ Test basic multiple matching works """ matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 10) self.assertEqual(len(matches['metric']), 1) def test_matching_with_max_results_cap(self): """ Test that basic matching with results limit works """ registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 5) matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 5) self.assertEqual(len(matches['metric']), 1) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS') def test_matching_with_max_results_cap_and_elasticity(self): """ Test that simple elastic results """ registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 5) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 5) setattr(auto_settings, 'ELASTIC_RESULTS', True) matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 9) self.assertEqual(len(matches['metric']), 1) setattr(auto_settings, 'ELASTIC_RESULTS', False) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS') def test_matching_with_uneven_max_results_cap_and_elasticity(self): """ Test uneven redistribution of surplus result slots """ registry.set_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS',5) registry.set_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS', 4) registry.set_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS', 6) setattr(auto_settings, 'ELASTIC_RESULTS', True) matches = self.autocomp.suggest('pe') self.assertEqual(len(matches['stock']), 5) self.assertEqual(len(matches['ind']), 9) self.assertEqual(len(matches['metric']), 1) setattr(auto_settings, 'ELASTIC_RESULTS', False) registry.del_ac_provider_setting("mixed", IndicatorAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", StockAutocompleteProvider, 'MAX_RESULTS') registry.del_ac_provider_setting("mixed", CalcAutocompleteProvider, 'MAX_RESULTS')
class TextFacetSuggestView(AutocompleterTestCase): fixtures = ['stock_test_data_small.json'] def setUp(self): super(TextFacetSuggestView, self).setUp() self.autocomp = Autocompleter('faceted_stock') self.autocomp.store_all() def tearDown(self): self.autocomp.remove_all() def test_facet_suggest_match(self): """ Using suggest view works with facets """ suggest_url = reverse('suggest', kwargs={'name': 'faceted_stock'}) facets = [ { 'type': 'or', 'facets': [{'key': 'sector', 'value': 'Technology'}] } ] matches_symbol = self.autocomp.suggest('a', facets=facets) data = { settings.SUGGEST_PARAMETER_NAME: 'a', settings.FACET_PARAMETER_NAME: json.dumps(facets) } response = self.client.get(suggest_url, data=data) self.assertEqual(response.status_code, 200) json_response = json.loads(response.content.decode('utf-8')) self.assertEqual(len(json_response), len(matches_symbol)) def test_empty_facet_suggest(self): """ An empty facet parameter still returns 200 response """ suggest_url = reverse('suggest', kwargs={'name': 'faceted_stock'}) matches_symbol = self.autocomp.suggest('a', facets=[]) data = { settings.SUGGEST_PARAMETER_NAME: 'a', settings.FACET_PARAMETER_NAME: json.dumps([]) } response = self.client.get(suggest_url, data=data) self.assertEqual(response.status_code, 200) json_response = json.loads(response.content.decode('utf-8')) self.assertEqual(len(json_response), len(matches_symbol)) def test_invalid_facet(self): """ An invalid facet should return a 400 response """ suggest_url = reverse('suggest', kwargs={'name': 'faceted_stock'}) no_type_facets = [ { 'facets': [{'key': 'sector', 'value': 'Technology'}] } ] data = { settings.SUGGEST_PARAMETER_NAME: 'a', settings.FACET_PARAMETER_NAME: json.dumps(no_type_facets) } response = self.client.get(suggest_url, data=data) self.assertEqual(response.status_code, 400)
class StockMatchTestCase(AutocompleterTestCase): fixtures = ['stock_test_data_small.json'] def setUp(self): self.autocomp = Autocompleter("stock") self.autocomp.store_all() super(StockMatchTestCase, self).setUp() def tearDown(self): self.autocomp.remove_all() def test_simple_match(self): """ Basic matching works """ matches_symbol = self.autocomp.suggest('a') self.assertEqual(len(matches_symbol), 10) def test_exact_match(self): """ Exact matching works """ matches_symbol = self.autocomp.exact_suggest('ma') self.assertEqual(len(matches_symbol), 1) def test_no_match(self): """ Phrases that match nothing work """ matches_symbol = self.autocomp.suggest('gobblygook') self.assertEqual(len(matches_symbol), 0) def test_dual_term_matches(self): """ Items in autocompleter can match against multiple unique terms """ matches_symbol = self.autocomp.suggest('AAPL') self.assertEqual(len(matches_symbol), 1) matches_name = self.autocomp.suggest('Apple') self.assertEqual(len(matches_name), 1) def test_accented_matches(self): """ Accented phrases match against both their orignal accented form, and their non-accented basic form. """ matches = self.autocomp.suggest('estee lauder') self.assertEqual(len(matches), 1) self.assertEqual(matches[0]['search_name'], 'EL') matches = self.autocomp.suggest(u'estée lauder') self.assertEqual(len(matches), 1) self.assertEqual(matches[0]['search_name'], 'EL') def test_exact_matches_setting(self): """ MOVE_EXACT_MATCHES_TO_TOP works """ matches = self.autocomp.suggest('Ma') setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', True) matches2 = self.autocomp.suggest('Ma') self.assertNotEqual(matches[0]['search_name'], matches2[0]['search_name']) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MOVE_EXACT_MATCHES_TO_TOP', False) def test_max_results_setting(self): """ MAX_RESULTS is respected. """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) setattr(auto_settings, 'MAX_RESULTS', 2) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 2) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'MAX_RESULTS', 10) def test_ac_provider_specific_max_results_setting(self): """ Autocompleter/Provider specific MAX_RESULTS is respected """ matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 10) registry.set_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS', 5) matches = self.autocomp.suggest('a') self.assertEqual(len(matches), 5) # Must set the setting back to where it was as it will persist registry.del_ac_provider_setting("stock", StockAutocompleteProvider, 'MAX_RESULTS') def test_caching(self): """ Caching works """ matches = self.autocomp.suggest('a') setattr(auto_settings, 'CACHE_TIMEOUT', 3600) for i in range(0, 3): matches2 = self.autocomp.suggest('a') self.assertEqual(len(matches), len(matches2)) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0) def test_exact_caching(self): """ Exact caching works """ matches = self.autocomp.exact_suggest('aapl') setattr(auto_settings, 'CACHE_TIMEOUT', 3600) for i in range(0, 10): matches2 = self.autocomp.exact_suggest('aapl') self.assertEqual(len(matches), len(matches2)) # Must set the setting back to where it was as it will persist setattr(auto_settings, 'CACHE_TIMEOUT', 0)