Skip to content

Commit 06ffe14

Browse files
committed
Add tests for export admin actions
1 parent dc0ce20 commit 06ffe14

File tree

2 files changed

+171
-13
lines changed

2 files changed

+171
-13
lines changed

import_export_extensions/admin/model_admins/export_job_admin.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
from http import HTTPStatus
2+
import http
33

44
from django.contrib import admin, messages
55
from django.core.handlers.wsgi import WSGIRequest
@@ -96,7 +96,7 @@ def export_job_progress_view(
9696
except self.export_job_model.DoesNotExist as error:
9797
return JsonResponse(
9898
dict(validation_error=error.args[0]),
99-
status=HTTPStatus.NOT_FOUND,
99+
status=http.HTTPStatus.NOT_FOUND,
100100
)
101101

102102
response_data = dict(status=job.export_status.title())
@@ -131,7 +131,9 @@ def get_readonly_fields(self, request, obj=None):
131131
Some fields are editable for new ExportJob.
132132
133133
"""
134-
readonly_fields = [
134+
base_readonly_fields = super().get_readonly_fields(request, obj)
135+
readonly_fields = (
136+
*base_readonly_fields,
135137
"export_status",
136138
"traceback",
137139
"file_format_path",
@@ -140,15 +142,10 @@ def get_readonly_fields(self, request, obj=None):
140142
"export_finished",
141143
"error_message",
142144
"_model",
143-
]
144-
if obj:
145-
readonly_fields.extend(
146-
[
147-
"resource_path",
148-
"data_file",
149-
"resource_kwargs",
150-
],
151-
)
145+
"resource_path",
146+
"data_file",
147+
"resource_kwargs",
148+
)
152149

153150
return readonly_fields
154151

test_project/tests/integration_tests/test_admin/test_export.py

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,165 @@ def test_export_progress_with_failed_celery_task(
190190
assert (
191191
artist_export_job.export_status == ExportJob.ExportStatus.EXPORT_ERROR
192192
)
193-
assert artist_export_job.error_message == expected_error_message
193+
194+
195+
@pytest.mark.django_db(transaction=True)
196+
def test_cancel_export_admin_action(
197+
client: Client,
198+
superuser: User,
199+
mocker: pytest_mock.MockerFixture,
200+
):
201+
"""Test `cancel_export` via admin action."""
202+
client.force_login(superuser)
203+
204+
revoke_mock = mocker.patch("celery.current_app.control.revoke")
205+
export_data_mock = mocker.patch(
206+
"import_export_extensions.models.ExportJob.export_data",
207+
)
208+
job: ExportJob = ArtistExportJobFactory()
209+
210+
response = client.post(
211+
reverse("admin:import_export_extensions_exportjob_changelist"),
212+
data={
213+
"action": "cancel_jobs",
214+
"_selected_action": [job.pk],
215+
},
216+
)
217+
job.refresh_from_db()
218+
219+
assert response.status_code == status.HTTP_302_FOUND
220+
assert job.export_status == ExportJob.ExportStatus.CANCELLED
221+
assert (
222+
response.wsgi_request._messages._queued_messages[0].message
223+
== f"Export of {job} canceled"
224+
)
225+
export_data_mock.assert_called_once()
226+
revoke_mock.assert_called_once_with(job.export_task_id, terminate=True)
227+
228+
229+
@pytest.mark.django_db(transaction=True)
230+
def test_cancel_export_admin_action_with_incorrect_export_job_status(
231+
client: Client,
232+
superuser: User,
233+
mocker: pytest_mock.MockerFixture,
234+
):
235+
"""Test `cancel_export` via admin action with wrong export job status."""
236+
client.force_login(superuser)
237+
238+
revoke_mock = mocker.patch("celery.current_app.control.revoke")
239+
job: ExportJob = ArtistExportJobFactory()
240+
241+
expected_error_message = f"ExportJob with id {job.pk} has incorrect status"
242+
243+
response = client.post(
244+
reverse("admin:import_export_extensions_exportjob_changelist"),
245+
data={
246+
"action": "cancel_jobs",
247+
"_selected_action": [job.pk],
248+
},
249+
)
250+
job.refresh_from_db()
251+
252+
assert response.status_code == status.HTTP_302_FOUND
253+
assert job.export_status == ExportJob.ExportStatus.EXPORTED
254+
assert (
255+
expected_error_message
256+
in response.wsgi_request._messages._queued_messages[0].message
257+
)
258+
revoke_mock.assert_not_called()
259+
260+
261+
@pytest.mark.parametrize(
262+
argnames=["job_status", "expected_fieldsets"],
263+
argvalues=[
264+
pytest.param(
265+
ExportJob.ExportStatus.CREATED,
266+
(
267+
(
268+
"export_status",
269+
"_model",
270+
"created",
271+
"export_started",
272+
"export_finished",
273+
),
274+
),
275+
id="Get fieldsets for job in status CREATED",
276+
),
277+
pytest.param(
278+
ExportJob.ExportStatus.EXPORTED,
279+
(
280+
(
281+
"export_status",
282+
"_model",
283+
"created",
284+
"export_started",
285+
"export_finished",
286+
),
287+
("data_file",),
288+
),
289+
id="Get fieldsets for job in status EXPORTED",
290+
),
291+
pytest.param(
292+
ExportJob.ExportStatus.EXPORTING,
293+
(
294+
(
295+
"export_status",
296+
"export_progressbar",
297+
),
298+
),
299+
id="Get fieldsets for job in status EXPORTING",
300+
),
301+
pytest.param(
302+
ExportJob.ExportStatus.EXPORT_ERROR,
303+
(
304+
(
305+
"export_status",
306+
"_model",
307+
"created",
308+
"export_started",
309+
"export_finished",
310+
),
311+
(
312+
"error_message",
313+
"traceback",
314+
),
315+
),
316+
id="Get fieldsets for job in status EXPORT_ERROR",
317+
),
318+
],
319+
)
320+
def test_get_fieldsets_by_export_job_status(
321+
client: Client,
322+
superuser: User,
323+
job_status: ExportJob.ExportStatus,
324+
expected_fieldsets: tuple[tuple[str]],
325+
mocker: pytest_mock.MockerFixture,
326+
):
327+
"""Test that appropriate fieldsets returned for different job statuses."""
328+
client.force_login(superuser)
329+
330+
mocker.patch(
331+
"import_export_extensions.models.ExportJob.export_data",
332+
)
333+
job: ExportJob = ArtistExportJobFactory()
334+
job.export_status = job_status
335+
job.save()
336+
337+
response = client.get(
338+
reverse(
339+
"admin:import_export_extensions_exportjob_change",
340+
kwargs={"object_id": job.pk},
341+
),
342+
)
343+
344+
fieldsets = response.context["adminform"].fieldsets
345+
fields = [fields["fields"] for _, fields in fieldsets]
346+
347+
assert tuple(fields) == (
348+
*expected_fieldsets,
349+
(
350+
"resource_path",
351+
"resource_kwargs",
352+
"file_format_path",
353+
),
354+
)

0 commit comments

Comments
 (0)