|
3 | 3 | from werkzeug.test import Client |
4 | 4 | from django.contrib.auth.models import User |
5 | 5 | from django.core.management import execute_from_command_line |
6 | | -from django.db.utils import OperationalError |
| 6 | +from django.db.utils import OperationalError, ProgrammingError, DataError |
7 | 7 |
|
8 | 8 |
|
9 | 9 | try: |
@@ -186,49 +186,95 @@ def test_sql_queries(sentry_init, capture_events): |
186 | 186 | @pytest.mark.django_db |
187 | 187 | def test_sql_dict_query_params(sentry_init, capture_events): |
188 | 188 | sentry_init(integrations=[DjangoIntegration()], send_default_pii=True) |
189 | | - from django.db import connection |
190 | 189 |
|
191 | | - sql = connection.cursor() |
| 190 | + from django.db import connections |
| 191 | + |
| 192 | + if "postgres" not in connections: |
| 193 | + pytest.skip("postgres tests disabled") |
| 194 | + |
| 195 | + sql = connections["postgres"].cursor() |
192 | 196 |
|
193 | 197 | events = capture_events() |
194 | | - with pytest.raises(OperationalError): |
195 | | - # This really only works with postgres. sqlite will crash with syntax error |
| 198 | + with pytest.raises(ProgrammingError): |
196 | 199 | sql.execute( |
197 | 200 | """SELECT count(*) FROM people_person WHERE foo = %(my_foo)s""", |
198 | 201 | {"my_foo": 10}, |
199 | 202 | ) |
200 | 203 |
|
201 | 204 | capture_message("HI") |
202 | | - |
203 | 205 | event, = events |
204 | 206 |
|
205 | 207 | crumb, = event["breadcrumbs"] |
206 | 208 | assert crumb["message"] == ("SELECT count(*) FROM people_person WHERE foo = 10") |
207 | 209 |
|
208 | 210 |
|
| 211 | +@pytest.mark.parametrize( |
| 212 | + "query", |
| 213 | + [ |
| 214 | + lambda sql: sql.SQL("SELECT %(my_param)s FROM {mytable}").format( |
| 215 | + mytable=sql.Identifier("foobar") |
| 216 | + ), |
| 217 | + lambda sql: sql.SQL('SELECT %(my_param)s FROM "foobar"'), |
| 218 | + ], |
| 219 | +) |
209 | 220 | @pytest.mark.django_db |
210 | | -def test_sql_psycopg2_string_composition(sentry_init, capture_events): |
| 221 | +def test_sql_psycopg2_string_composition(sentry_init, capture_events, query): |
211 | 222 | sentry_init(integrations=[DjangoIntegration()], send_default_pii=True) |
212 | | - from django.db import connection |
| 223 | + from django.db import connections |
213 | 224 |
|
214 | | - psycopg2 = pytest.importorskip("psycopg2") |
215 | | - psycopg2_sql = psycopg2.sql |
| 225 | + if "postgres" not in connections: |
| 226 | + pytest.skip("postgres tests disabled") |
216 | 227 |
|
217 | | - sql = connection.cursor() |
| 228 | + import psycopg2 |
| 229 | + |
| 230 | + sql = connections["postgres"].cursor() |
218 | 231 |
|
219 | 232 | events = capture_events() |
220 | | - with pytest.raises(TypeError): |
221 | | - # crashes because we use sqlite |
222 | | - sql.execute( |
223 | | - psycopg2_sql.SQL("SELECT %(my_param)s FROM people_person"), {"my_param": 10} |
224 | | - ) |
| 233 | + with pytest.raises(ProgrammingError): |
| 234 | + sql.execute(query(psycopg2.sql), {"my_param": 10}) |
225 | 235 |
|
226 | 236 | capture_message("HI") |
227 | 237 |
|
228 | 238 | event, = events |
229 | | - |
230 | 239 | crumb, = event["breadcrumbs"] |
231 | | - assert crumb["message"] == ("SELECT 10 FROM people_person") |
| 240 | + assert crumb["message"] == ('SELECT 10 FROM "foobar"') |
| 241 | + |
| 242 | + |
| 243 | +@pytest.mark.django_db |
| 244 | +def test_sql_psycopg2_placeholders(sentry_init, capture_events): |
| 245 | + sentry_init(integrations=[DjangoIntegration()], send_default_pii=True) |
| 246 | + from django.db import connections |
| 247 | + |
| 248 | + if "postgres" not in connections: |
| 249 | + pytest.skip("postgres tests disabled") |
| 250 | + |
| 251 | + import psycopg2 |
| 252 | + |
| 253 | + sql = connections["postgres"].cursor() |
| 254 | + |
| 255 | + events = capture_events() |
| 256 | + with pytest.raises(DataError): |
| 257 | + names = ["foo", "bar"] |
| 258 | + identifiers = [psycopg2.sql.Identifier(name) for name in names] |
| 259 | + placeholders = [ |
| 260 | + psycopg2.sql.Placeholder(var) for var in ["first_var", "second_var"] |
| 261 | + ] |
| 262 | + sql.execute("create table my_test_table (foo text, bar date)") |
| 263 | + |
| 264 | + query = psycopg2.sql.SQL("insert into my_test_table ({}) values ({})").format( |
| 265 | + psycopg2.sql.SQL(", ").join(identifiers), |
| 266 | + psycopg2.sql.SQL(", ").join(placeholders), |
| 267 | + ) |
| 268 | + sql.execute(query, {"first_var": "fizz", "second_var": "not a date"}) |
| 269 | + |
| 270 | + capture_message("HI") |
| 271 | + |
| 272 | + event, = events |
| 273 | + crumb1, crumb2 = event["breadcrumbs"] |
| 274 | + assert crumb1["message"] == ("create table my_test_table (foo text, bar date)") |
| 275 | + assert crumb2["message"] == ( |
| 276 | + """insert into my_test_table ("foo", "bar") values ('fizz', 'not a date')""" |
| 277 | + ) |
232 | 278 |
|
233 | 279 |
|
234 | 280 | @pytest.mark.django_db |
|
0 commit comments