add a manager query for level-up-able characters

will be used by the IRC plugin

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
Brian S. Stephan 2024-05-15 12:00:14 -05:00
parent 2730978663
commit 15df477fa4
Signed by: bss
GPG Key ID: 3DE06D3180895FCB
2 changed files with 53 additions and 0 deletions

View File

@ -86,6 +86,19 @@ class CharacterManager(models.Manager):
character.game.name, character.name, character.next_level)
return character
def levelable(self, game) -> models.QuerySet:
"""Provide the characters that are ready to level.
Args:
game: the game instance to filter characters on
Returns:
QuerySet of the characters that can be leveled up
"""
if not game.active:
raise ValueError(f"{game.name} is not an active game!")
return self.filter(enabled=True, status=Character.CHARACTER_STATUS_LOGGED_IN,
next_level__lte=timezone.now(), game=game)
class Character(models.Model):
"""A character in a game."""

View File

@ -218,3 +218,43 @@ class CharacterTest(TestCase):
char.log_out()
with self.assertRaises(ValueError):
char.level_up()
def test_levelable_query(self):
"""Test that the right things are returned by the levelable query used to find characters to update."""
game = Game.objects.get(pk=1)
# base data is one character ready to level
assert len(Character.objects.levelable(game)) == 1
# add one to fiddle with
with patch('django.utils.timezone.now', return_value=timezone.now() - timedelta(days=1)):
new_char = Character.objects.register('levelable-test', game, 'pass',
'bss!bss@levelable_test', 'unit tester')
assert len(Character.objects.levelable(game)) == 2
# log the new one out
new_char.log_out()
new_char.save()
assert len(Character.objects.levelable(game)) == 1
# log the new one back in but penalize it heavily
new_char.log_in('pass', 'bss!bss@levelable_test')
new_char.save()
assert len(Character.objects.levelable(game)) == 2
new_char.penalize(60*60*24*2, 'test')
new_char.save()
assert len(Character.objects.levelable(game)) == 1
# actually level them
new_char.next_level = timezone.now() - timedelta(seconds=30)
new_char.save()
assert len(Character.objects.levelable(game)) == 2
new_char.level_up()
new_char.save()
assert len(Character.objects.levelable(game)) == 1
def test_levelable_query_bad_game(self):
"""Test that trying to find levelable characters for a non-active game errors."""
game = Game.objects.get(pk=1)
game.active = False
game.save()
with self.assertRaises(ValueError):
Character.objects.levelable(game)
# clean up
game.active = True
game.save()