# 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()