def test_callback_called_when_resource_is_not_filtered(self): config = self.make_app() event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) event.payload['resource_name'] = 'mushroom' config.registry.notify(event) self.assertTrue(self.redis_mocked.return_value.called)
def test_user_validation_listener(self): request = DummyRequest() old_inactive = {"id": "alice", "password": "******", "validated": False} old_active = {"id": "alice", "password": "******", "validated": True} new_inactive = {"id": "alice", "password": "******", "validated": False} new_active = {"id": "alice", "password": "******", "validated": True} with mock.patch("kinto.plugins.accounts.mails.Emailer.send_mail" ) as mocked_send_mail: # No email sent if account validation is not enabled. event = ResourceChanged( {"action": ACTIONS.UPDATE.value}, [{ "old": old_inactive, "new": new_inactive }], request, ) on_account_activated(event) mocked_send_mail.assert_not_called() # No email sent if the old account was already active. request.registry.settings["account_validation"] = True event = ResourceChanged({"action": ACTIONS.UPDATE.value}, [{ "old": old_active, "new": new_active }], request) request.registry.cache.get = mock.MagicMock(return_value=None) on_account_activated(event) mocked_send_mail.assert_not_called() # No email sent if the new account is still inactive. event = ResourceChanged( {"action": ACTIONS.UPDATE.value}, [{ "old": old_inactive, "new": new_inactive }], request, ) request.registry.cache.get = mock.MagicMock(return_value=None) on_account_activated(event) mocked_send_mail.assert_not_called() # Email sent if there is an activation key in the cache. event = ResourceChanged( {"action": ACTIONS.UPDATE.value}, [{ "old": old_inactive, "new": new_active }], request, ) on_account_activated(event) mocked_send_mail.assert_called_once()
def test_loading_can_read_configuration_from_environment(self): environ = { "KINTO_EVENT_LISTENERS": "kvstore", "KINTO_EVENT_LISTENERS_KVSTORE_USE": "tests.core.listeners", "KINTO_EVENT_LISTENERS_KVSTORE_URL": "demo://demo:6379/0", "KINTO_EVENT_LISTENERS_KVSTORE_POOL_SIZE": "5", "KINTO_EVENT_LISTENERS_KVSTORE_LISTNAME": "queue", "KINTO_EVENT_LISTENERS_KVSTORE_ACTIONS": "delete", "KINTO_EVENT_LISTENERS_KVSTORE_RESOURCES": "toad", } os.environ.update(**environ) config = self.make_app({ # With real/full initialization, these should not be necessary: "settings_prefix": "kinto", "event_listeners": "kvstore", }) # Listener is instantiated. self.assertTrue(self.demo_mocked.called) # Action filtering is read from ENV. event = ResourceChanged( { "action": ACTIONS.DELETE.value, "resource_name": "toad" }, [], Request()) config.registry.notify(event) self.assertTrue(self.demo_mocked.return_value.called) self.demo_mocked.reset_mock() # Action filtering is read from ENV. event = ResourceChanged({"action": ACTIONS.CREATE.value}, [], Request()) config.registry.notify(event) self.assertFalse(self.demo_mocked.return_value.called) # Resource filtering is read from ENV. event = ResourceChanged( { "action": ACTIONS.CREATE.value, "resource_name": "mushroom" }, [], Request()) config.registry.notify(event) self.assertFalse(self.demo_mocked.return_value.called) # Clean-up. for k in environ.keys(): os.environ.pop(k)
def test_callback_is_not_called_when_action_is_filtered(self): config = self.make_app({ 'event_listeners.redis.actions': 'delete', }) event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) config.registry.notify(event) self.assertFalse(self.redis_mocked.return_value.called)
def test_notification_is_broken(self): with self.redis_listening(): # an event with a bad JSON should silently break and send nothing # date time objects cannot be dumped event2 = ResourceChanged(ACTIONS.CREATE, datetime.now(), [], Request()) self.notify(event2) self.assertFalse(self.has_redis_changed())
def test_user_creation_listener(self): request = DummyRequest() impacted_object = {"new": {"id": "alice", "password": "******"}} with mock.patch("kinto.plugins.accounts.mails.Emailer.send_mail") as mocked_send_mail: # No email sent if account validation is not enabled. event = ResourceChanged({"action": ACTIONS.UPDATE.value}, [impacted_object], request) on_account_created(event) mocked_send_mail.assert_not_called() # No email sent if there's no activation key in the cache. request.registry.settings["account_validation"] = True event = ResourceChanged({"action": ACTIONS.UPDATE.value}, [impacted_object], request) request.registry.cache.get = mock.MagicMock(return_value=None) on_account_created(event) mocked_send_mail.assert_not_called() # Email sent if there is an activation key in the cache. request.registry.cache.get = mock.MagicMock(return_value="some activation key") on_account_created(event) mocked_send_mail.assert_called_once()
def test_callback_called_when_action_is_not_filtered(self): config = self.make_app({ 'event_listeners': 'demo', 'event_listeners.demo.use': 'tests.core.listeners', }) ev = ResourceChanged({'action': ACTIONS.CREATE.value}, [], Request()) config.registry.notify(ev) self.assertTrue(self.demo_mocked.return_value.called)
def test_loading_can_read_configuration_from_environment(self): environ = { "KINTO_EVENT_LISTENERS": "kvstore", "KINTO_EVENT_LISTENERS_KVSTORE_USE": "kinto.core.listeners.redis", "KINTO_EVENT_LISTENERS_KVSTORE_URL": "redis://redis:6379/0", "KINTO_EVENT_LISTENERS_KVSTORE_POOL_SIZE": "5", "KINTO_EVENT_LISTENERS_KVSTORE_LISTNAME": "queue", "KINTO_EVENT_LISTENERS_KVSTORE_ACTIONS": "delete", "KINTO_EVENT_LISTENERS_KVSTORE_RESOURCES": "toad", } os.environ.update(**environ) config = self.make_app({ # With real/full initialization, these should not be necessary: 'project_name': 'kinto', 'event_listeners': 'kvstore' }) # Listener is instantiated. self.assertTrue(self.redis_mocked.called) # Action filtering is read from ENV. event = ResourceChanged(ACTIONS.DELETE, 123456, [], Request()) event.payload['resource_name'] = 'toad' config.registry.notify(event) self.assertTrue(self.redis_mocked.return_value.called) self.redis_mocked.reset_mock() # Action filtering is read from ENV. event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) config.registry.notify(event) self.assertFalse(self.redis_mocked.return_value.called) # Resource filtering is read from ENV. event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) event.payload['resource_name'] = 'mushroom' config.registry.notify(event) self.assertFalse(self.redis_mocked.return_value.called) # Clean-up. for k in environ.keys(): os.environ.pop(k)
def test_redis_is_broken(self): with self.redis_listening(): # if the redis call fails, same deal: we should ignore it self._save_redis() with broken_redis(): event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) self.config.registry.notify(event) self.assertFalse(self.has_redis_changed())
def test_callback_is_not_called_when_action_is_filtered(self): config = self.make_app({ "event_listeners": "demo", "event_listeners.demo.use": "tests.core.listeners", "event_listeners.demo.actions": "delete", }) ev = ResourceChanged({"action": ACTIONS.CREATE.value}, [], Request()) config.registry.notify(ev) self.assertFalse(self.demo_mocked.return_value.called)
def test_callback_is_not_called_when_resource_is_filtered(self): config = self.make_app({ 'event_listeners': 'demo', 'event_listeners.demo.use': 'tests.core.listeners', 'event_listeners.demo.resources': 'toad', }) event = ResourceChanged({'action': ACTIONS.CREATE.value, 'resource_name': 'mushroom'}, [], Request()) config.registry.notify(event) self.assertFalse(self.demo_mocked.return_value.called)
def test_same_callback_is_called_for_read_and_write_specified(self): config = self.make_app({ 'event_listeners.redis.actions': 'read create delete', }) event = ResourceRead(ACTIONS.READ, 123456, [], Request()) config.registry.notify(event) event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) config.registry.notify(event) self.assertEqual(self.redis_mocked.return_value.call_count, 2)
def test_redis_is_notified(self): with self.redis_listening(): # let's trigger an event event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) self.notify(event) self.assertTrue(self.has_redis_changed()) # okay, we should have the first event in Redis last = self._redis.lpop('kinto.core.events') last = json.loads(last.decode('utf8')) self.assertEqual(last['action'], ACTIONS.CREATE.value)
def test_same_callback_is_called_for_read_and_write_specified(self): config = self.make_app({ 'event_listeners': 'demo', 'event_listeners.demo.use': 'tests.core.listeners', 'event_listeners.demo.actions': 'read create delete', }) ev = ResourceRead({'action': ACTIONS.READ.value}, [], Request()) config.registry.notify(ev) ev = ResourceChanged({'action': ACTIONS.CREATE.value}, [], Request()) config.registry.notify(ev) self.assertEqual(self.demo_mocked.return_value.call_count, 2)
def test_callback_is_not_called_when_resource_is_filtered(self): config = self.make_app({ "event_listeners": "demo", "event_listeners.demo.use": "tests.core.listeners", "event_listeners.demo.resources": "toad", }) event = ResourceChanged( { "action": ACTIONS.CREATE.value, "resource_name": "mushroom" }, [], Request()) config.registry.notify(event) self.assertFalse(self.demo_mocked.return_value.called)
def test_a_statsd_timer_is_used_for_signature_if_configured(self): settings = { "statsd_url": "udp://127.0.0.1:8125", "signer.resources": ("/buckets/sb1/collections/sc1 -> /buckets/db1/collections/dc1"), "signer.ecdsa.public_key": "/path/to/key", "signer.ecdsa.private_key": "/path/to/private", } config = self.includeme(settings) payload = dict(resource_name="collection", action="update", bucket_id="foo") event = ResourceChanged(payload=payload, impacted_objects=[], request=mock.MagicMock()) statsd_client = config.registry.statsd._client with mock.patch.object(statsd_client, "timing") as mocked: config.registry.notify(event) timers = set(c[0][0] for c in mocked.call_args_list) assert "plugins.signer" in timers
def test_impacted_records_is_deprecated(self): event = ResourceChanged(None, [], None) event.impacted_records message = "`impacted_records` is deprecated, use `impacted_objects` instead." self.mocked_warnings.assert_called_with(message, DeprecationWarning)
def test_callback_called_when_action_is_not_filtered(self): config = self.make_app() event = ResourceChanged(ACTIONS.CREATE, 123456, [], Request()) config.registry.notify(event) self.assertTrue(self.redis_mocked.return_value.called)