def test_transfer_mets_includes_statute_rights(tmp_path, transfer, file_obj,
                                               statute_rights):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    statute_db_obj = statute_rights.rightsstatementstatuteinformation_set.first(
    )
    statute_note_db_obj = (
        statute_db_obj.rightsstatementstatuteinformationnote_set.first())
    doc_identifier_db_obj = (
        statute_db_obj.rightsstatementstatutedocumentationidentifier_set.first(
        ))

    statute_info = mets_xml.find(".//premis:statuteInformation",
                                 namespaces=PREMIS_NAMESPACES)
    statute_jurisdiction = statute_info.find("premis:statuteJurisdiction",
                                             namespaces=PREMIS_NAMESPACES)
    statute_determination_date = statute_info.find(
        "premis:statuteInformationDeterminationDate",
        namespaces=PREMIS_NAMESPACES)
    statute_citation = statute_info.find("premis:statuteCitation",
                                         namespaces=PREMIS_NAMESPACES)
    statute_note = statute_info.find("premis:statuteNote",
                                     namespaces=PREMIS_NAMESPACES)
    doc_identifier = statute_info.find("premis:statuteDocumentationIdentifier",
                                       namespaces=PREMIS_NAMESPACES)
    doc_identifier_type = doc_identifier.find(
        "premis:statuteDocumentationIdentifierType",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_value = doc_identifier.find(
        "premis:statuteDocumentationIdentifierValue",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_role = doc_identifier.find(
        "premis:statuteDocumentationRole", namespaces=PREMIS_NAMESPACES)
    applicable_dates = statute_info.find("premis:statuteApplicableDates",
                                         namespaces=PREMIS_NAMESPACES)
    state_date = applicable_dates.find("premis:startDate",
                                       namespaces=PREMIS_NAMESPACES)
    end_date = applicable_dates.find("premis:endDate",
                                     namespaces=PREMIS_NAMESPACES)

    assert statute_jurisdiction.text == statute_db_obj.statutejurisdiction
    assert statute_citation.text == statute_db_obj.statutecitation
    assert statute_determination_date.text == statute_db_obj.statutedeterminationdate
    assert statute_note.text == statute_note_db_obj.statutenote
    assert (doc_identifier_type.text ==
            doc_identifier_db_obj.statutedocumentationidentifiertype)
    assert (doc_identifier_value.text ==
            doc_identifier_db_obj.statutedocumentationidentifiervalue)
    assert (doc_identifier_role.text ==
            doc_identifier_db_obj.statutedocumentationidentifierrole)
    assert state_date.text == statute_db_obj.statuteapplicablestartdate
    assert end_date.text == "OPEN"
def test_transfer_mets_objid(tmp_path, transfer):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()
    objids = mets_xml.xpath("/*/@OBJID", namespaces=mets_xml.nsmap)

    assert len(objids) == 1
    assert objids[0] == str(transfer.uuid)
def test_transfer_mets_includes_basic_rights(tmp_path, transfer, file_obj,
                                             basic_rights_statement):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    grant_db_obj = basic_rights_statement.rightsstatementrightsgranted_set.first(
    )
    restriction_db_obj = grant_db_obj.restrictions.first()
    grant_notes = grant_db_obj.notes.order_by("id")

    rights_statement = mets_xml.find(".//premis:rightsStatement",
                                     namespaces=PREMIS_NAMESPACES)
    rights_id = rights_statement.find(
        "premis:rightsStatementIdentifier/premis:rightsStatementIdentifierValue",
        namespaces=PREMIS_NAMESPACES,
    )
    rights_basis = rights_statement.find("premis:rightsBasis",
                                         namespaces=PREMIS_NAMESPACES)
    rights_granted = rights_statement.find("premis:rightsGranted",
                                           namespaces=PREMIS_NAMESPACES)
    rights_granted_act = rights_granted.find("premis:act",
                                             namespaces=PREMIS_NAMESPACES)
    rights_granted_restriction = rights_granted.find(
        "premis:restriction", namespaces=PREMIS_NAMESPACES)
    rights_term_of_grant = rights_granted.find("premis:termOfGrant",
                                               namespaces=PREMIS_NAMESPACES)
    rights_term_of_grant_start = rights_term_of_grant.find(
        "premis:startDate", namespaces=PREMIS_NAMESPACES)
    rights_term_of_grant_end = rights_term_of_grant.find(
        "premis:endDate", namespaces=PREMIS_NAMESPACES)
    rights_granted_notes = rights_granted.findall("premis:rightsGrantedNote",
                                                  namespaces=PREMIS_NAMESPACES)
    linking_obj_id = rights_statement.find("premis:linkingObjectIdentifier",
                                           namespaces=PREMIS_NAMESPACES)
    linking_obj_id_type = linking_obj_id.find(
        "premis:linkingObjectIdentifierType", namespaces=PREMIS_NAMESPACES)
    linking_obj_id_value = linking_obj_id.find(
        "premis:linkingObjectIdentifierValue", namespaces=PREMIS_NAMESPACES)

    assert rights_id.text == basic_rights_statement.rightsstatementidentifiervalue
    assert rights_basis.text == basic_rights_statement.rightsbasis

    assert rights_granted_act.text == grant_db_obj.act
    assert rights_granted_restriction.text == restriction_db_obj.restriction
    assert rights_term_of_grant_start.text == grant_db_obj.startdate
    assert rights_term_of_grant_end.text == "OPEN"

    assert linking_obj_id_type.text == "UUID"
    assert linking_obj_id_value.text == str(file_obj.uuid)

    for index, note in enumerate(grant_notes):
        assert rights_granted_notes[index].text == note.rightsgrantednote
def test_transfer_mets_includes_copyright_rights(tmp_path, transfer, file_obj,
                                                 copyright_rights):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    copyright_db_obj = copyright_rights.rightsstatementcopyright_set.first()
    copyright_note = copyright_db_obj.rightsstatementcopyrightnote_set.first()
    doc_identifier_db_obj = (
        copyright_db_obj.rightsstatementcopyrightdocumentationidentifier_set.
        first())

    copyright_info = mets_xml.find(".//premis:copyrightInformation",
                                   namespaces=PREMIS_NAMESPACES)
    rights_jurisdiction = copyright_info.find("premis:copyrightJurisdiction",
                                              namespaces=PREMIS_NAMESPACES)
    rights_status_date = copyright_info.find(
        "premis:copyrightStatusDeterminationDate",
        namespaces=PREMIS_NAMESPACES)
    rights_note = copyright_info.find("premis:copyrightNote",
                                      namespaces=PREMIS_NAMESPACES)
    doc_identifier = copyright_info.find(
        "premis:copyrightDocumentationIdentifier",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_type = doc_identifier.find(
        "premis:copyrightDocumentationIdentifierType",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_value = doc_identifier.find(
        "premis:copyrightDocumentationIdentifierValue",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_role = doc_identifier.find(
        "premis:copyrightDocumentationRole", namespaces=PREMIS_NAMESPACES)
    applicable_dates = copyright_info.find("premis:copyrightApplicableDates",
                                           namespaces=PREMIS_NAMESPACES)
    copyright_state_date = applicable_dates.find("premis:startDate",
                                                 namespaces=PREMIS_NAMESPACES)
    copyright_end_date = applicable_dates.find("premis:endDate",
                                               namespaces=PREMIS_NAMESPACES)

    assert rights_jurisdiction.text == "CA"
    assert rights_status_date.text == copyright_db_obj.copyrightstatusdeterminationdate
    assert rights_note.text == copyright_note.copyrightnote
    assert (doc_identifier_type.text ==
            doc_identifier_db_obj.copyrightdocumentationidentifiertype)
    assert (doc_identifier_value.text ==
            doc_identifier_db_obj.copyrightdocumentationidentifiervalue)
    assert (doc_identifier_role.text ==
            doc_identifier_db_obj.copyrightdocumentationidentifierrole)
    assert copyright_state_date.text == copyright_db_obj.copyrightapplicablestartdate
    assert copyright_end_date.text == "OPEN"
def test_transfer_mets_accession_id(tmp_path, transfer):
    transfer.accessionid = "12345"
    transfer.save()
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()
    alt_record_id = mets_xml.xpath(".//mets:metsHdr/mets:altRecordID",
                                   namespaces=mets_xml.nsmap)[0]

    assert alt_record_id.get("TYPE") == "Accession ID"
    assert alt_record_id.text == "12345"
def test_transfer_mets_includes_other_rights(tmp_path, transfer, file_obj,
                                             other_rights):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    other_rights_db_obj = other_rights.rightsstatementotherrightsinformation_set.first(
    )
    other_rights_note_db_obj = (
        other_rights_db_obj.rightsstatementotherrightsinformationnote_set.
        first())
    doc_identifier_db_obj = (
        other_rights_db_obj.
        rightsstatementotherrightsdocumentationidentifier_set.first())

    other_rights_info = mets_xml.find(".//premis:otherRightsInformation",
                                      namespaces=PREMIS_NAMESPACES)
    other_rights_basis = other_rights_info.find("premis:otherRightsBasis",
                                                namespaces=PREMIS_NAMESPACES)
    other_rights_note = other_rights_info.find("premis:otherRightsNote",
                                               namespaces=PREMIS_NAMESPACES)
    doc_identifier = other_rights_info.find(
        "premis:otherRightsDocumentationIdentifier",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_type = doc_identifier.find(
        "premis:otherRightsDocumentationIdentifierType",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_value = doc_identifier.find(
        "premis:otherRightsDocumentationIdentifierValue",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_role = doc_identifier.find(
        "premis:otherRightsDocumentationRole", namespaces=PREMIS_NAMESPACES)
    applicable_dates = other_rights_info.find(
        "premis:otherRightsApplicableDates", namespaces=PREMIS_NAMESPACES)
    state_date = applicable_dates.find("premis:startDate",
                                       namespaces=PREMIS_NAMESPACES)
    end_date = applicable_dates.find("premis:endDate",
                                     namespaces=PREMIS_NAMESPACES)

    assert other_rights_basis.text == other_rights_db_obj.otherrightsbasis
    assert other_rights_note.text == other_rights_note_db_obj.otherrightsnote
    assert (doc_identifier_type.text ==
            doc_identifier_db_obj.otherrightsdocumentationidentifiertype)
    assert (doc_identifier_value.text ==
            doc_identifier_db_obj.otherrightsdocumentationidentifiervalue)
    assert (doc_identifier_role.text ==
            doc_identifier_db_obj.otherrightsdocumentationidentifierrole)
    assert state_date.text == other_rights_db_obj.otherrightsapplicablestartdate
    assert end_date.text == "OPEN"
def test_transfer_mets_premis_object_includes_type(tmp_path, transfer,
                                                   file_obj, fpcommand_output):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()
    premis_objects = mets_xml.xpath(".//premis:object",
                                    namespaces=PREMIS_NAMESPACES)

    assert len(premis_objects) == 1

    attr = "{%s}type" % PREMIS_NAMESPACES["xsi"]
    assert premis_objects[0].get(attr) == "premis:file"
def test_transfer_mets_filegrp_format(tmp_path, transfer, file_obj,
                                      subdir_path, empty_subdir_path,
                                      file_path):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    file_entries = mets_xml.xpath(".//mets:fileGrp/mets:file",
                                  namespaces=mets_xml.nsmap)
    expected_file_path = subdir_path.relative_to(tmp_path) / file_path.name

    assert file_entries[0].get("ID") == f"file-{file_obj.uuid}"
    assert file_entries[0][0].get("{http://www.w3.org/1999/xlink}href") == str(
        expected_file_path)
def test_transfer_mets_includes_license_rights(tmp_path, transfer, file_obj,
                                               license_rights):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    license_db_obj = license_rights.rightsstatementlicense_set.first()
    license_note_db_obj = license_db_obj.rightsstatementlicensenote_set.first()
    doc_identifier_db_obj = (
        license_db_obj.rightsstatementlicensedocumentationidentifier_set.first(
        ))

    license_info = mets_xml.find(".//premis:licenseInformation",
                                 namespaces=PREMIS_NAMESPACES)
    license_terms = license_info.find("premis:licenseTerms",
                                      namespaces=PREMIS_NAMESPACES)
    license_note = license_info.find("premis:licenseNote",
                                     namespaces=PREMIS_NAMESPACES)
    doc_identifier = license_info.find("premis:licenseDocumentationIdentifier",
                                       namespaces=PREMIS_NAMESPACES)
    doc_identifier_type = doc_identifier.find(
        "premis:licenseDocumentationIdentifierType",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_value = doc_identifier.find(
        "premis:licenseDocumentationIdentifierValue",
        namespaces=PREMIS_NAMESPACES)
    doc_identifier_role = doc_identifier.find(
        "premis:licenseDocumentationRole", namespaces=PREMIS_NAMESPACES)
    applicable_dates = license_info.find("premis:licenseApplicableDates",
                                         namespaces=PREMIS_NAMESPACES)
    state_date = applicable_dates.find("premis:startDate",
                                       namespaces=PREMIS_NAMESPACES)
    end_date = applicable_dates.find("premis:endDate",
                                     namespaces=PREMIS_NAMESPACES)

    assert license_note.text == license_note_db_obj.licensenote
    assert license_terms.text == license_db_obj.licenseterms
    assert (doc_identifier_type.text ==
            doc_identifier_db_obj.licensedocumentationidentifiertype)
    assert (doc_identifier_value.text ==
            doc_identifier_db_obj.licensedocumentationidentifiervalue)
    assert (doc_identifier_role.text ==
            doc_identifier_db_obj.licensedocumentationidentifierrole)
    assert state_date.text == license_db_obj.licenseapplicablestartdate
    assert end_date.text == "OPEN"
def test_transfer_mets_file_identifiers(tmp_path, transfer, file_obj):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    expected_identifier = file_obj.identifiers.first()
    premis_obj = mets_xml.find(".//premis:object",
                               namespaces=PREMIS_NAMESPACES)
    identifiers = premis_obj.findall("premis:objectIdentifier",
                                     namespaces=PREMIS_NAMESPACES)

    assert identifiers[0][0].text == "UUID"
    assert identifiers[0][1].text == str(file_obj.uuid)
    assert identifiers[1][0].text == expected_identifier.type
    assert identifiers[1][1].text == expected_identifier.value
def test_transfer_mets_includes_fpcommand_output(tmp_path, transfer, file_obj,
                                                 fpcommand_output):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    expected_embed = etree.fromstring(fpcommand_output.content.encode("utf-8"))

    extensions = mets_xml.xpath(".//premis:objectCharacteristicsExtension",
                                namespaces=PREMIS_NAMESPACES)

    assert len(extensions) == 1

    assert extensions[0][0].tag == expected_embed.tag
    assert extensions[0][0].text == expected_embed.text
def test_transfer_mets_includes_events(tmp_path, transfer, event):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    premis_event = mets_xml.find(".//premis:event",
                                 namespaces=PREMIS_NAMESPACES)
    premis_event_id_type = premis_event.findtext(
        "premis:eventIdentifier/premis:eventIdentifierType",
        namespaces=PREMIS_NAMESPACES,
    )
    premis_event_id_value = premis_event.findtext(
        "premis:eventIdentifier/premis:eventIdentifierValue",
        namespaces=PREMIS_NAMESPACES,
    )
    premis_event_type = premis_event.findtext("premis:eventType",
                                              namespaces=PREMIS_NAMESPACES)
    premis_event_date_time = premis_event.findtext(
        "premis:eventDateTime", namespaces=PREMIS_NAMESPACES)
    premis_event_detail = premis_event.findtext(
        "premis:eventDetailInformation/premis:eventDetail",
        namespaces=PREMIS_NAMESPACES)
    premis_event_outcome_note = premis_event.findtext(
        "premis:eventOutcomeInformation/premis:eventOutcomeDetail/premis:eventOutcomeDetailNote",
        namespaces=PREMIS_NAMESPACES,
    )
    premis_event_agent_id_type = premis_event.findtext(
        "premis:linkingAgentIdentifier/premis:linkingAgentIdentifierType",
        namespaces=PREMIS_NAMESPACES,
    )
    premis_event_agent_id_value = premis_event.findtext(
        "premis:linkingAgentIdentifier/premis:linkingAgentIdentifierValue",
        namespaces=PREMIS_NAMESPACES,
    )

    assert premis_event_id_type == "UUID"
    assert premis_event_id_value == str(event.event_id)
    assert premis_event_type == event.event_type
    assert premis_event_date_time == str(event.event_datetime)
    assert premis_event_detail == event.event_detail
    assert premis_event_outcome_note == event.event_outcome_detail
    assert premis_event_agent_id_type == event.agents.first().identifiertype
    assert premis_event_agent_id_value == event.agents.first().identifiervalue
def test_transfer_mets_header(tmp_path, transfer, file_obj, settings):
    settings.INSTANCE_ID = "12345"
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    header = mets_xml.find(".//mets:metsHdr", namespaces=mets_xml.nsmap)
    agent = header.find("mets:agent", namespaces=mets_xml.nsmap)
    agent_name = agent.find("mets:name", namespaces=mets_xml.nsmap)
    agent_note = agent.find("mets:note", namespaces=mets_xml.nsmap)

    assert agent.get("ROLE") == "CREATOR"
    assert agent.get("TYPE") == "OTHER"
    assert agent.get("OTHERTYPE") == "SOFTWARE"
    assert agent_name.text == "12345"
    assert agent_note.text == "Archivematica dashboard UUID"
def test_transfer_mets_directory_identifiers(tmp_path, transfer, dir_obj):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()

    expected_identifier = dir_obj.identifiers.first()
    premis_ie = mets_xml.find(".//premis:object", namespaces=PREMIS_NAMESPACES)
    identifiers = premis_ie.findall("premis:objectIdentifier",
                                    namespaces=PREMIS_NAMESPACES)

    namespaced_attr = "{%s}type" % PREMIS_NAMESPACES["xsi"]
    assert premis_ie.get(namespaced_attr) == "premis:intellectualEntity"

    assert identifiers[0][0].text == "UUID"
    assert identifiers[0][1].text == str(dir_obj.uuid)
    assert identifiers[1][0].text == expected_identifier.type
    assert identifiers[1][1].text == expected_identifier.value
def test_transfer_mets_structmap_format(tmp_path, transfer, file_obj,
                                        subdir_path, empty_subdir_path,
                                        file_path):
    mets_path = tmp_path / "METS.xml"
    write_mets(str(mets_path), str(tmp_path), "transferDirectory",
               transfer.uuid)
    mets_doc = metsrw.METSDocument.fromfile(str(mets_path))
    mets_xml = mets_doc.serialize()
    structmap_types = mets_xml.xpath(".//mets:structMap/@TYPE",
                                     namespaces=mets_xml.nsmap)
    root_div_labels = mets_xml.xpath(".//mets:structMap/mets:div/@LABEL",
                                     namespaces=mets_xml.nsmap)
    subdir_div_labels = mets_xml.xpath(
        ".//mets:structMap/mets:div/mets:div/@LABEL",
        namespaces=mets_xml.nsmap)
    file_div_labels = mets_xml.xpath(
        ".//mets:structMap/mets:div/mets:div/mets:div/@LABEL",
        namespaces=mets_xml.nsmap)
    file_ids = mets_xml.xpath(
        ".//mets:structMap/mets:div/mets:div/mets:div/mets:fptr/@FILEID",
        namespaces=mets_xml.nsmap,
    )

    assert len(mets_doc.all_files()) == 4

    # Test that we have physical and logical structmaps
    assert len(structmap_types) == 2
    assert "physical" in structmap_types
    assert "logical" in structmap_types

    # Test that our physical structmap is labeled properly.
    assert root_div_labels[0] == tmp_path.name
    assert subdir_div_labels[0] == subdir_path.name
    assert file_div_labels[0] == file_path.name
    assert file_ids[0] == f"file-{file_obj.uuid}"

    # Test that both (empty and not empty) dirs show up in logical structmap
    assert subdir_div_labels[1] == subdir_path.name
    assert subdir_div_labels[2] == empty_subdir_path.name