예제 #1
0
 def setUp(self):
     self.t = tracking.MessageTracker()
     self.listener = unittest.mock.Mock()
     for ev in ["on_closed", "on_state_changed"]:
         cb = getattr(self.listener, ev)
         cb.return_value = None
         getattr(self.t, ev).connect(cb)
예제 #2
0
    def test_attach_tracker_sets_aborted_on_other_exception(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        token = unittest.mock.Mock()
        self.assertIs(self.s.attach_tracker(msg, tracker, token), tracker)

        class FooException(Exception):
            pass

        token.future.add_done_callback.assert_called_once_with(
            unittest.mock.ANY, )
        token.future.result.side_effect = FooException()

        _, (cb, ), _ = token.future.add_done_callback.mock_calls[0]

        cb(token.future)

        self.assertEqual(
            tracker.state,
            tracking.MessageState.ABORTED,
        )
예제 #3
0
    def test_attach_tracker_with_subsequent_error_from_bare_modifies_tracking(
            self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(
            self.s.attach_tracker(msg, tracker),
            tracker
        )

        error = msg.make_error(aioxmpp.stanza.Error.from_exception(
            aioxmpp.XMPPCancelError(
                (namespaces.stanzas, "feature-not-implemented")
            )
        ))
        error.from_ = error.from_.bare()

        self.assertIsNone(self.s._inbound_message_filter(error))

        self.assertEqual(
            tracker.state,
            tracking.MessageState.ERROR
        )
        self.assertIs(
            tracker.response,
            error,
        )
예제 #4
0
    def test_attach_tracker_does_not_set_error_if_in_seen_state(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(
            self.s.attach_tracker(msg, tracker),
            tracker
        )

        tracker._set_state(tracking.MessageState.SEEN_BY_RECIPIENT)

        error = msg.make_error(aioxmpp.stanza.Error.from_exception(
            aioxmpp.XMPPCancelError(
                (namespaces.stanzas, "feature-not-implemented")
            )
        ))

        self.assertIsNone(self.s._inbound_message_filter(error))

        self.assertEqual(
            tracker.state,
            tracking.MessageState.SEEN_BY_RECIPIENT
        )
        self.assertIs(
            tracker.response,
            None,
        )
예제 #5
0
    def test_inbound_message_filter_ignores_closed_tracker(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(
            self.s.attach_tracker(msg, tracker),
            tracker
        )

        tracker.close()

        error = msg.make_error(aioxmpp.stanza.Error.from_exception(
            aioxmpp.XMPPCancelError(
                (namespaces.stanzas, "feature-not-implemented")
            )
        ))

        self.assertIs(error, self.s._inbound_message_filter(error))

        self.assertEqual(
            tracker.state,
            tracking.MessageState.IN_TRANSIT,
        )
        self.assertTrue(tracker.closed)
예제 #6
0
    def test_attach_tracker_ignores_cancelled_stanza_token(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        token = unittest.mock.Mock()
        self.assertIs(
            self.s.attach_tracker(msg, tracker, token),
            tracker
        )

        token.future.add_done_callback.assert_called_once_with(
            unittest.mock.ANY,
        )
        token.future.result.side_effect = asyncio.CancelledError()

        _, (cb, ), _ = token.future.add_done_callback.mock_calls[0]

        cb(token.future)

        self.assertEqual(
            tracker.state,
            tracking.MessageState.IN_TRANSIT,
        )
예제 #7
0
    def test_attach_tracker_sets_delivered_to_server_if_ok(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        token = unittest.mock.Mock()
        self.assertIs(
            self.s.attach_tracker(msg, tracker, token),
            tracker
        )

        token.future.add_done_callback.assert_called_once_with(
            unittest.mock.ANY,
        )

        _, (cb, ), _ = token.future.add_done_callback.mock_calls[0]

        cb(token.future)

        self.assertEqual(
            tracker.state,
            tracking.MessageState.DELIVERED_TO_SERVER,
        )
예제 #8
0
    def test_attach_tracker_with_subsequent_error_from_other_id_untracked(
            self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(
            self.s.attach_tracker(msg, tracker),
            tracker
        )

        error = msg.make_error(aioxmpp.stanza.Error.from_exception(
            aioxmpp.XMPPCancelError(
                (namespaces.stanzas, "feature-not-implemented")
            )
        ))
        error.id_ = "fnord"

        self.assertIs(self.s._inbound_message_filter(error), error)

        self.assertEqual(
            tracker.state,
            tracking.MessageState.IN_TRANSIT
        )
        self.assertIs(
            tracker.response,
            None,
        )
예제 #9
0
    def test_attach_tracker_with_subsequent_chat_is_not_tracked(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(self.s.attach_tracker(msg, tracker), tracker)

        reply = msg.make_reply()
        reply.id_ = msg.id_
        self.assertIs(reply, self.s._inbound_message_filter(reply))

        self.assertEqual(tracker.state, tracking.MessageState.IN_TRANSIT)
예제 #10
0
 def test__set_state_rejects_transitions_to_in_transit(self):
     for state in tracking.MessageState:
         t = tracking.MessageTracker()
         if state != t.state:
             t._set_state(state, unittest.mock.sentinel.response)
         on_state_changed = unittest.mock.Mock()
         t.on_state_changed.connect(on_state_changed)
         with self.assertRaisesRegex(ValueError,
                                     "transition from .* to .*not allowed"):
             t._set_state(tracking.MessageState.IN_TRANSIT)
         on_state_changed.assert_not_called()
         self.assertEqual(
             t.state,
             state,
         )
         if state != t.state:
             self.assertEqual(
                 t.response,
                 unittest.mock.sentinel.response,
             )
예제 #11
0
    def test_attach_tracker_with_subsequent_error_modifies_tracking(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(self.s.attach_tracker(msg, tracker), tracker)

        error = msg.make_error(
            aioxmpp.stanza.Error.from_exception(
                aioxmpp.XMPPCancelError(
                    aioxmpp.ErrorCondition.FEATURE_NOT_IMPLEMENTED)))

        self.assertIsNone(self.s._inbound_message_filter(error))

        self.assertEqual(tracker.state, tracking.MessageState.ERROR)
        self.assertIs(
            tracker.response,
            error,
        )
예제 #12
0
    def test_inbound_message_filter_ignores_closed_tracker(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(self.s.attach_tracker(msg, tracker), tracker)

        tracker.close()

        error = msg.make_error(
            aioxmpp.stanza.Error.from_exception(
                aioxmpp.XMPPCancelError(
                    aioxmpp.ErrorCondition.FEATURE_NOT_IMPLEMENTED)))

        self.assertIs(error, self.s._inbound_message_filter(error))

        self.assertEqual(
            tracker.state,
            tracking.MessageState.IN_TRANSIT,
        )
        self.assertTrue(tracker.closed)
예제 #13
0
    def test_attach_tracker_handler_does_not_raise_exception_if_state_already_set(
            self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        token = unittest.mock.Mock()
        self.assertIs(self.s.attach_tracker(msg, tracker, token), tracker)

        token.future.add_done_callback.assert_called_once_with(
            unittest.mock.ANY, )

        _, (cb, ), _ = token.future.add_done_callback.mock_calls[0]

        tracker._set_state(tracking.MessageState.DELIVERED_TO_RECIPIENT)

        cb(token.future)

        self.assertEqual(
            tracker.state,
            tracking.MessageState.DELIVERED_TO_RECIPIENT,
        )
예제 #14
0
    def test_attach_tracker_does_not_set_error_if_in_delivered_state(self):
        tracker = tracking.MessageTracker()
        msg = aioxmpp.Message(
            type_=aioxmpp.MessageType.CHAT,
            from_=TEST_LOCAL,
            to=TEST_PEER,
        )
        self.assertIs(self.s.attach_tracker(msg, tracker), tracker)

        tracker._set_state(tracking.MessageState.DELIVERED_TO_RECIPIENT)

        error = msg.make_error(
            aioxmpp.stanza.Error.from_exception(
                aioxmpp.XMPPCancelError(
                    aioxmpp.ErrorCondition.FEATURE_NOT_IMPLEMENTED)))

        self.assertIsNone(self.s._inbound_message_filter(error))

        self.assertEqual(tracker.state,
                         tracking.MessageState.DELIVERED_TO_RECIPIENT)
        self.assertIs(
            tracker.response,
            None,
        )
예제 #15
0
 def setUp(self):
     self.stanza = aioxmpp.stanza.Message(type_=structs.MessageType.CHAT)
     self.token = stream.StanzaToken(self.stanza)
     self.tr = tracking.MessageTracker(self.token)
예제 #16
0
 def setUp(self):
     self.stanza = aioxmpp.stanza.Message(type_="chat")
     self.token = stream.StanzaToken(self.stanza)
     self.tr = tracking.MessageTracker(self.token)
예제 #17
0
    def test__set_state_rejects_some_other_transitions(self):
        to_reject = [
            (
                tracking.MessageState.DELIVERED_TO_RECIPIENT,
                tracking.MessageState.DELIVERED_TO_SERVER,
            ),
            (
                tracking.MessageState.SEEN_BY_RECIPIENT,
                tracking.MessageState.DELIVERED_TO_SERVER,
            ),
            (
                tracking.MessageState.SEEN_BY_RECIPIENT,
                tracking.MessageState.DELIVERED_TO_RECIPIENT,
            ),
        ]

        for state1, state2 in itertools.product(tracking.MessageState,
                                                tracking.MessageState):
            if state1 == tracking.MessageState.ABORTED:
                # already tested elsewhere
                continue
            if state1 == tracking.MessageState.ERROR:
                # already tested elsewhere
                continue
            if state2 == tracking.MessageState.IN_TRANSIT:
                # already tested elsewhere
                continue
            t = tracking.MessageTracker()

            if state1 != t.state:
                t._set_state(state1, unittest.mock.sentinel.response)

            on_state_changed = unittest.mock.Mock()
            t.on_state_changed.connect(on_state_changed)

            if (state1, state2) in to_reject:
                with self.assertRaisesRegex(
                        ValueError,
                        "transition from .* to .*not allowed",
                        msg=(state1, state2)):
                    t._set_state(state2)
                on_state_changed.assert_not_called()
                self.assertEqual(
                    t.state,
                    state1,
                )
                if state1 != t.state:
                    self.assertEqual(
                        t.response,
                        unittest.mock.sentinel.response,
                    )

            else:
                t._set_state(state2, unittest.mock.sentinel.response2)
                self.assertEqual(
                    t.state,
                    state2,
                )
                self.assertEqual(
                    t.response,
                    unittest.mock.sentinel.response2,
                )