def test_resource_interference(self): stanza = aioxmpp.Presence() self.s._handle_on_available(TEST_FROM_OTHER, stanza) self.assertCountEqual( self.s._vcard_resource_interference, [TEST_FROM_OTHER] ) stanza = aioxmpp.Presence() self.s._handle_on_unavailable(TEST_FROM_OTHER, stanza) self.assertCountEqual( self.s._vcard_resource_interference, [] )
async def test_presence_bookkeeping(self): pres = aioxmpp.Presence( to=self.b.local_jid.bare(), type_=aioxmpp.PresenceType.AVAILABLE, ) svc = self.b.summon(aioxmpp.PresenceClient) bare_fut = asyncio.Future() # we use the future as a synchronisation primitive to avoid reading # from the service before the stanza has actually been received def on_bare_available(stanza): if stanza.from_ == self.b.local_jid: return False bare_fut.set_result(None) return True svc.on_bare_available.connect(on_bare_available) await self.a.send(pres) await bare_fut most_available = svc.get_most_available_stanza(self.a.local_jid.bare()) self.assertIsNotNone(most_available) peer_resources = svc.get_peer_resources(self.a.local_jid.bare()) self.assertIn( self.a.local_jid.resource, peer_resources, ) last_presence = svc.get_stanza(self.a.local_jid) self.assertIsNotNone(last_presence)
def _on_unsubscribe(self, stanza): if self.approve_all: self.client.stream.enqueue( aioxmpp.Presence( type_=aioxmpp.structs.PresenceType.UNSUBSCRIBED, to=stanza.from_.bare())) else: self.on_unsubscribe(str(stanza.from_))
async def test_events_on_presence(self): pres = aioxmpp.Presence( to=self.b.local_jid.bare(), type_=aioxmpp.PresenceType.AVAILABLE, ) svc = self.b.summon(aioxmpp.PresenceClient) bare_fut = asyncio.Future() avail_fut = asyncio.Future() changed_fut = asyncio.Future() def on_bare_available(stanza): if stanza.from_ == self.b.local_jid: return False bare_fut.set_result(stanza) return True def on_available(full_jid, stanza): if full_jid == self.b.local_jid: return False avail_fut.set_result((full_jid, stanza)) return True def on_changed(full_jid, stanza): changed_fut.set_result((full_jid, stanza)) return True svc.on_bare_available.connect(on_bare_available) svc.on_available.connect(on_available) svc.on_changed.connect(on_changed) await self.a.send(pres) stanza = await bare_fut self.assertIsInstance(stanza, aioxmpp.Presence) self.assertEqual(stanza.type_, aioxmpp.PresenceType.AVAILABLE) self.assertEqual(stanza.from_, self.a.local_jid) full_jid, stanza = await avail_fut self.assertIsInstance(stanza, aioxmpp.Presence) self.assertEqual(stanza.type_, aioxmpp.PresenceType.AVAILABLE) self.assertEqual(stanza.from_, self.a.local_jid) self.assertEqual(full_jid, stanza.from_) self.assertFalse(changed_fut.done()) pres.show = aioxmpp.PresenceShow.DND await self.a.send(pres) full_jid, stanza = await changed_fut self.assertIsInstance(stanza, aioxmpp.Presence) self.assertEqual(stanza.type_, aioxmpp.PresenceType.AVAILABLE) self.assertEqual(stanza.show, aioxmpp.PresenceShow.DND) self.assertEqual(stanza.from_, self.a.local_jid) self.assertEqual(full_jid, stanza.from_)
def test_handle_notify_without_photo_is_noop(self): mock_handler = unittest.mock.Mock() self.s.on_metadata_changed.connect(mock_handler) stanza = aioxmpp.Presence() self.s._handle_notify(TEST_JID1, stanza) stanza.xep0153_x = avatar_xso.VCardTempUpdate() self.s._handle_notify(TEST_JID1, stanza) self.assertEqual(len(mock_handler.mock_calls), 0)
def test_attach_vcard_notify_to_presence(self): stanza = aioxmpp.Presence() stanza = self.s._attach_vcard_notify_to_presence(stanza) self.assertIsInstance(stanza.xep0153_x, avatar_xso.VCardTempUpdate) self.assertIsNone(stanza.xep0153_x.photo) vcard_id = '1234' self.s._vcard_id = vcard_id stanza = aioxmpp.Presence() stanza = self.s._attach_vcard_notify_to_presence(stanza) self.assertIsInstance(stanza.xep0153_x, avatar_xso.VCardTempUpdate) self.assertEqual(stanza.xep0153_x.photo, vcard_id) self.s._vcard_resource_interference.add(TEST_JID1) stanza = aioxmpp.Presence() stanza = self.s._attach_vcard_notify_to_presence(stanza) self.assertIsNotNone(stanza.xep0153_x) self.assertIsNone(stanza.xep0153_x.photo)
async def send_presence(self, to=None, status=None): _status = {} if status is None: _status = None elif isinstance(status, str): _status['Status'] = status elif isinstance(status, dict): _status = status else: raise TypeError('status must be None, str or dict') pres = aioxmpp.Presence(type_=aioxmpp.PresenceType.AVAILABLE, to=to) if _status is not None: pres.status[None] = json.dumps(_status) await self.stream.send(pres)
async def send_presence_probe(self, to: aioxmpp.JID) -> None: presence = aioxmpp.Presence(type_=aioxmpp.PresenceType.PROBE, to=to) await self.stream.send(presence)
def test_trigger_rehash(self): mock_handler = unittest.mock.Mock() self.s.on_metadata_changed.connect(mock_handler) stanza = aioxmpp.Presence() stanza.xep0153_x = avatar_xso.VCardTempUpdate("1234") self.s._handle_on_available(TEST_FROM_OTHER, stanza) first_rehash_task = self.s._vcard_rehash_task self.assertIsNot(first_rehash_task, None) # presence with the same hash does not affect the rehash task self.s._vcard_id = "1234" stanza = aioxmpp.Presence() stanza.xep0153_x = avatar_xso.VCardTempUpdate("1234") self.s._handle_on_available(TEST_FROM_OTHER, stanza) self.assertIs(self.s._vcard_rehash_task, first_rehash_task) # presence with another hash cancels the task stanza = aioxmpp.Presence() stanza.xep0153_x = avatar_xso.VCardTempUpdate("4321") self.s._handle_on_available(TEST_FROM_OTHER, stanza) with unittest.mock.patch.object(self.vcard, "get_vcard", new=CoroutineMock()): vcard = vcard_xso.VCard() self.vcard.get_vcard.return_value = vcard vcard.set_photo_data("image/png", TEST_IMAGE) loop = asyncio.get_event_loop() with self.assertRaises(asyncio.CancelledError): loop.run_until_complete(first_rehash_task) self.assertTrue(first_rehash_task.cancelled()) loop.run_until_complete( self.s._vcard_rehash_task ) self.assertEqual(self.s._vcard_id, TEST_IMAGE_SHA1) with contextlib.ExitStack() as stack: stack.enter_context( unittest.mock.patch.object(self.vcard, "get_vcard", new=CoroutineMock()) ) resend_presence = stack.enter_context( unittest.mock.patch.object( self.presence_server, "resend_presence", ) ) vcard = vcard_xso.VCard() self.vcard.get_vcard.return_value = vcard stanza = aioxmpp.Presence() stanza.xep0153_x = avatar_xso.VCardTempUpdate("9132752") self.s._handle_on_available(TEST_FROM_OTHER, stanza) loop.run_until_complete( self.s._vcard_rehash_task ) resend_presence.assert_called_once_with() self.assertEqual(self.s._vcard_id, "") # XXX: should we test minutely that we get the right metadata mock_handler.assert_called_with(TEST_FROM_OTHER.bare(), unittest.mock.ANY)
async def main(local, password, peer, strip_newlines, add_newlines): loop = asyncio.get_event_loop() swrite = await stdout_writer() sread = asyncio.StreamReader() tread, pread = await loop.connect_read_pipe( lambda: asyncio.StreamReaderProtocol(sread), sys.stdin, ) client = aioxmpp.Client( local, aioxmpp.make_security_layer( password, ) ) sigint = asyncio.Event() loop.add_signal_handler(signal.SIGINT, sigint.set) loop.add_signal_handler(signal.SIGTERM, sigint.set) def recv(message): body = message.body.lookup( [aioxmpp.structs.LanguageRange.fromstr("*")] ) if add_newlines: body += "\n" swrite.write(body.encode("utf-8")) client.stream.register_message_callback( "chat", peer, recv ) sigint_future = asyncio.ensure_future(sigint.wait()) read_future = asyncio.ensure_future(sread.readline()) try: async with client.connected() as stream: # we send directed presence to the peer pres = aioxmpp.Presence( type_=aioxmpp.PresenceType.AVAILABLE, to=peer, ) await stream.send(pres) while True: done, pending = await asyncio.wait( [ sigint_future, read_future, ], return_when=asyncio.FIRST_COMPLETED, ) if sigint_future in done: break if read_future in done: line = read_future.result().decode() if not line: break if strip_newlines: line = line.rstrip() msg = aioxmpp.Message( type_="chat", to=peer, ) msg.body[None] = line await stream.send(msg) read_future = asyncio.ensure_future( sread.readline() ) finally: sigint_future.cancel() read_future.cancel()