|
| 1 | +class FAIRTest |
| 2 | + def self.fc_data_identifier_in_metadata_meta |
| 3 | + { |
| 4 | + testversion: HARVESTER_VERSION + ':' + 'Tst-2.0.1', |
| 5 | + testname: 'OSTrails Core: Data Identifier in Metadata', |
| 6 | + testid: 'fc_data_identifier_in_metadata', |
| 7 | + description: 'Test that the identifier of the data is an unambiguous element of the metadata. Tested options are schema:distribution, http://www.w3.org/ns/ldp#contains, iao:IAO_0000136, IAO:0000136,ldp:contains,foaf:primaryTopic,schema:distribution,schema:contentUrl,schema,mainEntity,schema:codeRepository,schema:distribution,schema:contentUrl, dcat:distribution, dcat:dataset,dcat:downloadURL,dcat:accessURL,sio:SIO_000332, sio:is-about, obo:IAO_0000136', |
| 8 | + metric: 'https://w3id.org/fair-metrics/general/FM_F3_M_MetaIdent', |
| 9 | + indicators: 'https://doi.org/10.25504/FAIRsharing.820324', |
| 10 | + type: 'http://edamontology.org/operation_2428', |
| 11 | + license: 'https://creativecommons.org/publicdomain/zero/1.0/', |
| 12 | + keywords: ['FAIR Assessment', 'FAIR Principles'], |
| 13 | + themes: ['http://edamontology.org/topic_4012'], |
| 14 | + organization: 'OSTrails Project', |
| 15 | + org_url: 'https://ostrails.eu/', |
| 16 | + responsible_developer: 'Mark D Wilkinson', |
| 17 | + email: 'mark.wilkinson@upm.es', |
| 18 | + response_description: 'The response is "pass", "fail" or "indeterminate"', |
| 19 | + schemas: { 'resource_identifier' => ['string', 'the GUID being tested'] }, |
| 20 | + organizations: [{ 'name' => 'OSTrails Project', 'url' => 'https://ostrails.eu/' }], |
| 21 | + individuals: [{ 'name' => 'Mark D Wilkinson', 'email' => 'mark.wilkinson@upm.es' }], |
| 22 | + creator: 'https://orcid.org/0000-0001-6960-357X', |
| 23 | + protocol: ENV.fetch('TEST_PROTOCOL', 'https'), |
| 24 | + host: ENV.fetch('TEST_HOST', 'localhost'), |
| 25 | + basePath: ENV.fetch('TEST_PATH', '/tests') |
| 26 | + } |
| 27 | + end |
| 28 | + |
| 29 | + def self.fc_data_identifier_in_metadata(guid:) |
| 30 | + FtrRuby::Output.clear_comments |
| 31 | + |
| 32 | + output = FtrRuby::Output.new( |
| 33 | + testedGUID: guid, |
| 34 | + meta: fc_data_identifier_in_metadata_meta |
| 35 | + ) |
| 36 | + output.comments << "INFO: TEST VERSION '#{fc_data_identifier_in_metadata_meta[:testversion]}'\n" |
| 37 | + |
| 38 | + metadata = FAIRChampionHarvester::Core.resolveit(guid) # this is where the magic happens! |
| 39 | + |
| 40 | + metadata.comments.each do |c| |
| 41 | + output.comments << c |
| 42 | + end |
| 43 | + |
| 44 | + if metadata.guidtype == 'unknown' |
| 45 | + output.score = 'indeterminate' |
| 46 | + output.comments << "INDETERMINATE: The identifier #{guid} did not match any known identification system.\n" |
| 47 | + return output.createEvaluationResponse |
| 48 | + end |
| 49 | + |
| 50 | + hash = metadata.hash |
| 51 | + graph = metadata.graph |
| 52 | + properties = FAIRChampionHarvester::Core.deep_dive_properties(hash) |
| 53 | + ############################################################################################################# |
| 54 | + ############################################################################################################# |
| 55 | + ############################################################################################################# |
| 56 | + ############################################################################################################# |
| 57 | + |
| 58 | + output.comments << "INFO: Searching metadata for likely identifiers to the data record\n" |
| 59 | + identifier = nil |
| 60 | + |
| 61 | + properties.each do |keyval| |
| 62 | + _ = nil |
| 63 | + (key, value) = keyval |
| 64 | + key = key.to_s |
| 65 | + |
| 66 | + output.comments << "INFO: Searching hash-style metadata for keys indicating a pointer to data.\n" |
| 67 | + FAIRChampionHarvester::Utils::DATA_PREDICATES.each do |prop| |
| 68 | + prop =~ %r{.*[#/]([^#/]+)$} |
| 69 | + prop = ::Regexp.last_match(1) |
| 70 | + output.comments << "INFO: Searching for key: #{prop}.\n" |
| 71 | + if key == prop |
| 72 | + output.comments << "INFO: found '#{prop}' in metadata. Setting data GUID to #{value} for next test.\n" |
| 73 | + identifier = value.to_s |
| 74 | + end |
| 75 | + end |
| 76 | + end |
| 77 | + |
| 78 | + if graph.size > 0 # have we found anything yet? |
| 79 | + output.comments << "INFO: Searching Linked Data metadata for predicates indicating a pointer to data.\n" |
| 80 | + identifier = FAIRChampionHarvester::CommonQueries::GetDataIdentifier(graph: graph) |
| 81 | + end |
| 82 | + |
| 83 | + if identifier =~ /\w+/ |
| 84 | + output.comments << "INFO: Now resolving #{identifier} to test its properties.\n" |
| 85 | + testIdentifier(guid: identifier, output: output) # this will add more comments and a score to @swagger |
| 86 | + else |
| 87 | + output.score = 'fail' |
| 88 | + output.comments << "INFO: Tested the following #{FAIRChampionHarvester::Utils::DATA_PREDICATES}(or their plain JSON hash-key equivalents)\n" |
| 89 | + output.comments << 'FAILURE: Was unable to locate the data identifier in the metadata using any (common) property/predicate reserved for this purpose.' |
| 90 | + end |
| 91 | + output.createEvaluationResponse |
| 92 | + end |
| 93 | + |
| 94 | + def self.testIdentifier(guid:, output:) |
| 95 | + # This is verbatim from the gen2_metadata_identifier_persistence |
| 96 | + type = FAIRChampionHarvester::Core.typeit(guid) # this is where the magic happens! |
| 97 | + |
| 98 | + output.comments << "INFO: The data guid (#{guid}) is detected as a #{type}.\n" |
| 99 | + |
| 100 | + if !type |
| 101 | + output.comments << "FAILURE: The GUID identifier of the data #{guid} did not match any known identification system.\n" |
| 102 | + output.score = 'fail' |
| 103 | + elsif type == 'uri' |
| 104 | + output.comments << "INFO: The data GUID appears to be a URL. Testing known URL persistence schemas (purl, oclc, fdlp, purlz, w3id, ark, doi(as URL)).\n" |
| 105 | + if (guid =~ /(purl)\./) or (guid =~ /(oclc)\./) or (guid =~ /(fdlp)\./) or (guid =~ /(purlz)\./) or (guid =~ /(w3id)\./) or (guid =~ /(ark):/) or (guid =~ /(doi.org)/) |
| 106 | + output.comments << "SUCCESS: The GUID conforms with #{::Regexp.last_match(1)}, which is known to be persistent.\n" |
| 107 | + output.score = 'pass' |
| 108 | + else |
| 109 | + output.comments << "FAILURE: The GUID does not conform with any known permanent-URL system.\n" |
| 110 | + output.score = 'fail' |
| 111 | + end |
| 112 | + else |
| 113 | + output.comments << "SUCCESS: The GUID of the data is a #{type}, which is known to be persistent.\n" |
| 114 | + output.score = 'pass' |
| 115 | + end |
| 116 | + end |
| 117 | + |
| 118 | + def self.fc_data_identifier_in_metadata_api |
| 119 | + api = FtrRuby::OpenAPI.new(meta: fc_data_identifier_in_metadata_meta) |
| 120 | + api.get_api |
| 121 | + end |
| 122 | + |
| 123 | + def self.fc_data_identifier_in_metadata_about |
| 124 | + dcat = FtrRuby::DCAT_Record.new(meta: fc_data_identifier_in_metadata_meta) |
| 125 | + dcat.get_dcat |
| 126 | + end |
| 127 | +end |
0 commit comments