diff --git a/src/dashboard/src/components/archival_storage/tests/test_archival_storage.py b/src/dashboard/src/components/archival_storage/tests/test_archival_storage.py index 560f9e4054..91964ebf80 100644 --- a/src/dashboard/src/components/archival_storage/tests/test_archival_storage.py +++ b/src/dashboard/src/components/archival_storage/tests/test_archival_storage.py @@ -399,3 +399,112 @@ def test_view_aip_metadata_only_dip_upload_with_missing_description_slug( assert "Description with slug missing-slug not found!" in response.content.decode( "utf8" ) + + +def test_create_aic_fails_if_query_is_not_passed(amsetup, admin_client): + params = {} + response = admin_client.get( + "{}?{}".format( + reverse("archival_storage:create_aic"), + urlencode(params), + ), + follow=True, + ) + + assert "Unable to create AIC: No AIPs selected" in response.content.decode() + + +def test_create_aic_creates_temporary_files( + mocker, admin_client, settings, tmp_path, amsetup +): + aipfiles_search_results = { + "aggregations": { + "aip_uuids": { + "buckets": [ + {"key": "a79e23a1-fd5d-4e54-bc02-b88521f9f35b", "doc_count": 15}, + {"key": "786e25a5-fa60-48ab-9ff7-baabc52a9591", "doc_count": 15}, + ] + } + } + } + aip_search_results = { + "_shards": {"failed": 0, "skipped": 0, "successful": 5, "total": 5}, + "hits": { + "hits": [ + { + "_id": "LkAKUIkB6j_bcPXdWtl-", + "_index": "aips", + "_score": None, + "_source": { + "AICID": None, + "accessionids": [], + "countAIPsinAIC": None, + "created": 1689264994, + "encrypted": False, + "isPartOf": None, + "location": "Store AIP in standard " "Archivematica Directory", + "name": "artefactual", + "size": 4.80488395690918, + "status": "UPLOADED", + "uuid": "a79e23a1-fd5d-4e54-bc02-b88521f9f35b", + }, + "_type": "_doc", + "sort": ["artefactual"], + }, + { + "_id": "HEAIUIkB6j_bcPXdedka", + "_index": "aips", + "_score": None, + "_source": { + "AICID": None, + "accessionids": [], + "countAIPsinAIC": None, + "created": 1689264872, + "encrypted": False, + "isPartOf": None, + "location": "Store AIP in standard " "Archivematica Directory", + "name": "bunny_1", + "size": 4.805169105529785, + "status": "UPLOADED", + "uuid": "786e25a5-fa60-48ab-9ff7-baabc52a9591", + }, + "_type": "_doc", + "sort": ["bunny_1"], + }, + ], + "max_score": None, + "total": 2, + }, + "timed_out": False, + "took": 4, + } + mocker.patch( + "elasticSearchFunctions.get_client", + return_value=mocker.Mock( + **{"search.side_effect": [aipfiles_search_results, aip_search_results]} + ), + ) + mocker.patch("databaseFunctions.createSIP") + mocker.patch("uuid.uuid4", return_value="1e23e6e2-02d7-4b2d-a648-caffa3b489f3") + d = tmp_path / "test-aic" + d.mkdir() + (d / "tmp").mkdir() + settings.SHARED_DIRECTORY = str(d) + + params = {"query": "", "field": "", "fieldName": "", "type": "term"} + response = admin_client.get( + "{}?{}".format( + reverse("archival_storage:create_aic"), + urlencode(params), + ), + ) + + assert response.status_code == 302 + expected_file_contents = { + ("a79e23a1-fd5d-4e54-bc02-b88521f9f35b", "artefactual"), + ("786e25a5-fa60-48ab-9ff7-baabc52a9591", "bunny_1"), + } + temporary_files = set() + for path in (d / "tmp" / "1e23e6e2-02d7-4b2d-a648-caffa3b489f3").iterdir(): + temporary_files.add((path.name, path.read_text().strip())) + assert expected_file_contents == temporary_files diff --git a/src/dashboard/src/components/archival_storage/views.py b/src/dashboard/src/components/archival_storage/views.py index 986fc94445..97cc667d29 100644 --- a/src/dashboard/src/components/archival_storage/views.py +++ b/src/dashboard/src/components/archival_storage/views.py @@ -488,23 +488,46 @@ def search_augment_file_results(es_client, raw_results): def create_aic(request): - """Create an AIC from POSTed list of AIP UUIDs. + """Create an AIC from POSTed list of search params. :param request: Django request object. :return: Redirect to appropriate view. """ - uuids = request.GET.get("uuids") - if not uuids: + + if "query" not in request.GET: messages.error(request, "Unable to create AIC: No AIPs selected") return redirect("archival_storage:archival_storage_index") - # Make a list of UUIDs from from comma-separated string in request. - aip_uuids = uuids.split(",") + queries, ops, fields, types = advanced_search.search_parameter_prep(request) + + if types[0] == "range": + fields = ["indexedAt"] + query = advanced_search.assemble_query(queries, ops, fields, types) + es_client = es.get_client() + + try: + query["aggs"] = { + "aip_uuids": { + "terms": { + "field": "AIPUUID", + "size": str(settings.ELASTICSEARCH_MAX_QUERY_SIZE), + } + } + } + query["size"] = 0 + results = es_client.search(body=query, index=es.AIP_FILES_INDEX) + buckets = results["aggregations"]["aip_uuids"]["buckets"] + aip_uuids = [bucket["key"] for bucket in buckets] + + except ElasticsearchException: + err_desc = "Error accessing AIPs index" + logger.exception(err_desc) + return HttpResponse(err_desc) + logger.info(f"AIC AIP UUIDs: {aip_uuids}") # Use the AIP UUIDs to fetch names, which are used to produce files below. query = {"query": {"terms": {"uuid": aip_uuids}}} - es_client = es.get_client() results = es_client.search( body=query, index=es.AIPS_INDEX, _source="uuid,name", size=es.MAX_QUERY_SIZE ) diff --git a/src/dashboard/src/media/js/archival_storage/archival_storage_search.js b/src/dashboard/src/media/js/archival_storage/archival_storage_search.js index c6041fffb3..ef45c3547b 100644 --- a/src/dashboard/src/media/js/archival_storage/archival_storage_search.js +++ b/src/dashboard/src/media/js/archival_storage/archival_storage_search.js @@ -408,20 +408,10 @@ $(document).ready(function() { } }); + // hide create_aic button by default + $("#create-aic-btn").hide(); $("#create-aic-btn").click(function() { - var aip_uuids = [] - // Get object containing UUIDs from the DataTable. - var table_uuids = $('#id_show_files').prop('checked') - ? [] - : $('#archival-storage-entries').DataTable().column(1).data(); - // Add each UUID in the returned object to our clean aip_uuids array. - for (i = 0; i < table_uuids.length; i++) { - aip_uuids.push(table_uuids[i]); - } - // Redirect window URL to Django create_aic view, including the AIP UUIDs - // as a comma-separated string in the URL parameters. - var uuids_string = aip_uuids.join(","); - window.location = "/archival-storage/search/create_aic/?uuids=" + uuids_string; + window.location = "/archival-storage/search/create_aic/?" + search.toUrlParams() }); // Vars and functions to Enable the download of the Archival Storage table