Beispiel #1
0
def test_id(logger):
    ('XMLStream.id should return the id of its stream node')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)
    stream.stream_node = Stream.create(id='what')

    # Then the id is none
    stream.id.should.equal('what')
Beispiel #2
0
def test_route_nodes_undefined(logger):
    ('XMLStream.route_nodes() should warn about undefined nodes')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # When I call route_nodes with a bare Node
    empty = Node.create(type='character', name='romeo')
    stream.route_nodes(None, empty)

    # Then the logger should have been called appropriately
    logger.warning.assert_called_once_with(
        'no model defined for %s: %r', '<xmpp-unknown name="romeo" type="character" />',
        empty
    )
Beispiel #3
0
def test_parse_noxml(logger):
    ('XMLStream.parse should return None when failed to parse')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # When I feed it with valid XML
    stream.feed(
        '''<monteque name="Romeo" Loves Julietmonteque'''
    )

    # And call parse
    result = stream.parse()

    result.should.be.none
Beispiel #4
0
def test_handle_presence():
    ('XMLStream.handle_presence() should forward the `on.presence` event')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # And an event handler
    handle_presence = EventHandlerMock('on_presence')
    stream.on.presence(handle_presence)

    # When I call handle presence
    presence = Presence.create()
    stream.handle_presence(presence)

    handle_presence.assert_called_once_with(ANY, presence)
Beispiel #5
0
def test_route_nodes_error():
    ('XMLStream.route_nodes() should warn about error nodes')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # And an event handler
    handle_error = EventHandlerMock('on_error')
    stream.on.error(handle_error)

    # When I call route_nodes
    node = ServiceUnavailable.create()
    stream.route_nodes(None, node)

    handle_error.assert_called_once_with(ANY, node)
Beispiel #6
0
def test_handle_iq_result():
    ('XMLStream.handle_iq() should forward the `on.iq_result` event')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # And an event handler
    handle_iq_result = EventHandlerMock('on_iq_result')
    stream.on.iq_result(handle_iq_result)

    # When I call handle iq
    node = IQ.create(type='result')
    stream.handle_iq(node)

    handle_iq_result.assert_called_once_with(ANY, node)
Beispiel #7
0
def test_handle_message():
    ('XMLStream.handle_message() should forward the `on.message` event')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # And an event handler
    handle_message = EventHandlerMock('on_message')
    stream.on.message(handle_message)

    # When I call handle message
    message = Message.create()
    stream.route_nodes(None, message)

    handle_message.assert_called_once_with(ANY, message)
Beispiel #8
0
def test_id_empty(logger):
    ('XMLStream.id should return None if there is no stream node stored')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # Then the id is none
    stream.id.should.be.none
Beispiel #9
0
def test_stream_reader_open(context):
    ('XMLStream#feed should set the state to "open" if received the tag <stream> completely')

    # Given a connection
    connection = Mock(name='connection')
    # And an event handler
    event_handler = EventHandlerMock('on_open')

    # And a XMLStream
    stream = XMLStream(connection, debug=True)
    stream.on.open(event_handler)

    # When I feed the reader
    stream.feed(
        ' <stream:stream from="*****@*****.**" to="im.example.com" version="1.0" xml:lang="en" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams"> ')

    # Then it should have returned a Node object
    stream.state.should.equal('OPEN')

    # And it dispatched the expected signal
    event_handler.assert_called_once_with(ANY, stream.stream_node)
Beispiel #10
0
def test_parse_ok(logger):
    ('XMLStream.parse should return a node')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # When I feed it with valid XML
    stream.feed(
        '''<monteque name="Romeo">Loves Juliet</monteque>'''
    )

    # And call parse
    result = stream.parse()

    result.should.be.a(Node)
    result.to_xml().should.look_like('''
    <monteque name="Romeo">Loves Juliet</monteque>
    ''')
Beispiel #11
0
def test_send_message():
    ('XMLStream.send_message() should send a message with body')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # When I call send_presence
    stream.send_message(
        'Hello',
        **{
            'to': 'juliet@capulet',
            'from': 'romeu@monteque',
        }
    )

    # Then it should have sent the correct XML
    connection.output.should.equal([
        '<message from="romeu@monteque" to="juliet@capulet" type="chat"><body>Hello</body></message>'
    ])
Beispiel #12
0
def test_send_presence_delay():
    ('XMLStream.send_presence should be able to send delay')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # When I call send_presence
    stream.send_presence(
        **{
            'to': 'juliet@capulet',
            'from': 'romeu@monteque',
            'delay': 'foobar'
        }
    )

    # Then it should have sent the correct XML
    connection.output.should.equal([
        '<presence from="romeu@monteque" to="juliet@capulet"><delay from="romeu@monteque" stamp="foobar" xmlns="urn:xmpp:delay" /><priority>10</priority></presence>'
    ])
Beispiel #13
0
def test_send_presence_jid():
    ('XMLStream.send_presence when no `from` '
     'defined fallbacks')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # When I call send_presence
    stream.send_presence(
        **{
            'to': 'juliet@capulet',
            'from': 'romeu@monteque',
        }
    )

    # Then it should have sent the correct XML
    connection.output.should.equal([
        '<presence from="romeu@monteque" to="juliet@capulet"><priority>10</priority></presence>',
    ])
Beispiel #14
0
def test_stream_reader_set_invalid_State(context):
    ('XMLStream#set_state should raise an error when raising a wrong state')

    # Given a connection
    connection = Mock(name='connection')
    # And a XMLStream
    stream = XMLStream(connection)

    # When I call set_state with an invalid stage
    when_called = stream.set_state.when.called_with('wat')

    # Then it should have raised
    when_called.should.have.raised(TypeError, 'invalid state was given: wat')
Beispiel #15
0
def test_stream_parse_stream_features(context):
    ('XMLStream.feed can recognize StreamFeatures')

    open_stream = XML('''
    <stream:stream
        from="my.server"
        id="c2a55811-7b4f-4429-919a-c3d91a666f83"
        version="1.0"
        xmlns="jabber:client"
        xmlns:stream="http://etherx.jabber.org/streams" xml:lang="en">
    ''')

    features = XML('''
       <stream:features>
             <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
                 <mechanism>SCRAM-SHA-1</mechanism>
             </mechanisms>
             <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
             <register xmlns="http://jabber.org/features/iq-register"/>
       </stream:features>
    ''')

    # Given a connection
    connection = Mock(name='connection')
    # And a node handler
    node_handler = EventHandlerMock('on_node')
    unhandled_handler = EventHandlerMock('on_unhandled_xml')

    # And a XMLStream
    stream = XMLStream(connection)
    stream.on.node(node_handler)
    stream.on.unhandled_xml(unhandled_handler)

    # When I feed the reader
    stream.feed(open_stream)
    stream.feed(features)

    # Then it should have triggered the calls
    node_handler.assert_has_calls([
        call(ANY, ANY),
        call(ANY, ANY),
        call(ANY, ANY),
        call(ANY, ANY),
    ])
    nodes_from_call(node_handler).should.equal([
        SASLMechanism,
        SASLMechanismSet,
        StartTLS,
        IQRegister,
        StreamFeatures
    ])
    unhandled_handler.assert_has_calls([])
Beispiel #16
0
def test_send_presence_missing_jid():
    ('XMLStream.send_presence() complains '
     'if there is no bound jid and no provided `from` jid')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)

    # When I call send_presence
    stream.send_presence.when.called_with(
        **{
            'to': 'juliet@capulet',
        }
    ).should.have.raised(
        MissingJID, 'Presence cannot be sent when missing the "from" jid'
    )
Beispiel #17
0
def test_send_presence():
    ('XMLStream.send_presence when no `from` '
     'defined fallbacks to bound_jid')

    # Given a connection
    connection = FakeConnection()

    # And a XMLStream
    stream = XMLStream(connection)
    stream.handle_bound_jid(
        ResourceBind.create('juliet@capulet')
    )

    # When I call send_presence
    stream.send_presence(
        to='romeo@monteque',
    )

    # Then it should have sent the correct XML
    connection.output.should.equal([
        '<presence from="juliet@capulet" to="romeo@monteque"><priority>10</priority></presence>'
    ])
def application():
    # Setting up logs
    coloredlogs.install(level=DEBUG and logging.DEBUG or logging.INFO)

    # create a non-blocking XMPP-connection
    connection = XMPPConnection(DOMAIN, PORT, debug=DEBUG)

    # create a XML stream
    stream = XMLStream(connection, debug=DEBUG)

    # prepare the SASL mechanism
    sasl = SASLAuthenticationHandler(SASL_MECHANISM, jid, password)
    sasl.bind(stream)

    @stream.on.closed
    def stream_closed(event, node):
        connection.disconnect()
        connection.connect()
        stream.reset()

    @stream.on.presence
    def handle_presence(event, presence):
        if not presence.attr.get('from'):
            return

        logging.debug("presence from: %s %s(%s)", presence.attr['from'],
                      presence.status.strip(), presence.show.strip())

    @connection.on.tcp_established
    def step1_open_stream(event, host_ip):
        "sends a <stream:stream> to the XMPP server"
        logging.info("connected to %s", host_ip)
        stream.open_client(jid.domain)

    @stream.on.sasl_support
    def step2_send_sasl_auth(event, node):
        "sends a <auth /> to the XMPP server"
        sasl.authenticate()

    @sasl.on.success
    def step3_handle_success(event, result):
        "the SASL authentication succeeded, it's our time to reopen the stream"
        stream.open_client(jid.domain)

    @stream.on.bind_support
    def step4_bind_to_a_resource_name(event, node):
        "the server said it supports binding"
        stream.bind_to_resource(jid.resource)

    @stream.on.bound_jid
    def step5_send_presence(event, jid):
        stream.send_presence()
        logging.info("echobot jid: %s", jid.text)

    @stream.on.presence
    def step6_auto_subscribe(event, presence):
        if not presence.attr.get('from'):
            return

        presence_type = presence.attr.get('type')

        params = {'from': jid.bare, 'to': presence.attr['from']}
        if presence_type == 'subscribe':
            stream.send_presence(type='subscribed', **params)

        elif presence_type == 'subscribed':
            stream.add_contact(presence.attr['from'])
        else:
            stream.send_presence(**params)

    @connection.on.ready_to_write
    def keep_alive(event, connection):
        "send whitespace keep alive every 60 seconds"
        if stream.has_gone_through_sasl() and (time.time() % 60 == 0):
            print 'keepalive'
            connection.send_whitespace_keepalive()

    connection.connect()

    try:
        while connection.is_alive():
            connection.loop_once()

    except KeyboardInterrupt as e:
        print "\r{0}".format(traceback.format_exc(e))

        raise SystemExit(1)
Beispiel #19
0
def application():
    # Setting up logs
    coloredlogs.install(level=DEBUG and logging.DEBUG or logging.INFO)

    # create a non-blocking XMPP-connection
    connection = XMPPConnection(DOMAIN, PORT, debug=DEBUG)

    # create a XML stream
    stream = XMLStream(connection, debug=DEBUG)

    @stream.on.closed
    def auto_reconnect(event, node):
        logging.warning("server closed stream %s:", node)

    @stream.on.error
    def stream_error(event, error):
        logging.error(error.to_xml())

    @connection.on.ready_to_write
    def keep_alive(event, connection):
        "send whitespace keep alive every 60 seconds"
        if stream.is_authenticated_component() and (int(time.time()) % 60
                                                    == 0):
            print 'keepalive'
            connection.send_whitespace_keepalive()

    @connection.on.tcp_established
    def step1_open_stream(event, host_ip):
        "sends a <stream:stream> to the XMPP server"
        logging.info("connected to %s", host_ip)
        stream.open_component(COMPONENT_NAME)

    @stream.on.open
    def step2_send_handshake(event, node):
        "sends a <auth /> to the XMPP server"
        stream.send_secret_handshake(COMPONENT_SECRET)

    @stream.on.presence
    def step3_auto_subscribe(event, presence):
        from_jid = presence.attr['to']
        presence_type = presence.attr.get('type')

        params = {'from': from_jid, 'to': presence.attr['from']}
        if presence_type == 'subscribe':
            stream.send_presence(type='subscribed', **params)

        elif presence_type == 'subscribed':
            stream.send_presence(**params)

    @stream.on.success_handshake
    def send_presence(event, node):
        stream.send_presence(**{
            'from': random.choice(PRESENCE_JIDS),
            'to': 'falcao.it'
        })

    connection.connect()

    try:
        while connection.is_alive():
            connection.loop_once()
            from_jid = random.choice(PRESENCE_JIDS)
            if stream.is_authenticated_component():
                stream.send_presence(**{'from': from_jid, 'to': MANAGER_JID})
                connection.loop_once()
                stream.add_contact(MANAGER_JID, from_jid=from_jid)
                connection.loop_once()

    except KeyboardInterrupt as e:
        print "\r{0}".format(traceback.format_exc(e))

        raise SystemExit(1)
Beispiel #20
0
def application():
    # Setting up logs
    coloredlogs.install(level=DEBUG and logging.DEBUG or logging.INFO)

    # create a non-blocking XMPP-connection
    connection = XMPPConnection(DOMAIN, 5222, debug=DEBUG)

    # create a XML stream
    stream = XMLStream(connection, debug=DEBUG)

    # prepare the SASL mechanism
    sasl = SASLAuthenticationHandler(SASL_MECHANISM, jid, password)
    sasl.bind(stream)

    # prepare service discovery helper
    service_discovery = stream.extension['0030']

    @stream.on.closed
    def stream_closed(event, node):
        connection.disconnect()
        connection.connect()
        stream.reset()

    @stream.on.presence
    def handle_presence(event, presence):
        logging.debug("presence from: %s %s(%s)", presence.attr['from'], presence.status.strip(), presence.show.strip())

    @connection.on.tcp_established
    def step1_open_stream(event, host_ip):
        "sends a <stream:stream> to the XMPP server"
        logging.info("connected to %s", host_ip)
        stream.open_client(jid.domain)

    @stream.on.sasl_support
    def step2_send_sasl_auth(event, node):
        "sends a <auth /> to the XMPP server"
        sasl.authenticate()

    @sasl.on.success
    def step3_handle_success(event, result):
        "the SASL authentication succeeded, it's our time to reopen the stream"
        stream.open_client(jid.domain)

    @stream.on.bind_support
    def step4_bind_to_a_resource_name(event, node):
        "the server said it supports binding"
        stream.bind_to_resource(jid.resource)

    @stream.on.bound_jid
    def step5_send_presence(event, jid):
        stream.send_presence()
        logging.info("Querying %s for disco items", jid.domain)
        service_discovery.query_items(to=jid.domain)
        logging.info("Querying %s for disco features and components", jid.domain)
        service_discovery.query_info(to=jid.domain)

    @stream.on.presence
    def step6_ensure_connectivity(event, presence):
        if presence.delay:
            stream.send_presence()

    @connection.on.ready_to_write
    def keep_alive(event, connection):
        if stream.has_gone_through_sasl() and (time.time() % 60 == 0):
            print 'keepalive'
            connection.send_whitespace_keepalive()

    @service_discovery.on.query_items
    def handle_disco_items(event, query):
        logging.info("Disco Items:\n%s", "\n".join(map(repr, query.get_children())))

    @service_discovery.on.query_info
    def handle_disco_info(event, query):
        logging.info("Disco Features and Components:\n%s", "\n".join(map(repr, query.get_children())))

    connection.connect()

    try:
        while connection.is_alive():
            connection.loop_once()

    except KeyboardInterrupt as e:
        print "\r{0}".format(traceback.format_exc(e))

        raise SystemExit(1)
Beispiel #21
0
def application():
    # Setting up logs
    coloredlogs.install(level=DEBUG and logging.DEBUG or logging.INFO)

    # create a non-blocking XMPP-connection
    connection = XMPPConnection(DOMAIN, 5222, debug=DEBUG)

    # create a XML stream
    stream = XMLStream(connection, debug=DEBUG)

    # prepare the SASL mechanism
    sasl = SASLAuthenticationHandler(SASL_MECHANISM, jid, password)
    sasl.bind(stream)

    @stream.on.closed
    def stream_closed(event, node):
        connection.disconnect()
        connection.connect()
        stream.reset()

    @stream.on.presence
    def handle_presence(event, presence):
        logging.debug("presence from: %s %s(%s)", presence.attr['from'],
                      presence.status.strip(), presence.show.strip())

    @connection.on.tcp_established
    def step1_open_stream(event, host_ip):
        "sends a <stream:stream> to the XMPP server"
        logging.info("connected to %s", host_ip)
        stream.open_client(jid.domain)

    @stream.on.sasl_support
    def step2_send_sasl_auth(event, node):
        "sends a <auth /> to the XMPP server"
        sasl.authenticate()

    @sasl.on.success
    def step3_handle_success(event, result):
        "the SASL authentication succeeded, it's our time to reopen the stream"
        stream.open_client(jid.domain)

    @stream.on.bind_support
    def step4_bind_to_a_resource_name(event, node):
        "the server said it supports binding"
        stream.bind_to_resource(jid.resource)

    @stream.on.bound_jid
    def step5_send_presence(event, jid):
        stream.send_presence()
        logging.info("echobot jid: %s", jid.text)

    @stream.on.presence
    def step6_ensure_connectivity(event, presence):
        if presence.delay:
            stream.send_presence()

    @connection.on.ready_to_write
    def keep_alive(event, connection):
        if stream.has_gone_through_sasl() and (time.time() % 60 == 0):
            print 'keepalive'
            connection.send_whitespace_keepalive()

    @stream.on.message
    def auto_reply(event, message):
        stream.send_presence()

        from_jid = JID(message.attr['from'])
        if message.is_composing():
            logging.warning("%s is composing", from_jid.nick)

        if message.is_active():
            logging.warning("%s is active", from_jid.nick)

        body = message.get_body()
        if body:
            logging.critical("%s says: %s", from_jid.nick, body)
            stream.send_message(body, to=from_jid.text)
            stream.send_presence(to=from_jid.text)

    connection.connect()

    try:
        while connection.is_alive():
            connection.loop_once()

    except KeyboardInterrupt as e:
        print "\r{0}".format(traceback.format_exc(e))

        raise SystemExit(1)