def test_render_qfilter02(self): "Q instance." widget = EntitySelector(content_type=13) name = 'my_field' value = '2' render_dom = assert_and_parse_html( self, widget.render(name, value, attrs={'qfilter': Q(name='foobar')}), user_msg=None, msg='Widget render is not valid !', ) qfilter_attr = self.assertQFilter(render_dom, {'val': [['name', 'foobar']], 'op': 'AND'}) html = \ '''<span class="ui-creme-widget widget-auto ui-creme-entityselector" widget="ui-creme-entityselector" labelURL="{text_url}" label="{label}" popupURL="{url}" popupSelection="single" qfilter="{q_filter}"> <input name="{name}" type="hidden" class="ui-creme-input ui-creme-entityselector" value="{value}"/> <button type="button">{label}</button> </span>'''.format( name=name, value=value, label=_('Select…'), text_url=TemplateURLBuilder(entity_id=(TemplateURLBuilder.Int, '${id}')) .resolve('creme_core__entity_as_json'), url=reverse('creme_core__listview_popup') + '?ct_id=13&selection=${selection}&q_filter=${qfilter}', q_filter=escape(qfilter_attr), ) self.assertDOMEqual(assert_and_parse_html(self, html, None, 'Expected HTML is not valid !'), render_dom)
def assertHTMLEqual(self, html1, html2, msg=None): """ Clone of django's method, but with support for JSON in data- tag attributes """ # Parse the HTML into a dom err1 = 'First argument is not a valid HTML element:' err2 = 'Second argument is not a valid HTML element:' dom1 = testcases.assert_and_parse_html(self, html1, msg, err1) dom2 = testcases.assert_and_parse_html(self, html2, msg, err2) # Check it actually managed to parse something self.assertNotEqual(dom1.name, None, msg='%s\n%s' % (err1, html1)) self.assertNotEqual(dom2.name, None, msg='%s\n%s' % (err2, html2)) # Walk the trees and pull out json dom1, json1 = self._extract_json(dom1) dom2, json2 = self._extract_json(dom2) # Convert dom back to string, call super to test doms # Yes it's inefficient, but it's tests and saves me from forking it super(TagTestManager, self).assertHTMLEqual( six.text_type(dom1), six.text_type(dom2), ) # Test jsons # Assert we've found the same elements self.assertSequenceEqual(json1.keys(), json2.keys()) for dom_path in json1.keys(): # Assert the element has the same attributes self.assertSequenceEqual( json1[dom_path].keys(), json2[dom_path].keys(), msg='%s has attributes do not match: %r != %r' % ( dom_path, json1[dom_path].keys(), json2[dom_path].keys(), )) for attr_name in json1[dom_path].keys(): # Django 1.4 doesn't support assertJSONEqual # For now, just have a copy of it from 1.5 try: json1_val = json.loads(json1[dom_path][attr_name]) except ValueError: self.fail( "%s %s test result is not valid JSON: %r" % (dom_path, attr_name, json1[dom_path][attr_name])) else: try: json2_val = json.loads(json2[dom_path][attr_name]) except ValueError: self.fail( "%s %s expected is not valid JSON: %r" % (dom_path, attr_name, json2[dom_path][attr_name])) else: self.assertEqual(json1_val, json2_val, msg='%s %s JSON does not match' % (dom_path, attr_name))
def assertTagInTemplateScript(self, needle, haystack, count=None, msg_prefix=''): needle = assert_and_parse_html(self, needle, None, 'First argument is not valid HTML:') haystack = assert_and_parse_html(self, haystack, None, 'Second argument is not valid HTML:') real_count = 0 for script_tag in self._find_template_script_tags(haystack): if script_tag.children: self.assertEqual(len(script_tag.children), 1) script_html = assert_and_parse_html( self, script_tag.children[0], None, 'Script tag content is not valid HTML:') real_count += self._count_tag_occurrences(needle, script_html) if count is not None: self.assertEqual( real_count, count, msg_prefix + "Found %d instances of '%s' in template script (expected %d)" % (real_count, needle, count)) else: self.assertTrue( real_count != 0, msg_prefix + "Couldn't find '%s' in template script" % needle)
def assertFormErrors(self, response, count=0, message=None, context_name="form"): """Check for form errors. Asserts that the response does contain a form in its context, and that form has errors, if count were given, it must match the exact numbers of errors """ context = getattr(response, "context", {}) assert (context and context_name in context), \ "The response did not contain a form." errors = response.context[context_name]._errors if count: assert len(errors) == count, \ "%d errors were found on the form, %d expected" % \ (len(errors), count) if message: text = testcases.assert_and_parse_html( self, message, None, '"message" contains invalid HTML:') content = testcases.assert_and_parse_html( self, str(errors), None, '"_errors" in the response context is not valid HTML:') match_count = content.count(text) self.assertGreaterEqual(match_count, 1) else: assert len(errors) > 0, "No errors were found on the form"
def assertHTMLEqual(self, html1, html2, msg=None): """ Clone of django's method, but with support for JSON in data- tag attributes """ # Parse the HTML into a dom err1 = 'First argument is not a valid HTML element:' err2 = 'Second argument is not a valid HTML element:' dom1 = testcases.assert_and_parse_html(self, html1, msg, err1) dom2 = testcases.assert_and_parse_html(self, html2, msg, err2) # Check it actually managed to parse something self.assertNotEqual(dom1.name, None, msg='%s\n%s' % (err1, html1)) self.assertNotEqual(dom2.name, None, msg='%s\n%s' % (err2, html2)) # Walk the trees and pull out json dom1, json1 = self._extract_json(dom1) dom2, json2 = self._extract_json(dom2) # Convert dom back to string, call super to test doms # Yes it's inefficient, but it's tests and saves me from forking it super(TagTestManager, self).assertHTMLEqual( six.text_type(dom1), six.text_type(dom2), ) # Test jsons # Assert we've found the same elements self.assertSequenceEqual(json1.keys(), json2.keys()) for dom_path in json1.keys(): # Assert the element has the same attributes self.assertSequenceEqual( json1[dom_path].keys(), json2[dom_path].keys(), msg='%s has attributes do not match: %r != %r' % ( dom_path, json1[dom_path].keys(), json2[dom_path].keys(), ) ) for attr_name in json1[dom_path].keys(): # Django 1.4 doesn't support assertJSONEqual # For now, just have a copy of it from 1.5 try: json1_val = json.loads(json1[dom_path][attr_name]) except ValueError: self.fail( "%s %s test result is not valid JSON: %r" % (dom_path, attr_name, json1[dom_path][attr_name]) ) else: try: json2_val = json.loads(json2[dom_path][attr_name]) except ValueError: self.fail( "%s %s expected is not valid JSON: %r" % (dom_path, attr_name, json2[dom_path][attr_name]) ) else: self.assertEqual( json1_val, json2_val, msg='%s %s JSON does not match' % (dom_path, attr_name) )
def assertTagInHTML(self, needle, haystack, count=None, msg_prefix='', allow_extra_attrs=False): needle = assert_and_parse_html(self, needle, None, 'First argument is not valid HTML:') haystack = assert_and_parse_html(self, haystack, None, 'Second argument is not valid HTML:') real_count = self._count_tag_occurrences(needle, haystack, allow_extra_attrs=allow_extra_attrs) if count is not None: self.assertEqual( real_count, count, msg_prefix + "Found %d instances of '%s' in response (expected %d)" % (real_count, needle, count) ) else: self.assertTrue(real_count != 0, msg_prefix + "Couldn't find '%s' in response" % needle)
def assertHTMLContains(self, html_content, html_substring, count = None, msg_prefix = ''): """ Asserts that a HTML string contains another HTML string """ if msg_prefix: msg_prefix += ": " content = assert_and_parse_html(self, unicode(html_content), None, u"Content is not valid HTML:") text = assert_and_parse_html(self, unicode(html_substring), None, u"Second argument is not valid HTML:") real_count = content.count(text) if count is not None: self.assertEqual(real_count, count, msg_prefix + "Found %d instances of '%s' in content (expected %d)" % (real_count, text, count)) else: self.assertTrue(real_count != 0, msg_prefix + "Couldn't find '{}' in content '{}'".format(text, content))
def _assertNotContains(self, response, text, status_code=200, msg_prefix='', html=False): """Asserts that a response indicates that some content was retrieved successfully, (i.e., the HTTP status code was as expected), and that ``text`` doesn't occurs in the content of the response. This is an override of django_test.TestCase.assertNotContains method, which is able to work with StreamingHttpResponse. Should be called for Django versions prior to 1.7. """ # If the response supports deferred rendering and hasn't been rendered # yet, then ensure that it does get rendered before proceeding further. if (hasattr(response, 'render') and callable(response.render) and not response.is_rendered): response.render() if msg_prefix: msg_prefix += ": " self.assertEqual( response.status_code, status_code, msg_prefix + "Couldn't retrieve content: Response code was %d" " (expected %d)" % (response.status_code, status_code)) if getattr(response, 'streaming', False): content = b''.join(response.streaming_content) else: content = response.content if not isinstance(text, bytes) or html: text = force_text(text, encoding=response._charset) content = content.decode(response._charset) text_repr = "'%s'" % text else: text_repr = repr(text) if html: content = testcases.assert_and_parse_html( self, content, None, 'Response\'s content is not valid HTML:') text = testcases.assert_and_parse_html( self, text, None, 'Second argument is not valid HTML:') self.assertEqual( content.count(text), 0, msg_prefix + "Response should not contain %s" % text_repr)
def assertHTMLEqual(self, html1, html2, msg=None): """ Clone of django's method, but with support for JSON in data- tag attributes and backwards-compatible support for HTML 5 "required" """ # Add backwards compatibility for HTML 5 "required" REQUIRED = "{{required}}" required = " required " if REQUIRED in html1: html1 = html1.replace(REQUIRED, required) if REQUIRED in html2: html2 = html2.replace(REQUIRED, required) # Parse the HTML into a dom err1 = "First argument is not a valid HTML element:" err2 = "Second argument is not a valid HTML element:" dom1 = testcases.assert_and_parse_html(self, html1, msg, err1) dom2 = testcases.assert_and_parse_html(self, html2, msg, err2) # Check it actually managed to parse something self.assertNotEqual(dom1.name, None, msg="%s\n%s" % (err1, html1)) self.assertNotEqual(dom2.name, None, msg="%s\n%s" % (err2, html2)) # Walk the trees and pull out json dom1, json1 = self._extract_json(dom1) dom2, json2 = self._extract_json(dom2) # Convert dom back to string, call super to test doms # Yes it's inefficient, but it's tests and saves me from forking it super(TagTestManager, self).assertHTMLEqual(str(dom1), str(dom2)) # Test jsons # Assert we've found the same elements self.assertSequenceEqual(json1.keys(), json2.keys()) for dom_path in json1.keys(): # Assert the element has the same attributes self.assertSequenceEqual( json1[dom_path].keys(), json2[dom_path].keys(), msg="%s has attributes do not match: %r != %r" % (dom_path, json1[dom_path].keys(), json2[dom_path].keys()), ) for attr_name in json1[dom_path].keys(): self.assertJSONEqual(json1[dom_path][attr_name], json2[dom_path][attr_name])
def assertHTMLContains(self, text, content, count=None, msg=None): """ Assert that the HTML snippet ``text`` is found within the HTML snippet ``content``. Like assertContains, but works with plain strings instead of Response instances. """ content = assert_and_parse_html( self, content, None, "HTML content to search in is not valid:") text = assert_and_parse_html( self, text, None, "HTML content to search for is not valid:") matches = content.count(text) if count is None: self.assertTrue( matches > 0, msg=msg or 'Could not find HTML snippet') else: self.assertEqual( matches, count, msg=msg or 'Found %d matches, expecting %d' % (matches, count))
def assertTagInTemplateScript(self, needle, haystack, count=None, msg_prefix=''): needle = assert_and_parse_html(self, needle, None, 'First argument is not valid HTML:') haystack = assert_and_parse_html(self, haystack, None, 'Second argument is not valid HTML:') real_count = 0 for script_tag in self._find_template_script_tags(haystack): if script_tag.children: self.assertEqual(len(script_tag.children), 1) script_html = assert_and_parse_html( self, script_tag.children[0], None, 'Script tag content is not valid HTML:' ) real_count += self._count_tag_occurrences(needle, script_html) if count is not None: self.assertEqual( real_count, count, msg_prefix + "Found %d instances of '%s' in template script (expected %d)" % (real_count, needle, count) ) else: self.assertTrue(real_count != 0, msg_prefix + "Couldn't find '%s' in template script" % needle)
def assertInHTML(self, needle, haystack, count=None, msg_prefix=''): """Backport from Django 1.6. """ from django.test.testcases import assert_and_parse_html needle = assert_and_parse_html( self, needle, None, 'First argument is not valid HTML:', ) haystack = assert_and_parse_html( self, haystack, None, 'Second argument is not valid HTML:', ) real_count = haystack.count(needle) if count is not None: self.assertEqual( real_count, count, msg_prefix + "Found %d instances of '%s' in response" " (expected %d)" % (real_count, needle, count), ) else: self.assertTrue( real_count != 0, msg_prefix + "Couldn't find '%s' in response" % needle, )
def assertHTMLEqual(self, html1, html2, msg=None): """ Clone of django's method, but with support for JSON in data- tag attributes and backwards-compatible support for HTML 5 "required" """ # Add backwards compatibility for HTML 5 "required" REQUIRED = "{{required}}" required = "" if django.VERSION >= (1, 10): required = " required " if REQUIRED in html1: html1 = html1.replace(REQUIRED, required) if REQUIRED in html2: html2 = html2.replace(REQUIRED, required) # Parse the HTML into a dom err1 = "First argument is not a valid HTML element:" err2 = "Second argument is not a valid HTML element:" dom1 = testcases.assert_and_parse_html(self, html1, msg, err1) dom2 = testcases.assert_and_parse_html(self, html2, msg, err2) # Check it actually managed to parse something self.assertNotEqual(dom1.name, None, msg="%s\n%s" % (err1, html1)) self.assertNotEqual(dom2.name, None, msg="%s\n%s" % (err2, html2)) # Walk the trees and pull out json dom1, json1 = self._extract_json(dom1) dom2, json2 = self._extract_json(dom2) # Convert dom back to string, call super to test doms # Yes it's inefficient, but it's tests and saves me from forking it super(TagTestManager, self).assertHTMLEqual(six.text_type(dom1), six.text_type(dom2)) # Test jsons # Assert we've found the same elements self.assertSequenceEqual(json1.keys(), json2.keys()) for dom_path in json1.keys(): # Assert the element has the same attributes self.assertSequenceEqual( json1[dom_path].keys(), json2[dom_path].keys(), msg="%s has attributes do not match: %r != %r" % (dom_path, json1[dom_path].keys(), json2[dom_path].keys()), ) for attr_name in json1[dom_path].keys(): # Django 1.4 doesn't support assertJSONEqual # For now, just have a copy of it from 1.5 try: json1_val = json.loads(json1[dom_path][attr_name]) except ValueError: self.fail( "%s %s test result is not valid JSON: %r" % (dom_path, attr_name, json1[dom_path][attr_name])) else: try: json2_val = json.loads(json2[dom_path][attr_name]) except ValueError: self.fail( "%s %s expected is not valid JSON: %r" % (dom_path, attr_name, json2[dom_path][attr_name])) else: self.assertEqual( json1_val, json2_val, msg="%s %s JSON does not match" % (dom_path, attr_name), )
def visit(self, user, url): client = Client() client.login(email=user.email, password='******') resp = client.get(url) dom = assert_and_parse_html(self, resp.content, None, "Invalid HTML") return resp, dom