unique constraint for only one hostmask enabled at a time
this replaces the need for a game+hostmask unique constraint, with this change, a player can only have one active character they're playing with anyway, regardless of how many games there are Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
parent
d0531bff53
commit
2ad79285b3
@ -0,0 +1,26 @@
|
||||
# Generated by Django 5.0.5 on 2024-05-14 16:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('idlerpg', '0006_alter_character_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveConstraint(
|
||||
model_name='character',
|
||||
name='one_player_character_per_game',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='character',
|
||||
name='enabled',
|
||||
field=models.BooleanField(default=True),
|
||||
),
|
||||
migrations.AddConstraint(
|
||||
model_name='character',
|
||||
constraint=models.UniqueConstraint(condition=models.Q(('enabled', True)), fields=('hostmask',), name='one_enabled_character_at_a_time'),
|
||||
),
|
||||
]
|
@ -95,6 +95,7 @@ class Character(models.Model):
|
||||
password = models.CharField(max_length=256)
|
||||
hostmask = models.CharField(max_length=256)
|
||||
status = models.CharField(max_length=8, choices=CHARACTER_STATUSES, default='OFFLINE')
|
||||
enabled = models.BooleanField(default=True)
|
||||
|
||||
character_class = models.CharField(max_length=30)
|
||||
level = models.PositiveIntegerField(default=0)
|
||||
@ -119,7 +120,8 @@ class Character(models.Model):
|
||||
"""Options for the Character and its objects."""
|
||||
|
||||
constraints = [
|
||||
models.UniqueConstraint("game", "hostmask", name="one_player_character_per_game"),
|
||||
models.UniqueConstraint(fields=['hostmask'], condition=models.Q(enabled=True),
|
||||
name='one_enabled_character_at_a_time'),
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
|
@ -7,6 +7,8 @@ import logging
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.utils import IntegrityError
|
||||
from django.test import TestCase
|
||||
from django.utils import timezone
|
||||
|
||||
@ -152,6 +154,27 @@ class CharacterTest(TestCase):
|
||||
assert new_char.last_login == register_time
|
||||
assert new_char.password[0:13] == 'pbkdf2_sha256'
|
||||
|
||||
def test_cant_register_twice(self):
|
||||
"""Test that we get a unique constraint error if we try to make a second enabled character."""
|
||||
game = Game.objects.get(pk=1)
|
||||
|
||||
register_time = timezone.now()
|
||||
with patch('django.utils.timezone.now', return_value=register_time):
|
||||
new_char = Character.objects.register('new1', game, 'pass', 'bss!bss@test_double_register', 'unit tester')
|
||||
with self.assertRaises(IntegrityError):
|
||||
with transaction.atomic():
|
||||
Character.objects.register('new2', game, 'pass', 'bss!bss@test_double_register', 'unit tester')
|
||||
|
||||
# try again with the first character un-enabled
|
||||
new_char.enabled = False
|
||||
new_char.save()
|
||||
|
||||
register_time = timezone.now()
|
||||
with patch('django.utils.timezone.now', return_value=register_time):
|
||||
newer_char = Character.objects.register('new2', game, 'pass', 'bss!bss@test_double_register', 'unit tester')
|
||||
|
||||
assert new_char.hostmask == newer_char.hostmask
|
||||
|
||||
def test_level_up(self):
|
||||
"""Test the level up functionality."""
|
||||
char = Character.objects.get(pk=1)
|
||||
|
Loading…
Reference in New Issue
Block a user