|
@@ -1,8 +1,8 @@
|
|
|
-describe('A VCard', function () {
|
|
|
+describe('An incoming presence with a XEP-0153 vcard:update element', function () {
|
|
|
beforeAll(() => jasmine.addMatchers({ toEqualStanza: jasmine.toEqualStanza }));
|
|
|
|
|
|
it(
|
|
|
- 'is replaced when a XEP-0153 presence update is received',
|
|
|
+ 'will cause a VCard avatar to be replaced',
|
|
|
mock.initConverse(['chatBoxesFetched'], { no_vcard_mocks: true }, async function (_converse) {
|
|
|
const { api } = _converse;
|
|
|
const { u, sizzle } = _converse.env;
|
|
@@ -24,7 +24,10 @@ describe('A VCard', function () {
|
|
|
</presence>`
|
|
|
)
|
|
|
);
|
|
|
- const sent_stanza = await u.waitUntil(() => IQ_stanzas.filter((s) => sizzle('vCard', s).length).pop(), 1000);
|
|
|
+ const sent_stanza = await u.waitUntil(
|
|
|
+ () => IQ_stanzas.filter((s) => sizzle('vCard', s).length).pop(),
|
|
|
+ 1000
|
|
|
+ );
|
|
|
expect(sent_stanza).toEqualStanza(stx`
|
|
|
<iq type="get"
|
|
|
to="mercutio@montague.lit"
|
|
@@ -49,16 +52,16 @@ describe('A VCard', function () {
|
|
|
<vCard xmlns='vcard-temp'>
|
|
|
<BDAY>1476-06-09</BDAY>
|
|
|
<ADR>
|
|
|
- <CTRY>Italy</CTRY>
|
|
|
- <LOCALITY>Verona</LOCALITY>
|
|
|
- <HOME/>
|
|
|
+ <CTRY>Italy</CTRY>
|
|
|
+ <LOCALITY>Verona</LOCALITY>
|
|
|
+ <HOME/>
|
|
|
</ADR>
|
|
|
<NICKNAME/>
|
|
|
<N><GIVEN>Mercutio</GIVEN><FAMILY>Capulet</FAMILY></N>
|
|
|
<EMAIL><USERID>mercutio@shakespeare.lit</USERID></EMAIL>
|
|
|
<PHOTO>
|
|
|
- <TYPE>${blob.type}</TYPE>
|
|
|
- <BINVAL>${base64Image}</BINVAL>
|
|
|
+ <TYPE>${blob.type}</TYPE>
|
|
|
+ <BINVAL>${base64Image}</BINVAL>
|
|
|
</PHOTO>
|
|
|
</vCard>
|
|
|
</iq>`)
|
|
@@ -90,7 +93,7 @@ describe('A VCard', function () {
|
|
|
);
|
|
|
|
|
|
it(
|
|
|
- 'is removed when a XEP-0153 presence update is received',
|
|
|
+ 'will cause a VCard avatar to be removed',
|
|
|
mock.initConverse(['chatBoxesFetched'], { no_vcard_mocks: true }, async function (_converse) {
|
|
|
const { api } = _converse;
|
|
|
const { u, sizzle } = _converse.env;
|
|
@@ -100,9 +103,7 @@ describe('A VCard', function () {
|
|
|
const own_jid = _converse.session.get('jid');
|
|
|
|
|
|
const IQ_stanzas = _converse.api.connection.get().IQ_stanzas;
|
|
|
- let sent_stanza = await u.waitUntil(() =>
|
|
|
- IQ_stanzas.filter((s) => sizzle(`vCard`, s).length).pop()
|
|
|
- , 500);
|
|
|
+ let sent_stanza = await u.waitUntil(() => IQ_stanzas.filter((s) => sizzle(`vCard`, s).length).pop(), 500);
|
|
|
_converse.api.connection.get()._dataRecv(
|
|
|
mock.createRequest(stx`
|
|
|
<iq from='${own_jid}'
|
|
@@ -202,3 +203,132 @@ describe('A VCard', function () {
|
|
|
})
|
|
|
);
|
|
|
});
|
|
|
+
|
|
|
+describe('An outgoing presence with a XEP-0153 vcard:update element', function () {
|
|
|
+ beforeAll(() => jasmine.addMatchers({ toEqualStanza: jasmine.toEqualStanza }));
|
|
|
+
|
|
|
+ it(
|
|
|
+ 'is sent when the user updates their VCard avatar',
|
|
|
+ mock.initConverse(['chatBoxesFetched'], { no_vcard_mocks: true }, async function (_converse) {
|
|
|
+ const { api } = _converse;
|
|
|
+ const { u, sizzle } = _converse.env;
|
|
|
+ await mock.waitForRoster(_converse, 'current', 0);
|
|
|
+ mock.openControlBox(_converse);
|
|
|
+ const own_jid = _converse.session.get('jid');
|
|
|
+ const own_bare_jid = _converse.session.get('bare_jid');
|
|
|
+
|
|
|
+ const IQ_stanzas = _converse.api.connection.get().IQ_stanzas;
|
|
|
+ let sent_stanza = await u.waitUntil(() => IQ_stanzas.filter((s) => sizzle(`vCard`, s).length).pop(), 500);
|
|
|
+ _converse.api.connection.get()._dataRecv(
|
|
|
+ mock.createRequest(stx`
|
|
|
+ <iq from='${own_jid}'
|
|
|
+ xmlns="jabber:client"
|
|
|
+ to='${_converse.session.get('jid')}'
|
|
|
+ type='result'
|
|
|
+ id='${sent_stanza.getAttribute('id')}'>
|
|
|
+ <vCard xmlns='vcard-temp'></vCard>
|
|
|
+ </iq>`)
|
|
|
+ );
|
|
|
+
|
|
|
+ const vcard = await u.waitUntil(() => _converse.state.vcards.get(own_bare_jid));
|
|
|
+ expect(vcard.get('image_hash')).not.toBeDefined();
|
|
|
+ const vcard_updated = await u.waitUntil(() => vcard.get('vcard_updated'));
|
|
|
+
|
|
|
+ while (IQ_stanzas.length) IQ_stanzas.pop();
|
|
|
+
|
|
|
+ const response = await fetch('/base/logo/conversejs-filled-192.png');
|
|
|
+ const blob = await response.blob();
|
|
|
+ const arrayBuffer = await blob.arrayBuffer();
|
|
|
+ const byteArray = new Uint8Array(arrayBuffer);
|
|
|
+ const hash_ab = await crypto.subtle.digest('SHA-1', byteArray);
|
|
|
+ const image_hash = u.arrayBufferToHex(hash_ab);
|
|
|
+ const base64Image = btoa(String.fromCharCode(...byteArray));
|
|
|
+
|
|
|
+ // Call the API to set a new avatar
|
|
|
+ api.vcard.set(own_bare_jid, {
|
|
|
+ image: base64Image,
|
|
|
+ image_type: blob.type,
|
|
|
+ });
|
|
|
+
|
|
|
+ sent_stanza = await u.waitUntil(() => IQ_stanzas.filter((s) => sizzle(`vCard`, s).length).pop(), 500);
|
|
|
+ expect(sent_stanza).toEqualStanza(stx`
|
|
|
+ <iq type="set" to="${own_bare_jid}" xmlns="jabber:client" id="${sent_stanza.getAttribute('id')}">
|
|
|
+ <vCard xmlns="vcard-temp">
|
|
|
+ <FN/><NICKNAME/><URL/><ROLE/><EMAIL><INTERNET/><PREF/><USERID/></EMAIL><PHOTO><TYPE>image/png</TYPE>
|
|
|
+ <BINVAL>${base64Image}</BINVAL></PHOTO>
|
|
|
+ </vCard>
|
|
|
+ </iq>`);
|
|
|
+
|
|
|
+ // Check optimistic save
|
|
|
+ expect(vcard.get('image')).toBe(base64Image);
|
|
|
+ expect(vcard.get('image_hash')).toBe(image_hash);
|
|
|
+ expect(vcard.get('image_type')).toBe(blob.type);
|
|
|
+ expect(vcard.get('vcard_updated')).toBe(vcard_updated); // didn't change
|
|
|
+
|
|
|
+ while (IQ_stanzas.length) IQ_stanzas.pop();
|
|
|
+
|
|
|
+ // Some servers send their own update presence, before sending the
|
|
|
+ // return IQ. This should not create a new VCard get request
|
|
|
+ _converse.api.connection.get()._dataRecv(
|
|
|
+ mock.createRequest(
|
|
|
+ stx`<presence xmlns="jabber:client"
|
|
|
+ to="${_converse.session.get('jid')}"
|
|
|
+ from="${own_jid}">
|
|
|
+ <x xmlns='vcard-temp:x:update'>
|
|
|
+ <photo>${image_hash}</photo>
|
|
|
+ </x>
|
|
|
+ </presence>`
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ _converse.api.connection.get()._dataRecv(
|
|
|
+ mock.createRequest(stx`
|
|
|
+ <iq from='${own_bare_jid}'
|
|
|
+ xmlns="jabber:client"
|
|
|
+ to='${own_jid}'
|
|
|
+ type='result'
|
|
|
+ id='${sent_stanza.getAttribute('id')}'></iq>`)
|
|
|
+ );
|
|
|
+
|
|
|
+ // A new get IQ is sent out to fetch the latest VCard
|
|
|
+ sent_stanza = await u.waitUntil(
|
|
|
+ () => IQ_stanzas.filter((s) => sizzle('vCard', s).length).pop(),
|
|
|
+ 1000
|
|
|
+ );
|
|
|
+ expect(sent_stanza).toEqualStanza(stx`
|
|
|
+ <iq type="get" xmlns="jabber:client" id="${sent_stanza.getAttribute('id')}">
|
|
|
+ <vCard xmlns="vcard-temp"/>
|
|
|
+ </iq>`);
|
|
|
+
|
|
|
+ _converse.api.connection.get()._dataRecv(
|
|
|
+ mock.createRequest(stx`
|
|
|
+ <iq from='${own_bare_jid}'
|
|
|
+ xmlns="jabber:client"
|
|
|
+ to='${own_jid}'
|
|
|
+ type='result'
|
|
|
+ id='${sent_stanza.getAttribute('id')}'>
|
|
|
+ <vCard xmlns='vcard-temp'>
|
|
|
+ <BDAY>1476-06-09</BDAY>
|
|
|
+ <ADR>
|
|
|
+ <CTRY>Italy</CTRY>
|
|
|
+ <LOCALITY>Verona</LOCALITY>
|
|
|
+ <HOME/>
|
|
|
+ </ADR>
|
|
|
+ <NICKNAME/>
|
|
|
+ <N><GIVEN>Romeo</GIVEN><FAMILY>Montague</FAMILY></N>
|
|
|
+ <EMAIL><USERID>romeo@shakespeare.lit</USERID></EMAIL>
|
|
|
+ <PHOTO>
|
|
|
+ <TYPE>${blob.type}</TYPE>
|
|
|
+ <BINVAL>${base64Image}</BINVAL>
|
|
|
+ </PHOTO>
|
|
|
+ </vCard>
|
|
|
+ </iq>`)
|
|
|
+ );
|
|
|
+
|
|
|
+ await u.waitUntil(() => vcard.get('vcard_updated'));
|
|
|
+ expect(vcard.get('image')).toBe(base64Image);
|
|
|
+ expect(vcard.get('image_hash')).toBe(image_hash);
|
|
|
+ expect(vcard.get('image_type')).toBe(blob.type);
|
|
|
+ })
|
|
|
+ );
|
|
|
+});
|