def send_feature(self, data, method='mask', use_values=True, timeout=1): """ """ sent_data = self.xmpp.socket.next_sent(timeout) xml = self.parse_xml(data) sent_xml = self.parse_xml(sent_data) if sent_data is None: self.fail("No stanza was sent.") if method == 'exact': self.assertTrue(self.compare(xml, sent_xml), "Features do not match.\nDesired:\n%s\nReceived:\n%s" % ( highlight(tostring(xml)), highlight(tostring(sent_xml)))) elif method == 'mask': matcher = MatchXMLMask(xml) self.assertTrue(matcher.match(sent_xml), "Stanza did not match using %s method:\n" % method + \ "Criteria:\n%s\n" % highlight(tostring(xml)) + \ "Stanza:\n%s" % highlight(tostring(sent_xml))) else: raise ValueError("Uknown matching method: %s" % method)
def check(self, stanza, criteria, method='exact', defaults=None, use_values=True): """ Create and compare several stanza objects to a correct XML string. If use_values is False, tests using stanza.values will not be used. Some stanzas provide default values for some interfaces, but these defaults can be problematic for testing since they can easily be forgotten when supplying the XML string. A list of interfaces that use defaults may be provided and the generated stanzas will use the default values for those interfaces if needed. However, correcting the supplied XML is not possible for interfaces that add or remove XML elements. Only interfaces that map to XML attributes may be set using the defaults parameter. The supplied XML must take into account any extra elements that are included by default. Arguments: stanza -- The stanza object to test. criteria -- An expression the stanza must match against. method -- The type of matching to use; one of: 'exact', 'mask', 'id', 'xpath', and 'stanzapath'. Defaults to the value of self.match_method. defaults -- A list of stanza interfaces that have default values. These interfaces will be set to their defaults for the given and generated stanzas to prevent unexpected test failures. use_values -- Indicates if testing using stanza.values should be used. Defaults to True. """ if method is None and hasattr(self, 'match_method'): method = getattr(self, 'match_method') if method != 'exact': matchers = { 'stanzapath': StanzaPath, 'xpath': MatchXPath, 'mask': MatchXMLMask, 'idsender': MatchIDSender, 'id': MatcherId } Matcher = matchers.get(method, None) if Matcher is None: raise ValueError("Unknown matching method.") test = Matcher(criteria) self.assertTrue(test.match(stanza), "Stanza did not match using %s method:\n" % method + \ "Criteria:\n%s\n" % str(criteria) + \ "Stanza:\n%s" % str(stanza)) else: stanza_class = stanza.__class__ if not isinstance(criteria, ElementBase): xml = self.parse_xml(criteria) else: xml = criteria.xml # Ensure that top level namespaces are used, even if they # were not provided. self.fix_namespaces(stanza.xml, 'jabber:client') self.fix_namespaces(xml, 'jabber:client') stanza2 = stanza_class(xml=xml) if use_values: # Using stanza.values will add XML for any interface that # has a default value. We need to set those defaults on # the existing stanzas and XML so that they will compare # correctly. default_stanza = stanza_class() if defaults is None: known_defaults = { Message: ['type'], Presence: ['priority'] } defaults = known_defaults.get(stanza_class, []) for interface in defaults: stanza[interface] = stanza[interface] stanza2[interface] = stanza2[interface] # Can really only automatically add defaults for top # level attribute values. Anything else must be accounted # for in the provided XML string. if interface not in xml.attrib: if interface in default_stanza.xml.attrib: value = default_stanza.xml.attrib[interface] xml.attrib[interface] = value values = stanza2.values stanza3 = stanza_class() stanza3.values = values debug = "Three methods for creating stanzas do not match.\n" debug += "Given XML:\n%s\n" % highlight(tostring(xml)) debug += "Given stanza:\n%s\n" % highlight(tostring( stanza.xml)) debug += "Generated stanza:\n%s\n" % highlight( tostring(stanza2.xml)) debug += "Second generated stanza:\n%s\n" % highlight( tostring(stanza3.xml)) result = self.compare(xml, stanza.xml, stanza2.xml, stanza3.xml) else: debug = "Two methods for creating stanzas do not match.\n" debug += "Given XML:\n%s\n" % highlight(tostring(xml)) debug += "Given stanza:\n%s\n" % highlight(tostring( stanza.xml)) debug += "Generated stanza:\n%s\n" % highlight( tostring(stanza2.xml)) result = self.compare(xml, stanza.xml, stanza2.xml) self.assertTrue(result, debug)
def check(self, stanza, criteria, method='exact', defaults=None, use_values=True): """ Create and compare several stanza objects to a correct XML string. If use_values is False, tests using stanza.values will not be used. Some stanzas provide default values for some interfaces, but these defaults can be problematic for testing since they can easily be forgotten when supplying the XML string. A list of interfaces that use defaults may be provided and the generated stanzas will use the default values for those interfaces if needed. However, correcting the supplied XML is not possible for interfaces that add or remove XML elements. Only interfaces that map to XML attributes may be set using the defaults parameter. The supplied XML must take into account any extra elements that are included by default. Arguments: stanza -- The stanza object to test. criteria -- An expression the stanza must match against. method -- The type of matching to use; one of: 'exact', 'mask', 'id', 'xpath', and 'stanzapath'. Defaults to the value of self.match_method. defaults -- A list of stanza interfaces that have default values. These interfaces will be set to their defaults for the given and generated stanzas to prevent unexpected test failures. use_values -- Indicates if testing using stanza.values should be used. Defaults to True. """ if method is None and hasattr(self, 'match_method'): method = getattr(self, 'match_method') if method != 'exact': matchers = {'stanzapath': StanzaPath, 'xpath': MatchXPath, 'mask': MatchXMLMask, 'idsender': MatchIDSender, 'id': MatcherId} Matcher = matchers.get(method, None) if Matcher is None: raise ValueError("Unknown matching method.") test = Matcher(criteria) self.assertTrue(test.match(stanza), "Stanza did not match using %s method:\n" % method + \ "Criteria:\n%s\n" % str(criteria) + \ "Stanza:\n%s" % str(stanza)) else: stanza_class = stanza.__class__ if not isinstance(criteria, ElementBase): xml = self.parse_xml(criteria) else: xml = criteria.xml # Ensure that top level namespaces are used, even if they # were not provided. self.fix_namespaces(stanza.xml, 'jabber:client') self.fix_namespaces(xml, 'jabber:client') stanza2 = stanza_class(xml=xml) if use_values: # Using stanza.values will add XML for any interface that # has a default value. We need to set those defaults on # the existing stanzas and XML so that they will compare # correctly. default_stanza = stanza_class() if defaults is None: known_defaults = { Message: ['type'], Presence: ['priority'] } defaults = known_defaults.get(stanza_class, []) for interface in defaults: stanza[interface] = stanza[interface] stanza2[interface] = stanza2[interface] # Can really only automatically add defaults for top # level attribute values. Anything else must be accounted # for in the provided XML string. if interface not in xml.attrib: if interface in default_stanza.xml.attrib: value = default_stanza.xml.attrib[interface] xml.attrib[interface] = value values = stanza2.values stanza3 = stanza_class() stanza3.values = values debug = "Three methods for creating stanzas do not match.\n" debug += "Given XML:\n%s\n" % highlight(tostring(xml)) debug += "Given stanza:\n%s\n" % highlight(tostring(stanza.xml)) debug += "Generated stanza:\n%s\n" % highlight(tostring(stanza2.xml)) debug += "Second generated stanza:\n%s\n" % highlight(tostring(stanza3.xml)) result = self.compare(xml, stanza.xml, stanza2.xml, stanza3.xml) else: debug = "Two methods for creating stanzas do not match.\n" debug += "Given XML:\n%s\n" % highlight(tostring(xml)) debug += "Given stanza:\n%s\n" % highlight(tostring(stanza.xml)) debug += "Generated stanza:\n%s\n" % highlight(tostring(stanza2.xml)) result = self.compare(xml, stanza.xml, stanza2.xml) self.assertTrue(result, debug)