def test_bind_pid(self): """Test the bind_pid function end-to-end and ensure that the result is that which is anticipated. The bind_pid module is responsible for binding persistent identifiers to the SIP's files and so we test for that here. """ files = File.objects.filter(sip=self.package_uuid).all() assert len(files) is len( self.package_files ), "Number of files returned from package is incorrect" for file_ in files: with vcr_cassettes.use_cassette( "test_bind_pid_to_files.yaml") as cassette: bind_pid.main(self.job, file_.pk) assert cassette.all_played for file_mdl in files: bound = { idfr.type: idfr.value for idfr in file_mdl.identifiers.all() } assert ( "hdl" in bound ), "An expected hdl persistent identifier isn't in the result set" assert "URI" in bound, "An expected URI isn't in the result set" bound_hdl = "{}{}".format(self.bound_hdl, file_mdl.pk) bound_uri = "{}{}".format(self.bound_uri, file_mdl.pk) assert bound.get("hdl") == bound_hdl assert bound.get("URI") == bound_uri # Then test to see that the PREMIS objects are created correctly in # the AIP METS generation code. file_level_premis = create_mets_v2.create_premis_object( file_mdl.pk) id_type = file_level_premis.xpath( "//premis:objectIdentifierType", namespaces={"premis": ns.premisNS}) id_value = file_level_premis.xpath( "//premis:objectIdentifierValue", namespaces={"premis": ns.premisNS}) id_types = [item.text for item in id_type] id_values = [item.text for item in id_value] identifiers_dict = dict(zip(id_types, id_values)) for key in identifiers_dict.keys(): assert key in chain( self.traditional_identifiers, self.bound_identifier_types ), "Identifier type not in expected schemes list" assert bound_hdl in identifiers_dict.values() assert bound_uri in identifiers_dict.values()
def test_bind_pid_not_set(self, caplog): """Ensure that the behavior of bind_pid is as anticipated when we're not asking it to bind_pids, i.e. it doesn't runaway and try and bind anyway, or something that isn't there. """ assert ( bind_pid.main(self.job, None, None) == 0 ), "Return from bind_pid is incorrect" assert ( caplog.records[0].message == self.do_not_bind ), "Captured logging message from bind_pid is incorrect" assert ( bind_pid.main(self.job, None, False) == 0 ), "Return from bind_pid is something other than expected" assert ( caplog.records[1].message == self.do_not_bind ), "Captured logging message from bind_pid is incorrect"
def test_bind_pid_no_settings(self, caplog): """Test the output of the code when bind_pids is set to True but there are no handle settings in the Dashboard. Conceivably then the dashboard settings could be in-between two states, complete and not-complete, here we test for the two opposites on the assumption they'll be the most visible errors to the user. """ file_count = 5 DashboardSetting.objects.filter(scope="handle").delete() files = File.objects.filter(sip=self.package_uuid).all() assert (files is not None ), "Files haven't been retrieved from the model as expected" for file_ in files: bind_pid.main(self.job, file_.pk) for file_number in range(file_count): assert caplog.records[file_number].message.startswith( self.incomplete_configuration_msg)
def test_bind_pid_no_config(self, caplog): """Test the output of the code when bind_pids is set to True but there are no handle settings in the Dashboard. Conceivably then the dashboard settings could be in-between two states, complete and not-complete, here we test for the two opposites on the assumption they'll be the most visible errors to the user. """ DashboardSetting.objects.filter(scope="handle").delete() assert bind_pid.main(self.job, self.package_uuid, True) == 1 assert caplog.records[0].message.startswith(self.incomplete_configuration_msg)
def test_pid_declaration(self, mocker): """Test that the overall functionality of the PID declaration functions work as expected. """ job = self.job files_no = 2 dirs_no = 2 example_ulid = "EXAMPLE0RE60SW7SVM2C8EGQAD" example_uri = "https://éxample.com/" expected_identifiers = 2 identifers_file = "identifiers.json" identifiers_loc = os.path.join( THIS_DIR, "fixtures", self.pid_declaration_dir, identifers_file ) all_identifier_types = ( self.traditional_identifiers + self.bound_identifier_types + self.declared_identifier_types ) mocker.patch.object( DeclarePIDs, "_retrieve_identifiers_path", return_value=identifiers_loc ) DeclarePIDs(job).pid_declaration(unit_uuid=self.package_uuid, sip_directory="") # Declare PIDs allows us to assign PIDs to very specific objects in a # transfer. sip_mdl = SIP.objects.filter(uuid=self.package_uuid).first() files = File.objects.filter(sip=self.package_uuid, filegrpuse="original").all() dir_mdl = Directory.objects.filter( currentlocation__contains="%SIPDirectory%objects/" ) assert len(files) == files_no, "Number of files returned is incorrect" assert len(dir_mdl) == dirs_no, "Number of directories returned is incorrect" for mdl in chain((sip_mdl,), files, dir_mdl): bound = {idfr.type: idfr.value for idfr in mdl.identifiers.all()} assert ( len(bound) == expected_identifiers ), "Number of identifiers is incorrect" assert set(bound.keys()) == set( self.declared_identifier_types ), "Returned keys are not in expected list" for key, value in bound.items(): assert value, "Returned an empty value for an identifier" if key == self.pid_exid: assert example_uri in value, "Example URI type not preserved" if key == self.pid_ulid: assert len(example_ulid) == len(value) # Use the previous PID binding vcr cassettes to ensure declared PIDs can # co-exist with bound ones. mocker.patch.object( bind_pids, "_get_unique_acc_no", return_value=self.package_uuid ) mocker.patch.object( bind_pids, "_validate_handle_server_config", return_value=None ) with vcr_cassettes.use_cassette( "test_bind_pids_to_sip_and_dirs.yaml" ) as cassette: # Primary entry-point for the bind_pids microservice job. bind_pids.main(self.job, self.package_uuid, "", True) for mdl in chain((sip_mdl,), dir_mdl): dir_dmd_sec = create_mets_v2.getDirDmdSec(mdl, "") id_type = dir_dmd_sec.xpath( "//premis:objectIdentifierType", namespaces={"premis": ns.premisNS} ) id_value = dir_dmd_sec.xpath( "//premis:objectIdentifierValue", namespaces={"premis": ns.premisNS} ) assert len(id_type) == len( all_identifier_types ), "Identifier type count is incorrect" assert len(id_value) == len( all_identifier_types ), "Identifier value count is incorrect" for key, value in dict(zip(id_type, id_value)).items(): if key == self.pid_exid: assert example_uri in value, "Example URI not preserved" if key == self.pid_ulid: assert len(example_ulid) == len(value) for file_ in files: with vcr_cassettes.use_cassette("test_bind_pid_to_files.yaml") as cassette: bind_pid.main(self.job, file_.pk, True) assert cassette.all_played for file_mdl in files: file_level_premis = create_mets_v2.create_premis_object(file_mdl.pk) id_type = file_level_premis.xpath( "//premis:objectIdentifierType", namespaces={"premis": ns.premisNS} ) id_value = file_level_premis.xpath( "//premis:objectIdentifierValue", namespaces={"premis": ns.premisNS} ) assert len(id_type) == len( all_identifier_types ), "Identifier type count is incorrect" assert len(id_value) == len( all_identifier_types ), "Identifier value count is incorrect" for key, value in dict(zip(id_type, id_value)).items(): if key == self.pid_exid: assert example_uri in value, "Example URI not preserved" if key == self.pid_ulid: assert len(example_ulid) == len(value)