# vim: set fileencoding=utf-8 import unittest from unittest.mock import Mock from bemani.backend.jubeat.prop import JubeatProp from bemani.common import Profile 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( [ (UserID(5), 12345), ], ), ( [ UserID(5), ], [], [], ), ) # Verify correct behavior with two entrants (should be one promotion, one demotion) self.assertEqual( JubeatProp._get_league_buckets( [ (UserID(5), 12345), (UserID(7), 54321), ], ), ( [ UserID(7), ], [], [ UserID(5), ], ), ) # Verify correct behavior with three entrants (should be one promotion, one demotion, one same) self.assertEqual( JubeatProp._get_league_buckets( [ (UserID(5), 12345), (UserID(7), 54321), (UserID(9), 33333), ], ), ( [ UserID(7), ], [ UserID(9), ], [ UserID(5), ], ), ) # Verify correct behavior with ten entrants (should be 3 promotions, 3 demotions, 4 same) self.assertEqual( JubeatProp._get_league_buckets( [ (UserID(5), 55555), (UserID(7), 77777), (UserID(9), 99999), (UserID(1), 11111), (UserID(6), 66666), (UserID(8), 88888), (UserID(2), 22222), (UserID(3), 33333), (UserID(10), 100000), (UserID(4), 44444), ], ), ( [ UserID(10), UserID(9), UserID(8), ], [ UserID(7), UserID(6), UserID(5), UserID(4), ], [ UserID(3), UserID(2), UserID(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), Profile(JubeatProp.game, JubeatProp.version, "", 0))], ), ( [(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), Profile(JubeatProp.game, JubeatProp.version, "", 0))], ), ( [], [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, [UserID(1337)], ), [], ) data.local.user.get_achievements.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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, [UserID(1337)], ), [], ) data.local.user.get_achievements.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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, [UserID(1337)], ), [UserID(1337)], ) data.local.user.get_achievements.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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, [UserID(1337)], ), [], ) data.local.user.get_achievements.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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, [UserID(1337)], ), [UserID(1337)], ) data.local.user.get_achievements.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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=Profile( JubeatProp.game, JubeatProp.version, "", 0, { "league_class": 1, "league_subclass": 5, }, ) ) JubeatProp._modify_profile( data, UserID(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=Profile( JubeatProp.game, JubeatProp.version, "", 0, { "league_class": 4, "league_subclass": 1, }, ) ) JubeatProp._modify_profile( data, UserID(1337), "promote", ) self.assertFalse(data.local.user.put_profile.called) # Test regular promotion updates profile properly data.local.user.get_profile = Mock( return_value=Profile( JubeatProp.game, JubeatProp.version, "", 0, { "league_class": 1, "league_subclass": 5, "league_is_checked": True, }, ) ) JubeatProp._modify_profile( data, UserID(1337), "promote", ) data.local.user.put_profile.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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=Profile( JubeatProp.game, JubeatProp.version, "", 0, { "league_class": 1, "league_subclass": 3, "league_is_checked": True, }, ) ) JubeatProp._modify_profile( data, UserID(1337), "demote", ) data.local.user.put_profile.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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=Profile( JubeatProp.game, JubeatProp.version, "", 0, { "league_class": 1, "league_subclass": 4, "league_is_checked": False, "last": { "league_class": 1, "league_subclass": 3, }, }, ) ) JubeatProp._modify_profile( data, UserID(1337), "demote", ) data.local.user.put_profile.assert_called_once_with( JubeatProp.game, JubeatProp.version, UserID(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()