Skip to content

Commit

Permalink
Modify release files button based on uploading status
Browse files Browse the repository at this point in the history
Modify the label, enabled state, and tooltip for the "release
files" button based on whether the request is:
- reviewed, yet to be released (enable, show label "release files")
- approved, uploads still in progress (disable, show "re-release files")
- approved, not all files uploaded, all non-uploaded files have been
  attempted the max times (enabled, show "re-release files")
  • Loading branch information
rebkwok committed Feb 12, 2025
1 parent 44eb65f commit 11e1941
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 4 deletions.
4 changes: 2 additions & 2 deletions airlock/templates/file_browser/request/request.html
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,14 @@
{% if content_buttons.release_files.show %}
{% if content_buttons.release_files.disabled %}
{% #button disabled=True class="relative group" small=True variant="warning" id="release-files-button" %}
Release files
{{ content_buttons.release_files.display_label }}
{% tooltip class="airlock-tooltip" content=content_buttons.release_files.tooltip %}
{% /button %}
{% else %}
<form action="{{ content_buttons.release_files.url }}" method="POST" hx-post="{{ content_buttons.release_files.url }}" hx-disabled-elt="button">
{% csrf_token %}
{% #button small=True type="submit" tooltip=content_buttons.release_files.tooltip variant="warning" id="release-files-button" %}
Release files
{{ content_buttons.release_files.display_label }}
<img height="16" width="16" class="icon icon--green-700 animate-spin htmx-indicator" src="{% static 'icons/progress_activity.svg' %}" alt="">
{% /button %}
</form>
Expand Down
1 change: 1 addition & 0 deletions airlock/views/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ButtonContext:
disabled: bool = True
url: str = ""
tooltip: str = ""
display_label: str = ""

@classmethod
def with_request_defaults(cls, release_request_id, url_name, **extra_kwargs):
Expand Down
21 changes: 19 additions & 2 deletions airlock/views/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,18 +150,35 @@ def _get_request_button_context(user, release_request):
return_btn.tooltip = "Returning a request is disabled until review has been submitted by two reviewers"

if not release_request.can_be_released():
release_files_btn.display_label = "Release files"
release_files_btn.tooltip = "Releasing to jobs.opensafely.org is disabled until all files have been approved by by two reviewers"

# A request can be released if it is in REVIEWED status and all files are
# approved - a first release attempt
# If a request is in APPROVED status, it isn't currently reviewable by a user,
# but it can be released by a user with permissions, so we need to show the
# release files button
# BUT we only enable the button if it can be re-released - i.e. all of its
# un-uploaded files have been attempted the max number of times
if (
permissions.user_can_review_request(user, release_request)
and release_request.can_be_released()
):
release_files_btn.show = True
release_files_btn.disabled = False
release_files_btn.tooltip = "Release files to jobs.opensafely.org"
if release_request.upload_in_progress():
release_files_btn.display_label = "Re-release files"
release_files_btn.disabled = True
release_files_btn.tooltip = "Files are uploading to jobs.opensafely.org"
elif release_request.can_be_rereleased():
release_files_btn.display_label = "Re-release files"
release_files_btn.disabled = False
release_files_btn.tooltip = (
"Some files failed to upload; re-attempt release to jobs.opensafely.org"
)
else:
release_files_btn.display_label = "Release files"
release_files_btn.disabled = False
release_files_btn.tooltip = "Release files to jobs.opensafely.org"

return {
"submit": submit_btn,
Expand Down
84 changes: 84 additions & 0 deletions tests/integration/views/test_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
import requests
from django.conf import settings
from django.contrib.messages import get_messages
from django.template.response import TemplateResponse

Expand Down Expand Up @@ -365,6 +366,89 @@ def test_request_view_with_reviewed_request(airlock_client):
assert "You have already submitted your review" in response.rendered_content


@pytest.mark.parametrize(
"files,button_label,button_tooltip",
[
( # one file uploaded, one still uploading
{
"test1.txt": {"uploaded": True, "attempts": 1, "content": "1"},
"test2.txt": {"uploaded": False, "attempts": 1, "content": "2"},
},
"Re-release files",
"Files are uploading to jobs.opensafely.org",
),
(
# one file uploaded, one past max attempts
{
"test1.txt": {"uploaded": True, "attempts": 1, "content": "1"},
"test2.txt": {
"uploaded": False,
"attempts": settings.UPLOAD_MAX_ATTEMPTS,
"content": "2",
},
},
"Re-release files",
"Some files failed to upload; re-attempt release to jobs.opensafely.org",
),
(
# neither file uploaded, one past max attempts
{
"test1.txt": {"uploaded": False, "attempts": 1, "content": "1"},
"test2.txt": {
"uploaded": False,
"attempts": settings.UPLOAD_MAX_ATTEMPTS,
"content": "2",
},
},
"Re-release files",
"Files are uploading to jobs.opensafely.org",
),
(
# one file uploaded on the max attempt, one still uploading
{
"test1.txt": {"uploaded": False, "attempts": 1, "content": "1"},
"test2.txt": {
"uploaded": True,
"attempts": settings.UPLOAD_MAX_ATTEMPTS,
"content": "2",
},
},
"Re-release files",
"Files are uploading to jobs.opensafely.org",
),
],
)
def test_request_view_with_approved_request(
mock_old_api,
mock_notifications,
airlock_client,
files,
button_label,
button_tooltip,
):
airlock_client.login(username="output-checker-0", output_checker=True)
release_request = factories.create_request_at_status(
"workspace",
status=RequestStatus.APPROVED,
files=[
factories.request_file(approved=True, path=path, contents=file["content"])
for path, file in files.items()
],
)
for path, file in files.items():
for _ in range(file["attempts"]):
bll.register_file_upload_attempt(release_request, UrlPath(path))
if file["uploaded"]:
bll.register_file_upload(
release_request, UrlPath(path), airlock_client.user
)

response = airlock_client.get(f"/requests/view/{release_request.id}/", follow=True)

assert button_label in response.rendered_content
assert button_tooltip in response.rendered_content


@pytest.mark.parametrize("status", list(RequestStatus))
def test_request_view_with_authored_request_file(mock_old_api, airlock_client, status):
airlock_client.login(output_checker=True, workspaces=["workspace"])
Expand Down

0 comments on commit 11e1941

Please sign in to comment.