Changeset 172:ea2774e1c71c for wokkel/test/test_xmppim.py
- Timestamp:
- May 9, 2012, 2:24:28 PM (10 years ago)
- Branch:
- default
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
wokkel/test/test_xmppim.py
r96 r172 8 8 from twisted.internet import defer 9 9 from twisted.trial import unittest 10 from twisted.words.protocols.jabber import error 10 11 from twisted.words.protocols.jabber.jid import JID 11 12 from twisted.words.protocols.jabber.xmlstream import toResponse … … 14 15 from wokkel import xmppim 15 16 from wokkel.generic import ErrorStanza, parseXml 16 from wokkel.test.helpers import XmlStreamStub17 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub 17 18 18 19 NS_XML = 'http://www.w3.org/XML/1998/namespace' … … 450 451 451 452 452 class RosterClientProtocolTest(unittest.TestCase): 453 class RosterItemTest(unittest.TestCase): 454 """ 455 Tests for L{xmppim.RosterItem}. 456 """ 457 458 def test_toElement(self): 459 """ 460 A roster item has the correct namespace/name, lacks unset attributes. 461 """ 462 item = xmppim.RosterItem(JID('user@example.org')) 463 element = item.toElement() 464 self.assertEqual('item', element.name) 465 self.assertEqual(NS_ROSTER, element.uri) 466 self.assertFalse(element.hasAttribute('subscription')) 467 self.assertFalse(element.hasAttribute('ask')) 468 self.assertEqual(u"", element.getAttribute('name', u"")) 469 self.assertFalse(element.hasAttribute('approved')) 470 self.assertEquals(0, len(list(element.elements()))) 471 472 473 def test_toElementMinimal(self): 474 """ 475 A bare roster item only has a jid attribute. 476 """ 477 item = xmppim.RosterItem(JID('user@example.org')) 478 element = item.toElement() 479 self.assertEqual(u'user@example.org', element.getAttribute('jid')) 480 481 482 def test_toElementSubscriptionNone(self): 483 """ 484 A roster item with no subscription has no subscription attribute. 485 """ 486 item = xmppim.RosterItem(JID('user@example.org'), 487 subscriptionTo=False, 488 subscriptionFrom=False) 489 element = item.toElement() 490 self.assertIdentical(None, element.getAttribute('subscription')) 491 492 493 def test_toElementSubscriptionTo(self): 494 """ 495 A roster item with subscriptionTo set has subscription 'to'. 496 """ 497 item = xmppim.RosterItem(JID('user@example.org'), 498 subscriptionTo=True, 499 subscriptionFrom=False) 500 element = item.toElement() 501 self.assertEqual('to', element.getAttribute('subscription')) 502 503 504 def test_toElementSubscriptionFrom(self): 505 """ 506 A roster item with subscriptionFrom set has subscription 'to'. 507 """ 508 item = xmppim.RosterItem(JID('user@example.org'), 509 subscriptionTo=False, 510 subscriptionFrom=True) 511 element = item.toElement() 512 self.assertEqual('from', element.getAttribute('subscription')) 513 514 515 def test_toElementSubscriptionBoth(self): 516 """ 517 A roster item with mutual subscription has subscription 'both'. 518 """ 519 item = xmppim.RosterItem(JID('user@example.org'), 520 subscriptionTo=True, 521 subscriptionFrom=True) 522 element = item.toElement() 523 self.assertEqual('both', element.getAttribute('subscription')) 524 525 526 def test_toElementSubscriptionRemove(self): 527 """ 528 A roster item with remove set has subscription 'remove'. 529 """ 530 item = xmppim.RosterItem(JID('user@example.org')) 531 item.remove = True 532 element = item.toElement() 533 self.assertEqual('remove', element.getAttribute('subscription')) 534 535 536 def test_toElementAsk(self): 537 """ 538 A roster item with pendingOut set has subscription 'ask'. 539 """ 540 item = xmppim.RosterItem(JID('user@example.org')) 541 item.pendingOut = True 542 element = item.toElement() 543 self.assertEqual('subscribe', element.getAttribute('ask')) 544 545 546 def test_toElementName(self): 547 """ 548 A roster item's name is rendered to the 'name' attribute. 549 """ 550 item = xmppim.RosterItem(JID('user@example.org'), 551 name='Joe User') 552 element = item.toElement() 553 self.assertEqual(u'Joe User', element.getAttribute('name')) 554 555 556 def test_toElementGroups(self): 557 """ 558 A roster item's groups are rendered as 'group' child elements. 559 """ 560 groups = set(['Friends', 'Jabber']) 561 item = xmppim.RosterItem(JID('user@example.org'), 562 groups=groups) 563 564 element = item.toElement() 565 foundGroups = set() 566 for child in element.elements(): 567 if child.uri == NS_ROSTER and child.name == 'group': 568 foundGroups.add(unicode(child)) 569 570 self.assertEqual(groups, foundGroups) 571 572 573 def test_toElementApproved(self): 574 """ 575 A pre-approved subscription for a roster item has an 'approved' flag. 576 """ 577 item = xmppim.RosterItem(JID('user@example.org')) 578 item.approved = True 579 element = item.toElement() 580 self.assertEqual(u'true', element.getAttribute('approved')) 581 582 583 def test_fromElementMinimal(self): 584 """ 585 A minimal roster item has a reference to the JID of the contact. 586 """ 587 588 xml = """ 589 <item xmlns="jabber:iq:roster" 590 jid="test@example.org"/> 591 """ 592 593 item = xmppim.RosterItem.fromElement(parseXml(xml)) 594 self.assertEqual(JID(u"test@example.org"), item.entity) 595 self.assertEqual(u"", item.name) 596 self.assertFalse(item.subscriptionTo) 597 self.assertFalse(item.subscriptionFrom) 598 self.assertFalse(item.pendingOut) 599 self.assertFalse(item.approved) 600 self.assertEqual(set(), item.groups) 601 602 603 def test_fromElementName(self): 604 """ 605 A roster item may have an optional name. 606 """ 607 608 xml = """ 609 <item xmlns="jabber:iq:roster" 610 jid="test@example.org" 611 name="Test User"/> 612 """ 613 614 item = xmppim.RosterItem.fromElement(parseXml(xml)) 615 self.assertEqual(u"Test User", item.name) 616 617 618 def test_fromElementGroups(self): 619 """ 620 A roster item may have one or more groups. 621 """ 622 623 xml = """ 624 <item xmlns="jabber:iq:roster" 625 jid="test@example.org"> 626 <group>Friends</group> 627 <group>Twisted</group> 628 </item> 629 """ 630 631 item = xmppim.RosterItem.fromElement(parseXml(xml)) 632 self.assertIn(u"Twisted", item.groups) 633 self.assertIn(u"Friends", item.groups) 634 635 636 def test_fromElementSubscriptionNone(self): 637 """ 638 Subscription 'none' sets both attributes to False. 639 """ 640 641 xml = """ 642 <item xmlns="jabber:iq:roster" 643 jid="test@example.org" 644 subscription="none"/> 645 """ 646 647 item = xmppim.RosterItem.fromElement(parseXml(xml)) 648 self.assertFalse(item.remove) 649 self.assertFalse(item.subscriptionTo) 650 self.assertFalse(item.subscriptionFrom) 651 652 653 def test_fromElementSubscriptionTo(self): 654 """ 655 Subscription 'to' sets the corresponding attribute to True. 656 """ 657 658 xml = """ 659 <item xmlns="jabber:iq:roster" 660 jid="test@example.org" 661 subscription="to"/> 662 """ 663 664 item = xmppim.RosterItem.fromElement(parseXml(xml)) 665 self.assertFalse(item.remove) 666 self.assertTrue(item.subscriptionTo) 667 self.assertFalse(item.subscriptionFrom) 668 669 670 def test_fromElementSubscriptionFrom(self): 671 """ 672 Subscription 'from' sets the corresponding attribute to True. 673 """ 674 675 xml = """ 676 <item xmlns="jabber:iq:roster" 677 jid="test@example.org" 678 subscription="from"/> 679 """ 680 681 item = xmppim.RosterItem.fromElement(parseXml(xml)) 682 self.assertFalse(item.remove) 683 self.assertFalse(item.subscriptionTo) 684 self.assertTrue(item.subscriptionFrom) 685 686 687 def test_fromElementSubscriptionBoth(self): 688 """ 689 Subscription 'both' sets both attributes to True. 690 """ 691 692 xml = """ 693 <item xmlns="jabber:iq:roster" 694 jid="test@example.org" 695 subscription="both"/> 696 """ 697 698 item = xmppim.RosterItem.fromElement(parseXml(xml)) 699 self.assertFalse(item.remove) 700 self.assertTrue(item.subscriptionTo) 701 self.assertTrue(item.subscriptionFrom) 702 703 704 def test_fromElementSubscriptionRemove(self): 705 """ 706 Subscription 'remove' sets the remove attribute. 707 """ 708 709 xml = """ 710 <item xmlns="jabber:iq:roster" 711 jid="test@example.org" 712 subscription="remove"/> 713 """ 714 715 item = xmppim.RosterItem.fromElement(parseXml(xml)) 716 self.assertTrue(item.remove) 717 718 719 def test_fromElementPendingOut(self): 720 """ 721 The ask attribute, if set to 'subscription', means pending out. 722 """ 723 724 xml = """ 725 <item xmlns="jabber:iq:roster" 726 jid="test@example.org" 727 ask="subscribe"/> 728 """ 729 730 item = xmppim.RosterItem.fromElement(parseXml(xml)) 731 self.assertTrue(item.pendingOut) 732 733 734 def test_fromElementApprovedTrue(self): 735 """ 736 The approved attribute (true) signals a pre-approved subscription. 737 """ 738 739 xml = """ 740 <item xmlns="jabber:iq:roster" 741 jid="test@example.org" 742 approved="true"/> 743 """ 744 745 item = xmppim.RosterItem.fromElement(parseXml(xml)) 746 self.assertTrue(item.approved) 747 748 749 def test_fromElementApproved1(self): 750 """ 751 The approved attribute (1) signals a pre-approved subscription. 752 """ 753 754 xml = """ 755 <item xmlns="jabber:iq:roster" 756 jid="test@example.org" 757 approved="1"/> 758 """ 759 760 item = xmppim.RosterItem.fromElement(parseXml(xml)) 761 self.assertTrue(item.approved) 762 763 764 def test_jidDeprecationGet(self): 765 """ 766 Getting the jid attribute works as entity and warns deprecation. 767 """ 768 item = xmppim.RosterItem(JID('user@example.org')) 769 entity = self.assertWarns(DeprecationWarning, 770 "wokkel.xmppim.RosterItem.jid is deprecated. " 771 "Use RosterItem.entity instead.", 772 xmppim.__file__, 773 getattr, item, 'jid') 774 self.assertIdentical(entity, item.entity) 775 776 777 def test_jidDeprecationSet(self): 778 """ 779 Setting the jid attribute works as entity and warns deprecation. 780 """ 781 item = xmppim.RosterItem(JID('user@example.org')) 782 self.assertWarns(DeprecationWarning, 783 "wokkel.xmppim.RosterItem.jid is deprecated. " 784 "Use RosterItem.entity instead.", 785 xmppim.__file__, 786 setattr, item, 'jid', 787 JID('other@example.org')) 788 self.assertEqual(JID('other@example.org'), item.entity) 789 790 791 def test_askDeprecationGet(self): 792 """ 793 Getting the ask attribute works as entity and warns deprecation. 794 """ 795 item = xmppim.RosterItem(JID('user@example.org')) 796 item.pendingOut = True 797 ask = self.assertWarns(DeprecationWarning, 798 "wokkel.xmppim.RosterItem.ask is deprecated. " 799 "Use RosterItem.pendingOut instead.", 800 xmppim.__file__, 801 getattr, item, 'ask') 802 self.assertTrue(ask) 803 804 805 def test_askDeprecationSet(self): 806 """ 807 Setting the ask attribute works as entity and warns deprecation. 808 """ 809 item = xmppim.RosterItem(JID('user@example.org')) 810 self.assertWarns(DeprecationWarning, 811 "wokkel.xmppim.RosterItem.ask is deprecated. " 812 "Use RosterItem.pendingOut instead.", 813 xmppim.__file__, 814 setattr, item, 'ask', 815 True) 816 self.assertTrue(item.pendingOut) 817 818 819 820 class RosterRequestTest(unittest.TestCase): 821 """ 822 Tests for L{xmppim.RosterRequest}. 823 """ 824 825 def test_fromElement(self): 826 """ 827 A bare roster request is parsed and missing information is None. 828 """ 829 xml = """ 830 <iq type='get' to='this@example.org/Home' from='this@example.org'> 831 <query xmlns='jabber:iq:roster'/> 832 </iq> 833 """ 834 835 request = xmppim.RosterRequest.fromElement(parseXml(xml)) 836 self.assertEqual('get', request.stanzaType) 837 self.assertEqual(JID('this@example.org/Home'), request.recipient) 838 self.assertEqual(JID('this@example.org'), request.sender) 839 self.assertEqual(None, request.item) 840 841 842 def test_fromElementItem(self): 843 """ 844 If an item is present, parse it and put it in the request item. 845 """ 846 xml = """ 847 <iq type='set' to='this@example.org/Home' from='this@example.org'> 848 <query xmlns='jabber:iq:roster'> 849 <item jid='user@example.org'/> 850 </query> 851 </iq> 852 """ 853 854 request = xmppim.RosterRequest.fromElement(parseXml(xml)) 855 self.assertNotIdentical(None, request.item) 856 self.assertEqual(JID('user@example.org'), request.item.entity) 857 858 859 def test_toElement(self): 860 """ 861 A roster request has a query element in the roster namespace. 862 """ 863 request = xmppim.RosterRequest() 864 element = request.toElement() 865 children = element.elements() 866 child = children.next() 867 self.assertEqual(NS_ROSTER, child.uri) 868 self.assertEqual('query', child.name) 869 870 871 def test_toElementItem(self): 872 """ 873 If an item is set, it is rendered as a child of the query. 874 """ 875 request = xmppim.RosterRequest() 876 request.item = xmppim.RosterItem(JID('user@example.org')) 877 element = request.toElement() 878 children = element.query.elements() 879 child = children.next() 880 self.assertEqual(NS_ROSTER, child.uri) 881 self.assertEqual('item', child.name) 882 883 884 885 class FakeClient(object): 886 """ 887 Fake client stream manager for roster tests. 888 """ 889 890 def __init__(self, xmlstream, jid): 891 self.xmlstream = xmlstream 892 self.jid = jid 893 894 895 def request(self, request): 896 element = request.toElement() 897 self.xmlstream.send(element) 898 return defer.Deferred() 899 900 901 def addHandler(self, handler): 902 handler.makeConnection(self.xmlstream) 903 handler.connectionInitialized() 904 905 906 907 class RosterClientProtocolTest(unittest.TestCase, TestableRequestHandlerMixin): 453 908 """ 454 909 Tests for L{xmppim.RosterClientProtocol}. … … 457 912 def setUp(self): 458 913 self.stub = XmlStreamStub() 459 self. protocol = xmppim.RosterClientProtocol()460 self. protocol.xmlstream = self.stub.xmlstream461 self. protocol.connectionInitialized()914 self.client = FakeClient(self.stub.xmlstream, JID('this@example.org')) 915 self.service = xmppim.RosterClientProtocol() 916 self.service.setHandlerParent(self.client) 462 917 463 918 … … 466 921 Removing a roster item is setting an item with subscription C{remove}. 467 922 """ 468 d = self. protocol.removeItem(JID('test@example.org'))923 d = self.service.removeItem(JID('test@example.org')) 469 924 470 925 # Inspect outgoing iq request 471 926 472 927 iq = self.stub.output[-1] 473 self.assertEqual s('set', iq.getAttribute('type'))928 self.assertEqual('set', iq.getAttribute('type')) 474 929 self.assertNotIdentical(None, iq.query) 475 self.assertEqual s(NS_ROSTER, iq.query.uri)930 self.assertEqual(NS_ROSTER, iq.query.uri) 476 931 477 932 children = list(domish.generateElementsQNamed(iq.query.children, 478 933 'item', NS_ROSTER)) 479 self.assertEqual s(1, len(children))934 self.assertEqual(1, len(children)) 480 935 child = children[0] 481 self.assertEqual s('test@example.org', child['jid'])482 self.assertEqual s('remove', child['subscription'])936 self.assertEqual('test@example.org', child['jid']) 937 self.assertEqual('remove', child.getAttribute('subscription')) 483 938 484 939 # Fake successful response 485 940 486 941 response = toResponse(iq, 'result') 487 self.stub.send(response) 488 return d 942 d.callback(response) 943 return d 944 945 946 def test_getRoster(self): 947 """ 948 A request for the roster is sent out and the response is parsed. 949 """ 950 def cb(roster): 951 self.assertIn(JID('user@example.org'), roster) 952 953 d = self.service.getRoster() 954 d.addCallback(cb) 955 956 # Inspect outgoing iq request 957 958 iq = self.stub.output[-1] 959 self.assertEqual('get', iq.getAttribute('type')) 960 self.assertNotIdentical(None, iq.query) 961 self.assertEqual(NS_ROSTER, iq.query.uri) 962 963 # Fake successful response 964 response = toResponse(iq, 'result') 965 query = response.addElement((NS_ROSTER, 'query')) 966 item = query.addElement('item') 967 item['jid'] = 'user@example.org' 968 969 d.callback(response) 970 return d 971 972 973 def test_onRosterSet(self): 974 """ 975 A roster push causes onRosterSet to be called with the parsed item. 976 """ 977 xml = """ 978 <iq type='set'> 979 <query xmlns='jabber:iq:roster'> 980 <item jid='user@example.org'/> 981 </query> 982 </iq> 983 """ 984 985 items = [] 986 987 def onRosterSet(item): 988 items.append(item) 989 990 def cb(result): 991 self.assertEqual(1, len(items)) 992 self.assertEqual(JID('user@example.org'), items[0].entity) 993 994 self.service.onRosterSet = onRosterSet 995 996 d = self.assertWarns(DeprecationWarning, 997 "wokkel.xmppim.RosterClientProtocol.onRosterSet " 998 "is deprecated. " 999 "Use RosterClientProtocol.setReceived instead.", 1000 xmppim.__file__, 1001 self.handleRequest, xml) 1002 d.addCallback(cb) 1003 return d 1004 1005 1006 def test_onRosterRemove(self): 1007 """ 1008 A roster push causes onRosterSet to be called with the parsed item. 1009 """ 1010 xml = """ 1011 <iq type='set'> 1012 <query xmlns='jabber:iq:roster'> 1013 <item jid='user@example.org' subscription='remove'/> 1014 </query> 1015 </iq> 1016 """ 1017 1018 entities = [] 1019 1020 def onRosterRemove(entity): 1021 entities.append(entity) 1022 1023 def cb(result): 1024 self.assertEqual([JID('user@example.org')], entities) 1025 1026 self.service.onRosterRemove = onRosterRemove 1027 1028 d = self.assertWarns(DeprecationWarning, 1029 "wokkel.xmppim.RosterClientProtocol.onRosterRemove " 1030 "is deprecated. " 1031 "Use RosterClientProtocol.removeReceived instead.", 1032 xmppim.__file__, 1033 self.handleRequest, xml) 1034 d.addCallback(cb) 1035 return d 1036 1037 1038 def test_setReceived(self): 1039 """ 1040 A roster set push causes setReceived. 1041 """ 1042 xml = """ 1043 <iq type='set'> 1044 <query xmlns='jabber:iq:roster'> 1045 <item jid='user@example.org'/> 1046 </query> 1047 </iq> 1048 """ 1049 1050 requests = [] 1051 1052 def setReceived(request): 1053 requests.append(request) 1054 1055 def cb(result): 1056 self.assertEqual(1, len(requests), "setReceived was not called") 1057 self.assertEqual(JID('user@example.org'), requests[0].item.entity) 1058 1059 self.service.setReceived = setReceived 1060 1061 d = self.handleRequest(xml) 1062 d.addCallback(cb) 1063 return d 1064 1065 1066 def test_setReceivedOtherSource(self): 1067 """ 1068 Roster pushes can be sent from other entities, too, ignore them. 1069 """ 1070 xml = """ 1071 <iq type='set' to='this@example.org/Home' from='other@example.org'> 1072 <query xmlns='jabber:iq:roster'> 1073 <item jid='user@example.org'/> 1074 </query> 1075 </iq> 1076 """ 1077 1078 def cb(result): 1079 self.assertEquals('service-unavailable', result.condition) 1080 1081 d = self.handleRequest(xml) 1082 self.assertFailure(d, error.StanzaError) 1083 d.addCallback(cb) 1084 return d 1085 1086 1087 def test_setReceivedOtherSourceAllowed(self): 1088 """ 1089 Roster pushes can be sent from other entities, allow them. 1090 """ 1091 xml = """ 1092 <iq type='set' to='this@example.org/Home' from='other@example.org'> 1093 <query xmlns='jabber:iq:roster'> 1094 <item jid='user@example.org'/> 1095 </query> 1096 </iq> 1097 """ 1098 1099 self.service.allowAnySender = True 1100 requests = [] 1101 1102 def setReceived(request): 1103 requests.append(request) 1104 1105 def cb(result): 1106 self.assertEqual(1, len(requests), "setReceived was not called") 1107 1108 self.service.setReceived = setReceived 1109 1110 d = self.handleRequest(xml) 1111 d.addCallback(cb) 1112 return d 1113 1114 1115 def test_setReceivedOtherSourceIgnored(self): 1116 """ 1117 Roster pushes can be sent from other entities, allow them. 1118 """ 1119 xml = """ 1120 <iq type='set' to='this@example.org/Home' from='bad@example.org'> 1121 <query xmlns='jabber:iq:roster'> 1122 <item jid='user@example.org'/> 1123 </query> 1124 </iq> 1125 """ 1126 1127 self.service.allowAnySender = True 1128 1129 def setReceived(request): 1130 if request.sender == JID('bad@example.org'): 1131 raise xmppim.RosterPushIgnored() 1132 1133 def cb(result): 1134 self.assertEquals('service-unavailable', result.condition) 1135 1136 self.service.setReceived = setReceived 1137 1138 1139 d = self.handleRequest(xml) 1140 self.assertFailure(d, error.StanzaError) 1141 d.addCallback(cb) 1142 return d 1143 1144 1145 def test_removeReceived(self): 1146 """ 1147 A roster remove push causes removeReceived. 1148 """ 1149 xml = """ 1150 <iq type='set'> 1151 <query xmlns='jabber:iq:roster'> 1152 <item jid='user@example.org' subscription='remove'/> 1153 </query> 1154 </iq> 1155 """ 1156 1157 requests = [] 1158 1159 def removeReceived(request): 1160 requests.append(request) 1161 1162 def cb(result): 1163 self.assertEqual(1, len(requests), "removeReceived was not called") 1164 self.assertEqual(JID('user@example.org'), requests[0].item.entity) 1165 1166 self.service.removeReceived = removeReceived 1167 1168 d = self.handleRequest(xml) 1169 d.addCallback(cb) 1170 return d
Note: See TracChangeset
for help on using the changeset viewer.