434 lines
12 KiB
Python
434 lines
12 KiB
Python
# vim: set fileencoding=utf-8
|
|
import unittest
|
|
from unittest.mock import Mock
|
|
|
|
from bemani.backend.jubeat.prop import JubeatProp
|
|
from bemani.common import ValidatedDict
|
|
from bemani.data.types import Achievement, UserID
|
|
|
|
|
|
class TestJubeatProp(unittest.TestCase):
|
|
|
|
def test_increment_class(self) -> None:
|
|
# Verify normal increase
|
|
self.assertEqual(JubeatProp._increment_class(1, 5), (1, 4))
|
|
self.assertEqual(JubeatProp._increment_class(1, 4), (1, 3))
|
|
self.assertEqual(JubeatProp._increment_class(3, 3), (3, 2))
|
|
|
|
# Verify bumping class when minor class is at max
|
|
self.assertEqual(JubeatProp._increment_class(1, 1), (2, 5))
|
|
self.assertEqual(JubeatProp._increment_class(2, 1), (3, 5))
|
|
|
|
# Verify bumping class to legend which only has one subclass
|
|
self.assertEqual(JubeatProp._increment_class(3, 1), (4, 1))
|
|
|
|
# Verify bumping when already at max
|
|
self.assertEqual(JubeatProp._increment_class(4, 1), (4, 1))
|
|
|
|
def test_decrement_class(self) -> None:
|
|
# Verify normal decrease
|
|
self.assertEqual(JubeatProp._decrement_class(1, 3), (1, 4))
|
|
self.assertEqual(JubeatProp._decrement_class(1, 4), (1, 5))
|
|
self.assertEqual(JubeatProp._decrement_class(3, 2), (3, 3))
|
|
|
|
# Verify demoting class when minor class is at min
|
|
self.assertEqual(JubeatProp._decrement_class(2, 5), (1, 1))
|
|
self.assertEqual(JubeatProp._decrement_class(3, 5), (2, 1))
|
|
|
|
# Verify demoting class when starting at legend
|
|
self.assertEqual(JubeatProp._decrement_class(4, 1), (3, 1))
|
|
|
|
# Verify decrease when already at min
|
|
self.assertEqual(JubeatProp._decrement_class(1, 5), (1, 5))
|
|
|
|
def test_get_league_buckets(self) -> None:
|
|
# Verify correct behavior with empty input
|
|
self.assertEqual(
|
|
JubeatProp._get_league_buckets(
|
|
[],
|
|
),
|
|
(
|
|
[],
|
|
[],
|
|
[],
|
|
),
|
|
)
|
|
|
|
# Verify correct behavior with only one entrant (should be promoted)
|
|
self.assertEqual(
|
|
JubeatProp._get_league_buckets(
|
|
[
|
|
(5, 12345),
|
|
],
|
|
),
|
|
(
|
|
[
|
|
5,
|
|
],
|
|
[],
|
|
[],
|
|
),
|
|
)
|
|
|
|
# Verify correct behavior with two entrants (should be one promotion, one demotion)
|
|
self.assertEqual(
|
|
JubeatProp._get_league_buckets(
|
|
[
|
|
(5, 12345),
|
|
(7, 54321),
|
|
],
|
|
),
|
|
(
|
|
[
|
|
7,
|
|
],
|
|
[],
|
|
[
|
|
5,
|
|
],
|
|
),
|
|
)
|
|
|
|
# Verify correct behavior with three entrants (should be one promotion, one demotion, one same)
|
|
self.assertEqual(
|
|
JubeatProp._get_league_buckets(
|
|
[
|
|
(5, 12345),
|
|
(7, 54321),
|
|
(9, 33333),
|
|
],
|
|
),
|
|
(
|
|
[
|
|
7,
|
|
],
|
|
[
|
|
9,
|
|
],
|
|
[
|
|
5,
|
|
],
|
|
),
|
|
)
|
|
|
|
# Verify correct behavior with ten entrants (should be 3 promotions, 3 demotions, 4 same)
|
|
self.assertEqual(
|
|
JubeatProp._get_league_buckets(
|
|
[
|
|
(5, 55555),
|
|
(7, 77777),
|
|
(9, 99999),
|
|
(1, 11111),
|
|
(6, 66666),
|
|
(8, 88888),
|
|
(2, 22222),
|
|
(3, 33333),
|
|
(10, 100000),
|
|
(4, 44444),
|
|
],
|
|
),
|
|
(
|
|
[
|
|
10,
|
|
9,
|
|
8,
|
|
],
|
|
[
|
|
7,
|
|
6,
|
|
5,
|
|
4,
|
|
],
|
|
[
|
|
3,
|
|
2,
|
|
1,
|
|
],
|
|
),
|
|
)
|
|
|
|
def test_get_league_scores(self) -> None:
|
|
data = Mock()
|
|
data.local = Mock()
|
|
data.local.user = Mock()
|
|
|
|
# Test correct behavior on empty input
|
|
self.assertEqual(
|
|
JubeatProp._get_league_scores(
|
|
None,
|
|
999,
|
|
[]
|
|
),
|
|
(
|
|
[],
|
|
[],
|
|
),
|
|
)
|
|
|
|
# Test that we can load last week's score if it exists for a user
|
|
data.local.user.get_achievement = Mock(return_value={'score': [123, 456, 789]})
|
|
self.assertEqual(
|
|
JubeatProp._get_league_scores(
|
|
data,
|
|
999,
|
|
[(UserID(1337), {})],
|
|
),
|
|
(
|
|
[(1337, 1368)],
|
|
[],
|
|
),
|
|
)
|
|
data.local.user.get_achievement.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
998,
|
|
'league',
|
|
)
|
|
data.local.user.get_achievement.reset_mock()
|
|
|
|
# Test that if it doesn't exist last week they get marked as absent
|
|
data.local.user.get_achievement = Mock(return_value=None)
|
|
self.assertEqual(
|
|
JubeatProp._get_league_scores(
|
|
data,
|
|
999,
|
|
[(UserID(1337), {})],
|
|
),
|
|
(
|
|
[],
|
|
[1337],
|
|
),
|
|
)
|
|
data.local.user.get_achievement.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
998,
|
|
'league',
|
|
)
|
|
data.local.user.get_achievement.reset_mock()
|
|
|
|
def test_get_league_absentees(self) -> None:
|
|
data = Mock()
|
|
data.local = Mock()
|
|
data.local.user = Mock()
|
|
|
|
# Test that we do the right thing with empty input
|
|
self.assertEqual(
|
|
JubeatProp._get_league_absentees(
|
|
None,
|
|
999,
|
|
[],
|
|
),
|
|
[],
|
|
)
|
|
|
|
# Test that a user who never played doesn't get flagged absentee
|
|
data.local.user.get_achievements = Mock(return_value=[])
|
|
self.assertEqual(
|
|
JubeatProp._get_league_absentees(
|
|
data,
|
|
999,
|
|
[1337],
|
|
),
|
|
[],
|
|
)
|
|
data.local.user.get_achievements.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
)
|
|
data.local.user.get_achievements.reset_mock()
|
|
|
|
# Test that a user who only skipped last week doesn't get flagged absentee
|
|
data.local.user.get_achievements = Mock(return_value=[
|
|
Achievement(997, 'league', None, {}),
|
|
])
|
|
self.assertEqual(
|
|
JubeatProp._get_league_absentees(
|
|
data,
|
|
999,
|
|
[1337],
|
|
),
|
|
[],
|
|
)
|
|
data.local.user.get_achievements.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
)
|
|
data.local.user.get_achievements.reset_mock()
|
|
|
|
# Test that a user who skipped last two week gets flagged absentee
|
|
data.local.user.get_achievements = Mock(return_value=[
|
|
Achievement(996, 'league', None, {}),
|
|
])
|
|
self.assertEqual(
|
|
JubeatProp._get_league_absentees(
|
|
data,
|
|
999,
|
|
[1337],
|
|
),
|
|
[1337],
|
|
)
|
|
data.local.user.get_achievements.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
)
|
|
data.local.user.get_achievements.reset_mock()
|
|
|
|
# Test that a user who skipped last three week doesn't get flagged
|
|
# (they got flagged last week)
|
|
data.local.user.get_achievements = Mock(return_value=[
|
|
Achievement(995, 'league', None, {}),
|
|
])
|
|
self.assertEqual(
|
|
JubeatProp._get_league_absentees(
|
|
data,
|
|
999,
|
|
[1337],
|
|
),
|
|
[],
|
|
)
|
|
data.local.user.get_achievements.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
)
|
|
data.local.user.get_achievements.reset_mock()
|
|
|
|
# Test that a user who skipped last four week gets flagged absentee
|
|
data.local.user.get_achievements = Mock(return_value=[
|
|
Achievement(994, 'league', None, {}),
|
|
])
|
|
self.assertEqual(
|
|
JubeatProp._get_league_absentees(
|
|
data,
|
|
999,
|
|
[1337],
|
|
),
|
|
[1337],
|
|
)
|
|
data.local.user.get_achievements.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
)
|
|
data.local.user.get_achievements.reset_mock()
|
|
|
|
def test_modify_profile(self) -> None:
|
|
data = Mock()
|
|
data.local = Mock()
|
|
data.local.user = Mock()
|
|
|
|
# Test demoting a user at the bottom does nothing.
|
|
data.local.user.get_profile = Mock(return_value=ValidatedDict({
|
|
'league_class': 1,
|
|
'league_subclass': 5,
|
|
}))
|
|
JubeatProp._modify_profile(
|
|
data,
|
|
1337,
|
|
'demote',
|
|
)
|
|
self.assertFalse(data.local.user.put_profile.called)
|
|
|
|
# Test promoting a user at the top does nothing.
|
|
data.local.user.get_profile = Mock(return_value=ValidatedDict({
|
|
'league_class': 4,
|
|
'league_subclass': 1,
|
|
}))
|
|
JubeatProp._modify_profile(
|
|
data,
|
|
1337,
|
|
'promote',
|
|
)
|
|
self.assertFalse(data.local.user.put_profile.called)
|
|
|
|
# Test regular promotion updates profile properly
|
|
data.local.user.get_profile = Mock(return_value=ValidatedDict({
|
|
'league_class': 1,
|
|
'league_subclass': 5,
|
|
'league_is_checked': True,
|
|
}))
|
|
JubeatProp._modify_profile(
|
|
data,
|
|
1337,
|
|
'promote',
|
|
)
|
|
data.local.user.put_profile.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
{
|
|
'league_class': 1,
|
|
'league_subclass': 4,
|
|
'league_is_checked': False,
|
|
'last': {
|
|
'league_class': 1,
|
|
'league_subclass': 5,
|
|
},
|
|
},
|
|
)
|
|
data.local.user.put_profile.reset_mock()
|
|
|
|
# Test regular demote updates profile properly
|
|
data.local.user.get_profile = Mock(return_value=ValidatedDict({
|
|
'league_class': 1,
|
|
'league_subclass': 3,
|
|
'league_is_checked': True,
|
|
}))
|
|
JubeatProp._modify_profile(
|
|
data,
|
|
1337,
|
|
'demote',
|
|
)
|
|
data.local.user.put_profile.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
{
|
|
'league_class': 1,
|
|
'league_subclass': 4,
|
|
'league_is_checked': False,
|
|
'last': {
|
|
'league_class': 1,
|
|
'league_subclass': 3,
|
|
},
|
|
},
|
|
)
|
|
data.local.user.put_profile.reset_mock()
|
|
|
|
# Test demotion after not checking doesn't update old values
|
|
data.local.user.get_profile = Mock(return_value=ValidatedDict({
|
|
'league_class': 1,
|
|
'league_subclass': 4,
|
|
'league_is_checked': False,
|
|
'last': {
|
|
'league_class': 1,
|
|
'league_subclass': 3,
|
|
},
|
|
}))
|
|
JubeatProp._modify_profile(
|
|
data,
|
|
1337,
|
|
'demote',
|
|
)
|
|
data.local.user.put_profile.assert_called_once_with(
|
|
JubeatProp.game,
|
|
JubeatProp.version,
|
|
1337,
|
|
{
|
|
'league_class': 1,
|
|
'league_subclass': 5,
|
|
'league_is_checked': False,
|
|
'last': {
|
|
'league_class': 1,
|
|
'league_subclass': 3,
|
|
},
|
|
},
|
|
)
|
|
data.local.user.put_profile.reset_mock()
|