branch: elpa/jabber
commit d033c3e065de38aa99146cbcb1fff19cc4d36bd7
Author: Thanos Apollo <[email protected]>
Commit: Thanos Apollo <[email protected]>
disco: Invert presence refresh dependency
---
lisp/jabber-disco.el | 18 +++++-------------
lisp/jabber-presence.el | 8 ++++++++
tests/jabber-test-disco.el | 16 ++++++++++++++++
tests/jabber-test-presence.el | 9 +++++++++
4 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/lisp/jabber-disco.el b/lisp/jabber-disco.el
index 799ec5de8d..62839a1fc4 100644
--- a/lisp/jabber-disco.el
+++ b/lisp/jabber-disco.el
@@ -29,16 +29,11 @@
;;; Code:
(require 'cl-lib)
+(require 'jabber-db)
(require 'jabber-iq)
(require 'jabber-xml)
(require 'jabber-xdata)
-;; Global reference declarations
-
-(declare-function jabber-db-caps-store "jabber-db.el"
- (hash ver identities features))
-(declare-function jabber-db-caps-lookup "jabber-db.el" (hash ver))
-
(defvar jabber-xdata-xmlns) ; jabber-xml.el
(defconst jabber-disco-xmlns-info "http://jabber.org/protocol/disco#info"
@@ -128,12 +123,11 @@ Second item is access control function. That function is
passed the
JID, and returns non-nil if access is granted. If the second item is
nil, access is always granted.")
-;; Global reference declarations
-
-(declare-function jabber-send-current-presence "jabber-presence.el"
- (&optional jc))
(defvar jabber-presence-element-functions nil) ; jabber-presence.el
+(defvar jabber-disco-features-changed-hook nil
+ "Hook run after connected clients advertise a new feature.")
+
;;
(add-to-list 'jabber-iq-get-xmlns-alist
@@ -414,9 +408,7 @@ The value should be a key in `jabber-caps-hash-names'.")
(push feature jabber-advertised-features)
(when jabber-caps-current-hash
(jabber-caps-recalculate-hash)
- ;; If we're already connected, we need to send updated presence
- ;; for the new feature.
- (mapc #'jabber-send-current-presence jabber-connections))))
+ (run-hooks 'jabber-disco-features-changed-hook))))
(defun jabber-caps-recalculate-hash ()
"Update `jabber-caps-current-hash' for feature list change.
diff --git a/lisp/jabber-presence.el b/lisp/jabber-presence.el
index cc43a971da..58a3ed71ee 100644
--- a/lisp/jabber-presence.el
+++ b/lisp/jabber-presence.el
@@ -28,6 +28,7 @@
;;; Code:
(require 'jabber-core)
+(require 'jabber-disco)
(require 'jabber-iq)
(require 'jabber-alert)
(require 'jabber-util)
@@ -556,6 +557,13 @@ If JC is non-nil, send only for that connection."
jabber-current-priority jc)
(jabber-send-default-presence jc)))
+(defun jabber-presence--refresh-advertised-features ()
+ "Resend presence with the current advertised feature set."
+ (mapc #'jabber-send-current-presence jabber-connections))
+
+(add-hook 'jabber-disco-features-changed-hook
+ #'jabber-presence--refresh-advertised-features)
+
(defun jabber-send-subscription-request (jc to &optional request)
"Send a subscription request to TO.
REQUEST, if non-empty, is included as the status text.
diff --git a/tests/jabber-test-disco.el b/tests/jabber-test-disco.el
index bcd379ba3a..157040994a 100644
--- a/tests/jabber-test-disco.el
+++ b/tests/jabber-test-disco.el
@@ -177,5 +177,21 @@
;; Query should have been sent.
(should iq-sent))))
+(ert-deftest jabber-test-disco-advertise-feature-runs-change-hook-once ()
+ "Advertising a new connected feature runs the change hook once."
+ (let ((jabber-advertised-features nil)
+ (jabber-caps-current-hash "old")
+ (jabber-disco-features-changed-hook nil)
+ (recalculations 0)
+ (changes 0))
+ (add-hook 'jabber-disco-features-changed-hook
+ (lambda () (cl-incf changes)))
+ (cl-letf (((symbol-function 'jabber-caps-recalculate-hash)
+ (lambda () (cl-incf recalculations))))
+ (jabber-disco-advertise-feature "urn:test:feature")
+ (jabber-disco-advertise-feature "urn:test:feature"))
+ (should (= recalculations 1))
+ (should (= changes 1))))
+
(provide 'jabber-test-disco)
;;; jabber-test-disco.el ends here
diff --git a/tests/jabber-test-presence.el b/tests/jabber-test-presence.el
index 8b76dad89f..bfe3c234cc 100644
--- a/tests/jabber-test-presence.el
+++ b/tests/jabber-test-presence.el
@@ -46,6 +46,15 @@
(should (equal (jabber-presence-children nil)
'((c ((xmlns . "urn:xmpp:caps"))))))))
+(ert-deftest jabber-test-presence-refreshes-features-on-all-connections ()
+ "A discovery feature change resends presence on every connection."
+ (let ((jabber-connections '(first second))
+ (sent nil))
+ (cl-letf (((symbol-function 'jabber-send-current-presence)
+ (lambda (jc) (push jc sent))))
+ (jabber-presence--refresh-advertised-features))
+ (should (equal (nreverse sent) jabber-connections))))
+
;;; Group 2: jabber--roster-valid-push-p
(ert-deftest jabber-test-presence-valid-push-nil-from ()