Skip to content

Commit 87fc606

Browse files
committed
fix(app):Added mow to pacer_to_cl_ids and implemented a logger to detect similar issues
Fixes:
1 parent 977ad23 commit 87fc606

File tree

7 files changed

+107
-7
lines changed

7 files changed

+107
-7
lines changed

.pre-commit-config.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@ repos:
2121
args: [--markdown-linebreak-ext=md]
2222

2323
- repo: https://github.com/ikamensh/flynt/
24-
rev: '0.76'
24+
rev: '1.0.1'
2525
hooks:
2626
- id: flynt
2727
args: [--line-length=79, --transform-concats]
2828

2929
- repo: https://github.com/psf/black
30-
rev: 21.12b0
30+
rev: 25.1.0
3131
hooks:
3232
- id: black
3333

3434
- repo: https://github.com/PyCQA/isort
35-
rev: 5.10.1
35+
rev: 6.0.0
3636
hooks:
3737
- id: isort
3838
name: isort (python)

cl/events/pacer-2.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@
161161
}
162162
],
163163
"commonHeaders": {
164-
"returnPath": "buttons@whlawpartners.com",
164+
"returnPath": "ecfMOW.notification@mow.uscourts.gov",
165165
"from": [
166-
"Buttons McGee <buttons@whlawpartners.com>"
166+
"<ecfMOW.notification@mow.uscourts.gov>"
167167
],
168168
"date": "Mon, 28 Jun 2021 13:51:08 -0500",
169169
"to": [

cl/recap_email/app/app.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import os
3+
import re
34
import sys
45

56
import requests
@@ -139,6 +140,22 @@ def get_cl_court_id(email):
139140
return map_pacer_to_cl_id(sub_domain)
140141

141142

143+
def log_invalid_court_error(response):
144+
"""Checks if the response indicates an invalid court pk then send a report
145+
to Sentry.
146+
"""
147+
if response.status_code != 400:
148+
return
149+
150+
for msg in response.json().get("court", []):
151+
if "Invalid pk" in msg:
152+
match = re.search(r'Invalid pk "([^"]+)"', msg)
153+
if match:
154+
error_message = f"Invalid court pk: {match.group(1)}"
155+
sentry_sdk.capture_message(error_message, level="error")
156+
break
157+
158+
142159
@retry(
143160
(RequestsConnectionError, HTTPError, Timeout),
144161
tries=5,
@@ -161,7 +178,7 @@ def send_to_court_listener(email, receipt):
161178
timeout=5,
162179
headers={
163180
"Content-Type": "application/json",
164-
"Authorization": "Token " + os.getenv("AUTH_TOKEN"),
181+
"Authorization": f"Token {os.getenv('AUTH_TOKEN')}",
165182
},
166183
)
167184

@@ -170,6 +187,8 @@ def send_to_court_listener(email, receipt):
170187
# Gateway Timeout status codes.
171188
court_listener_response.raise_for_status()
172189

190+
log_invalid_court_error(court_listener_response)
191+
173192
print(
174193
f"Got {court_listener_response.status_code=} and content "
175194
f"{court_listener_response.json()=}"

cl/recap_email/app/pacer.py

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"neb": "nebraskab", # Nebraska Bankruptcy
66
"nysb-mega": "nysb", # Remove the mega thing
77
"txs": "txsd", # Southern District Of Texas
8+
"mow": "mowd", # Western District of Missouri
89
}
910

1011
# Reverse dict of pacer_to_cl_ids

cl/tests/unit/test_recap_email_handler.py

+71
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import requests # noqa: F401
88
import requests_mock # noqa: F401
99
from recap_email.app import app # pylint: disable=import-error
10+
from recap_email.app.pacer import pacer_to_cl_ids
11+
from tests.unit.utils import MockResponse
1012

1113

1214
@pytest.fixture()
@@ -112,6 +114,17 @@ def test_multiple_domains_success():
112114
assert app.check_valid_domain(email) == 1
113115

114116

117+
def test_get_cl_court_id_using_mapping():
118+
for pacer_id, expected_cl in pacer_to_cl_ids.items():
119+
email = {
120+
"common_headers": {"from": [f"ecfnotices@{pacer_id}.uscourts.gov"]}
121+
}
122+
result = app.get_cl_court_id(email)
123+
assert (
124+
result == expected_cl
125+
), f"For PACER id '{pacer_id}', expected CL id '{expected_cl}' but got '{result}'."
126+
127+
115128
@pytest.fixture()
116129
def valid_domain_failure_ses_event():
117130
with open("./events/ses-valid-domain-failure.json") as file:
@@ -208,3 +221,61 @@ def test_success(
208221
assert response["statusCode"] == 200
209222
assert "mail" in data
210223
assert "receipt" in data
224+
225+
226+
@mock.patch.dict(
227+
os.environ,
228+
{
229+
"RECAP_EMAIL_ENDPOINT": "http://host.docker.internal:8000/api/rest/v3/recap-email/",
230+
"AUTH_TOKEN": "************************",
231+
},
232+
)
233+
def test_request_court_field_actual_value(pacer_event_two, requests_mock):
234+
"""Confirm that the court_id in the request uses the right value
235+
from map_pacer_to_cl_id"""
236+
requests_mock.post(
237+
"http://host.docker.internal:8000/api/rest/v3/recap-email/",
238+
json={"mail": {}, "receipt": {}},
239+
)
240+
241+
response = app.handler(pacer_event_two, "")
242+
assert response["statusCode"] == 200
243+
244+
# Retrieve the request that made by send_to_court_listener
245+
request = requests_mock.request_history[0]
246+
body = json.loads(request.body)
247+
assert (
248+
body.get("court") == "mowd"
249+
), f"Expected 'mowd', but got '{body.get('court')}'"
250+
251+
252+
@mock.patch.dict(
253+
os.environ,
254+
{
255+
"RECAP_EMAIL_ENDPOINT": "http://host.docker.internal:8000/api/rest/v3/recap-email/",
256+
"AUTH_TOKEN": "************************",
257+
},
258+
)
259+
def test_report_request_for_invalid_court(pacer_event_one, requests_mock):
260+
"""Confirm that if an invalid court_id is sent to CL, an error event is
261+
sent to Sentry."""
262+
263+
mock_response = MockResponse(
264+
400, {"court": ['Invalid pk "whla" - object does not exist.']}
265+
)
266+
with (
267+
mock.patch(
268+
"recap_email.app.app.requests.post", return_value=mock_response
269+
),
270+
mock.patch(
271+
"recap_email.app.app.sentry_sdk.capture_message"
272+
) as mock_sentry_capture,
273+
):
274+
requests_mock.post(
275+
"http://host.docker.internal:8000/api/rest/v3/recap-email/",
276+
json={"mail": {}, "receipt": {}},
277+
)
278+
app.handler(pacer_event_one, "")
279+
# The expected error message should be sent to Sentry.
280+
expected_error = "Invalid court pk: whla"
281+
mock_sentry_capture.assert_called_with(expected_error, level="error")

cl/tests/unit/utils.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
3+
class MockResponse:
4+
def __init__(self, status_code, json_data):
5+
self.status_code = status_code
6+
self._json_data = json_data
7+
8+
def json(self):
9+
return self._json_data

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
pre-commit==2.17.0
1+
pre-commit==4.1.0

0 commit comments

Comments
 (0)