diff --git a/src/endpoints/interoperability.py b/src/endpoints/interoperability.py index 5758dc1..752f7e8 100644 --- a/src/endpoints/interoperability.py +++ b/src/endpoints/interoperability.py @@ -1,12 +1,13 @@ +import json from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import JSONResponse from auto_archiver import Metadata -from loguru import logger import sqlalchemy +from core.config import ALLOW_ANY_EMAIL from web.security import token_api_key_auth from db import models, schemas -from worker.main import insert_result_into_db +from worker.main import insert_result_into_db, get_all_urls, get_store_until from core.logging import log_error @@ -15,13 +16,28 @@ interoperability_router = APIRouter(prefix="/interop", tags=["Interoperability e # ----- endpoint to submit data archived elsewhere @interoperability_router.post("/submit-archive", status_code=201, summary="Submit a manual archive entry, for data that was archived elsewhere.") -def submit_manual_archive(manual: schemas.SubmitManual, auth=Depends(token_api_key_auth)): - result = Metadata.from_json(manual.result) - logger.info(f"MANUAL SUBMIT {result.get_url()} {manual.author_id}") +def submit_manual_archive( + manual: schemas.SubmitManualArchive, + auth=Depends(token_api_key_auth) +): + result: Metadata = Metadata.from_json(manual.result) + manual.author_id = manual.author_id or ALLOW_ANY_EMAIL manual.tags.add("manual") + try: - archive_id = insert_result_into_db(result, manual.tags, manual.public, manual.group_id, manual.author_id, models.generate_uuid()) + archive = schemas.ArchiveCreate( + author_id=manual.author_id, + url=result.get_url(), + public=manual.public, + group_id=manual.group_id, + tags=manual.tags, + id=models.generate_uuid(), + result=json.loads(result.to_json()), + urls=get_all_urls(result), + store_until=get_store_until(manual.group_id), + ) + archive_id = insert_result_into_db(archive) except sqlalchemy.exc.IntegrityError as e: log_error(e) - raise HTTPException(status_code=422, detail=f"Cannot insert into DB due to integrity error") + raise HTTPException(status_code=422, detail=f"Cannot insert into DB due to integrity error, likely duplicate urls.") return JSONResponse({"id": archive_id}, status_code=201) diff --git a/src/tests/endpoints/test_interoperability.py b/src/tests/endpoints/test_interoperability.py index 8021bfe..fa97d86 100644 --- a/src/tests/endpoints/test_interoperability.py +++ b/src/tests/endpoints/test_interoperability.py @@ -1,4 +1,9 @@ +from datetime import datetime import json +from unittest.mock import patch + +from core.config import ALLOW_ANY_EMAIL +from db import crud def test_submit_manual_archive_unauthenticated(client, test_no_auth): @@ -9,15 +14,27 @@ def test_submit_manual_archive_not_user_auth(client_with_auth, test_no_auth): test_no_auth(client_with_auth.post, "/interop/submit-archive") -def test_submit_manual_archive(client_with_token): - aa_metadata = json.dumps({"status": "test: success", "metadata": {"url": "http://example.com"}, "media": []}) - - r = client_with_token.post("/interop/submit-archive", json={"result": aa_metadata, "public": False, "author_id": "jerry@gmail.com", "group_id": None, "tags": ["test"]}) +@patch("endpoints.interoperability.get_store_until", return_value=datetime.now()) +def test_submit_manual_archive(m1, client_with_token, db_session): + # normal workflow + aa_metadata = json.dumps({"status": "test: success", "metadata": {"url": "http://example.com"}, "media": [{"filename": "fn1", "urls": ["http://example.s3.com"]}]}) + r = client_with_token.post("/interop/submit-archive", json={"result": aa_metadata, "public": True, "author_id": "jerry@gmail.com", "group_id": "spaceship", "tags": ["test"]}) assert r.status_code == 201 assert "id" in r.json() - # cannot have the same URL twice + inserted = crud.get_archive(db_session, r.json()["id"], ALLOW_ANY_EMAIL) + assert inserted.url == "http://example.com" + assert inserted.group_id == "spaceship" + assert inserted.author_id == "jerry@gmail.com" + assert sorted([t.id for t in inserted.tags]) == sorted(["test", "manual"]) + assert inserted.public + assert type(inserted.result) == dict + assert [u.url for u in inserted.urls] == ["http://example.s3.com"] + assert type(inserted.store_until) == datetime + + + # cannot have the same URL twice aa_metadata = json.dumps({"status": "test: success", "metadata": {"url": "http://example.com"}, "media": [{"filename": "fn1", "urls": ["http://example.com", "http://example.com"]}]}) - r = client_with_token.post("/interop/submit-archive", json={"result": aa_metadata, "public": False, "author_id": "jerry@gmail.com", "group_id": None, "tags": ["test"]}) + r = client_with_token.post("/interop/submit-archive", json={"result": aa_metadata, "public": False, "author_id": "jerry@gmail.com", "tags": ["test"]}) assert r.status_code == 422 - assert r.json() == {"detail": "Cannot insert into DB due to integrity error"} + assert r.json() == {"detail": "Cannot insert into DB due to integrity error, likely duplicate urls."}