diff --git a/AIPscan/Aggregator/tests/test_views.py b/AIPscan/Aggregator/tests/test_views.py index bd44e4e0..b806586c 100644 --- a/AIPscan/Aggregator/tests/test_views.py +++ b/AIPscan/Aggregator/tests/test_views.py @@ -29,3 +29,43 @@ def test_new_fetch_job_bad_connection(app_with_populated_files, mocker): response = test_client.post("/aggregator/new_fetch_job/1") task.assert_not_called() assert response.status_code == 400 + + +def test_view_storage_service(app_with_populated_files): + with current_app.test_client() as test_client: + response = test_client.get("/aggregator/storage_service/1") + assert response.status_code == 200 + + response = test_client.get("/aggregator/storage_service/0") + assert response.status_code == 404 + + +def test_edit_storage_service(app_with_populated_files): + with current_app.test_client() as test_client: + response = test_client.post("/aggregator/edit_storage_service/1") + assert response.status_code == 200 + + response = test_client.post("/aggregator/edit_storage_service/0") + assert response.status_code == 404 + + +def test_delete_storage_service(app_with_populated_files, mocker): + with current_app.test_client() as test_client: + response = test_client.get("/aggregator/delete_storage_service/0") + assert response.status_code == 404 + + mocker.patch("AIPscan.Aggregator.tasks.delete_storage_service.delay") + + response = test_client.get("/aggregator/delete_storage_service/1") + assert response.status_code == 302 + + +def test_delete_fetch_job(app_with_populated_files, mocker): + with current_app.test_client() as test_client: + response = test_client.get("/aggregator/delete_fetch_job/0") + assert response.status_code == 404 + + mocker.patch("AIPscan.Aggregator.tasks.delete_fetch_job.delay") + + response = test_client.get("/aggregator/delete_fetch_job/1") + assert response.status_code == 302 diff --git a/AIPscan/Aggregator/views.py b/AIPscan/Aggregator/views.py index 60ba7770..1f3cda4e 100644 --- a/AIPscan/Aggregator/views.py +++ b/AIPscan/Aggregator/views.py @@ -4,7 +4,16 @@ from datetime import datetime from celery.result import AsyncResult -from flask import Blueprint, flash, jsonify, redirect, render_template, request, url_for +from flask import ( + Blueprint, + abort, + flash, + jsonify, + redirect, + render_template, + request, + url_for, +) from AIPscan import db from AIPscan.Aggregator import database_helpers, tasks @@ -77,6 +86,10 @@ def ss_default(): @aggregator.route("/storage_service/", methods=["GET"]) def storage_service(storage_service_id): storage_service = StorageService.query.get(storage_service_id) + + if storage_service is None: + abort(404) + mets_fetch_jobs = FetchJob.query.filter_by( storage_service_id=storage_service_id ).all() @@ -97,6 +110,10 @@ def storage_services(): def edit_storage_service(storage_service_id): form = StorageServiceForm() storage_service = StorageService.query.get(storage_service_id) + + if storage_service is None: + abort(404) + if request.method == "GET": form.name.data = storage_service.name form.url.data = storage_service.url @@ -149,8 +166,13 @@ def new_storage_service(): @aggregator.route("/delete_storage_service/", methods=["GET"]) def delete_storage_service(storage_service_id): - tasks.delete_storage_service.delay(storage_service_id) storage_service = StorageService.query.get(storage_service_id) + + if storage_service is None: + abort(404) + + tasks.delete_storage_service.delay(storage_service_id) + flash("Storage service '{}' is being deleted".format(storage_service.name)) return redirect(url_for("aggregator.storage_services")) @@ -214,9 +236,14 @@ def new_fetch_job(fetch_job_id): @aggregator.route("/delete_fetch_job/", methods=["GET"]) def delete_fetch_job(fetch_job_id): - tasks.delete_fetch_job.delay(fetch_job_id) fetch_job = FetchJob.query.get(fetch_job_id) + + if fetch_job is None: + abort(404) + storage_service = StorageService.query.get(fetch_job.storage_service_id) + tasks.delete_fetch_job.delay(fetch_job_id) + flash("Fetch job {} is being deleted".format(fetch_job.download_start)) return redirect( url_for("aggregator.storage_service", storage_service_id=storage_service.id) diff --git a/AIPscan/Reporter/tests/test_views.py b/AIPscan/Reporter/tests/test_views.py index 04865ec2..548b7a58 100644 --- a/AIPscan/Reporter/tests/test_views.py +++ b/AIPscan/Reporter/tests/test_views.py @@ -77,3 +77,21 @@ def test_get_file_pager(app_instance, mocker, page, pager_page): assert pager.per_page == 2 assert pager.prev_num is None assert pager.next_num is None + + +def test_view_aip(app_with_populated_files): + with current_app.test_client() as test_client: + response = test_client.get("/reporter/aip/1") + assert response.status_code == 200 + + response = test_client.get("/reporter/aip/0") + assert response.status_code == 404 + + +def test_view_file(app_with_populated_files): + with current_app.test_client() as test_client: + response = test_client.get("/reporter/file/1") + assert response.status_code == 200 + + response = test_client.get("/reporter/file/0") + assert response.status_code == 404 diff --git a/AIPscan/Reporter/views.py b/AIPscan/Reporter/views.py index 640f589b..a618026d 100644 --- a/AIPscan/Reporter/views.py +++ b/AIPscan/Reporter/views.py @@ -8,7 +8,15 @@ from datetime import datetime import requests -from flask import Response, jsonify, make_response, render_template, request, session +from flask import ( + Response, + abort, + jsonify, + make_response, + render_template, + request, + session, +) from AIPscan.Aggregator.task_helpers import get_mets_url from AIPscan.models import ( @@ -153,6 +161,10 @@ def view_aips(): def view_aip(aip_id): """Detailed view of specific AIP.""" aip = AIP.query.get(aip_id) + + if aip is None: + abort(404) + fetch_job = FetchJob.query.get(aip.fetch_job_id) storage_service = StorageService.query.get(fetch_job.storage_service_id) storage_location = StorageLocation.query.get(aip.storage_location_id) @@ -205,6 +217,10 @@ def view_aip(aip_id): def view_file(file_id): """File page displays Object and Event metadata for file""" file_ = File.query.get(file_id) + + if file_ is None: + abort(404) + aip = AIP.query.get(file_.aip_id) events = Event.query.filter_by(file_id=file_id).all() preservation_file = File.query.filter_by(