123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- from django.core.exceptions import PermissionDenied
- from django.test import TestCase
- from django.test.client import RequestFactory
- from django.urls import reverse
- from misago.core.utils import (
- clean_ids_list,
- clean_return_path,
- format_plaintext_for_html,
- get_exception_message,
- get_host_from_address,
- is_referer_local,
- is_request_to_misago,
- parse_iso8601_string,
- slugify,
- )
- class IsRequestToMisagoTests(TestCase):
- def test_is_request_to_misago(self):
- """
- is_request_to_misago correctly detects requests directed at Misago
- """
- VALID_PATHS = ("/", "/threads/")
- INVALID_PATHS = ("", "somewhere/")
- misago_prefix = reverse("misago:index")
- for path in VALID_PATHS:
- request = RequestFactory().get("/")
- request.path = path
- self.assertTrue(
- is_request_to_misago(request),
- '"%s" is not overlapped by "%s"' % (path, misago_prefix),
- )
- for path in INVALID_PATHS:
- request = RequestFactory().get("/")
- request.path = path
- self.assertFalse(
- is_request_to_misago(request),
- '"%s" is overlapped by "%s"' % (path, misago_prefix),
- )
- class SlugifyTests(TestCase):
- def test_valid_slugify_output(self):
- """Misago's slugify correctly slugifies string"""
- test_cases = [
- ("User", "user"),
- ("Eric The Fish", "eric-the-fish"),
- ("John Snow", "john-snow"),
- ("J0n", "j0n"),
- ("An###ne", "anne"),
- ("S**t", "st"),
- ("Łók", "lok"),
- ]
- for original, slug in test_cases:
- self.assertEqual(slugify(original), slug)
- class ParseIso8601StringTests(TestCase):
- def test_valid_input(self):
- """util parses iso 8601 strings"""
- INPUTS = [
- "2016-10-22T20:55:39.185085Z",
- "2016-10-22T20:55:39.185085-01:00",
- "2016-10-22T20:55:39-01:00",
- "2016-10-22T20:55:39.185085+01:00",
- ]
- for test_input in INPUTS:
- self.assertTrue(parse_iso8601_string(test_input))
- def test_invalid_input(self):
- """util throws ValueError on invalid input"""
- INPUTS = [
- "",
- "2016-10-22",
- "2016-10-22T30:55:39.185085+11:00",
- "2016-10-22T20:55:39.18SSSSS5085Z",
- ]
- for test_input in INPUTS:
- with self.assertRaises(ValueError):
- self.assertTrue(parse_iso8601_string(test_input))
- PLAINTEXT_FORMAT_CASES = [
- ("Lorem ipsum.", "<p>Lorem ipsum.</p>"),
- ("Lorem <b>ipsum</b>.", "<p>Lorem <b>ipsum</b>.</p>"),
- ('Lorem "ipsum" dolor met.', "<p>Lorem "ipsum" dolor met.</p>"),
- ("Lorem ipsum.\nDolor met.", "<p>Lorem ipsum.<br />Dolor met.</p>"),
- ("Lorem ipsum.\n\nDolor met.", "<p>Lorem ipsum.</p>\n\n<p>Dolor met.</p>"),
- (
- "http://misago-project.org/login/",
- '<p><a href="http://misago-project.org/login/">http://misago-project.org/login/</a></p>',
- ),
- ]
- class FormatPlaintextForHtmlTests(TestCase):
- def test_format_plaintext_for_html(self):
- """format_plaintext_for_html correctly formats plaintext for html"""
- for plaintext, html in PLAINTEXT_FORMAT_CASES:
- output = format_plaintext_for_html(plaintext)
- assertion_message = """
- format_plaintext_for_html failed to produce expected output:
- expected: %s
- return: %s
- """ % (
- html,
- output,
- )
- self.assertEqual(output, html, assertion_message)
- class MockRequest(object):
- scheme = "http"
- def __init__(self, method, meta=None, post=None):
- self.method = method
- self.META = meta or {}
- self.POST = post or {}
- class CleanReturnPathTests(TestCase):
- def test_get_request(self):
- """clean_return_path works for GET requests"""
- bad_request = MockRequest(
- "GET",
- {"HTTP_REFERER": "http://cookies.com", "HTTP_HOST": "misago-project.org"},
- )
- self.assertIsNone(clean_return_path(bad_request))
- bad_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "https://misago-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertIsNone(clean_return_path(bad_request))
- bad_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "https://misago-project.org/",
- "HTTP_HOST": "misago-project.org/assadsa/",
- },
- )
- self.assertIsNone(clean_return_path(bad_request))
- ok_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "http://misago-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertEqual(clean_return_path(ok_request), "/")
- ok_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "http://misago-project.org/login/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertEqual(clean_return_path(ok_request), "/login/")
- def test_post_request(self):
- """clean_return_path works for POST requests"""
- bad_request = MockRequest(
- "POST",
- {
- "HTTP_REFERER": "http://misago-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- {"return_path": "/sdasdsa/"},
- )
- self.assertIsNone(clean_return_path(bad_request))
- ok_request = MockRequest(
- "POST",
- {
- "HTTP_REFERER": "http://misago-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- {"return_path": "/login/"},
- )
- self.assertEqual(clean_return_path(ok_request), "/login/")
- class IsRefererLocalTests(TestCase):
- def test_local_referers(self):
- """local referers return true"""
- ok_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "http://misago-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertTrue(is_referer_local(ok_request))
- ok_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "http://misago-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertTrue(is_referer_local(ok_request))
- ok_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "http://misago-project.org/login/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertTrue(is_referer_local(ok_request))
- def test_foreign_referers(self):
- """non-local referers return false"""
- bad_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "http://else-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertFalse(is_referer_local(bad_request))
- bad_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "https://misago-project.org/",
- "HTTP_HOST": "misago-project.org/",
- },
- )
- self.assertFalse(is_referer_local(bad_request))
- bad_request = MockRequest(
- "GET",
- {
- "HTTP_REFERER": "http://misago-project.org/",
- "HTTP_HOST": "misago-project.org/assadsa/",
- },
- )
- self.assertFalse(is_referer_local(bad_request))
- class GetExceptionMessageTests(TestCase):
- def test_no_args(self):
- """both of helper args are optional"""
- message = get_exception_message()
- self.assertIsNone(message)
- def test_no_default_message(self):
- """helper's default message arg is optional"""
- message = get_exception_message(PermissionDenied("Lorem Ipsum"))
- self.assertEqual(message, "Lorem Ipsum")
- message = get_exception_message(PermissionDenied())
- self.assertIsNone(message)
- def test_default_message(self):
- """helper's default message arg is used"""
- message = get_exception_message(PermissionDenied("Lorem Ipsum"), "Default")
- self.assertEqual(message, "Lorem Ipsum")
- message = get_exception_message(PermissionDenied(), "Default")
- self.assertEqual(message, "Default")
- message = get_exception_message(default_message="Lorem Ipsum")
- self.assertEqual(message, "Lorem Ipsum")
- class CleanIdsListTests(TestCase):
- def test_valid_list(self):
- """list of valid ids is cleaned"""
- self.assertEqual(clean_ids_list(["1", 3, "42"], None), [1, 3, 42])
- def test_empty_list(self):
- """empty list passes validation"""
- self.assertEqual(clean_ids_list([], None), [])
- def test_string_list(self):
- """string list passes validation"""
- self.assertEqual(clean_ids_list("1234", None), [1, 2, 3, 4])
- def test_message(self):
- """utility uses passed message for exception"""
- with self.assertRaisesMessage(PermissionDenied, "Test error message!"):
- clean_ids_list(None, "Test error message!")
- def test_invalid_inputs(self):
- """utility raises exception for invalid inputs"""
- INVALID_INPUTS = (
- None,
- "abc",
- [None],
- [1, 2, "a", 4],
- [1, None, 3],
- {1: 2, "a": 4},
- )
- for invalid_input in INVALID_INPUTS:
- with self.assertRaisesMessage(PermissionDenied, "Test error message!"):
- clean_ids_list(invalid_input, "Test error message!")
- class GetHostFromAddressTests(TestCase):
- def test_none(self):
- """get_host_from_address returns None for None"""
- result = get_host_from_address(None)
- self.assertIsNone(result)
- def test_empty_string(self):
- """get_host_from_address returns None for empty string"""
- result = get_host_from_address("")
- self.assertIsNone(result)
- def test_hostname(self):
- """get_host_from_address returns hostname unchanged"""
- result = get_host_from_address("hostname")
- self.assertEqual(result, "hostname")
- def test_hostname_with_trailing_slash(self):
- """get_host_from_address returns hostname for hostname with trailing slash"""
- result = get_host_from_address("//hostname")
- self.assertEqual(result, "hostname")
- def test_hostname_with_port(self):
- """get_host_from_address returns hostname for hostname with port"""
- result = get_host_from_address("hostname:8888")
- self.assertEqual(result, "hostname")
- def test_hostname_with_port_path_and_protocol(self):
- """get_host_from_address returns hostname for hostname with port and path"""
- result = get_host_from_address("https://hostname:8888/somewhere/else/")
- self.assertEqual(result, "hostname")
|