Browse Source

Test updates after updating to use latest strophe.js

`toLocaleString` now returns element attributes in alphabetical order
(for better cross-browser consistency).

Also, `toLocaleString` is now used in favor of `outerHTML` because
browsers aren't consistent with one another in their output.
JC Brand 6 years ago
parent
commit
9bc8bdf34c
20 changed files with 5687 additions and 5144 deletions
  1. 5058 4461
      dist/converse.js
  2. 2 4
      package-lock.json
  3. 1 1
      package.json
  4. 48 48
      spec/bookmarks.js
  5. 149 157
      spec/chatroom.js
  6. 6 6
      spec/controlbox.js
  7. 2 6
      spec/converse.js
  8. 65 65
      spec/http-file-upload.js
  9. 120 125
      spec/mam.js
  10. 37 37
      spec/messages.js
  11. 60 59
      spec/omemo.js
  12. 3 3
      spec/ping.js
  13. 31 35
      spec/presence.js
  14. 22 22
      spec/protocol.js
  15. 26 46
      spec/push.js
  16. 6 6
      spec/register.js
  17. 28 24
      spec/room_registration.js
  18. 20 26
      spec/roster.js
  19. 2 12
      src/converse-muc.js
  20. 1 1
      webpack.config.js

File diff suppressed because it is too large
+ 5058 - 4461
dist/converse.js


+ 2 - 4
package-lock.json

@@ -14089,9 +14089,7 @@
       "dev": true
       "dev": true
     },
     },
     "strophe.js": {
     "strophe.js": {
-      "version": "1.2.16",
-      "resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.2.16.tgz",
-      "integrity": "sha512-r/Uq7aqrusg25Y0qHwV48cFnMY6K/CuZdGt3EggRx3kY4sMv8lG+AFoMlrmTcYVMG1BaJvQfv9Cthw4Ll8z7fQ==",
+      "version": "github:strophe/strophejs#a2692dcfdaf7d591254ac73f3d8584992b6f8da7",
       "dev": true
       "dev": true
     },
     },
     "strophejs-plugin-ping": {
     "strophejs-plugin-ping": {
@@ -14100,7 +14098,7 @@
       "integrity": "sha1-NXEmxTZZSwZmjhh4c4Ey+sNciJY=",
       "integrity": "sha1-NXEmxTZZSwZmjhh4c4Ey+sNciJY=",
       "dev": true,
       "dev": true,
       "requires": {
       "requires": {
-        "strophe.js": "1.2.16"
+        "strophe.js": "github:strophe/strophejs#a2692dcfdaf7d591254ac73f3d8584992b6f8da7"
       }
       }
     },
     },
     "strophejs-plugin-register": {
     "strophejs-plugin-register": {

+ 1 - 1
package.json

@@ -79,7 +79,7 @@
     "sinon": "^2.1.0",
     "sinon": "^2.1.0",
     "sizzle": "^2.3.3",
     "sizzle": "^2.3.3",
     "snabbdom": "0.7.1",
     "snabbdom": "0.7.1",
-    "strophe.js": "1.2.16",
+    "strophe.js": "strophe/strophejs#a2692dcfdaf7d591254ac73f3d8584992b6f8da7",
     "strophejs-plugin-ping": "0.0.1",
     "strophejs-plugin-ping": "0.0.1",
     "strophejs-plugin-register": "0.0.1",
     "strophejs-plugin-register": "0.0.1",
     "strophejs-plugin-rsm": "0.0.1",
     "strophejs-plugin-rsm": "0.0.1",

+ 48 - 48
spec/bookmarks.js

@@ -97,32 +97,32 @@
                     return test_utils.waitUntil(() => sent_stanza);
                     return test_utils.waitUntil(() => sent_stanza);
                 }).then(() => {
                 }).then(() => {
                     expect(sent_stanza.toLocaleString()).toBe(
                     expect(sent_stanza.toLocaleString()).toBe(
-                        "<iq type='set' from='dummy@localhost/resource' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<pubsub xmlns='http://jabber.org/protocol/pubsub'>"+
-                                "<publish node='storage:bookmarks'>"+
-                                    "<item id='current'>"+
-                                        "<storage xmlns='storage:bookmarks'>"+
-                                            "<conference name='Play&amp;apos;s the Thing' autojoin='true' jid='theplay@conference.shakespeare.lit'>"+
-                                                "<nick>JC</nick>"+
-                                            "</conference>"+
-                                        "</storage>"+
-                                    "</item>"+
-                                "</publish>"+
-                                "<publish-options>"+
-                                    "<x xmlns='jabber:x:data' type='submit'>"+
-                                        "<field var='FORM_TYPE' type='hidden'>"+
-                                            "<value>http://jabber.org/protocol/pubsub#publish-options</value>"+
-                                        "</field>"+
-                                        "<field var='pubsub#persist_items'>"+
-                                            "<value>true</value>"+
-                                        "</field>"+
-                                        "<field var='pubsub#access_model'>"+
-                                            "<value>whitelist</value>"+
-                                        "</field>"+
-                                    "</x>"+
-                                "</publish-options>"+
-                            "</pubsub>"+
-                        "</iq>"
+                        `<iq from="dummy@localhost/resource" id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                                `<publish node="storage:bookmarks">`+
+                                    `<item id="current">`+
+                                        `<storage xmlns="storage:bookmarks">`+
+                                            `<conference autojoin="true" jid="theplay@conference.shakespeare.lit" name="Play&amp;apos;s the Thing">`+
+                                                `<nick>JC</nick>`+
+                                            `</conference>`+
+                                        `</storage>`+
+                                    `</item>`+
+                                `</publish>`+
+                                `<publish-options>`+
+                                    `<x type="submit" xmlns="jabber:x:data">`+
+                                        `<field type="hidden" var="FORM_TYPE">`+
+                                            `<value>http://jabber.org/protocol/pubsub#publish-options</value>`+
+                                        `</field>`+
+                                        `<field var="pubsub#persist_items">`+
+                                            `<value>true</value>`+
+                                        `</field>`+
+                                        `<field var="pubsub#access_model">`+
+                                            `<value>whitelist</value>`+
+                                        `</field>`+
+                                    `</x>`+
+                                `</publish-options>`+
+                            `</pubsub>`+
+                        `</iq>`
                     );
                     );
                     /* Server acknowledges successful storage
                     /* Server acknowledges successful storage
                      *
                      *
@@ -245,28 +245,28 @@
                     // conferences to bookmark (since we removed the one and
                     // conferences to bookmark (since we removed the one and
                     // only bookmark).
                     // only bookmark).
                     expect(sent_stanza.toLocaleString()).toBe(
                     expect(sent_stanza.toLocaleString()).toBe(
-                        "<iq type='set' from='dummy@localhost/resource' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<pubsub xmlns='http://jabber.org/protocol/pubsub'>"+
-                                "<publish node='storage:bookmarks'>"+
-                                    "<item id='current'>"+
-                                        "<storage xmlns='storage:bookmarks'/>"+
-                                    "</item>"+
-                                "</publish>"+
-                                "<publish-options>"+
-                                    "<x xmlns='jabber:x:data' type='submit'>"+
-                                        "<field var='FORM_TYPE' type='hidden'>"+
-                                            "<value>http://jabber.org/protocol/pubsub#publish-options</value>"+
-                                        "</field>"+
-                                        "<field var='pubsub#persist_items'>"+
-                                            "<value>true</value>"+
-                                        "</field>"+
-                                        "<field var='pubsub#access_model'>"+
-                                            "<value>whitelist</value>"+
-                                        "</field>"+
-                                    "</x>"+
-                                "</publish-options>"+
-                            "</pubsub>"+
-                        "</iq>"
+                        `<iq from="dummy@localhost/resource" id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                                `<publish node="storage:bookmarks">`+
+                                    `<item id="current">`+
+                                        `<storage xmlns="storage:bookmarks"/>`+
+                                    `</item>`+
+                                `</publish>`+
+                                `<publish-options>`+
+                                    `<x type="submit" xmlns="jabber:x:data">`+
+                                        `<field type="hidden" var="FORM_TYPE">`+
+                                            `<value>http://jabber.org/protocol/pubsub#publish-options</value>`+
+                                        `</field>`+
+                                        `<field var="pubsub#persist_items">`+
+                                            `<value>true</value>`+
+                                        `</field>`+
+                                        `<field var="pubsub#access_model">`+
+                                            `<value>whitelist</value>`+
+                                        `</field>`+
+                                    `</x>`+
+                                `</publish-options>`+
+                            `</pubsub>`+
+                        `</iq>`
                     );
                     );
                     done();
                     done();
                 });
                 });

+ 149 - 157
spec/chatroom.js

@@ -221,8 +221,8 @@
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
                     expect(_converse.connection.sendIQ).toHaveBeenCalled();
                     expect(_converse.connection.sendIQ).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='room@conference.example.org' type='get' xmlns='jabber:client' id='"+IQ_id+
-                        "'><query xmlns='http://jabber.org/protocol/muc#owner'/></iq>"
+                        `<iq id="${IQ_id}" to="room@conference.example.org" type="get" xmlns="jabber:client">`+
+                        `<query xmlns="http://jabber.org/protocol/muc#owner"/></iq>`
                     );
                     );
                     var node = Strophe.xmlHtmlNode(
                     var node = Strophe.xmlHtmlNode(
                        '<iq xmlns="jabber:client"'+
                        '<iq xmlns="jabber:client"'+
@@ -334,16 +334,17 @@
                      *          node="x-roomuser-item"/>
                      *          node="x-roomuser-item"/>
                      * </iq>
                      * </iq>
                      */
                      */
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                             IQ_stanzas,
                             IQ_stanzas,
                             s => sizzle(`iq[to="${room_jid}"] query[node="x-roomuser-item"]`, s.nodeTree).length
                             s => sizzle(`iq[to="${room_jid}"] query[node="x-roomuser-item"]`, s.nodeTree).length
-                        ).pop(), 'nodeTree')
+                        ).pop()
                     );
                     );
-                }).then(stanza => {
-                    expect(stanza.outerHTML.trim()).toBe(
-                        `<iq to="lounge@localhost" from="dummy@localhost/resource" `+
-                            `type="get" xmlns="jabber:client" id="${stanza.getAttribute("id")}">`+
-                                `<query xmlns="http://jabber.org/protocol/disco#info" node="x-roomuser-item"/></iq>`);
+                }).then(node => {
+                    const stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq from="dummy@localhost/resource" id="${stanza.getAttribute("id")}" to="lounge@localhost" `+
+                            `type="get" xmlns="jabber:client">`+
+                                `<query node="x-roomuser-item" xmlns="http://jabber.org/protocol/disco#info"/></iq>`);
 
 
                     /* <iq xmlns="jabber:client" type="error" to="jordie.langen@chat.example.org/converse.js-11659299" from="myroom@conference.chat.example.org">
                     /* <iq xmlns="jabber:client" type="error" to="jordie.langen@chat.example.org/converse.js-11659299" from="myroom@conference.chat.example.org">
                      *      <error type="cancel">
                      *      <error type="cancel">
@@ -403,9 +404,9 @@
                      * </iq>
                      * </iq>
                      */
                      */
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#owner'><x xmlns='jabber:x:data' type='submit'/>"+
-                        "</query></iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#owner"><x type="submit" xmlns="jabber:x:data"/>`+
+                        `</query></iq>`);
                     done();
                     done();
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
             }));
             }));
@@ -882,9 +883,9 @@
                     *  </iq>
                     *  </iq>
                     */
                     */
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#owner'/>"+
-                        "</iq>");
+                        `<iq id="`+IQ_id+`" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#owner"/>`+
+                        `</iq>`);
 
 
                     /* Server responds with the configuration form.
                     /* Server responds with the configuration form.
                     * See: // http://xmpp.org/extensions/xep-0045.html#example-165
                     * See: // http://xmpp.org/extensions/xep-0045.html#example-165
@@ -1291,16 +1292,17 @@
                      *         node='x-roomuser-item'/>
                      *         node='x-roomuser-item'/>
                      * </iq>
                      * </iq>
                      */
                      */
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                             IQ_stanzas,
                             IQ_stanzas,
                             s => sizzle(`iq[to="${room_jid}"] query[node="x-roomuser-item"]`, s.nodeTree).length
                             s => sizzle(`iq[to="${room_jid}"] query[node="x-roomuser-item"]`, s.nodeTree).length
-                        ).pop(), 'nodeTree')
+                        ).pop()
                     );
                     );
-                }).then(iq => {
-                    expect(iq.outerHTML).toBe(
-                        `<iq to="lounge@localhost" from="dummy@localhost/resource" `+
-                            `type="get" xmlns="jabber:client" id="${iq.getAttribute('id')}">`+
-                                `<query xmlns="http://jabber.org/protocol/disco#info" node="x-roomuser-item"/></iq>`);
+                }).then(node => {
+                    const iq = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq from="dummy@localhost/resource" id="${iq.getAttribute('id')}" to="lounge@localhost" `+
+                            `type="get" xmlns="jabber:client">`+
+                                `<query node="x-roomuser-item" xmlns="http://jabber.org/protocol/disco#info"/></iq>`);
 
 
                     /* <iq from='coven@chat.shakespeare.lit'
                     /* <iq from='coven@chat.shakespeare.lit'
                      *     id='getnick1'
                      *     id='getnick1'
@@ -1403,11 +1405,12 @@
                         expect(window.prompt).toHaveBeenCalled();
                         expect(window.prompt).toHaveBeenCalled();
                         expect(view.model.directInvite).toHaveBeenCalled();
                         expect(view.model.directInvite).toHaveBeenCalled();
                         expect(sent_stanza.toLocaleString()).toBe(
                         expect(sent_stanza.toLocaleString()).toBe(
-                            "<message from='dummy@localhost/resource' to='felix.amsel@localhost' id='" +
-                                    sent_stanza.nodeTree.getAttribute('id') +
-                                    "' xmlns='jabber:client'>"+
-                                "<x xmlns='jabber:x:conference' jid='lounge@localhost' reason='Please join!'/>"+
-                            "</message>"
+                            `<message from="dummy@localhost/resource" `+
+                                    `id="${sent_stanza.nodeTree.getAttribute("id")}" `+
+                                    `to="felix.amsel@localhost" `+
+                                    `xmlns="jabber:client">`+
+                                `<x jid="lounge@localhost" reason="Please join!" xmlns="jabber:x:conference"/>`+
+                            `</message>`
                         );
                         );
                     }
                     }
                     done();
                     done();
@@ -1722,15 +1725,16 @@
 
 
                 _converse.api.rooms.open(room_jid, {'nick': 'some1'})
                 _converse.api.rooms.open(room_jid, {'nick': 'some1'})
                 .then(() => {
                 .then(() => {
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                         IQ_stanzas,
                         IQ_stanzas,
                         iq => iq.nodeTree.querySelector(
                         iq => iq.nodeTree.querySelector(
                             `iq[to="${room_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
                             `iq[to="${room_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
-                        )).pop(), 'nodeTree'));
-                }).then(stanza => {
+                        )).pop());
+                }).then(node => {
                     // Check that the groupchat queried for the feautures.
                     // Check that the groupchat queried for the feautures.
-                    expect(stanza.outerHTML).toBe(
-                        `<iq from="dummy@localhost/resource" to="${room_jid}" type="get" xmlns="jabber:client" id="${stanza.getAttribute("id")}">`+
+                    const stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq from="dummy@localhost/resource" id="${stanza.getAttribute("id")}" to="${room_jid}" type="get" xmlns="jabber:client">`+
                             `<query xmlns="http://jabber.org/protocol/disco#info"/>`+
                             `<query xmlns="http://jabber.org/protocol/disco#info"/>`+
                         `</iq>`);
                         `</iq>`);
 
 
@@ -2130,8 +2134,8 @@
                         keyCode: 13
                         keyCode: 13
                     });
                     });
                     expect(_converse.connection.send).toHaveBeenCalled();
                     expect(_converse.connection.send).toHaveBeenCalled();
-                    expect(sent_stanza.outerHTML).toBe(
-                        `<iq to="lounge@muc.localhost" type="set" xmlns="jabber:client" id="${sent_stanza.getAttribute('id')}">`+
+                    expect(Strophe.serialize(sent_stanza)).toBe(
+                        `<iq id="${sent_stanza.getAttribute('id')}" to="lounge@muc.localhost" type="set" xmlns="jabber:client">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                                 `<item affiliation="member" jid="marc@localhost">`+
                                 `<item affiliation="member" jid="marc@localhost">`+
                                     `<reason>Welcome to the club!</reason>`+
                                     `<reason>Welcome to the club!</reason>`+
@@ -2148,19 +2152,14 @@
                     });
                     });
                     _converse.connection.IQ_stanzas = [];
                     _converse.connection.IQ_stanzas = [];
                     _converse.connection._dataRecv(test_utils.createRequest(result));
                     _converse.connection._dataRecv(test_utils.createRequest(result));
-
-                    return test_utils.waitUntil(() => {
-                        return _.filter(
-                            _converse.connection.IQ_stanzas,
-                            (iq) => {
-                                const node = iq.nodeTree.querySelector('iq[to="lounge@muc.localhost"][type="get"] item[affiliation="member"]');
-                                if (node) { iq_stanza = iq.nodeTree;}
-                                return node;
-                            }).length;
-                    });
-                }).then(() => {
-                    expect(iq_stanza.outerHTML).toBe(
-                        `<iq to="lounge@muc.localhost" type="get" xmlns="jabber:client" id="${iq_stanza.getAttribute('id')}">`+
+                    return test_utils.waitUntil(() => _.filter(
+                        _converse.connection.IQ_stanzas,
+                        iq => iq.nodeTree.querySelector('iq[to="lounge@muc.localhost"][type="get"] item[affiliation="member"]')).pop()
+                    );
+                }).then(node => {
+                    iq_stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq id="${iq_stanza.getAttribute('id')}" to="lounge@muc.localhost" type="get" xmlns="jabber:client">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                                 `<item affiliation="member"/>`+
                                 `<item affiliation="member"/>`+
                             `</query>`+
                             `</query>`+
@@ -2178,18 +2177,14 @@
                     _converse.connection._dataRecv(test_utils.createRequest(result));
                     _converse.connection._dataRecv(test_utils.createRequest(result));
 
 
                     expect(view.model.occupants.length).toBe(2);
                     expect(view.model.occupants.length).toBe(2);
-                    return test_utils.waitUntil(() => {
-                        return _.filter(
-                            _converse.connection.IQ_stanzas,
-                            (iq) => {
-                                const node = iq.nodeTree.querySelector('iq[to="lounge@muc.localhost"][type="get"] item[affiliation="owner"]');
-                                if (node) { iq_stanza = iq.nodeTree;}
-                                return node;
-                            }).length;
-                    });
-                }).then(() => {
-                    expect(iq_stanza.outerHTML).toBe(
-                        `<iq to="lounge@muc.localhost" type="get" xmlns="jabber:client" id="${iq_stanza.getAttribute('id')}">`+
+                    return test_utils.waitUntil(() => _.filter(
+                        _converse.connection.IQ_stanzas,
+                        (iq) => iq.nodeTree.querySelector('iq[to="lounge@muc.localhost"][type="get"] item[affiliation="owner"]')).pop()
+                    );
+                }).then(node => {
+                    iq_stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq id="${iq_stanza.getAttribute('id')}" to="lounge@muc.localhost" type="get" xmlns="jabber:client">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                                 `<item affiliation="owner"/>`+
                                 `<item affiliation="owner"/>`+
                             `</query>`+
                             `</query>`+
@@ -2207,18 +2202,14 @@
                     _converse.connection._dataRecv(test_utils.createRequest(result));
                     _converse.connection._dataRecv(test_utils.createRequest(result));
 
 
                     expect(view.model.occupants.length).toBe(2);
                     expect(view.model.occupants.length).toBe(2);
-                    return test_utils.waitUntil(() => {
-                        return _.filter(
-                            _converse.connection.IQ_stanzas,
-                            (iq) => {
-                                const node = iq.nodeTree.querySelector('iq[to="lounge@muc.localhost"][type="get"] item[affiliation="admin"]');
-                                if (node) { iq_stanza = iq.nodeTree;}
-                                return node;
-                            }).length;
-                    });
-                }).then(() => {
-                    expect(iq_stanza.outerHTML).toBe(
-                        `<iq to="lounge@muc.localhost" type="get" xmlns="jabber:client" id="${iq_stanza.getAttribute('id')}">`+
+                    return test_utils.waitUntil(() => _.filter(
+                        _converse.connection.IQ_stanzas,
+                        (iq) => iq.nodeTree.querySelector('iq[to="lounge@muc.localhost"][type="get"] item[affiliation="admin"]')).pop()
+                    );
+                }).then(node => {
+                    const iq_stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq id="${iq_stanza.getAttribute('id')}" to="lounge@muc.localhost" type="get" xmlns="jabber:client">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                             `<query xmlns="http://jabber.org/protocol/muc#admin">`+
                                 `<item affiliation="admin"/>`+
                                 `<item affiliation="admin"/>`+
                             `</query>`+
                             `</query>`+
@@ -2276,8 +2267,8 @@
                     });
                     });
 
 
                     expect(sent_stanza.textContent).toBe('This is a new subject');
                     expect(sent_stanza.textContent).toBe('This is a new subject');
-                    expect(sent_stanza.outerHTML).toBe(
-                        '<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
+                    expect(Strophe.serialize(sent_stanza).toLocaleString()).toBe(
+                        '<message from="dummy@localhost/resource" to="lounge@localhost" type="groupchat" xmlns="jabber:client">'+
                             '<subject xmlns="jabber:client">This is a new subject</subject>'+
                             '<subject xmlns="jabber:client">This is a new subject</subject>'+
                         '</message>');
                         '</message>');
 
 
@@ -2289,8 +2280,8 @@
                         keyCode: 13
                         keyCode: 13
                     });
                     });
                     expect(sent_stanza.textContent).toBe('This is yet another subject');
                     expect(sent_stanza.textContent).toBe('This is yet another subject');
-                    expect(sent_stanza.outerHTML).toBe(
-                        '<message to="lounge@localhost" from="dummy@localhost/resource" type="groupchat" xmlns="jabber:client">'+
+                    expect(Strophe.serialize(sent_stanza).toLocaleString()).toBe(
+                        '<message from="dummy@localhost/resource" to="lounge@localhost" type="groupchat" xmlns="jabber:client">'+
                             '<subject xmlns="jabber:client">This is yet another subject</subject>'+
                             '<subject xmlns="jabber:client">This is yet another subject</subject>'+
                         '</message>');
                         '</message>');
                     done();
                     done();
@@ -2380,13 +2371,13 @@
                     expect(view.showErrorMessage.calls.count()).toBe(2);
                     expect(view.showErrorMessage.calls.count()).toBe(2);
                     // Check that the member list now gets updated
                     // Check that the member list now gets updated
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item affiliation='owner' jid='annoyingGuy'>"+
-                                    "<reason>You&apos;re responsible</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item affiliation="owner" jid="annoyingGuy">`+
+                                    `<reason>You&apos;re responsible</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                     presence = $pres({
                     presence = $pres({
                             'from': 'lounge@localhost/annoyingGuy',
                             'from': 'lounge@localhost/annoyingGuy',
@@ -2461,13 +2452,13 @@
                     expect(view.model.setAffiliation).toHaveBeenCalled();
                     expect(view.model.setAffiliation).toHaveBeenCalled();
                     // Check that the member list now gets updated
                     // Check that the member list now gets updated
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item affiliation='outcast' jid='annoyingGuy'>"+
-                                    "<reason>You&apos;re annoying</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item affiliation="outcast" jid="annoyingGuy">`+
+                                    `<reason>You&apos;re annoying</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                     presence = $pres({
                     presence = $pres({
                             'from': 'lounge@localhost/annoyingGuy',
                             'from': 'lounge@localhost/annoyingGuy',
@@ -2541,13 +2532,13 @@
                     expect(view.showErrorMessage.calls.count()).toBe(1);
                     expect(view.showErrorMessage.calls.count()).toBe(1);
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item nick='annoyingGuy' role='none'>"+
-                                    "<reason>You&apos;re annoying</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item nick="annoyingGuy" role="none">`+
+                                    `<reason>You&apos;re annoying</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                     /* <presence
                     /* <presence
                      *     from='harfleur@chat.shakespeare.lit/pistol'
                      *     from='harfleur@chat.shakespeare.lit/pistol'
@@ -2645,13 +2636,13 @@
                     expect(view.showErrorMessage.calls.count()).toBe(1);
                     expect(view.showErrorMessage.calls.count()).toBe(1);
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item nick='trustworthyguy' role='moderator'>"+
-                                    "<reason>You&apos;re trustworthy</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item nick="trustworthyguy" role="moderator">`+
+                                    `<reason>You&apos;re trustworthy</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                    /* <presence
                    /* <presence
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
@@ -2682,13 +2673,13 @@
                     expect(view.showChatEvent.calls.count()).toBe(1);
                     expect(view.showChatEvent.calls.count()).toBe(1);
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item nick='trustworthyguy' role='participant'>"+
-                                    "<reason>Perhaps not</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item nick="trustworthyguy" role="participant">`+
+                                    `<reason>Perhaps not</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                    /* <presence
                    /* <presence
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
@@ -2783,13 +2774,13 @@
                     expect(view.showErrorMessage.calls.count()).toBe(1);
                     expect(view.showErrorMessage.calls.count()).toBe(1);
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item nick='annoyingGuy' role='visitor'>"+
-                                    "<reason>You&apos;re annoying</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item nick="annoyingGuy" role="visitor">`+
+                                    `<reason>You&apos;re annoying</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                    /* <presence
                    /* <presence
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
@@ -2820,13 +2811,13 @@
                     expect(view.showChatEvent.calls.count()).toBe(1);
                     expect(view.showChatEvent.calls.count()).toBe(1);
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(view.modifyRole).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq to='lounge@localhost' type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item nick='annoyingGuy' role='participant'>"+
-                                    "<reason>Now you can talk again</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item nick="annoyingGuy" role="participant">`+
+                                    `<reason>Now you can talk again</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                    /* <presence
                    /* <presence
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
                     *     from='coven@chat.shakespeare.lit/thirdwitch'
@@ -3160,15 +3151,16 @@
 
 
                 _converse.api.rooms.open(room_jid, {'nick': 'dummy'})
                 _converse.api.rooms.open(room_jid, {'nick': 'dummy'})
                 .then(() => {
                 .then(() => {
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                         IQ_stanzas,
                         IQ_stanzas,
                         iq => iq.nodeTree.querySelector(
                         iq => iq.nodeTree.querySelector(
                             `iq[to="${room_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
                             `iq[to="${room_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
-                        )).pop(), 'nodeTree'));
-                }).then(stanza => {
+                        )).pop());
+                }).then(node => {
                     // Check that the groupchat queried for the feautures.
                     // Check that the groupchat queried for the feautures.
-                    expect(stanza.outerHTML).toBe(
-                        `<iq from="dummy@localhost/resource" to="${room_jid}" type="get" xmlns="jabber:client" id="${stanza.getAttribute("id")}">`+
+                    const stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq from="dummy@localhost/resource" id="${stanza.getAttribute("id")}" to="${room_jid}" type="get" xmlns="jabber:client">`+
                             `<query xmlns="http://jabber.org/protocol/disco#info"/>`+
                             `<query xmlns="http://jabber.org/protocol/disco#info"/>`+
                         `</iq>`);
                         `</iq>`);
 
 
@@ -3215,23 +3207,23 @@
                    var member_iq_id = IQ_ids.pop();
                    var member_iq_id = IQ_ids.pop();
 
 
                    expect(sent_IQs.pop().toLocaleString()).toBe(
                    expect(sent_IQs.pop().toLocaleString()).toBe(
-                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+admin_iq_id+"'>"+
-                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                               "<item affiliation='admin'/>"+
-                           "</query>"+
-                       "</iq>");
+                       `<iq id="${admin_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
+                           `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                               `<item affiliation="admin"/>`+
+                           `</query>`+
+                       `</iq>`);
                    expect(sent_IQs.pop().toLocaleString()).toBe(
                    expect(sent_IQs.pop().toLocaleString()).toBe(
-                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+owner_iq_id+"'>"+
-                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                               "<item affiliation='owner'/>"+
-                           "</query>"+
-                       "</iq>");
+                       `<iq id="${owner_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
+                           `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                               `<item affiliation="owner"/>`+
+                           `</query>`+
+                       `</iq>`);
                    expect(sent_IQs.pop().toLocaleString()).toBe(
                    expect(sent_IQs.pop().toLocaleString()).toBe(
-                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+member_iq_id+"'>"+
-                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                               "<item affiliation='member'/>"+
-                           "</query>"+
-                       "</iq>");
+                       `<iq id="${member_iq_id}" to="coven@chat.shakespeare.lit" type="get" xmlns="jabber:client">`+
+                           `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                               `<item affiliation="member"/>`+
+                           `</query>`+
+                       `</iq>`);
 
 
                    /* Now the service sends the member list to the user
                    /* Now the service sends the member list to the user
                     *
                     *
@@ -3294,18 +3286,18 @@
                         )).pop(), 'nodeTree'));
                         )).pop(), 'nodeTree'));
                 }).then(stanza => {
                 }).then(stanza => {
                     expect(stanza.outerHTML,
                     expect(stanza.outerHTML,
-                        "<iq to='coven@chat.shakespeare.lit' type='set' xmlns='jabber:client' id='"+IQ_ids.pop()+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                                "<item affiliation='member' jid='"+invitee_jid+"'>"+
-                                    "<reason>Please join this groupchat</reason>"+
-                                "</item>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_ids.pop()}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/muc#admin">`+
+                                `<item affiliation="member" jid="${invitee_jid}">`+
+                                    `<reason>Please join this groupchat</reason>`+
+                                `</item>`+
+                            `</query>`+
+                        `</iq>`);
                     // Finally check that the user gets invited.
                     // Finally check that the user gets invited.
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
-                        "<message from='dummy@localhost/resource' to='"+invitee_jid+"' id='"+sent_id+"' xmlns='jabber:client'>"+
-                            "<x xmlns='jabber:x:conference' jid='coven@chat.shakespeare.lit' reason='Please join this groupchat'/>"+
-                        "</message>"
+                        `<message from="dummy@localhost/resource" id="${sent_id}" to="${invitee_jid}" xmlns="jabber:client">`+
+                            `<x jid="coven@chat.shakespeare.lit" reason="Please join this groupchat" xmlns="jabber:x:conference"/>`+
+                        `</message>`
                     );
                     );
                     done();
                     done();
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
@@ -3443,9 +3435,9 @@
                     return test_utils.waitUntil(() => _converse.chatboxes.length);
                     return test_utils.waitUntil(() => _converse.chatboxes.length);
                 }).then(() => {
                 }).then(() => {
                     expect(sent_stanza.toLocaleString()).toBe(
                     expect(sent_stanza.toLocaleString()).toBe(
-                        "<iq to='chat.shakespear.lit' from='dummy@localhost/resource' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='http://jabber.org/protocol/disco#items'/>"+
-                        "</iq>"
+                        `<iq from="dummy@localhost/resource" id="${IQ_id}" to="chat.shakespear.lit" type="get" xmlns="jabber:client">`+
+                            `<query xmlns="http://jabber.org/protocol/disco#items"/>`+
+                        `</iq>`
                     );
                     );
 
 
                     var iq = $iq({
                     var iq = $iq({

+ 6 - 6
spec/controlbox.js

@@ -223,9 +223,9 @@
                 input_name.value = 'Someone';
                 input_name.value = 'Someone';
                 modal.el.querySelector('button[type="submit"]').click();
                 modal.el.querySelector('button[type="submit"]').click();
                 expect(sent_stanza.toLocaleString()).toEqual(
                 expect(sent_stanza.toLocaleString()).toEqual(
-                "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                    "<query xmlns='jabber:iq:roster'><item jid='someone@localhost' name='Someone'/></query>"+
-                "</iq>");
+                `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                    `<query xmlns="jabber:iq:roster"><item jid="someone@localhost" name="Someone"/></query>`+
+                `</iq>`);
                 done();
                 done();
             });
             });
         }));
         }));
@@ -294,9 +294,9 @@
                 expect(modal.el.querySelector('input[name="jid"]').value).toBe('marty@mcfly.net');
                 expect(modal.el.querySelector('input[name="jid"]').value).toBe('marty@mcfly.net');
                 modal.el.querySelector('button[type="submit"]').click();
                 modal.el.querySelector('button[type="submit"]').click();
                 expect(sent_stanza.toLocaleString()).toEqual(
                 expect(sent_stanza.toLocaleString()).toEqual(
-                "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                    "<query xmlns='jabber:iq:roster'><item jid='marty@mcfly.net' name='Marty McFly'/></query>"+
-                "</iq>");
+                `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                    `<query xmlns="jabber:iq:roster"><item jid="marty@mcfly.net" name="Marty McFly"/></query>`+
+                `</iq>`);
                 window.XMLHttpRequest = XMLHttpRequestBackup;
                 window.XMLHttpRequest = XMLHttpRequestBackup;
                 done();
                 done();
             });
             });

+ 2 - 6
spec/converse.js

@@ -74,14 +74,10 @@
                     i++;
                     i++;
                 }
                 }
                 expect(_converse.sendCSI).toHaveBeenCalledWith('inactive');
                 expect(_converse.sendCSI).toHaveBeenCalledWith('inactive');
-                expect(sent_stanza.toLocaleString()).toBe(
-                    "<inactive xmlns='urn:xmpp:csi:0'/>"
-                );
+                expect(sent_stanza.toLocaleString()).toBe('<inactive xmlns="urn:xmpp:csi:0"/>');
                 _converse.onUserActivity();
                 _converse.onUserActivity();
                 expect(_converse.sendCSI).toHaveBeenCalledWith('active');
                 expect(_converse.sendCSI).toHaveBeenCalledWith('active');
-                expect(sent_stanza.toLocaleString()).toBe(
-                    "<active xmlns='urn:xmpp:csi:0'/>"
-                );
+                expect(sent_stanza.toLocaleString()).toBe('<active xmlns="urn:xmpp:csi:0"/>');
                 // Reset values
                 // Reset values
                 _converse.csi_waiting_time = 0;
                 _converse.csi_waiting_time = 0;
                 _converse.disco_entities.get(_converse.domain).features['urn:xmpp:csi:0'] = false;
                 _converse.disco_entities.get(_converse.domain).features['urn:xmpp:csi:0'] = false;

+ 65 - 65
spec/http-file-upload.js

@@ -118,9 +118,9 @@
                         });
                         });
                         var IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
                         var IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
                         expect(stanza.toLocaleString()).toBe(
                         expect(stanza.toLocaleString()).toBe(
-                            "<iq from='dummy@localhost/resource' to='upload.localhost' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                                "<query xmlns='http://jabber.org/protocol/disco#info'/>"+
-                            "</iq>");
+                            `<iq from="dummy@localhost/resource" id="`+IQ_id+`" to="upload.localhost" type="get" xmlns="jabber:client">`+
+                                `<query xmlns="http://jabber.org/protocol/disco#info"/>`+
+                            `</iq>`);
 
 
                         // Upload service responds and reports a maximum file size of 5MiB
                         // Upload service responds and reports a maximum file size of 5MiB
                         /* <iq from='upload.montague.tld'
                         /* <iq from='upload.montague.tld'
@@ -301,16 +301,17 @@
                                 }).then(function () {
                                 }).then(function () {
                                     var iq = IQ_stanzas.pop();
                                     var iq = IQ_stanzas.pop();
                                     expect(iq.toLocaleString()).toBe(
                                     expect(iq.toLocaleString()).toBe(
-                                        "<iq from='dummy@localhost/resource' "+
-                                            "to='upload.montague.tld' "+
-                                            "type='get' "+
-                                            "xmlns='jabber:client' "+
-                                            "id='"+iq.nodeTree.getAttribute('id')+"'>"+
-                                        "<request xmlns='urn:xmpp:http:upload:0' "+
-                                            "filename='my-juliet.jpg' "+
-                                            "size='23456' "+
-                                            "content-type='image/jpeg'/>"+
-                                        "</iq>");
+                                        `<iq from="dummy@localhost/resource" `+
+                                            `id="${iq.nodeTree.getAttribute("id")}" `+
+                                            `to="upload.montague.tld" `+
+                                            `type="get" `+
+                                            `xmlns="jabber:client">`+
+                                        `<request `+
+                                            `content-type="image/jpeg" `+
+                                            `filename="my-juliet.jpg" `+
+                                            `size="23456" `+
+                                            `xmlns="urn:xmpp:http:upload:0"/>`+
+                                        `</iq>`);
 
 
                                     var base_url = document.URL.split(window.location.pathname)[0];
                                     var base_url = document.URL.split(window.location.pathname)[0];
                                     var message = base_url+"/logo/conversejs-filled.svg";
                                     var message = base_url+"/logo/conversejs-filled.svg";
@@ -352,19 +353,18 @@
                                         return sent_stanza;
                                         return sent_stanza;
                                     }, 1000).then(function () {
                                     }, 1000).then(function () {
                                         expect(sent_stanza.toLocaleString()).toBe(
                                         expect(sent_stanza.toLocaleString()).toBe(
-                                            "<message from='dummy@localhost/resource' "+
-                                                "to='irini.vlastuin@localhost' "+
-                                                "type='chat' "+
-                                                "id='"+sent_stanza.nodeTree.getAttribute('id')+"' xmlns='jabber:client'>"+
-                                                    "<body>"+message+"</body>"+
-                                                    "<active xmlns='http://jabber.org/protocol/chatstates'/>"+
-                                                    "<x xmlns='jabber:x:oob'>"+
-                                                        "<url>"+message+"</url>"+
-                                                    "</x>"+
-                                            "</message>");
-                                        return test_utils.waitUntil(function () {
-                                            return view.el.querySelector('.chat-image');
-                                        }, 1000);
+                                            `<message from="dummy@localhost/resource" `+
+                                                `id="${sent_stanza.nodeTree.getAttribute("id")}" `+
+                                                `to="irini.vlastuin@localhost" `+
+                                                `type="chat" `+
+                                                `xmlns="jabber:client">`+
+                                                    `<body>${message}</body>`+
+                                                    `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                                                    `<x xmlns="jabber:x:oob">`+
+                                                        `<url>${message}</url>`+
+                                                    `</x>`+
+                                            `</message>`);
+                                        return test_utils.waitUntil(() => view.el.querySelector('.chat-image'), 1000);
                                     }).then(function () {
                                     }).then(function () {
                                         // Check that the image renders
                                         // Check that the image renders
                                         expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
                                         expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
@@ -408,16 +408,17 @@
                                         }).then(function () {
                                         }).then(function () {
                                             var iq = IQ_stanzas.pop();
                                             var iq = IQ_stanzas.pop();
                                             expect(iq.toLocaleString()).toBe(
                                             expect(iq.toLocaleString()).toBe(
-                                                "<iq from='dummy@localhost/resource' "+
-                                                    "to='upload.montague.tld' "+
-                                                    "type='get' "+
-                                                    "xmlns='jabber:client' "+
-                                                    "id='"+iq.nodeTree.getAttribute('id')+"'>"+
-                                                "<request xmlns='urn:xmpp:http:upload:0' "+
-                                                    "filename='my-juliet.jpg' "+
-                                                    "size='23456' "+
-                                                    "content-type='image/jpeg'/>"+
-                                                "</iq>");
+                                                `<iq from="dummy@localhost/resource" `+
+                                                    `id="${iq.nodeTree.getAttribute("id")}" `+
+                                                    `to="upload.montague.tld" `+
+                                                    `type="get" `+
+                                                    `xmlns="jabber:client">`+
+                                                `<request `+
+                                                    `content-type="image/jpeg" `+
+                                                    `filename="my-juliet.jpg" `+
+                                                    `size="23456" `+
+                                                    `xmlns="urn:xmpp:http:upload:0"/>`+
+                                                `</iq>`);
 
 
                                             var base_url = document.URL.split(window.location.pathname)[0];
                                             var base_url = document.URL.split(window.location.pathname)[0];
                                             var message = base_url+"/logo/conversejs-filled.svg";
                                             var message = base_url+"/logo/conversejs-filled.svg";
@@ -455,23 +456,21 @@
                                             });
                                             });
                                             _converse.connection._dataRecv(test_utils.createRequest(stanza));
                                             _converse.connection._dataRecv(test_utils.createRequest(stanza));
 
 
-                                            return test_utils.waitUntil(function () {
-                                                return sent_stanza;
-                                            }, 1000).then(function () {
+                                            return test_utils.waitUntil(() => sent_stanza, 1000).then(function () {
                                                 expect(sent_stanza.toLocaleString()).toBe(
                                                 expect(sent_stanza.toLocaleString()).toBe(
-                                                    "<message from='dummy@localhost/resource' "+
-                                                        "to='lounge@localhost' "+
-                                                        "type='groupchat' "+
-                                                        "id='"+sent_stanza.nodeTree.getAttribute('id')+"' xmlns='jabber:client'>"+
-                                                            "<body>"+message+"</body>"+
-                                                            "<active xmlns='http://jabber.org/protocol/chatstates'/>"+
-                                                            "<x xmlns='jabber:x:oob'>"+
-                                                                "<url>"+message+"</url>"+
-                                                            "</x>"+
-                                                    "</message>");
-                                                return test_utils.waitUntil(function () {
-                                                    return view.el.querySelector('.chat-image');
-                                                }, 1000);
+                                                    `<message `+
+                                                        `from="dummy@localhost/resource" `+
+                                                        `id="${sent_stanza.nodeTree.getAttribute("id")}" `+
+                                                        `to="lounge@localhost" `+
+                                                        `type="groupchat" `+
+                                                        `xmlns="jabber:client">`+
+                                                            `<body>${message}</body>`+
+                                                            `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                                                            `<x xmlns="jabber:x:oob">`+
+                                                                `<url>${message}</url>`+
+                                                            `</x>`+
+                                                    `</message>`);
+                                                return test_utils.waitUntil(() => view.el.querySelector('.chat-image'), 1000);
                                             }).then(function () {
                                             }).then(function () {
                                                 // Check that the image renders
                                                 // Check that the image renders
                                                 expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
                                                 expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
@@ -569,9 +568,9 @@
                             });
                             });
                             var IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
                             var IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
                             expect(stanza.toLocaleString()).toBe(
                             expect(stanza.toLocaleString()).toBe(
-                                "<iq from='dummy@localhost/resource' to='upload.localhost' type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                                    "<query xmlns='http://jabber.org/protocol/disco#info'/>"+
-                                "</iq>");
+                                `<iq from="dummy@localhost/resource" id="${IQ_id}" to="upload.localhost" type="get" xmlns="jabber:client">`+
+                                    `<query xmlns="http://jabber.org/protocol/disco#info"/>`+
+                                `</iq>`);
 
 
                             // Upload service responds and reports a maximum file size of 5MiB
                             // Upload service responds and reports a maximum file size of 5MiB
                             stanza = $iq({'type': 'result', 'to': 'dummy@localhost/resource', 'id': IQ_id, 'from': 'upload.localhost'})
                             stanza = $iq({'type': 'result', 'to': 'dummy@localhost/resource', 'id': IQ_id, 'from': 'upload.localhost'})
@@ -650,16 +649,17 @@
                         }).then(function () {
                         }).then(function () {
                             const iq = IQ_stanzas.pop();
                             const iq = IQ_stanzas.pop();
                             expect(iq.toLocaleString()).toBe(
                             expect(iq.toLocaleString()).toBe(
-                                "<iq from='dummy@localhost/resource' "+
-                                    "to='upload.montague.tld' "+
-                                    "type='get' "+
-                                    "xmlns='jabber:client' "+
-                                    "id='"+iq.nodeTree.getAttribute('id')+"'>"+
-                                "<request xmlns='urn:xmpp:http:upload:0' "+
-                                    "filename='my-juliet.jpg' "+
-                                    "size='23456' "+
-                                    "content-type='image/jpeg'/>"+
-                                "</iq>");
+                                `<iq from="dummy@localhost/resource" `+
+                                    `id="${iq.nodeTree.getAttribute("id")}" `+
+                                    `to="upload.montague.tld" `+
+                                    `type="get" `+
+                                    `xmlns="jabber:client">`+
+                                `<request `+
+                                    `content-type="image/jpeg" `+
+                                    `filename="my-juliet.jpg" `+
+                                    `size="23456" `+
+                                    `xmlns="urn:xmpp:http:upload:0"/>`+
+                                `</iq>`);
 
 
                             const base_url = document.URL.split(window.location.pathname)[0];
                             const base_url = document.URL.split(window.location.pathname)[0];
                             const message = base_url+"/logo/conversejs-filled.svg";
                             const message = base_url+"/logo/conversejs-filled.svg";

+ 120 - 125
spec/mam.js

@@ -81,7 +81,7 @@
                 _converse.api.archive.query();
                 _converse.api.archive.query();
                 var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                 var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                 expect(sent_stanza.toString()).toBe(
                 expect(sent_stanza.toString()).toBe(
-                    "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'><query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'/></iq>");
+                    `<iq id="${IQ_id}" type="set" xmlns="jabber:client"><query queryid="${queryid}" xmlns="urn:xmpp:mam:2"/></iq>`);
                 done();
                 done();
             }));
             }));
 
 
@@ -103,19 +103,18 @@
                     _converse.api.archive.query({'with':'juliet@capulet.lit'});
                     _converse.api.archive.query({'with':'juliet@capulet.lit'});
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                "<field var='FORM_TYPE' type='hidden'>"+
-                                    "<value>urn:xmpp:mam:2</value>"+
-                                "</field>"+
-                                "<field var='with'>"+
-                                    "<value>juliet@capulet.lit</value>"+
-                                "</field>"+
-                                "</x>"+
-                            "</query>"+
-                        "</iq>"
-                    );
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                `<field type="hidden" var="FORM_TYPE">`+
+                                    `<value>urn:xmpp:mam:2</value>`+
+                                `</field>`+
+                                `<field var="with">`+
+                                    `<value>juliet@capulet.lit</value>`+
+                                `</field>`+
+                                `</x>`+
+                            `</query>`+
+                        `</iq>`);
                     done();
                     done();
                 });
                 });
             }));
             }));
@@ -142,15 +141,15 @@
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
 
 
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' to='coven@chat.shakespeare.lit' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                    "<field var='FORM_TYPE' type='hidden'>"+
-                                        "<value>urn:xmpp:mam:2</value>"+
-                                    "</field>"+
-                                "</x>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                    `<field type="hidden" var="FORM_TYPE">`+
+                                        `<value>urn:xmpp:mam:2</value>`+
+                                    `</field>`+
+                                `</x>`+
+                            `</query>`+
+                        `</iq>`);
                     done();
                     done();
                 });
                 });
            }));
            }));
@@ -257,21 +256,21 @@
                     });
                     });
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                "<field var='FORM_TYPE' type='hidden'>"+
-                                    "<value>urn:xmpp:mam:2</value>"+
-                                "</field>"+
-                                "<field var='start'>"+
-                                    "<value>"+moment(start).format()+"</value>"+
-                                "</field>"+
-                                "<field var='end'>"+
-                                    "<value>"+moment(end).format()+"</value>"+
-                                "</field>"+
-                                "</x>"+
-                            "</query>"+
-                        "</iq>"
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                `<field type="hidden" var="FORM_TYPE">`+
+                                    `<value>urn:xmpp:mam:2</value>`+
+                                `</field>`+
+                                `<field var="start">`+
+                                    `<value>${moment(start).format()}</value>`+
+                                `</field>`+
+                                `<field var="end">`+
+                                    `<value>${moment(end).format()}</value>`+
+                                `</field>`+
+                                `</x>`+
+                            `</query>`+
+                        `</iq>`
                     );
                     );
                     done();
                     done();
                 });
                 });
@@ -315,18 +314,18 @@
                     _converse.api.archive.query({'start': start});
                     _converse.api.archive.query({'start': start});
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                "<field var='FORM_TYPE' type='hidden'>"+
-                                    "<value>urn:xmpp:mam:2</value>"+
-                                "</field>"+
-                                "<field var='start'>"+
-                                    "<value>"+moment(start).format()+"</value>"+
-                                "</field>"+
-                                "</x>"+
-                            "</query>"+
-                        "</iq>"
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                `<field type="hidden" var="FORM_TYPE">`+
+                                    `<value>urn:xmpp:mam:2</value>`+
+                                `</field>`+
+                                `<field var="start">`+
+                                    `<value>${moment(start).format()}</value>`+
+                                `</field>`+
+                                `</x>`+
+                            `</query>`+
+                        `</iq>`
                     );
                     );
                     done();
                     done();
                 });
                 });
@@ -352,21 +351,21 @@
                     _converse.api.archive.query({'start': start, 'max':10});
                     _converse.api.archive.query({'start': start, 'max':10});
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                    "<field var='FORM_TYPE' type='hidden'>"+
-                                        "<value>urn:xmpp:mam:2</value>"+
-                                    "</field>"+
-                                    "<field var='start'>"+
-                                        "<value>"+moment(start).format()+"</value>"+
-                                    "</field>"+
-                                "</x>"+
-                                "<set xmlns='http://jabber.org/protocol/rsm'>"+
-                                    "<max>10</max>"+
-                                "</set>"+
-                            "</query>"+
-                        "</iq>"
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                    `<field type="hidden" var="FORM_TYPE">`+
+                                        `<value>urn:xmpp:mam:2</value>`+
+                                    `</field>`+
+                                    `<field var="start">`+
+                                        `<value>${moment(start).format()}</value>`+
+                                    `</field>`+
+                                `</x>`+
+                                `<set xmlns="http://jabber.org/protocol/rsm">`+
+                                    `<max>10</max>`+
+                                `</set>`+
+                            `</query>`+
+                        `</iq>`
                     );
                     );
                     done();
                     done();
                 });
                 });
@@ -395,23 +394,22 @@
                     });
                     });
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                    "<field var='FORM_TYPE' type='hidden'>"+
-                                        "<value>urn:xmpp:mam:2</value>"+
-                                    "</field>"+
-                                    "<field var='start'>"+
-                                        "<value>"+moment(start).format()+"</value>"+
-                                    "</field>"+
-                                "</x>"+
-                                "<set xmlns='http://jabber.org/protocol/rsm'>"+
-                                    "<max>10</max>"+
-                                    "<after>09af3-cc343-b409f</after>"+
-                                "</set>"+
-                            "</query>"+
-                        "</iq>"
-                    );
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                    `<field type="hidden" var="FORM_TYPE">`+
+                                        `<value>urn:xmpp:mam:2</value>`+
+                                    `</field>`+
+                                    `<field var="start">`+
+                                        `<value>${moment(start).format()}</value>`+
+                                    `</field>`+
+                                `</x>`+
+                                `<set xmlns="http://jabber.org/protocol/rsm">`+
+                                    `<max>10</max>`+
+                                    `<after>09af3-cc343-b409f</after>`+
+                                `</set>`+
+                            `</query>`+
+                        `</iq>`);
                     done();
                     done();
                 });
                 });
            }));
            }));
@@ -434,20 +432,19 @@
                     _converse.api.archive.query({'before': '', 'max':10});
                     _converse.api.archive.query({'before': '', 'max':10});
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                    "<field var='FORM_TYPE' type='hidden'>"+
-                                        "<value>urn:xmpp:mam:2</value>"+
-                                    "</field>"+
-                                "</x>"+
-                                "<set xmlns='http://jabber.org/protocol/rsm'>"+
-                                    "<max>10</max>"+
-                                    "<before></before>"+
-                                "</set>"+
-                            "</query>"+
-                        "</iq>"
-                    );
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                    `<field type="hidden" var="FORM_TYPE">`+
+                                        `<value>urn:xmpp:mam:2</value>`+
+                                    `</field>`+
+                                `</x>`+
+                                `<set xmlns="http://jabber.org/protocol/rsm">`+
+                                    `<max>10</max>`+
+                                    `<before></before>`+
+                                `</set>`+
+                            `</query>`+
+                        `</iq>`);
                     done();
                     done();
                 });
                 });
            }));
            }));
@@ -478,25 +475,24 @@
 
 
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     var queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='urn:xmpp:mam:2' queryid='"+queryid+"'>"+
-                                "<x xmlns='jabber:x:data' type='submit'>"+
-                                    "<field var='FORM_TYPE' type='hidden'>"+
-                                        "<value>urn:xmpp:mam:2</value>"+
-                                    "</field>"+
-                                    "<field var='with'>"+
-                                        "<value>romeo@montague.lit</value>"+
-                                    "</field>"+
-                                    "<field var='start'>"+
-                                        "<value>"+moment(rsm.start).format()+"</value>"+
-                                    "</field>"+
-                                "</x>"+
-                                "<set xmlns='http://jabber.org/protocol/rsm'>"+
-                                    "<max>10</max>"+
-                                "</set>"+
-                            "</query>"+
-                        "</iq>"
-                    );
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query queryid="${queryid}" xmlns="urn:xmpp:mam:2">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
+                                    `<field type="hidden" var="FORM_TYPE">`+
+                                        `<value>urn:xmpp:mam:2</value>`+
+                                    `</field>`+
+                                    `<field var="with">`+
+                                        `<value>romeo@montague.lit</value>`+
+                                    `</field>`+
+                                    `<field var="start">`+
+                                        `<value>${moment(rsm.start).format()}</value>`+
+                                    `</field>`+
+                                `</x>`+
+                                `<set xmlns="http://jabber.org/protocol/rsm">`+
+                                    `<max>10</max>`+
+                                `</set>`+
+                            `</query>`+
+                        `</iq>`);
                     done();
                     done();
                 });
                 });
            }));
            }));
@@ -619,10 +615,9 @@
 
 
                     expect(_converse.connection.sendIQ).toHaveBeenCalled();
                     expect(_converse.connection.sendIQ).toHaveBeenCalled();
                     expect(sent_stanza.toLocaleString()).toBe(
                     expect(sent_stanza.toLocaleString()).toBe(
-                        "<iq type='get' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<prefs xmlns='urn:xmpp:mam:2'/>"+
-                        "</iq>"
-                    );
+                        `<iq id="${IQ_id}" type="get" xmlns="jabber:client">`+
+                            `<prefs xmlns="urn:xmpp:mam:2"/>`+
+                        `</iq>`);
 
 
                     /* Example 20. Server responds with current preferences
                     /* Example 20. Server responds with current preferences
                      *
                      *
@@ -643,12 +638,12 @@
                     expect(_converse.connection.sendIQ.calls.count()).toBe(2);
                     expect(_converse.connection.sendIQ.calls.count()).toBe(2);
 
 
                     expect(sent_stanza.toString()).toBe(
                     expect(sent_stanza.toString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<prefs xmlns='urn:xmpp:mam:2' default='never'>"+
-                                "<always><jid>romeo@montague.lit</jid></always>"+
-                                "<never><jid>montague@montague.lit</jid></never>"+
-                            "</prefs>"+
-                        "</iq>"
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<prefs default="never" xmlns="urn:xmpp:mam:2">`+
+                                `<always><jid>romeo@montague.lit</jid></always>`+
+                                `<never><jid>montague@montague.lit</jid></never>`+
+                            `</prefs>`+
+                        `</iq>`
                     );
                     );
 
 
                     expect(feature.get('preference')).toBe(undefined);
                     expect(feature.get('preference')).toBe(undefined);

+ 37 - 37
spec/messages.js

@@ -69,12 +69,12 @@
 
 
                 const msg = _converse.connection.send.calls.all()[0].args[0];
                 const msg = _converse.connection.send.calls.all()[0].args[0];
                 expect(msg.toLocaleString())
                 expect(msg.toLocaleString())
-                .toBe(`<message from='dummy@localhost/resource' `+
-                        `to='max.frankfurter@localhost' type='chat' id='${msg.nodeTree.getAttribute('id')}' `+
-                        `xmlns='jabber:client'>`+
+                .toBe(`<message from="dummy@localhost/resource" id="${msg.nodeTree.getAttribute("id")}" `+
+                        `to="max.frankfurter@localhost" type="chat" `+
+                        `xmlns="jabber:client">`+
                             `<body>But soft, what light through yonder window breaks?</body>`+
                             `<body>But soft, what light through yonder window breaks?</body>`+
-                            `<active xmlns='http://jabber.org/protocol/chatstates'/>`+
-                            `<replace xmlns='urn:xmpp:message-correct:0' id='${first_msg.get('msgid')}'/>`+
+                            `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                            `<replace id="${first_msg.get("msgid")}" xmlns="urn:xmpp:message-correct:0"/>`+
                     `</message>`);
                     `</message>`);
                 expect(view.model.messages.models.length).toBe(1);
                 expect(view.model.messages.models.length).toBe(1);
                 const corrected_message = view.model.messages.at(0);
                 const corrected_message = view.model.messages.at(0);
@@ -172,12 +172,12 @@
 
 
                 const msg = _converse.connection.send.calls.all()[0].args[0];
                 const msg = _converse.connection.send.calls.all()[0].args[0];
                 expect(msg.toLocaleString())
                 expect(msg.toLocaleString())
-                .toBe(`<message from='dummy@localhost/resource' `+
-                        `to='max.frankfurter@localhost' type='chat' id='${msg.nodeTree.getAttribute('id')}' `+
-                        `xmlns='jabber:client'>`+
+                .toBe(`<message from="dummy@localhost/resource" id="${msg.nodeTree.getAttribute("id")}" `+
+                        `to="max.frankfurter@localhost" type="chat" `+
+                        `xmlns="jabber:client">`+
                             `<body>But soft, what light through yonder window breaks?</body>`+
                             `<body>But soft, what light through yonder window breaks?</body>`+
-                            `<active xmlns='http://jabber.org/protocol/chatstates'/>`+
-                            `<replace xmlns='urn:xmpp:message-correct:0' id='${first_msg.get('msgid')}'/>`+
+                            `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                            `<replace id="${first_msg.get("msgid")}" xmlns="urn:xmpp:message-correct:0"/>`+
                     `</message>`);
                     `</message>`);
                 expect(view.model.messages.models.length).toBe(1);
                 expect(view.model.messages.models.length).toBe(1);
                 const corrected_message = view.model.messages.at(0);
                 const corrected_message = view.model.messages.at(0);
@@ -2090,12 +2090,12 @@
 
 
                 const msg = _converse.connection.send.calls.all()[0].args[0];
                 const msg = _converse.connection.send.calls.all()[0].args[0];
                 expect(msg.toLocaleString())
                 expect(msg.toLocaleString())
-                .toBe(`<message from='dummy@localhost/resource' `+
-                        `to='lounge@localhost' type='groupchat' id='${msg.nodeTree.getAttribute('id')}' `+
-                        `xmlns='jabber:client'>`+
+                .toBe(`<message from="dummy@localhost/resource" id="${msg.nodeTree.getAttribute("id")}" `+
+                        `to="lounge@localhost" type="groupchat" `+
+                        `xmlns="jabber:client">`+
                             `<body>But soft, what light through yonder window breaks?</body>`+
                             `<body>But soft, what light through yonder window breaks?</body>`+
-                            `<active xmlns='http://jabber.org/protocol/chatstates'/>`+
-                            `<replace xmlns='urn:xmpp:message-correct:0' id='${first_msg.get('msgid')}'/>`+
+                            `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                            `<replace id="${first_msg.get("msgid")}" xmlns="urn:xmpp:message-correct:0"/>`+
                     `</message>`);
                     `</message>`);
 
 
                 expect(view.model.messages.models.length).toBe(1);
                 expect(view.model.messages.models.length).toBe(1);
@@ -2291,14 +2291,14 @@
                     view.keyPressed(enter_event);
                     view.keyPressed(enter_event);
                     const msg = _converse.connection.send.calls.all()[0].args[0];
                     const msg = _converse.connection.send.calls.all()[0].args[0];
                     expect(msg.toLocaleString())
                     expect(msg.toLocaleString())
-                        .toBe(`<message from='dummy@localhost/resource' `+
-                                `to='lounge@localhost' type='groupchat' id='${msg.nodeTree.getAttribute('id')}' `+
-                                `xmlns='jabber:client'>`+
+                        .toBe(`<message from="dummy@localhost/resource" id="${msg.nodeTree.getAttribute("id")}" `+
+                                `to="lounge@localhost" type="groupchat" `+
+                                `xmlns="jabber:client">`+
                                     `<body>hello z3r0 gibson mr.robot, how are you?</body>`+
                                     `<body>hello z3r0 gibson mr.robot, how are you?</body>`+
-                                    `<active xmlns='http://jabber.org/protocol/chatstates'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='18' end='26' type='mention' uri='xmpp:mr.robot@localhost'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='11' end='17' type='mention' uri='xmpp:gibson@localhost'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='6' end='10' type='mention' uri='xmpp:z3r0@localhost'/>`+
+                                    `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                                    `<reference begin="18" end="26" type="mention" uri="xmpp:mr.robot@localhost" xmlns="urn:xmpp:reference:0"/>`+
+                                    `<reference begin="11" end="17" type="mention" uri="xmpp:gibson@localhost" xmlns="urn:xmpp:reference:0"/>`+
+                                    `<reference begin="6" end="10" type="mention" uri="xmpp:z3r0@localhost" xmlns="urn:xmpp:reference:0"/>`+
                               `</message>`);
                               `</message>`);
 
 
                     const first_msg = view.model.messages.findWhere({'message': 'hello z3r0 gibson mr.robot, how are you?'});
                     const first_msg = view.model.messages.findWhere({'message': 'hello z3r0 gibson mr.robot, how are you?'});
@@ -2316,15 +2316,15 @@
 
 
                     const correction = _converse.connection.send.calls.all()[1].args[0];
                     const correction = _converse.connection.send.calls.all()[1].args[0];
                     expect(correction.toLocaleString())
                     expect(correction.toLocaleString())
-                        .toBe(`<message from='dummy@localhost/resource' `+
-                                `to='lounge@localhost' type='groupchat' id='${correction.nodeTree.getAttribute('id')}' `+
-                                `xmlns='jabber:client'>`+
+                        .toBe(`<message from="dummy@localhost/resource" id="${correction.nodeTree.getAttribute("id")}" `+
+                                `to="lounge@localhost" type="groupchat" `+
+                                `xmlns="jabber:client">`+
                                     `<body>hello z3r0 gibson sw0rdf1sh, how are you?</body>`+
                                     `<body>hello z3r0 gibson sw0rdf1sh, how are you?</body>`+
-                                    `<active xmlns='http://jabber.org/protocol/chatstates'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='18' end='27' type='mention' uri='xmpp:sw0rdf1sh@localhost'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='11' end='17' type='mention' uri='xmpp:gibson@localhost'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='6' end='10' type='mention' uri='xmpp:z3r0@localhost'/>`+
-                                    `<replace xmlns='urn:xmpp:message-correct:0' id='${msg.nodeTree.getAttribute('id')}'/>`+
+                                    `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                                    `<reference begin="18" end="27" type="mention" uri="xmpp:sw0rdf1sh@localhost" xmlns="urn:xmpp:reference:0"/>`+
+                                    `<reference begin="11" end="17" type="mention" uri="xmpp:gibson@localhost" xmlns="urn:xmpp:reference:0"/>`+
+                                    `<reference begin="6" end="10" type="mention" uri="xmpp:z3r0@localhost" xmlns="urn:xmpp:reference:0"/>`+
+                                    `<replace id="${msg.nodeTree.getAttribute("id")}" xmlns="urn:xmpp:message-correct:0"/>`+
                               `</message>`);
                               `</message>`);
                     done();
                     done();
                 }).catch(_.partial(console.error, _));
                 }).catch(_.partial(console.error, _));
@@ -2365,14 +2365,14 @@
 
 
                     const msg = _converse.connection.send.calls.all()[0].args[0];
                     const msg = _converse.connection.send.calls.all()[0].args[0];
                     expect(msg.toLocaleString())
                     expect(msg.toLocaleString())
-                        .toBe(`<message from='dummy@localhost/resource' `+
-                                `to='lounge@localhost' type='groupchat' id='${msg.nodeTree.getAttribute('id')}' `+
-                                `xmlns='jabber:client'>`+
+                        .toBe(`<message from="dummy@localhost/resource" id="${msg.nodeTree.getAttribute("id")}" `+
+                                `to="lounge@localhost" type="groupchat" `+
+                                `xmlns="jabber:client">`+
                                     `<body>hello z3r0 gibson mr.robot, how are you?</body>`+
                                     `<body>hello z3r0 gibson mr.robot, how are you?</body>`+
-                                    `<active xmlns='http://jabber.org/protocol/chatstates'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='18' end='26' type='mention' uri='xmpp:mr.robot@localhost'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='11' end='17' type='mention' uri='xmpp:gibson@localhost'/>`+
-                                    `<reference xmlns='urn:xmpp:reference:0' begin='6' end='10' type='mention' uri='xmpp:z3r0@localhost'/>`+
+                                    `<active xmlns="http://jabber.org/protocol/chatstates"/>`+
+                                    `<reference begin="18" end="26" type="mention" uri="xmpp:mr.robot@localhost" xmlns="urn:xmpp:reference:0"/>`+
+                                    `<reference begin="11" end="17" type="mention" uri="xmpp:gibson@localhost" xmlns="urn:xmpp:reference:0"/>`+
+                                    `<reference begin="6" end="10" type="mention" uri="xmpp:z3r0@localhost" xmlns="urn:xmpp:reference:0"/>`+
                               `</message>`);
                               `</message>`);
                     done();
                     done();
                 }).catch(_.partial(console.error, _));
                 }).catch(_.partial(console.error, _));

+ 60 - 59
spec/omemo.js

@@ -183,18 +183,19 @@
                 return test_utils.waitUntil(() => sent_stanza);
                 return test_utils.waitUntil(() => sent_stanza);
             }).then(() => {
             }).then(() => {
                 expect(sent_stanza.toLocaleString()).toBe(
                 expect(sent_stanza.toLocaleString()).toBe(
-                    `<message from='dummy@localhost/resource' to='max.frankfurter@localhost' `+
-                             `type='chat' id='${sent_stanza.nodeTree.getAttribute('id')}' xmlns='jabber:client'>`+
+                    `<message from="dummy@localhost/resource" id="${sent_stanza.nodeTree.getAttribute("id")}" `+
+                             `to="max.frankfurter@localhost" `+
+                             `type="chat" xmlns="jabber:client">`+
                         `<body>This is an OMEMO encrypted message which your client doesn’t seem to support. Find more information on https://conversations.im/omemo</body>`+
                         `<body>This is an OMEMO encrypted message which your client doesn’t seem to support. Find more information on https://conversations.im/omemo</body>`+
-                        `<encrypted xmlns='eu.siacs.conversations.axolotl'>`+
-                            `<header sid='123456789'>`+
-                                `<key rid='482886413b977930064a5888b92134fe'>YzFwaDNSNzNYNw==</key>`+
-                                `<key rid='555'>YzFwaDNSNzNYNw==</key>`+
-                                `<iv>${sent_stanza.nodeTree.querySelector('iv').textContent}</iv>`+
+                        `<encrypted xmlns="eu.siacs.conversations.axolotl">`+
+                            `<header sid="123456789">`+
+                                `<key rid="482886413b977930064a5888b92134fe">YzFwaDNSNzNYNw==</key>`+
+                                `<key rid="555">YzFwaDNSNzNYNw==</key>`+
+                                `<iv>${sent_stanza.nodeTree.querySelector("iv").textContent}</iv>`+
                             `</header>`+
                             `</header>`+
-                            `<payload>${sent_stanza.nodeTree.querySelector('payload').textContent}</payload>`+
+                            `<payload>${sent_stanza.nodeTree.querySelector("payload").textContent}</payload>`+
                         `</encrypted>`+
                         `</encrypted>`+
-                        `<store xmlns='urn:xmpp:hints'/>`+
+                        `<store xmlns="urn:xmpp:hints"/>`+
                     `</message>`);
                     `</message>`);
 
 
                 // Test reception of an encrypted message
                 // Test reception of an encrypted message
@@ -296,20 +297,20 @@
             }).then(() => test_utils.waitUntil(() => bundleHasBeenPublished(_converse)))
             }).then(() => test_utils.waitUntil(() => bundleHasBeenPublished(_converse)))
             .then(iq_stanza => {
             .then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq from='dummy@localhost' type='set' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<publish node='eu.siacs.conversations.axolotl.bundles:123456789'>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" type="set" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<publish node="eu.siacs.conversations.axolotl.bundles:123456789">`+
                                 `<item>`+
                                 `<item>`+
-                                    `<bundle xmlns='eu.siacs.conversations.axolotl'>`+
-                                        `<signedPreKeyPublic signedPreKeyId='0'>${btoa('1234')}</signedPreKeyPublic>`+
-                                            `<signedPreKeySignature>${btoa('11112222333344445555')}</signedPreKeySignature>`+
-                                            `<identityKey>${btoa('1234')}</identityKey>`+
+                                    `<bundle xmlns="eu.siacs.conversations.axolotl">`+
+                                        `<signedPreKeyPublic signedPreKeyId="0">${btoa("1234")}</signedPreKeyPublic>`+
+                                            `<signedPreKeySignature>${btoa("11112222333344445555")}</signedPreKeySignature>`+
+                                            `<identityKey>${btoa("1234")}</identityKey>`+
                                         `<prekeys>`+
                                         `<prekeys>`+
-                                            `<preKeyPublic preKeyId='0'>${btoa('1234')}</preKeyPublic>`+
-                                            `<preKeyPublic preKeyId='1'>${btoa('1234')}</preKeyPublic>`+
-                                            `<preKeyPublic preKeyId='2'>${btoa('1234')}</preKeyPublic>`+
-                                            `<preKeyPublic preKeyId='3'>${btoa('1234')}</preKeyPublic>`+
-                                            `<preKeyPublic preKeyId='4'>${btoa('1234')}</preKeyPublic>`+
+                                            `<preKeyPublic preKeyId="0">${btoa("1234")}</preKeyPublic>`+
+                                            `<preKeyPublic preKeyId="1">${btoa("1234")}</preKeyPublic>`+
+                                            `<preKeyPublic preKeyId="2">${btoa("1234")}</preKeyPublic>`+
+                                            `<preKeyPublic preKeyId="3">${btoa("1234")}</preKeyPublic>`+
+                                            `<preKeyPublic preKeyId="4">${btoa("1234")}</preKeyPublic>`+
                                         `</prekeys>`+
                                         `</prekeys>`+
                                     `</bundle>`+
                                     `</bundle>`+
                                 `</item>`+
                                 `</item>`+
@@ -336,9 +337,9 @@
             test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid))
             test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid))
             .then(iq_stanza => {
             .then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq type='get' from='dummy@localhost' to='dummy@localhost' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<items node='eu.siacs.conversations.axolotl.devicelist'/>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" to="dummy@localhost" type="get" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<items node="eu.siacs.conversations.axolotl.devicelist"/>`+
                         `</pubsub>`+
                         `</pubsub>`+
                     `</iq>`);
                     `</iq>`);
 
 
@@ -453,13 +454,13 @@
                 // Check that our own device is added again, but that removed
                 // Check that our own device is added again, but that removed
                 // devices are not added.
                 // devices are not added.
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq from='dummy@localhost' type='set' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute(`id`)}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<publish node='eu.siacs.conversations.axolotl.devicelist'>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute(`id`)}" type="set" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<publish node="eu.siacs.conversations.axolotl.devicelist">`+
                                 `<item>`+
                                 `<item>`+
-                                    `<list xmlns='eu.siacs.conversations.axolotl'>`+
-                                        `<device id='123456789'/>`+
-                                        `<device id='444'/>`+
+                                    `<list xmlns="eu.siacs.conversations.axolotl">`+
+                                        `<device id="123456789"/>`+
+                                        `<device id="444"/>`+
                                     `</list>`+
                                     `</list>`+
                                 `</item>`+
                                 `</item>`+
                             `</publish>`+
                             `</publish>`+
@@ -487,9 +488,9 @@
             test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid))
             test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid))
             .then(iq_stanza => {
             .then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq type='get' from='dummy@localhost' to='dummy@localhost' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<items node='eu.siacs.conversations.axolotl.devicelist'/>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" to="dummy@localhost" type="get" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<items node="eu.siacs.conversations.axolotl.devicelist"/>`+
                         `</pubsub>`+
                         `</pubsub>`+
                     `</iq>`);
                     `</iq>`);
 
 
@@ -666,17 +667,17 @@
                 return test_utils.waitUntil(() => bundleHasBeenPublished(_converse));
                 return test_utils.waitUntil(() => bundleHasBeenPublished(_converse));
             }).then(iq_stanza => {
             }).then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq from='dummy@localhost' type='set' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<publish node='eu.siacs.conversations.axolotl.bundles:123456789'>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" type="set" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<publish node="eu.siacs.conversations.axolotl.bundles:123456789">`+
                                 `<item>`+
                                 `<item>`+
-                                    `<bundle xmlns='eu.siacs.conversations.axolotl'>`+
-                                        `<signedPreKeyPublic signedPreKeyId='0'>${btoa('1234')}</signedPreKeyPublic>`+
-                                            `<signedPreKeySignature>${btoa('11112222333344445555')}</signedPreKeySignature>`+
-                                            `<identityKey>${btoa('1234')}</identityKey>`+
+                                    `<bundle xmlns="eu.siacs.conversations.axolotl">`+
+                                        `<signedPreKeyPublic signedPreKeyId="0">${btoa("1234")}</signedPreKeyPublic>`+
+                                            `<signedPreKeySignature>${btoa("11112222333344445555")}</signedPreKeySignature>`+
+                                            `<identityKey>${btoa("1234")}</identityKey>`+
                                         `<prekeys>`+
                                         `<prekeys>`+
-                                            `<preKeyPublic preKeyId='0'>${btoa('1234')}</preKeyPublic>`+
-                                            `<preKeyPublic preKeyId='1'>${btoa('1234')}</preKeyPublic>`+
+                                            `<preKeyPublic preKeyId="0">${btoa("1234")}</preKeyPublic>`+
+                                            `<preKeyPublic preKeyId="1">${btoa("1234")}</preKeyPublic>`+
                                         `</prekeys>`+
                                         `</prekeys>`+
                                     `</bundle>`+
                                     `</bundle>`+
                                 `</item>`+
                                 `</item>`+
@@ -708,9 +709,9 @@
             test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid))
             test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid))
             .then(iq_stanza => {
             .then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq type='get' from='dummy@localhost' to='dummy@localhost' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<items node='eu.siacs.conversations.axolotl.devicelist'/>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" to="dummy@localhost" type="get" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<items node="eu.siacs.conversations.axolotl.devicelist"/>`+
                         `</pubsub>`+
                         `</pubsub>`+
                     `</iq>`);
                     `</iq>`);
 
 
@@ -736,13 +737,13 @@
                 return test_utils.waitUntil(() => ownDeviceHasBeenPublished(_converse));
                 return test_utils.waitUntil(() => ownDeviceHasBeenPublished(_converse));
             }).then(iq_stanza => {
             }).then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq from='dummy@localhost' type='set' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute(`id`)}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<publish node='eu.siacs.conversations.axolotl.devicelist'>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute(`id`)}" type="set" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<publish node="eu.siacs.conversations.axolotl.devicelist">`+
                                 `<item>`+
                                 `<item>`+
-                                    `<list xmlns='eu.siacs.conversations.axolotl'>`+
-                                        `<device id='482886413b977930064a5888b92134fe'/>`+
-                                        `<device id='123456789'/>`+
+                                    `<list xmlns="eu.siacs.conversations.axolotl">`+
+                                        `<device id="482886413b977930064a5888b92134fe"/>`+
+                                        `<device id="123456789"/>`+
                                     `</list>`+
                                     `</list>`+
                                 `</item>`+
                                 `</item>`+
                             `</publish>`+
                             `</publish>`+
@@ -781,9 +782,9 @@
                 return test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
                 return test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
             }).then(iq_stanza => {
             }).then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq type='get' from='dummy@localhost' to='${contact_jid}' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<items node='eu.siacs.conversations.axolotl.devicelist'/>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" to="${contact_jid}" type="get" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<items node="eu.siacs.conversations.axolotl.devicelist"/>`+
                         `</pubsub>`+
                         `</pubsub>`+
                     `</iq>`);
                     `</iq>`);
 
 
@@ -870,8 +871,8 @@
             }).then(() => test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid)))
             }).then(() => test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid)))
             .then(iq_stanza => {
             .then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq type='get' from='dummy@localhost' to='max.frankfurter@localhost' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'><items node='eu.siacs.conversations.axolotl.devicelist'/></pubsub>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" to="max.frankfurter@localhost" type="get" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub"><items node="eu.siacs.conversations.axolotl.devicelist"/></pubsub>`+
                     `</iq>`);
                     `</iq>`);
 
 
                 const stanza = $iq({
                 const stanza = $iq({
@@ -890,9 +891,9 @@
             }).then(() => test_utils.waitUntil(() => bundleFetched(_converse, contact_jid, '555')))
             }).then(() => test_utils.waitUntil(() => bundleFetched(_converse, contact_jid, '555')))
               .then(iq_stanza => {
               .then(iq_stanza => {
                 expect(iq_stanza.toLocaleString()).toBe(
                 expect(iq_stanza.toLocaleString()).toBe(
-                    `<iq type='get' from='dummy@localhost' to='max.frankfurter@localhost' xmlns='jabber:client' id='${iq_stanza.nodeTree.getAttribute('id')}'>`+
-                        `<pubsub xmlns='http://jabber.org/protocol/pubsub'>`+
-                            `<items node='eu.siacs.conversations.axolotl.bundles:555'/>`+
+                    `<iq from="dummy@localhost" id="${iq_stanza.nodeTree.getAttribute("id")}" to="max.frankfurter@localhost" type="get" xmlns="jabber:client">`+
+                        `<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
+                            `<items node="eu.siacs.conversations.axolotl.bundles:555"/>`+
                         `</pubsub>`+
                         `</pubsub>`+
                     `</iq>`);
                     `</iq>`);
 
 

+ 3 - 3
spec/ping.js

@@ -44,9 +44,9 @@
                 });
                 });
                 _converse.ping();
                 _converse.ping();
                 expect(sent_stanza.toLocaleString()).toBe(
                 expect(sent_stanza.toLocaleString()).toBe(
-                    "<iq type='get' to='localhost' id='"+IQ_id+"' xmlns='jabber:client'>"+
-                        "<ping xmlns='urn:xmpp:ping'/>"+
-                    "</iq>");
+                    `<iq id="${IQ_id}" to="localhost" type="get" xmlns="jabber:client">`+
+                        `<ping xmlns="urn:xmpp:ping"/>`+
+                    `</iq>`);
             }));
             }));
         });
         });
     });
     });

+ 31 - 35
spec/presence.js

@@ -34,42 +34,42 @@
 
 
                 const presence = _converse.xmppstatus.constructPresence();
                 const presence = _converse.xmppstatus.constructPresence();
                 expect(presence.toLocaleString()).toBe(
                 expect(presence.toLocaleString()).toBe(
-                    "<presence xmlns='jabber:client'>"+
-                        "<priority>0</priority>"+
-                        "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='QgayPKawpkPSDYmwT/WM94uAlu0='/>"+
-                    "</presence>")
+                    `<presence xmlns="jabber:client">`+
+                        `<priority>0</priority>`+
+                        `<c hash="sha-1" node="https://conversejs.org" ver="QgayPKawpkPSDYmwT/WM94uAlu0=" xmlns="http://jabber.org/protocol/caps"/>`+
+                    `</presence>`)
                 done();
                 done();
         }));
         }));
 
 
         it("has a given priority", mock.initConverse(function (_converse) {
         it("has a given priority", mock.initConverse(function (_converse) {
             var pres = _converse.xmppstatus.constructPresence('online', 'Hello world');
             var pres = _converse.xmppstatus.constructPresence('online', 'Hello world');
             expect(pres.toLocaleString()).toBe(
             expect(pres.toLocaleString()).toBe(
-                "<presence xmlns='jabber:client'>"+
-                    "<status>Hello world</status>"+
-                    "<priority>0</priority>"+
-                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='K7kn/M6VtmdMyo61pgn/jkZlax8='/>"+
-                "</presence>"
+                `<presence xmlns="jabber:client">`+
+                    `<status>Hello world</status>`+
+                    `<priority>0</priority>`+
+                    `<c hash="sha-1" node="https://conversejs.org" ver="K7kn/M6VtmdMyo61pgn/jkZlax8=" xmlns="http://jabber.org/protocol/caps"/>`+
+                `</presence>`
             );
             );
             _converse.priority = 2;
             _converse.priority = 2;
             pres = _converse.xmppstatus.constructPresence('away', 'Going jogging');
             pres = _converse.xmppstatus.constructPresence('away', 'Going jogging');
             expect(pres.toLocaleString()).toBe(
             expect(pres.toLocaleString()).toBe(
-                "<presence xmlns='jabber:client'>"+
-                    "<show>away</show>"+
-                    "<status>Going jogging</status>"+
-                    "<priority>2</priority>"+
-                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='K7kn/M6VtmdMyo61pgn/jkZlax8='/>"+
-                "</presence>"
+                `<presence xmlns="jabber:client">`+
+                    `<show>away</show>`+
+                    `<status>Going jogging</status>`+
+                    `<priority>2</priority>`+
+                    `<c hash="sha-1" node="https://conversejs.org" ver="K7kn/M6VtmdMyo61pgn/jkZlax8=" xmlns="http://jabber.org/protocol/caps"/>`+
+                `</presence>`
             );
             );
 
 
             delete _converse.priority;
             delete _converse.priority;
             pres = _converse.xmppstatus.constructPresence('dnd', 'Doing taxes');
             pres = _converse.xmppstatus.constructPresence('dnd', 'Doing taxes');
             expect(pres.toLocaleString()).toBe(
             expect(pres.toLocaleString()).toBe(
-                "<presence xmlns='jabber:client'>"+
-                    "<show>dnd</show>"+
-                    "<status>Doing taxes</status>"+
-                    "<priority>0</priority>"+
-                    "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='K7kn/M6VtmdMyo61pgn/jkZlax8='/>"+
-                "</presence>"
+                `<presence xmlns="jabber:client">`+
+                    `<show>dnd</show>`+
+                    `<status>Doing taxes</status>`+
+                    `<priority>0</priority>`+
+                    `<c hash="sha-1" node="https://conversejs.org" ver="K7kn/M6VtmdMyo61pgn/jkZlax8=" xmlns="http://jabber.org/protocol/caps"/>`+
+                `</presence>`
             );
             );
         }));
         }));
 
 
@@ -94,27 +94,23 @@
                 modal.el.querySelector('[type="submit"]').click();
                 modal.el.querySelector('[type="submit"]').click();
                 expect(view.model.sendPresence).toHaveBeenCalled();
                 expect(view.model.sendPresence).toHaveBeenCalled();
                 expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
                 expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
-                    .toBe("<presence xmlns='jabber:client'>"+
-                          "<status>My custom status</status>"+
-                          "<priority>0</priority>"+
-                          "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='K7kn/M6VtmdMyo61pgn/jkZlax8='/>"+
-                          "</presence>")
+                    .toBe(`<presence xmlns="jabber:client">`+
+                          `<status>My custom status</status>`+
+                          `<priority>0</priority>`+
+                          `<c hash="sha-1" node="https://conversejs.org" ver="K7kn/M6VtmdMyo61pgn/jkZlax8=" xmlns="http://jabber.org/protocol/caps"/>`+
+                          `</presence>`)
 
 
-                return test_utils.waitUntil(function () {
-                    return modal.el.getAttribute('aria-hidden') === "true";
-                });
+                return test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "true");
             }).then(function () {
             }).then(function () {
                 cbview.el.querySelector('.change-status').click()
                 cbview.el.querySelector('.change-status').click()
-                return test_utils.waitUntil(function () {
-                    return modal.el.getAttribute('aria-hidden') === "false";
-                }, 1000);
+                return test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "false", 1000);
             }).then(function () {
             }).then(function () {
                 modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
                 modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
                 modal.el.querySelector('[type="submit"]').click();
                 modal.el.querySelector('[type="submit"]').click();
                 expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
                 expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())
-                    .toBe("<presence xmlns='jabber:client'><show>dnd</show><status>My custom status</status><priority>0</priority>"+
-                          "<c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='https://conversejs.org' ver='K7kn/M6VtmdMyo61pgn/jkZlax8='/>"+
-                          "</presence>")
+                    .toBe(`<presence xmlns="jabber:client"><show>dnd</show><status>My custom status</status><priority>0</priority>`+
+                          `<c hash="sha-1" node="https://conversejs.org" ver="K7kn/M6VtmdMyo61pgn/jkZlax8=" xmlns="http://jabber.org/protocol/caps"/>`+
+                          `</presence>`)
                 done();
                 done();
             });
             });
         }));
         }));

+ 22 - 22
spec/protocol.js

@@ -121,11 +121,11 @@
                      */
                      */
                     expect(_converse.roster.sendContactAddIQ).toHaveBeenCalled();
                     expect(_converse.roster.sendContactAddIQ).toHaveBeenCalled();
                     expect(sent_stanza.toLocaleString()).toBe(
                     expect(sent_stanza.toLocaleString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='jabber:iq:roster'>"+
-                                "<item jid='contact@example.org' name='contact@example.org'/>"+
-                            "</query>"+
-                        "</iq>"
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="jabber:iq:roster">`+
+                                `<item jid="contact@example.org" name="contact@example.org"/>`+
+                            `</query>`+
+                        `</iq>`
                     );
                     );
                     /* As a result, the user's server (1) MUST initiate a roster push
                     /* As a result, the user's server (1) MUST initiate a roster push
                      * for the new roster item to all available resources associated
                      * for the new roster item to all available resources associated
@@ -185,9 +185,9 @@
                 }).then(function () {
                 }).then(function () {
                     expect(contact.subscribe).toHaveBeenCalled();
                     expect(contact.subscribe).toHaveBeenCalled();
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
-                        "<presence to='contact@example.org' type='subscribe' xmlns='jabber:client'>"+
-                            "<nick xmlns='http://jabber.org/protocol/nick'>Max Mustermann</nick>"+
-                        "</presence>"
+                        `<presence to="contact@example.org" type="subscribe" xmlns="jabber:client">`+
+                            `<nick xmlns="http://jabber.org/protocol/nick">Max Mustermann</nick>`+
+                        `</presence>`
                     );
                     );
                     /* As a result, the user's server MUST initiate a second roster
                     /* As a result, the user's server MUST initiate a second roster
                      * push to all of the user's available resources that have
                      * push to all of the user's available resources that have
@@ -254,7 +254,7 @@
                      */
                      */
                     expect(contact.ackSubscribe).toHaveBeenCalled();
                     expect(contact.ackSubscribe).toHaveBeenCalled();
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
-                        "<presence type='subscribe' to='contact@example.org' xmlns='jabber:client'/>"
+                        `<presence to="contact@example.org" type="subscribe" xmlns="jabber:client"/>`
                     );
                     );
 
 
                     /* The user's server MUST initiate a roster push to all of the user's
                     /* The user's server MUST initiate a roster push to all of the user's
@@ -283,7 +283,7 @@
                     _converse.connection._dataRecv(test_utils.createRequest(stanza));
                     _converse.connection._dataRecv(test_utils.createRequest(stanza));
                     // Check that the IQ set was acknowledged.
                     // Check that the IQ set was acknowledged.
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
                     expect(sent_stanza.toLocaleString()).toBe( // Strophe adds the xmlns attr (although not in spec)
-                        "<iq type='result' id='"+IQ_id+"' from='dummy@localhost/resource' xmlns='jabber:client'/>"
+                        `<iq from="dummy@localhost/resource" id="${IQ_id}" type="result" xmlns="jabber:client"/>`
                     );
                     );
                     expect(_converse.roster.updateContact).toHaveBeenCalled();
                     expect(_converse.roster.updateContact).toHaveBeenCalled();
 
 
@@ -341,7 +341,7 @@
                      */
                      */
                     expect(contact.authorize).toHaveBeenCalled();
                     expect(contact.authorize).toHaveBeenCalled();
                     expect(sent_stanza.toLocaleString()).toBe(
                     expect(sent_stanza.toLocaleString()).toBe(
-                        "<presence to='contact@example.org' type='subscribed' xmlns='jabber:client'/>"
+                        `<presence to="contact@example.org" type="subscribed" xmlns="jabber:client"/>`
                     );
                     );
 
 
                     /* As a result, the user's server MUST initiate a
                     /* As a result, the user's server MUST initiate a
@@ -446,18 +446,18 @@
                  */
                  */
                 expect(contact.ackUnsubscribe).toHaveBeenCalled();
                 expect(contact.ackUnsubscribe).toHaveBeenCalled();
                 expect(sent_stanza.toLocaleString()).toBe(
                 expect(sent_stanza.toLocaleString()).toBe(
-                    "<presence type='unsubscribe' to='contact@example.org' xmlns='jabber:client'/>"
+                    `<presence to="contact@example.org" type="unsubscribe" xmlns="jabber:client"/>`
                 );
                 );
 
 
                 /* _converse.js will then also automatically remove the
                 /* _converse.js will then also automatically remove the
                  * contact from the user's roster.
                  * contact from the user's roster.
                  */
                  */
                 expect(sent_IQ.toLocaleString()).toBe(
                 expect(sent_IQ.toLocaleString()).toBe(
-                    "<iq type='set' xmlns='jabber:client'>"+
-                        "<query xmlns='jabber:iq:roster'>"+
-                            "<item jid='contact@example.org' subscription='remove'/>"+
-                        "</query>"+
-                    "</iq>"
+                    `<iq type="set" xmlns="jabber:client">`+
+                        `<query xmlns="jabber:iq:roster">`+
+                            `<item jid="contact@example.org" subscription="remove"/>`+
+                        `</query>`+
+                    `</iq>`
                 );
                 );
                 done();
                 done();
             }));
             }));
@@ -511,11 +511,11 @@
                      * </iq>
                      * </iq>
                      */
                      */
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
-                            "<query xmlns='jabber:iq:roster'>"+
-                                "<item jid='annegreet.gomez@localhost' subscription='remove'/>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
+                            `<query xmlns="jabber:iq:roster">`+
+                                `<item jid="annegreet.gomez@localhost" subscription="remove"/>`+
+                            `</query>`+
+                        `</iq>`);
 
 
                     // Receive confirmation from the contact's server
                     // Receive confirmation from the contact's server
                     // <iq type='result' id='remove1'/>
                     // <iq type='result' id='remove1'/>

+ 26 - 46
spec/push.js

@@ -33,19 +33,14 @@
                     [{'category': 'account', 'type':'registered'}],
                     [{'category': 'account', 'type':'registered'}],
                     ['urn:xmpp:push:0'], [], 'info'))
                     ['urn:xmpp:push:0'], [], 'info'))
             .then(() => {
             .then(() => {
-                return test_utils.waitUntil(() => {
-                    const node = _.filter(IQ_stanzas, function (iq) {
-                        return iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]');
-                    }).pop();
-                    if (node) {
-                        stanza = node.nodeTree;
-                        return true;
-                    }
-                })
-            }).then(() => {
-                expect(stanza.outerHTML).toEqual(
-                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
-                        '<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
+                return test_utils.waitUntil(() => 
+                    _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]')).pop()
+                )
+            }).then(node => {
+                const stanza = node.nodeTree;
+                expect(node.toLocaleString()).toEqual(
+                    `<iq id="${stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
+                        '<enable jid="push-5@client.example" node="yxs32uqsflafdk3iuqo" xmlns="urn:xmpp:push:0"/>'+
                     '</iq>'
                     '</iq>'
                 )
                 )
                 _converse.connection._dataRecv(test_utils.createRequest($iq({
                 _converse.connection._dataRecv(test_utils.createRequest($iq({
@@ -85,9 +80,9 @@
                 return test_utils.waitUntil(
                 return test_utils.waitUntil(
                     () => _.filter(IQ_stanzas, (iq) => iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]')).pop())
                     () => _.filter(IQ_stanzas, (iq) => iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]')).pop())
             }).then(stanza => {
             }).then(stanza => {
-                expect(stanza.nodeTree.outerHTML).toEqual(
-                    `<iq type="set" xmlns="jabber:client" to="chat.shakespeare.lit" id="${stanza.nodeTree.getAttribute('id')}">`+
-                        '<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
+                expect(stanza.toLocaleString()).toEqual(
+                    `<iq id="${stanza.nodeTree.getAttribute('id')}" to="chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
+                        '<enable jid="push-5@client.example" node="yxs32uqsflafdk3iuqo" xmlns="urn:xmpp:push:0"/>'+
                     '</iq>'
                     '</iq>'
                 )
                 )
                 _converse.connection._dataRecv(test_utils.createRequest($iq({
                 _converse.connection._dataRecv(test_utils.createRequest($iq({
@@ -111,7 +106,6 @@
 
 
             const IQ_stanzas = _converse.connection.IQ_stanzas;
             const IQ_stanzas = _converse.connection.IQ_stanzas;
             let stanza;
             let stanza;
-
             expect(_converse.session.get('push_enabled')).toBeFalsy();
             expect(_converse.session.get('push_enabled')).toBeFalsy();
 
 
             test_utils.waitUntilDiscoConfirmed(
             test_utils.waitUntilDiscoConfirmed(
@@ -119,20 +113,13 @@
                 _converse.bare_jid,
                 _converse.bare_jid,
                 [{'category': 'account', 'type':'registered'}],
                 [{'category': 'account', 'type':'registered'}],
                 ['urn:xmpp:push:0'], [], 'info')
                 ['urn:xmpp:push:0'], [], 'info')
-            .then(() => {
-                return test_utils.waitUntil(() => {
-                    const node = _.filter(IQ_stanzas, function (iq) {
-                        return iq.nodeTree.querySelector('iq[type="set"] disable[xmlns="urn:xmpp:push:0"]');
-                    }).pop();
-                    if (node) {
-                        stanza = node.nodeTree;
-                        return true;
-                    }
-                })
-            }).then(() => {
-                expect(stanza.outerHTML).toEqual(
-                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
-                        '<disable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
+            .then(() => test_utils.waitUntil(
+                () => _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq[type="set"] disable[xmlns="urn:xmpp:push:0"]')).pop()
+            )).then(node => {
+                const stanza = node.nodeTree;
+                expect(node.toLocaleString()).toEqual(
+                    `<iq id="${stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
+                        '<disable jid="push-5@client.example" node="yxs32uqsflafdk3iuqo" xmlns="urn:xmpp:push:0"/>'+
                     '</iq>'
                     '</iq>'
                 )
                 )
                 _converse.connection._dataRecv(test_utils.createRequest($iq({
                 _converse.connection._dataRecv(test_utils.createRequest($iq({
@@ -168,21 +155,14 @@
                     _converse.bare_jid,
                     _converse.bare_jid,
                     [{'category': 'account', 'type':'registered'}],
                     [{'category': 'account', 'type':'registered'}],
                     ['urn:xmpp:push:0'], [], 'info'))
                     ['urn:xmpp:push:0'], [], 'info'))
-            .then(() => {
-                return test_utils.waitUntil(() => {
-                    const node = _.filter(IQ_stanzas, function (iq) {
-                        return iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]');
-                    }).pop();
-                    if (node) {
-                        stanza = node.nodeTree;
-                        return true;
-                    }
-                })
-            }).then(() => {
-                expect(stanza.outerHTML).toEqual(
-                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
-                        '<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo">'+
-                            '<x xmlns="jabber:x:data" type="submit">'+
+            .then(() => test_utils.waitUntil(
+                () => _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]')).pop()
+            )).then(node => {
+                const stanza = node.nodeTree;
+                expect(node.toLocaleString()).toEqual(
+                    `<iq id="${stanza.getAttribute('id')}" type="set" xmlns="jabber:client">`+
+                        '<enable jid="push-5@client.example" node="yxs32uqsflafdk3iuqo" xmlns="urn:xmpp:push:0">'+
+                            '<x type="submit" xmlns="jabber:x:data">'+
                                 '<field var="FORM_TYPE"><value>http://jabber.org/protocol/pubsub#publish-options</value></field>'+
                                 '<field var="FORM_TYPE"><value>http://jabber.org/protocol/pubsub#publish-options</value></field>'+
                                 '<field var="secret"><value>eruio234vzxc2kla-91</value></field>'+
                                 '<field var="secret"><value>eruio234vzxc2kla-91</value></field>'+
                             '</x>'+
                             '</x>'+

+ 6 - 6
spec/register.js

@@ -265,17 +265,17 @@
 
 
                 expect(_converse.connection.send).toHaveBeenCalled();
                 expect(_converse.connection.send).toHaveBeenCalled();
                 stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
                 stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
-                expect(stanza.outerHTML.trim().replace(/(\n|\s{2,})/g, '')).toEqual(
-                    '<iq type="set" id="'+stanza.getAttribute('id')+'" xmlns="jabber:client">'+
+                expect(Strophe.serialize(stanza).toLocaleString().trim().replace(/(\n|\s{2,})/g, '')).toEqual(
+                    '<iq id="'+stanza.getAttribute('id')+'" type="set" xmlns="jabber:client">'+
                         '<query xmlns="jabber:iq:register">'+
                         '<query xmlns="jabber:iq:register">'+
-                            '<x xmlns="jabber:x:data" type="submit">'+
-                                '<field xmlns="http://www.w3.org/1999/xhtml" var="username">'+
+                            '<x type="submit" xmlns="jabber:x:data">'+
+                                '<field var="username">'+
                                     '<value>testusername</value>'+
                                     '<value>testusername</value>'+
                                 '</field>'+
                                 '</field>'+
-                                '<field xmlns="http://www.w3.org/1999/xhtml" var="password">'+
+                                '<field var="password">'+
                                     '<value>testpassword</value>'+
                                     '<value>testpassword</value>'+
                                 '</field>'+
                                 '</field>'+
-                                '<field xmlns="http://www.w3.org/1999/xhtml" var="email">'+
+                                '<field var="email">'+
                                     '<value>test@email.local</value>'+
                                     '<value>test@email.local</value>'+
                                 '</field>'+
                                 '</field>'+
                             '</x>'+
                             '</x>'+

+ 28 - 24
spec/room_registration.js

@@ -30,14 +30,15 @@
                         preventDefault: _.noop,
                         preventDefault: _.noop,
                         keyCode: 13
                         keyCode: 13
                     });
                     });
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                         _converse.connection.IQ_stanzas,
                         _converse.connection.IQ_stanzas,
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
-                    ).pop(), 'nodeTree'));
-                }).then(stanza => {
-                    expect(stanza.outerHTML)
-                    .toBe(`<iq to="coven@chat.shakespeare.lit" from="dummy@localhost/resource" `+
-                                `type="get" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                    ).pop());
+                }).then(node => {
+                    const stanza = node.nodeTree;
+                    expect(node.toLocaleString())
+                    .toBe(`<iq from="dummy@localhost/resource" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
+                                `type="get" xmlns="jabber:client">`+
                             `<query xmlns="jabber:iq:register"/></iq>`);
                             `<query xmlns="jabber:iq:register"/></iq>`);
                     view = _converse.chatboxviews.get(room_jid);
                     view = _converse.chatboxviews.get(room_jid);
                     const result = $iq({
                     const result = $iq({
@@ -53,15 +54,16 @@
                                 'var': 'muc#register_roomnick'
                                 'var': 'muc#register_roomnick'
                             }).c('required');
                             }).c('required');
                     _converse.connection._dataRecv(test_utils.createRequest(result));
                     _converse.connection._dataRecv(test_utils.createRequest(result));
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                         _converse.connection.IQ_stanzas,
                         _converse.connection.IQ_stanzas,
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
-                    ).pop(), 'nodeTree'));
-                }).then(stanza => {
-                    expect(stanza.outerHTML).toBe(
-                        `<iq to="coven@chat.shakespeare.lit" from="dummy@localhost/resource" type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                    ).pop());
+                }).then(node => {
+                    const stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq from="dummy@localhost/resource" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
                             `<query xmlns="jabber:iq:register">`+
                             `<query xmlns="jabber:iq:register">`+
-                                `<x xmlns="jabber:x:data" type="submit">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
                                     `<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
                                     `<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
                                     `<field var="muc#register_roomnick"><value>romeo</value></field>`+
                                     `<field var="muc#register_roomnick"><value>romeo</value></field>`+
                                 `</x>`+
                                 `</x>`+
@@ -123,14 +125,15 @@
                         }).up()
                         }).up()
                         .c('status').attrs({code:'110'});
                         .c('status').attrs({code:'110'});
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                         _converse.connection.IQ_stanzas,
                         _converse.connection.IQ_stanzas,
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
-                    ).pop(), 'nodeTree'));
-                }).then(stanza => {
-                    expect(stanza.outerHTML)
-                    .toBe(`<iq to="coven@chat.shakespeare.lit" from="dummy@localhost/resource" `+
-                                `type="get" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                    ).pop());
+                }).then(node => {
+                    const stanza = node.nodeTree;
+                    expect(node.toLocaleString())
+                    .toBe(`<iq from="dummy@localhost/resource" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" `+
+                                `type="get" xmlns="jabber:client">`+
                             `<query xmlns="jabber:iq:register"/></iq>`);
                             `<query xmlns="jabber:iq:register"/></iq>`);
                     view = _converse.chatboxviews.get(room_jid);
                     view = _converse.chatboxviews.get(room_jid);
                     const result = $iq({
                     const result = $iq({
@@ -146,15 +149,16 @@
                                 'var': 'muc#register_roomnick'
                                 'var': 'muc#register_roomnick'
                             }).c('required');
                             }).c('required');
                     _converse.connection._dataRecv(test_utils.createRequest(result));
                     _converse.connection._dataRecv(test_utils.createRequest(result));
-                    return test_utils.waitUntil(() => _.get(_.filter(
+                    return test_utils.waitUntil(() => _.filter(
                         _converse.connection.IQ_stanzas,
                         _converse.connection.IQ_stanzas,
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
                         iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq.nodeTree).length
-                    ).pop(), 'nodeTree'));
-                }).then(stanza => {
-                    expect(stanza.outerHTML).toBe(
-                        `<iq to="coven@chat.shakespeare.lit" from="dummy@localhost/resource" type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                    ).pop());
+                }).then(node => {
+                    const stanza = node.nodeTree;
+                    expect(node.toLocaleString()).toBe(
+                        `<iq from="dummy@localhost/resource" id="${stanza.getAttribute('id')}" to="coven@chat.shakespeare.lit" type="set" xmlns="jabber:client">`+
                             `<query xmlns="jabber:iq:register">`+
                             `<query xmlns="jabber:iq:register">`+
-                                `<x xmlns="jabber:x:data" type="submit">`+
+                                `<x type="submit" xmlns="jabber:x:data">`+
                                     `<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
                                     `<field var="FORM_TYPE"><value>http://jabber.org/protocol/muc#register</value></field>`+
                                     `<field var="muc#register_roomnick"><value>romeo</value></field>`+
                                     `<field var="muc#register_roomnick"><value>romeo</value></field>`+
                                 `</x>`+
                                 `</x>`+

+ 20 - 26
spec/roster.js

@@ -40,21 +40,14 @@
                 null, ['rosterGroupsFetched'], {},
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
                 function (done, _converse) {
 
 
-            var IQ_stanzas = _converse.connection.IQ_stanzas;
-            var stanza;
-
-            test_utils.waitUntil(() => {
-                const node = _.filter(IQ_stanzas, function (iq) {
-                    return iq.nodeTree.querySelector('iq query[xmlns="jabber:iq:roster"]');
-                }).pop();
-                if (node) {
-                    stanza = node.nodeTree;
-                    return true;
-                }
-            }).then(() => {
+            const IQ_stanzas = _converse.connection.IQ_stanzas;
+            test_utils.waitUntil(
+                () => _.filter(IQ_stanzas, iq => iq.nodeTree.querySelector('iq query[xmlns="jabber:iq:roster"]')).pop()
+            ).then(node => {
+                let stanza = node.nodeTree;
                 expect(_converse.roster.data.get('version')).toBeUndefined();
                 expect(_converse.roster.data.get('version')).toBeUndefined();
-                expect(stanza.outerHTML).toBe(
-                    `<iq type="get" id="${stanza.getAttribute('id')}" xmlns="jabber:client">`+
+                expect(node.toLocaleString()).toBe(
+                    `<iq id="${stanza.getAttribute('id')}" type="get" xmlns="jabber:client">`+
                         `<query xmlns="jabber:iq:roster"/>`+
                         `<query xmlns="jabber:iq:roster"/>`+
                     `</iq>`);
                     `</iq>`);
                 let result = $iq({
                 let result = $iq({
@@ -71,10 +64,11 @@
                 expect(_converse.roster.models.length).toBe(2);
                 expect(_converse.roster.models.length).toBe(2);
 
 
                 _converse.roster.fetchFromServer();
                 _converse.roster.fetchFromServer();
-                stanza = _converse.connection.IQ_stanzas.pop().nodeTree;
-                expect(stanza.outerHTML).toBe(
-                    `<iq type="get" id="${stanza.getAttribute('id')}" xmlns="jabber:client">`+
-                        `<query xmlns="jabber:iq:roster" ver="ver7"/>`+
+                node = _converse.connection.IQ_stanzas.pop();
+                stanza = node.nodeTree;
+                expect(node.toLocaleString()).toBe(
+                    `<iq id="${stanza.getAttribute('id')}" type="get" xmlns="jabber:client">`+
+                        `<query ver="ver7" xmlns="jabber:iq:roster"/>`+
                     `</iq>`);
                     `</iq>`);
 
 
                 result = $iq({
                 result = $iq({
@@ -656,11 +650,11 @@
                     expect(window.confirm).toHaveBeenCalled();
                     expect(window.confirm).toHaveBeenCalled();
                     expect(contact.removeFromRoster).toHaveBeenCalled();
                     expect(contact.removeFromRoster).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq type='set' xmlns='jabber:client'>"+
-                            "<query xmlns='jabber:iq:roster'>"+
-                                "<item jid='suleyman.van.beusichem@localhost' subscription='remove'/>"+
-                            "</query>"+
-                        "</iq>");
+                        `<iq type="set" xmlns="jabber:client">`+
+                            `<query xmlns="jabber:iq:roster">`+
+                                `<item jid="suleyman.van.beusichem@localhost" subscription="remove"/>`+
+                            `</query>`+
+                        `</iq>`);
                     done();
                     done();
                 });
                 });
             }));
             }));
@@ -851,9 +845,9 @@
 
 
                     expect(window.confirm).toHaveBeenCalled();
                     expect(window.confirm).toHaveBeenCalled();
                     expect(sent_IQ.toLocaleString()).toBe(
                     expect(sent_IQ.toLocaleString()).toBe(
-                        "<iq type='set' xmlns='jabber:client'>"+
-                            "<query xmlns='jabber:iq:roster'><item jid='max.frankfurter@localhost' subscription='remove'/></query>"+
-                        "</iq>");
+                        `<iq type="set" xmlns="jabber:client">`+
+                            `<query xmlns="jabber:iq:roster"><item jid="max.frankfurter@localhost" subscription="remove"/></query>`+
+                        `</iq>`);
                     expect(contact.removeFromRoster).toHaveBeenCalled();
                     expect(contact.removeFromRoster).toHaveBeenCalled();
                     expect($(_converse.rosterview.el).find(".open-chat:contains('"+name+"')").length).toEqual(0);
                     expect($(_converse.rosterview.el).find(".open-chat:contains('"+name+"')").length).toEqual(0);
                     done();
                     done();

+ 2 - 12
src/converse-muc.js

@@ -69,19 +69,9 @@
         dependencies: ["converse-chatboxes", "converse-disco", "converse-controlbox"],
         dependencies: ["converse-chatboxes", "converse-disco", "converse-controlbox"],
 
 
         overrides: {
         overrides: {
-            // Overrides mentioned here will be picked up by converse.js's
-            // plugin architecture they will replace existing methods on the
-            // relevant objects or classes.
-            //
-            // New functions which don't exist yet can also be added.
-
             tearDown () {
             tearDown () {
-                const { _converse } = this.__super__,
-                      groupchats = this.chatboxes.where({'type': _converse.CHATROOMS_TYPE});
-
-                _.each(groupchats, function (groupchat) {
-                    u.safeSave(groupchat, {'connection_status': converse.ROOMSTATUS.DISCONNECTED});
-                });
+                const groupchats = this.chatboxes.where({'type': this.CHATROOMS_TYPE});
+                _.each(groupchats, gc => u.safeSave(gc, {'connection_status': this.ROOMSTATUS.DISCONNECTED}));
                 this.__super__.tearDown.call(this, arguments);
                 this.__super__.tearDown.call(this, arguments);
             },
             },
 
 

+ 1 - 1
webpack.config.js

@@ -106,7 +106,7 @@ const config = {
             "snabbdom-eventlisteners":  path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-eventlisteners"),
             "snabbdom-eventlisteners":  path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-eventlisteners"),
             "snabbdom-props":           path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-props"),
             "snabbdom-props":           path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-props"),
             "snabbdom-style":           path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-style"),
             "snabbdom-style":           path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-style"),
-            "strophe":                  path.resolve(__dirname, "node_modules/strophe.js/strophe"),
+            "strophe":                  path.resolve(__dirname, "node_modules/strophe.js/dist/strophe"),
             "strophe.ping":             path.resolve(__dirname, "node_modules/strophejs-plugin-ping/strophe.ping"),
             "strophe.ping":             path.resolve(__dirname, "node_modules/strophejs-plugin-ping/strophe.ping"),
             "strophe.rsm":              path.resolve(__dirname, "node_modules/strophejs-plugin-rsm/strophe.rsm"),
             "strophe.rsm":              path.resolve(__dirname, "node_modules/strophejs-plugin-rsm/strophe.rsm"),
             "tovnode":                  path.resolve(__dirname, "node_modules/snabbdom/dist/tovnode"),
             "tovnode":                  path.resolve(__dirname, "node_modules/snabbdom/dist/tovnode"),

Some files were not shown because too many files changed in this diff