File: test_transactions.py

package info (click to toggle)
sentry-python 2.18.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,004 kB
  • sloc: python: 55,908; makefile: 114; sh: 111; xml: 2
file content (153 lines) | stat: -rw-r--r-- 5,022 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from unittest import mock

import pytest
import django
from django.utils.translation import pgettext_lazy


# django<2.0 has only `url` with regex based patterns.
# django>=2.0 renames `url` to `re_path`, and additionally introduces `path`
# for new style URL patterns, e.g. <int:article_id>.
if django.VERSION >= (2, 0):
    from django.urls import path, re_path
    from django.urls.converters import PathConverter
    from django.conf.urls import include
else:
    from django.conf.urls import url as re_path, include

if django.VERSION < (1, 9):
    included_url_conf = (re_path(r"^foo/bar/(?P<param>[\w]+)", lambda x: ""),), "", ""
else:
    included_url_conf = ((re_path(r"^foo/bar/(?P<param>[\w]+)", lambda x: ""),), "")

from sentry_sdk.integrations.django.transactions import RavenResolver


example_url_conf = (
    re_path(r"^api/(?P<project_id>[\w_-]+)/store/$", lambda x: ""),
    re_path(r"^api/(?P<version>(v1|v2))/author/$", lambda x: ""),
    re_path(
        r"^api/(?P<project_id>[^\/]+)/product/(?P<pid>(?:\d+|[A-Fa-f0-9-]{32,36}))/$",
        lambda x: "",
    ),
    re_path(r"^report/", lambda x: ""),
    re_path(r"^example/", include(included_url_conf)),
)


def test_resolver_no_match():
    resolver = RavenResolver()
    result = resolver.resolve("/foo/bar", example_url_conf)
    assert result is None


def test_resolver_re_path_complex_match():
    resolver = RavenResolver()
    result = resolver.resolve("/api/1234/store/", example_url_conf)
    assert result == "/api/{project_id}/store/"


def test_resolver_re_path_complex_either_match():
    resolver = RavenResolver()
    result = resolver.resolve("/api/v1/author/", example_url_conf)
    assert result == "/api/{version}/author/"
    result = resolver.resolve("/api/v2/author/", example_url_conf)
    assert result == "/api/{version}/author/"


def test_resolver_re_path_included_match():
    resolver = RavenResolver()
    result = resolver.resolve("/example/foo/bar/baz", example_url_conf)
    assert result == "/example/foo/bar/{param}"


def test_resolver_re_path_multiple_groups():
    resolver = RavenResolver()
    result = resolver.resolve(
        "/api/myproject/product/cb4ef1caf3554c34ae134f3c1b3d605f/", example_url_conf
    )
    assert result == "/api/{project_id}/product/{pid}/"


@pytest.mark.skipif(
    django.VERSION < (2, 0),
    reason="Django>=2.0 required for <converter:parameter> patterns",
)
def test_resolver_path_group():
    url_conf = (path("api/v2/<int:project_id>/store/", lambda x: ""),)
    resolver = RavenResolver()
    result = resolver.resolve("/api/v2/1234/store/", url_conf)
    assert result == "/api/v2/{project_id}/store/"


@pytest.mark.skipif(
    django.VERSION < (2, 0),
    reason="Django>=2.0 required for <converter:parameter> patterns",
)
def test_resolver_path_multiple_groups():
    url_conf = (path("api/v2/<str:project_id>/product/<int:pid>", lambda x: ""),)
    resolver = RavenResolver()
    result = resolver.resolve("/api/v2/myproject/product/5689", url_conf)
    assert result == "/api/v2/{project_id}/product/{pid}"


@pytest.mark.skipif(
    django.VERSION < (2, 0),
    reason="Django>=2.0 required for <converter:parameter> patterns",
)
@pytest.mark.skipif(
    django.VERSION > (5, 1),
    reason="get_converter removed in 5.1",
)
def test_resolver_path_complex_path_legacy():
    class CustomPathConverter(PathConverter):
        regex = r"[^/]+(/[^/]+){0,2}"

    with mock.patch(
        "django.urls.resolvers.get_converter",
        return_value=CustomPathConverter,
    ):
        url_conf = (path("api/v3/<custom_path:my_path>", lambda x: ""),)
        resolver = RavenResolver()
        result = resolver.resolve("/api/v3/abc/def/ghi", url_conf)
        assert result == "/api/v3/{my_path}"


@pytest.mark.skipif(
    django.VERSION < (5, 1),
    reason="get_converters is used in 5.1",
)
def test_resolver_path_complex_path():
    class CustomPathConverter(PathConverter):
        regex = r"[^/]+(/[^/]+){0,2}"

    with mock.patch(
        "django.urls.resolvers.get_converters",
        return_value={"custom_path": CustomPathConverter},
    ):
        url_conf = (path("api/v3/<custom_path:my_path>", lambda x: ""),)
        resolver = RavenResolver()
        result = resolver.resolve("/api/v3/abc/def/ghi", url_conf)
        assert result == "/api/v3/{my_path}"


@pytest.mark.skipif(
    django.VERSION < (2, 0),
    reason="Django>=2.0 required for <converter:parameter> patterns",
)
def test_resolver_path_no_converter():
    url_conf = (path("api/v4/<project_id>", lambda x: ""),)
    resolver = RavenResolver()
    result = resolver.resolve("/api/v4/myproject", url_conf)
    assert result == "/api/v4/{project_id}"


@pytest.mark.skipif(
    django.VERSION < (2, 0),
    reason="Django>=2.0 required for path patterns",
)
def test_resolver_path_with_i18n():
    url_conf = (path(pgettext_lazy("url", "pgettext"), lambda x: ""),)
    resolver = RavenResolver()
    result = resolver.resolve("/pgettext", url_conf)
    assert result == "/pgettext"