diff --git a/bid_api/signals.py b/bid_api/signals.py index 9508382..f7b7b40 100644 --- a/bid_api/signals.py +++ b/bid_api/signals.py @@ -21,7 +21,7 @@ USER_SAVE_INTERESTING_FIELDS = { "avatar", "date_deletion_requested", "confirmed_email_at", - # FIXME(anna): add nickname + "nickname", } WEBHOOK_TIMEOUT_SECS = 5 @@ -115,6 +115,7 @@ def modified_user_to_webhooks(sender, user: UserModel, **kwargs): # either database ID or email address. webhook_pre_save = getattr(user, "webhook_pre_save", {}) old_email = webhook_pre_save.get("email") + old_nickname = webhook_pre_save.get("nickname") or "" # Map all falsey values to empty string for more consistent comparison later. # An empty avatar can be either '' or None. @@ -144,11 +145,10 @@ def modified_user_to_webhooks(sender, user: UserModel, **kwargs): "email": user.email, "roles": sorted(user.public_roles()), "avatar_changed": old_avatar != cur_avatar, - "date_deletion_requested": user.date_deletion_requested.isoformat() - if user.date_deletion_requested else None, - "confirmed_email_at": user.confirmed_email_at.isoformat() - if user.confirmed_email_at else None, - # FIXME(anna): add nickname + "date_deletion_requested": isoformat(user.date_deletion_requested), + "confirmed_email_at": isoformat(user.confirmed_email_at), + "old_nickname": old_nickname, + "nickname": user.nickname, } json_payload = json.dumps(payload).encode() @@ -156,3 +156,10 @@ def modified_user_to_webhooks(sender, user: UserModel, **kwargs): for hook in hooks: log.debug("Sending to %s, %s", hook, hook.url) hook.send(json_payload, sess) + + +def isoformat(timestamp): + """None-safe timestamp.isoformat().""" + if not timestamp: + return None + return timestamp.isoformat() diff --git a/bid_api/tests/test_webhooks.py b/bid_api/tests/test_webhooks.py index cd0cc09..c870e99 100644 --- a/bid_api/tests/test_webhooks.py +++ b/bid_api/tests/test_webhooks.py @@ -63,6 +63,8 @@ class WebhookTest(WebhookBaseTest): "avatar_changed": False, "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, ) @@ -99,6 +101,56 @@ class WebhookTest(WebhookBaseTest): "avatar_changed": False, "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", + }, + payload, + ) + + @responses.activate + def test_modify_user_nickname(self): + responses.add(responses.POST, self.HOOK_URL, json={"status": "success"}, status=200) + + user = UserModel.objects.create_user("test@user.com", "123456") + user.nickname = "propellorolleporp" + user.save() + + user.nickname = "maimuţă" + user.save() + + self.assertTrue(user.webhook_user_modified) + self.assertEqual(2, len(responses.calls)) + + payload = json.loads(responses.calls[0].request.body) + self.assertEqual( + { + "id": user.id, + "old_email": "test@user.com", + "full_name": "", + "email": "test@user.com", + "roles": [], + "avatar_changed": False, + "date_deletion_requested": None, + "confirmed_email_at": None, + "nickname": "propellorolleporp", + "old_nickname": "", + }, + payload, + ) + + payload = json.loads(responses.calls[1].request.body) + self.assertEqual( + { + "id": user.id, + "old_email": "test@user.com", + "full_name": "", + "email": "test@user.com", + "roles": [], + "avatar_changed": False, + "date_deletion_requested": None, + "confirmed_email_at": None, + "nickname": "maimuţă", + "old_nickname": "propellorolleporp", }, payload, ) @@ -127,6 +179,8 @@ class WebhookTest(WebhookBaseTest): "avatar_changed": True, "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, ) @@ -170,6 +224,8 @@ class WebhookTest(WebhookBaseTest): "roles": ["cloud_subscriber"], "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, ) @@ -184,6 +240,8 @@ class WebhookTest(WebhookBaseTest): "roles": [], "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, ) @@ -214,6 +272,8 @@ class WebhookTest(WebhookBaseTest): "avatar_changed": False, "date_deletion_requested": "2020-12-31T23:02:03+00:00", "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, ) @@ -244,6 +304,8 @@ class WebhookTest(WebhookBaseTest): "avatar_changed": False, "date_deletion_requested": None, "confirmed_email_at": "2021-01-01T02:05:06+00:00", + "nickname": "", + "old_nickname": "", }, payload, ) @@ -275,6 +337,8 @@ class WebhookTest(WebhookBaseTest): "roles": [], "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, "The payload in the queue should be the POSTed JSON", @@ -310,6 +374,8 @@ class WebhookTest(WebhookBaseTest): "roles": [], "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, "The payload in the queue should be the POSTed JSON", @@ -353,6 +419,8 @@ class WebhookTest(WebhookBaseTest): "roles": [], "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, ) @@ -454,6 +522,8 @@ class WebhookTest(WebhookBaseTest): "roles": [], "date_deletion_requested": None, "confirmed_email_at": None, + "nickname": "", + "old_nickname": "", }, payload, )