From c4faa6879bd10264126b9ac3872d64a64aa732c8 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 10 Feb 2019 02:08:21 +0100 Subject: [PATCH] Add tag/attr to create_account. More unit tests --- CHANGELOG.md | 3 +- evennia/accounts/accounts.py | 17 +++++-- evennia/accounts/tests.py | 84 ++++++++++++++++++++++++++++++--- evennia/utils/create.py | 11 ++++- evennia/utils/test_resources.py | 17 ++++--- 5 files changed, 114 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71f6dfc9fb..f64f67b110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,7 +85,8 @@ Web/Django standard initiative (@strikaco) ### Utils -- Added more unit tests. +- `evennia.utils.create.account` now also takes `tags` and `attrs` keywords. +- Added many more unit tests. ## Evennia 0.8 (2018) diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index ca79e5b10a..03c61c9a1a 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -1340,19 +1340,28 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)): # list of targets - make list to disconnect from db characters = list(tar for tar in target if tar) if target else [] sessions = self.sessions.all() + if not sessions: + # no sessions, nothing to report + return "" is_su = self.is_superuser # text shown when looking in the ooc area result = ["Account |g%s|n (you are Out-of-Character)" % self.key] nsess = len(sessions) - result.append(nsess == 1 and "\n\n|wConnected session:|n" or "\n\n|wConnected sessions (%i):|n" % nsess) + result.append(nsess == 1 and + "\n\n|wConnected session:|n" or + "\n\n|wConnected sessions (%i):|n" % nsess) for isess, sess in enumerate(sessions): csessid = sess.sessid addr = "%s (%s)" % (sess.protocol_key, isinstance(sess.address, tuple) and - str(sess.address[0]) or str(sess.address)) - result.append("\n %s %s" % (session.sessid == csessid and "|w* %s|n" % (isess + 1) or - " %s" % (isess + 1), addr)) + str(sess.address[0]) or + str(sess.address)) + result.append("\n %s %s" % ( + session and + session.sessid == csessid and + "|w* %s|n" % (isess + 1) or + " %s" % (isess + 1), addr)) result.append("\n\n |whelp|n - more commands") result.append("\n |wooc |n - talk on public channel") diff --git a/evennia/accounts/tests.py b/evennia/accounts/tests.py index 0e2dfbad94..a8b06a704a 100644 --- a/evennia/accounts/tests.py +++ b/evennia/accounts/tests.py @@ -62,19 +62,19 @@ class TestAccountSessionHandler(TestCase): self.assertEqual(self.handler.count(), len(self.handler.get())) +@override_settings(GUEST_ENABLED=True, GUEST_LIST=["bruce_wayne"]) class TestDefaultGuest(EvenniaTest): "Check DefaultGuest class" ip = '212.216.134.22' - - def test_authenticate(self): + + @override_settings(GUEST_ENABLED=False) + def test_create_not_enabled(self): # Guest account should not be permitted account, errors = DefaultGuest.authenticate(ip=self.ip) self.assertFalse(account, 'Guest account was created despite being disabled.') - settings.GUEST_ENABLED = True - settings.GUEST_LIST = ['bruce_wayne'] - + def test_authenticate(self): # Create a guest account account, errors = DefaultGuest.authenticate(ip=self.ip) self.assertTrue(account, 'Guest account should have been created.') @@ -83,7 +83,32 @@ class TestDefaultGuest(EvenniaTest): account, errors = DefaultGuest.authenticate(ip=self.ip) self.assertFalse(account, 'Two guest accounts were created with a single entry on the guest list!') - settings.GUEST_ENABLED = False + @patch("evennia.accounts.accounts.ChannelDB.objects.get_channel") + def test_create(self, get_channel): + get_channel.connect = MagicMock(return_value=True) + account, errors = DefaultGuest.create() + self.assertTrue(account, "Guest account should have been created.") + self.assertFalse(errors) + + def test_at_post_login(self): + self.account.db._last_puppet = self.char1 + self.account.at_post_login(self.session) + self.account.at_post_login() + + def test_at_server_shutdown(self): + account, errors = DefaultGuest.create(ip=self.ip) + self.char1.delete = MagicMock() + account.db._playable_characters = [self.char1] + account.at_server_shutdown() + self.char1.delete.assert_called() + + def test_at_post_disconnect(self): + account, errors = DefaultGuest.create(ip=self.ip) + self.char1.delete = MagicMock() + account.db._playable_characters = [self.char1] + account.at_post_disconnect() + self.char1.delete.assert_called() + class TestDefaultAccountAuth(EvenniaTest): @@ -315,3 +340,50 @@ class TestDefaultAccountEv(EvenniaTest): with patch("evennia.accounts.accounts._MULTISESSION_MODE", 2): self.account.puppet_object(self.session, self.char1) self.account.msg.assert_called_with("You are already puppeting this object.") + + @patch("evennia.accounts.accounts.time.time", return_value=10000) + def test_idle_time(self, mock_time): + self.session.cmd_last_visible = 10000 - 10 + idle = self.account.idle_time + self.assertEqual(idle, 10) + + # test no sessions + unload_module("evennia.accounts.accounts") + with patch("evennia.accounts.accounts._SESSIONS.sessions_from_account", return_value=[]) as mock_sessh: + idle = self.account.idle_time + self.assertEqual(idle, None) + + @patch("evennia.accounts.accounts.time.time", return_value=10000) + def test_connection_time(self, mock_time): + self.session.conn_time = 10000 - 10 + conn = self.account.connection_time + self.assertEqual(conn, 10) + + # test no sessions + unload_module("evennia.accounts.accounts") + with patch("evennia.accounts.accounts._SESSIONS.sessions_from_account", return_value=[]) as mock_sessh: + idle = self.account.connection_time + self.assertEqual(idle, None) + + def test_create_account(self): + acct = create.account( + "TestAccount3", "test@test.com", "testpassword123", + locks="test:all()", + tags=[("tag1", "category1"), ("tag2", "category2", "data1"), ("tag3", None)], + attributes=[("key1", "value1", "category1", + "edit:false()", True), + ("key2", "value2")]) + acct.save() + self.assertTrue(acct.pk) + + def test_at_look(self): + ret = self.account.at_look() + self.assertTrue("Out-of-Character" in ret) + ret = self.account.at_look(target=self.obj1) + self.assertTrue("Obj" in ret) + ret = self.account.at_look(session=self.session) + self.assertTrue("*" in ret) # * marks session is active in list + ret = self.account.at_look(target=self.obj1, session=self.session) + self.assertTrue("Obj" in ret) + ret = self.account.at_look(target="Invalid", session=self.session) + self.assertEqual(ret, 'Invalid has no in-game appearance.') diff --git a/evennia/utils/create.py b/evennia/utils/create.py index ae7e867f27..f141f6897b 100644 --- a/evennia/utils/create.py +++ b/evennia/utils/create.py @@ -402,6 +402,7 @@ def create_account(key, email, password, typeclass=None, is_superuser=False, locks=None, permissions=None, + tags=None, attributes=None, report_to=None): """ This creates a new account. @@ -414,14 +415,19 @@ def create_account(key, email, password, password (str): Password in cleartext. Kwargs: + typeclass (str): The typeclass to use for the account. is_superuser (bool): Wether or not this account is to be a superuser locks (str): Lockstring. permission (list): List of permission strings. + tags (list): List of Tags on form `(key, category[, data])` + attributes (list): List of Attributes on form + `(key, value [, category, [,lockstring [, default_pass]]])` report_to (Object): An object with a msg() method to report errors to. If not given, errors will be logged. Raises: ValueError: If `key` already exists in database. + Notes: Usually only the server admin should need to be superuser, all @@ -437,6 +443,8 @@ def create_account(key, email, password, typeclass = typeclass if typeclass else settings.BASE_ACCOUNT_TYPECLASS locks = make_iter(locks) if locks is not None else None permissions = make_iter(permissions) if permissions is not None else None + tags = make_iter(tags) if tags is not None else None + attributes = make_iter(attributes) if attributes is not None else None if isinstance(typeclass, basestring): # a path is given. Load the actual typeclass. @@ -462,7 +470,8 @@ def create_account(key, email, password, is_staff=is_superuser, is_superuser=is_superuser, last_login=now, date_joined=now) new_account.set_password(password) - new_account._createdict = dict(locks=locks, permissions=permissions, report_to=report_to) + new_account._createdict = dict(locks=locks, permissions=permissions, report_to=report_to, + tags=tags, attributes=attributes) # saving will trigger the signal that calls the # at_first_save hook on the typeclass, where the _createdict # can be used. diff --git a/evennia/utils/test_resources.py b/evennia/utils/test_resources.py index 64a186ebd4..6cff023cab 100644 --- a/evennia/utils/test_resources.py +++ b/evennia/utils/test_resources.py @@ -19,13 +19,15 @@ SESSIONS.data_out = Mock() SESSIONS.disconnect = Mock() -def unload_module(module_or_object): +def unload_module(module): """ Reset import so one can mock global constants. Args: - module_or_object (module or object): The module will - be removed so it will have to be imported again. + module (module, object or str): The module will + be removed so it will have to be imported again. If given + an object, the module in which that object sits will be unloaded. A string + should directly give the module pathname to unload. Example: # (in a test method) @@ -40,10 +42,13 @@ def unload_module(module_or_object): loaded once). """ - if hasattr(module_or_object, "__module__"): - modulename = module_or_object.__module__ + if isinstance(module, basestring): + modulename = module + elif hasattr(module, "__module__"): + modulename = module.__module__ else: - modulename = module_or_object.__name__ + modulename = module.__name__ + if modulename in sys.modules: del sys.modules[modulename]