• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

grafana / django-saml2-auth / 8878582181

29 Apr 2024 12:31PM UTC coverage: 90.335%. Remained the same
8878582181

Pull #288

github

web-flow
Merge 352170942 into b19971183
Pull Request #288: Bump interrogate from 1.5.0 to 1.7.0

916 of 1014 relevant lines covered (90.34%)

6.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.33
/django_saml2_auth/tests/test_utils.py
1
"""
7✔
2
Tests for utils.py
3
"""
4

5
import pytest
7✔
6
from django.http import HttpRequest, HttpResponse
7✔
7
from django.urls import NoReverseMatch
7✔
8
from django_saml2_auth.exceptions import SAMLAuthError
7✔
9
from django_saml2_auth.utils import exception_handler, get_reverse, run_hook, is_jwt_well_formed
7✔
10

11

12
def divide(a: int, b: int = 1) -> int:
7✔
13
    """Simple division function for testing run_hook
14

15
    Args:
16
        a (int): Dividend
17
        b (int, optional): Divisor. Defaults to 1.
18

19
    Returns:
20
        int: Quotient
21
    """
22
    return int(a / b)
7✔
23

24

25
def hello(_: HttpRequest) -> HttpResponse:
7✔
26
    """Simple view function for testing exception_handler
27

28
    Args:
29
        _ (HttpRequest): Incoming HTTP request (not used)
30

31
    Returns:
32
        HttpResponse: Outgoing HTTP response
33
    """
34
    return HttpResponse(content="Hello, world!")
7✔
35

36

37
def goodbye(_: HttpRequest) -> None:
7✔
38
    """Simple view function for testing exception_handler
39

40
    Args:
41
        _ (HttpRequest): Incoming HTTP request (not used)
42

43
    Raises:
44
        SAMLAuthError: Goodbye, world!
45
    """
46
    raise SAMLAuthError(
7✔
47
        "Goodbye, world!",
48
        extra={
49
            "exc": RuntimeError("World not found!"),
50
            "exc_type": RuntimeError,
51
            "error_code": 0,
52
            "reason": "Internal world error!",
53
            "status_code": 500,
54
        },
55
    )
56

57

58
def test_run_hook_success():
7✔
59
    """Test run_hook function against divide function imported from current module."""
60
    result = run_hook("django_saml2_auth.tests.test_utils.divide", 2, b=2)
7✔
61
    assert result == 1
7✔
62

63

64
def test_run_hook_no_function_path():
7✔
65
    """Test run_hook function by passing invalid function path and checking if it raises."""
66
    with pytest.raises(SAMLAuthError) as exc_info:
7✔
67
        run_hook("")
7✔
68
        run_hook(None)
×
69

70
    assert str(exc_info.value) == "function_path isn't specified"
7✔
71

72

73
def test_run_hook_nothing_to_import():
7✔
74
    """Test run_hook function by passing function name only (no path) and checking if it raises."""
75
    with pytest.raises(SAMLAuthError) as exc_info:
7✔
76
        run_hook("divide")
7✔
77

78
    assert str(exc_info.value) == "There's nothing to import. Check your hook's import path!"
7✔
79

80

81
def test_run_hook_import_error():
7✔
82
    """Test run_hook function by passing correct path, but nonexistent function and
83
    checking if it raises."""
84
    with pytest.raises(SAMLAuthError) as exc_info:
7✔
85
        run_hook("django_saml2_auth.tests.test_utils.nonexistent_divide", 2, b=2)
7✔
86

87
    assert str(exc_info.value) == (
7✔
88
        "module 'django_saml2_auth.tests.test_utils' has no attribute 'nonexistent_divide'"
89
    )
90
    assert isinstance(exc_info.value.extra["exc"], AttributeError)
7✔
91
    assert exc_info.value.extra["exc_type"] == AttributeError
7✔
92

93

94
def test_run_hook_division_by_zero():
7✔
95
    """Test function imported by run_hook to verify if run_hook correctly captures the exception."""
96
    with pytest.raises(SAMLAuthError) as exc_info:
7✔
97
        run_hook("django_saml2_auth.tests.test_utils.divide", 2, b=0)
7✔
98

99
    assert str(exc_info.value) == "division by zero"
7✔
100
    # Actually a ZeroDivisionError wrapped in SAMLAuthError
101
    assert isinstance(exc_info.value.extra["exc"], ZeroDivisionError)
7✔
102
    assert exc_info.value.extra["exc_type"] == ZeroDivisionError
7✔
103

104

105
def test_get_reverse_success():
7✔
106
    """Test get_reverse with existing view."""
107
    result = get_reverse("acs")
7✔
108
    assert result == "/acs/"
7✔
109

110

111
def test_get_reverse_no_reverse_match():
7✔
112
    """Test get_reverse with nonexistent view."""
113
    with pytest.raises(SAMLAuthError) as exc_info:
7✔
114
        get_reverse("nonexistent_view")
7✔
115

116
    assert str(exc_info.value) == "We got a URL reverse issue: ['nonexistent_view']"
7✔
117
    assert issubclass(exc_info.value.extra["exc_type"], NoReverseMatch)
7✔
118

119

120
def test_exception_handler_success():
7✔
121
    """Test exception_handler decorator with a normal view function that returns response."""
122
    decorated_hello = exception_handler(hello)
7✔
123
    result = decorated_hello(HttpRequest())
7✔
124
    assert result.content.decode("utf-8") == "Hello, world!"
7✔
125

126

127
def test_exception_handler_handle_exception():
7✔
128
    """Test exception_handler decorator with a view function that raises exception and see if the
129
    exception_handler catches and returns the correct errors response."""
130
    decorated_goodbye = exception_handler(goodbye)
7✔
131
    result = decorated_goodbye(HttpRequest())
7✔
132
    contents = result.content.decode("utf-8")
7✔
133
    assert result.status_code == 500
7✔
134
    assert "Reason: Internal world error!" in contents
7✔
135

136

137
def test_jwt_well_formed():
7✔
138
    """Test if passed RelayState is a well formed JWT"""
139
    token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MjQyIiwibmFtZSI6Ikplc3NpY2EgVGVtcG9yYWwiLCJuaWNrbmFtZSI6Ikplc3MifQ.EDkUUxaM439gWLsQ8a8mJWIvQtgZe0et3O3z4Fd_J8o"  # noqa
7✔
140
    res = is_jwt_well_formed(token)  # True
7✔
141
    assert res is True
7✔
142
    res = is_jwt_well_formed("/")  # False
7✔
143
    assert res is False
7✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc