avoid erroneous global searches

This commit is contained in:
Cal 2024-05-28 12:06:51 -06:00
parent 3b84ec1b42
commit bb2528276b
2 changed files with 48 additions and 22 deletions

View file

@ -392,7 +392,7 @@ def parse_sdescs_and_recogs(
# if no sdesc, include key plus aliases instead # if no sdesc, include key plus aliases instead
else: else:
candidate_map.append((obj, obj.key)) candidate_map.append((obj, obj.key))
candidate_map.extend([(obj, alias) for alias in obj.aliases.all()]) candidate_map.extend([(obj, alias) for alias in obj.aliases.all()])
# escape mapping syntax on the form {#id} if it exists already in emote, # escape mapping syntax on the form {#id} if it exists already in emote,
# if so it is replaced with just "id". # if so it is replaced with just "id".
@ -439,7 +439,7 @@ def parse_sdescs_and_recogs(
(re.search(rquery, text, _RE_FLAGS), obj, text) for obj, text in candidate_map (re.search(rquery, text, _RE_FLAGS), obj, text) for obj, text in candidate_map
) )
# filter out any non-matching candidates # filter out any non-matching candidates
bestmatches = [(obj, match.group()) for match, obj, text in matches if match] bestmatches = [(obj, m.group()) for m, obj, text in matches if m]
else: else:
# to find the longest match, we start from the marker and lengthen the # to find the longest match, we start from the marker and lengthen the
@ -1333,30 +1333,28 @@ class ContribRPObject(DefaultObject):
""" """
# we also want to use the default search method # we also want to use the default search method
search_obj = super().get_search_result search_obj = super().get_search_result
is_builder = self.locks.check_lockstring(self, "perm(Builder)") is_builder = self.permissions.check("Builder")
results = []
if candidates: if candidates is not None:
candidates = parse_sdescs_and_recogs( searched_results = parse_sdescs_and_recogs(
self, candidates, _PREFIX + searchdata, search_mode=True self, candidates, _PREFIX + searchdata, search_mode=True
) )
results = [] if not searched_results and is_builder:
for candidate in candidates: # builders get to do a search by key
# we search by candidate keys here; this allows full error results = search_obj(searchdata, candidates=candidates, **kwargs)
# management and use of all kwargs - we will use searchdata else:
# in eventual error reporting later (not their keys). Doing # we do a default search on each result by key, here, to apply extra filtering kwargs
# it like this e.g. allows for use of the typeclass kwarg for searched_obj in searched_results:
# limiter. results.extend(
results.extend( [
[obj for obj in search_obj(candidate.key, **kwargs) if obj not in results] obj
) for obj in search_obj(searched_obj.key, candidates=candidates, **kwargs)
if obj not in results
if not results and is_builder: ]
# builders get to do a global search by key+alias )
results = search_obj(searchdata, **kwargs)
else: else:
# global searches with #drefs end up here. Global searches are # no candidates means it's a global search, so we pass it back to the default
# only done in code, so is controlled, #dbrefs are turned off
# for non-Builders.
results = search_obj(searchdata, **kwargs) results = search_obj(searchdata, **kwargs)
return results return results

View file

@ -346,6 +346,34 @@ class TestRPSystem(BaseEvenniaTest):
self.assertEqual(self.speaker.search("receiver of emotes"), self.receiver1) self.assertEqual(self.speaker.search("receiver of emotes"), self.receiver1)
self.assertEqual(self.speaker.search("colliding"), self.receiver2) self.assertEqual(self.speaker.search("colliding"), self.receiver2)
def test_get_search_result(self):
self.obj1 = create_object(rpsystem.ContribRPObject, key="Obj1", location=self.room)
self.obj1.sdesc.add("something")
self.obj2 = create_object(rpsystem.ContribRPCharacter, key="Obj2", location=self.room)
self.obj2.sdesc.add("something")
candidates = [self.obj1, self.obj2]
# search candidates by sdesc: both objects should be found
result = self.speaker.get_search_result("something", candidates)
self.assertIn(self.obj1, result)
self.assertIn(self.obj2, result)
# search empty candidates: no objects should be found
result = self.speaker.get_search_result("something", candidates=[])
self.assertNotIn(self.obj1, result)
self.assertNotIn(self.obj2, result)
# typeclass was given: only matching object should be found
result = self.speaker.get_search_result(
"something", candidates=candidates, typeclass=rpsystem.ContribRPCharacter
)
self.assertNotIn(self.obj1, result)
self.assertIn(self.obj2, result)
# search by key with player permissions: no objects should be found
result = self.speaker.get_search_result("obj1", candidates)
self.assertNotIn(self.obj1, result)
# search by key with builder permissions: object should be found
self.speaker.permissions.add("builder")
result = self.speaker.get_search_result("obj1", candidates)
self.assertIn(self.obj1, result)
class TestRPSystemCommands(BaseEvenniaCommandTest): class TestRPSystemCommands(BaseEvenniaCommandTest):
def setUp(self): def setUp(self):