mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-05-02 10:56:06 -04:00
Add Module API for reading and writing global account data. (#12391)
This commit is contained in:
parent
98ec375b26
commit
85ca963c1a
3 changed files with 234 additions and 0 deletions
157
tests/module_api/test_account_data_manager.py
Normal file
157
tests/module_api/test_account_data_manager.py
Normal file
|
@ -0,0 +1,157 @@
|
|||
# Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from synapse.api.errors import SynapseError
|
||||
from synapse.rest import admin
|
||||
|
||||
from tests.unittest import HomeserverTestCase
|
||||
|
||||
|
||||
class ModuleApiTestCase(HomeserverTestCase):
|
||||
servlets = [
|
||||
admin.register_servlets,
|
||||
]
|
||||
|
||||
def prepare(self, reactor, clock, homeserver) -> None:
|
||||
self._store = homeserver.get_datastores().main
|
||||
self._module_api = homeserver.get_module_api()
|
||||
self._account_data_mgr = self._module_api.account_data_manager
|
||||
|
||||
self.user_id = self.register_user("kristina", "secret")
|
||||
|
||||
def test_get_global(self) -> None:
|
||||
"""
|
||||
Tests that getting global account data through the module API works as
|
||||
expected, including getting `None` for unset account data.
|
||||
"""
|
||||
self.get_success(
|
||||
self._store.add_account_data_for_user(
|
||||
self.user_id, "test.data", {"wombat": True}
|
||||
)
|
||||
)
|
||||
|
||||
# Getting existent account data works as expected.
|
||||
self.assertEqual(
|
||||
self.get_success(
|
||||
self._account_data_mgr.get_global(self.user_id, "test.data")
|
||||
),
|
||||
{"wombat": True},
|
||||
)
|
||||
|
||||
# Getting non-existent account data returns None.
|
||||
self.assertIsNone(
|
||||
self.get_success(
|
||||
self._account_data_mgr.get_global(self.user_id, "no.data.at.all")
|
||||
)
|
||||
)
|
||||
|
||||
def test_get_global_validation(self) -> None:
|
||||
"""
|
||||
Tests that invalid or remote user IDs are treated as errors and raised as exceptions,
|
||||
whilst getting global account data for a user.
|
||||
|
||||
This is a design choice to try and communicate potential bugs to modules
|
||||
earlier on.
|
||||
"""
|
||||
with self.assertRaises(SynapseError):
|
||||
self.get_success_or_raise(
|
||||
self._account_data_mgr.get_global("this isn't a user id", "test.data")
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
self.get_success_or_raise(
|
||||
self._account_data_mgr.get_global("@valid.but:remote", "test.data")
|
||||
)
|
||||
|
||||
def test_get_global_no_mutability(self) -> None:
|
||||
"""
|
||||
Tests that modules can't introduce bugs into Synapse by mutating the result
|
||||
of `get_global`.
|
||||
"""
|
||||
# First add some account data to set up the test.
|
||||
self.get_success(
|
||||
self._store.add_account_data_for_user(
|
||||
self.user_id, "test.data", {"wombat": True}
|
||||
)
|
||||
)
|
||||
|
||||
# Now request that data and then mutate it (out of negligence or otherwise).
|
||||
the_data = self.get_success(
|
||||
self._account_data_mgr.get_global(self.user_id, "test.data")
|
||||
)
|
||||
with self.assertRaises(TypeError):
|
||||
# This throws an exception because it's a frozen dict.
|
||||
the_data["wombat"] = False
|
||||
|
||||
def test_put_global(self) -> None:
|
||||
"""
|
||||
Tests that written account data using `put_global` can be read out again later.
|
||||
"""
|
||||
|
||||
self.get_success(
|
||||
self._module_api.account_data_manager.put_global(
|
||||
self.user_id, "test.data", {"wombat": True}
|
||||
)
|
||||
)
|
||||
|
||||
# Request that account data from the normal store; check it's as we expect.
|
||||
self.assertEqual(
|
||||
self.get_success(
|
||||
self._store.get_global_account_data_by_type_for_user(
|
||||
self.user_id, "test.data"
|
||||
)
|
||||
),
|
||||
{"wombat": True},
|
||||
)
|
||||
|
||||
def test_put_global_validation(self) -> None:
|
||||
"""
|
||||
Tests that a module can't write account data to user IDs that don't have
|
||||
actual users registered to them.
|
||||
Modules also must supply the correct types.
|
||||
"""
|
||||
|
||||
with self.assertRaises(SynapseError):
|
||||
self.get_success_or_raise(
|
||||
self._account_data_mgr.put_global(
|
||||
"this isn't a user id", "test.data", {}
|
||||
)
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
self.get_success_or_raise(
|
||||
self._account_data_mgr.put_global("@valid.but:remote", "test.data", {})
|
||||
)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
self.get_success_or_raise(
|
||||
self._module_api.account_data_manager.put_global(
|
||||
"@notregistered:test", "test.data", {}
|
||||
)
|
||||
)
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
# The account data type must be a string.
|
||||
self.get_success_or_raise(
|
||||
self._module_api.account_data_manager.put_global(
|
||||
self.user_id, 42, {} # type: ignore
|
||||
)
|
||||
)
|
||||
|
||||
with self.assertRaises(TypeError):
|
||||
# The account data dict must be a dict.
|
||||
self.get_success_or_raise(
|
||||
self._module_api.account_data_manager.put_global(
|
||||
self.user_id, "test.data", 42 # type: ignore
|
||||
)
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue