Skip to content

Commit 6e25361

Browse files
authored
Don't allow for empty 'more information' message (#17990)
1 parent a4d928d commit 6e25361

File tree

5 files changed

+91
-19
lines changed

5 files changed

+91
-19
lines changed

tests/unit/admin/views/test_organizations.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,6 +1074,44 @@ def test_request_more_information_for_not_found(self):
10741074
with pytest.raises(HTTPNotFound):
10751075
views.organization_application_request_more_information(request)
10761076

1077+
@pytest.mark.usefixtures("_enable_organizations")
1078+
def test_request_more_information_no_message(self, db_request):
1079+
admin = UserFactory.create()
1080+
user = UserFactory.create()
1081+
organization_application = OrganizationApplicationFactory.create(
1082+
name="example", submitted_by=user
1083+
)
1084+
1085+
organization_service = pretend.stub(
1086+
get_organization_application=lambda *a, **kw: organization_application,
1087+
request_more_information=pretend.call_recorder(pretend.raiser(ValueError)),
1088+
)
1089+
1090+
db_request.matchdict = {
1091+
"organization_application_id": organization_application.id
1092+
}
1093+
db_request.params = {}
1094+
db_request.user = admin
1095+
db_request.route_path = pretend.call_recorder(_organization_application_routes)
1096+
db_request.find_service = pretend.call_recorder(
1097+
lambda iface, context: organization_service
1098+
)
1099+
db_request.session.flash = pretend.call_recorder(lambda *a, **kw: None)
1100+
1101+
result = views.organization_application_request_more_information(db_request)
1102+
1103+
assert organization_service.request_more_information.calls == [
1104+
pretend.call(organization_application.id, db_request),
1105+
]
1106+
assert db_request.session.flash.calls == [
1107+
pretend.call("No message provided", queue="error"),
1108+
]
1109+
assert result.status_code == 303
1110+
assert (
1111+
result.location
1112+
== f"/admin/organization_applications/{organization_application.id}/"
1113+
)
1114+
10771115
@pytest.mark.usefixtures("_enable_organizations")
10781116
def test_decline(self, db_request):
10791117
admin = UserFactory.create()

tests/unit/organizations/test_services.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ def test_request_more_information_organization_application(
271271

272272
admin = UserFactory(username="admin", is_superuser=True)
273273
db_request.user = admin
274+
db_request.params["message"] = "some message"
274275

275276
organization_application = OrganizationApplicationFactory.create()
276277
organization_service.request_more_information(
@@ -288,10 +289,30 @@ def test_request_more_information_organization_application(
288289
organization_application.submitted_by,
289290
organization_name=organization_application.name,
290291
organization_application_id=organization_application.id,
291-
message="",
292+
message="some message",
292293
),
293294
]
294295

296+
def test_request_more_information_organization_application_no_message(
297+
self, db_request, organization_service, monkeypatch
298+
):
299+
send_email = pretend.call_recorder(lambda *a, **kw: None)
300+
monkeypatch.setattr(
301+
services, "send_new_organization_moreinformationneeded_email", send_email
302+
)
303+
304+
admin = UserFactory(username="admin", is_superuser=True)
305+
db_request.user = admin
306+
307+
organization_application = OrganizationApplicationFactory.create()
308+
with pytest.raises(ValueError): # noqa
309+
organization_service.request_more_information(
310+
organization_application.id, db_request
311+
)
312+
313+
assert len(organization_application.observations) == 0
314+
assert send_email.calls == []
315+
295316
def test_decline_organization_application(
296317
self, db_request, organization_service, monkeypatch
297318
):

warehouse/admin/static/js/warehouse.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -275,22 +275,28 @@ $(document).ready(function() {
275275
document.onkeyup = function(){};
276276
}
277277
function hotKeys(e) {
278-
console.log(e);
279278
if (keyBindings.has(String(e.which))) {
280279
unbindHotKeys();
281-
$(keyBindings.get(String(e.which))).modal("show");
282-
$(keyBindings.get(String(e.which))).on("hidden.bs.modal", bindHotKeys);
280+
const targetModal = $(keyBindings.get(String(e.which)));
281+
targetModal.one("shown.bs.modal", function () {
282+
const firstFocusableElement = $(this).find("input:visible, textarea:visible").first();
283+
if (firstFocusableElement.length) {
284+
firstFocusableElement.focus();
285+
}
286+
});
287+
targetModal.modal("show");
288+
targetModal.on("hidden.bs.modal", bindHotKeys);
283289
}
284290
}
285291
modalHotKeyBindings.forEach(function(modalHotKeyBinding) {
286292
if (! modalHotKeyBinding.disabled) {
287293
keyBindings.set(modalHotKeyBinding.dataset.hotkeyBinding, modalHotKeyBinding.dataset.target);
288294
}
289295
});
290-
const inputs = document.querySelectorAll("input");
291-
inputs.forEach(function(input) {
292-
input.addEventListener("focusin", unbindHotKeys);
293-
input.addEventListener("focusout", bindHotKeys);
296+
const focusable = document.querySelectorAll("input, textarea");
297+
focusable.forEach(function(element) {
298+
element.addEventListener("focusin", unbindHotKeys);
299+
element.addEventListener("focusout", bindHotKeys);
294300
});
295301
bindHotKeys();
296302
});

warehouse/admin/views/organizations.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -470,18 +470,22 @@ def organization_application_request_more_information(request):
470470
if organization_application is None:
471471
raise HTTPNotFound
472472

473-
organization_service.request_more_information(organization_application.id, request)
474-
475-
request.session.flash(
476-
(
477-
f'Request for more info from "{organization_application.name}" '
478-
"organization sent"
479-
),
480-
queue="success",
481-
)
473+
try:
474+
organization_service.request_more_information(
475+
organization_application.id, request
476+
)
477+
request.session.flash(
478+
(
479+
f'Request for more info from "{organization_application.name}" '
480+
"organization sent"
481+
),
482+
queue="success",
483+
)
482484

483-
if request.params.get("organization_applications_turbo_mode") == "true":
484-
return _turbo_mode(request)
485+
if request.params.get("organization_applications_turbo_mode") == "true":
486+
return _turbo_mode(request)
487+
except ValueError:
488+
request.session.flash("No message provided", queue="error")
485489

486490
return HTTPSeeOther(
487491
request.route_path(

warehouse/organizations/services.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ def request_more_information(self, organization_application_id, request):
270270

271271
message = request.params.get("message", "")
272272

273+
if not message:
274+
raise ValueError
275+
273276
organization_application.record_observation(
274277
request=request,
275278
actor=request.user,

0 commit comments

Comments
 (0)