diff --git a/.github/workflows/on_pr_to_main.yaml b/.github/workflows/on_pr_to_main.yaml index f41485b4..b8dec758 100644 --- a/.github/workflows/on_pr_to_main.yaml +++ b/.github/workflows/on_pr_to_main.yaml @@ -63,6 +63,6 @@ jobs: cd ../catprez && poetry run pytest cd ../profiles && poetry run pytest cd ../services && poetry run pytest - cd ../curies && poetry run pytest + cd ../identifier && poetry run pytest cd ../object && poetry run pytest cd ../caching && poetry run pytest diff --git a/.github/workflows/on_push_to_feature.yaml b/.github/workflows/on_push_to_feature.yaml index c37b07f7..1064d0c5 100644 --- a/.github/workflows/on_push_to_feature.yaml +++ b/.github/workflows/on_push_to_feature.yaml @@ -61,4 +61,5 @@ jobs: cd ../catprez && poetry run pytest cd ../profiles && poetry run pytest cd ../services && poetry run pytest + cd ../identifier && poetry run pytest # cd ../local_sparql_store && poetry run pytest diff --git a/README.md b/README.md index 075a9a78..d080c94d 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,14 @@ It expects "high quality" data to work well: Prez itself won't patch up bad or m Prez accesses data stored in an RDF database - a 'triplestore' - and uses the SPARQL Protocol to do so. Any SPARQL Protocol-compliant DB may be used. +## Redirect Service + +As a Linked Data server, Prez provides a redirect service at `/identifier/redirect` that accepts a query parameter `iri`, looks up the `iri` in the database for a `foaf:homepage` predicate with a value, and if it exists, return a redirect response to the value. + +This functionality is useful for institutions who issue their own persistent identifiers under a domain name that they control. The mapping from the persistent identifier to the target web resource is stored in the backend SPARQL store. + +This is an alternative solution to persistent identifier services such as the [w3id.org](https://w3id.org/). In some cases, it can be used together with such persistent identifier services to avoid the need to provide the redirect mapping in webserver config (NGINX, Apache HTTP, etc.) and instead, define the config as RDF data. + ## Development This section is for developing Prez locally. See the [Running](#running) options below for running Prez in production. @@ -84,20 +92,20 @@ via python-dotenv, or directly in the environment in which Prez is run. The envi instantiate a Pydantic `Settings` object which is used throughout Prez to configure its behaviour. To see how prez interprets/uses these environment variables see the `prez/config.py` file. -| Environment Variable | Description | -|---------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| SPARQL_ENDPOINT | Read-only SPARQL endpoint for SpacePrez | -| SPARQL_USERNAME | A username for Basic Auth against the SPARQL endpoint, if required by the SPARQL endpoint. | -| SPARQL_PASSWORD | A password for Basic Auth against the SPARQL endpoint, if required by the SPARQL endpoint. | -| PROTOCOL | The protocol used to deliver Prez. Usually 'http'. | -| HOST | The host on which to server prez, typically 'localhost'. | -| PORT | The port Prez is made accessible on. Default is 8000, could be 80 or anything else that your system has permission to use | -| SYSTEM_URI | Documentation property. An IRI for the Prez system as a whole. This value appears in the landing page RDF delivered by Prez ('/') | -| LOG_LEVEL | One of CRITICAL, ERROR, WARNING, INFO, DEBUG. Defaults to INFO. | -| LOG_OUTPUT | "file", "stdout", or "both" ("file" and "stdout"). Defaults to stdout. | -| PREZ_TITLE | The title to use for Prez instance | -| PREZ_DESC | A description to use for the Prez instance | -| DISABLE_PREFIX_GENERATION | Default value is `false`. Very large datasets may want to disable this setting and provide a predefined set of prefixes for namespaces as described in [Link Generation](README-Dev.md#link-generation). | +| Environment Variable | Description | +| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| SPARQL_ENDPOINT | Read-only SPARQL endpoint for SpacePrez | +| SPARQL_USERNAME | A username for Basic Auth against the SPARQL endpoint, if required by the SPARQL endpoint. | +| SPARQL_PASSWORD | A password for Basic Auth against the SPARQL endpoint, if required by the SPARQL endpoint. | +| PROTOCOL | The protocol used to deliver Prez. Usually 'http'. | +| HOST | The host on which to server prez, typically 'localhost'. | +| PORT | The port Prez is made accessible on. Default is 8000, could be 80 or anything else that your system has permission to use | +| SYSTEM_URI | Documentation property. An IRI for the Prez system as a whole. This value appears in the landing page RDF delivered by Prez ('/') | +| LOG_LEVEL | One of CRITICAL, ERROR, WARNING, INFO, DEBUG. Defaults to INFO. | +| LOG_OUTPUT | "file", "stdout", or "both" ("file" and "stdout"). Defaults to stdout. | +| PREZ_TITLE | The title to use for Prez instance | +| PREZ_DESC | A description to use for the Prez instance | +| DISABLE_PREFIX_GENERATION | Default value is `false`. Very large datasets may want to disable this setting and provide a predefined set of prefixes for namespaces as described in [Link Generation](README-Dev.md#link-generation). | ### Running in a Container diff --git a/prez/app.py b/prez/app.py index 530f669e..f9f0324c 100644 --- a/prez/app.py +++ b/prez/app.py @@ -25,7 +25,7 @@ from prez.routers.spaceprez import router as spaceprez_router from prez.routers.sparql import router as sparql_router from prez.routers.vocprez import router as vocprez_router -from prez.routers.curie import router as curie_router +from prez.routers.identifier import router as identifier_router from prez.services.app_service import healthcheck_sparql_endpoints, count_objects from prez.services.app_service import populate_api_info, add_prefixes_to_prefix_graph from prez.services.exception_catchers import ( @@ -61,7 +61,7 @@ app.include_router(catprez_router) app.include_router(vocprez_router) app.include_router(spaceprez_router) -app.include_router(curie_router) +app.include_router(identifier_router) @app.middleware("http") diff --git a/prez/queries/identifier.py b/prez/queries/identifier.py new file mode 100644 index 00000000..149170a3 --- /dev/null +++ b/prez/queries/identifier.py @@ -0,0 +1,18 @@ +from textwrap import dedent + +from jinja2 import Template + + +def get_foaf_homepage_query(iri: str) -> str: + query = Template( + """ + PREFIX foaf: + + SELECT DISTINCT ?url + WHERE { + <{{ iri }}> foaf:homepage ?url . + } + """ + ).render(iri=iri) + + return dedent(query) diff --git a/prez/queries/vocprez.py b/prez/queries/vocprez.py index 7378fac7..a1412b23 100644 --- a/prez/queries/vocprez.py +++ b/prez/queries/vocprez.py @@ -63,11 +63,15 @@ def get_concept_scheme_top_concepts_query(iri: str, page: int, per_page: int) -> ?concept prez:childrenCount ?narrowerChildrenCount . ?iri prez:childrenCount ?childrenCount . ?iri skos:hasTopConcept ?concept . + ?iri rdf:type ?type . + ?concept rdf:type ?conceptType . } WHERE { BIND(<{{ iri }}> as ?iri) ?iri skos:hasTopConcept ?concept . ?concept skos:prefLabel ?label . + ?iri rdf:type ?type . + ?concept rdf:type ?conceptType . { SELECT (COUNT(?childConcept) AS ?childrenCount) @@ -113,11 +117,15 @@ def get_concept_narrowers_query(iri: str, page: int, per_page: int) -> str: ?concept prez:childrenCount ?narrowerChildrenCount . ?iri prez:childrenCount ?childrenCount . ?iri skos:narrower ?concept . + ?iri rdf:type ?type . + ?concept rdf:type ?conceptType . } WHERE { BIND(<{{ iri }}> as ?iri) ?concept skos:broader ?iri . ?concept skos:prefLabel ?label . + ?iri rdf:type ?type . + ?concept rdf:type ?conceptType . { SELECT (COUNT(?childConcept) AS ?childrenCount) diff --git a/prez/reference_data/profiles/vocprez_default_profiles.ttl b/prez/reference_data/profiles/vocprez_default_profiles.ttl index e7adf7fa..505453ef 100644 --- a/prez/reference_data/profiles/vocprez_default_profiles.ttl +++ b/prez/reference_data/profiles/vocprez_default_profiles.ttl @@ -69,7 +69,7 @@ prez:VocPrezProfile dcterms:identifier "vocpub"^^xsd:token ; dcterms:title "VocPub" ; altr-ext:hasLabelPredicate skos:prefLabel ; - altr-ext:otherAnnotationProps schema:color ; + altr-ext:otherAnnotationProps schema:color, reg:status ; altr-ext:constrainsClass skos:ConceptScheme , skos:Concept , diff --git a/prez/renderers/renderer.py b/prez/renderers/renderer.py index 78ee6d81..8fa48b80 100644 --- a/prez/renderers/renderer.py +++ b/prez/renderers/renderer.py @@ -72,6 +72,24 @@ async def return_rdf(graph, mediatype, profile_headers): return StreamingResponse(content=obj, media_type=mediatype, headers=profile_headers) +async def get_annotations_graph(profile, graph, cache): + profile_annotation_props = get_annotation_predicates(profile) + queries_for_uncached, annotations_graph = await get_annotation_properties( + graph, **profile_annotation_props + ) + + if queries_for_uncached is None: + anots_from_triplestore = Graph() + else: + anots_from_triplestore = await queries_to_graph([queries_for_uncached]) + + if len(anots_from_triplestore) > 1: + annotations_graph += anots_from_triplestore + cache += anots_from_triplestore + + return annotations_graph + + async def return_annotated_rdf( graph: Graph, profile_headers, @@ -84,27 +102,19 @@ async def return_annotated_rdf( non_anot_mediatype = mediatype.replace("anot+", "") cache = tbox_cache - profile_annotation_props = get_annotation_predicates(profile) - queries_for_uncached, annotations_graph = await get_annotation_properties( - graph, **profile_annotation_props - ) - if queries_for_uncached is None: - anots_from_triplestore = Graph() - else: - anots_from_triplestore = await queries_to_graph([queries_for_uncached]) + previous_triples_count = len(graph) - if len(anots_from_triplestore) > 1: - annotations_graph += anots_from_triplestore - cache += anots_from_triplestore + # Expand the graph with annotations specified in the profile until no new statements are added. + while True: + graph += await get_annotations_graph(profile, graph, cache) + if len(graph) == previous_triples_count: + break + previous_triples_count = len(graph) generate_prez_links(graph, predicates_for_link_addition) - obj = io.BytesIO( - (graph + annotations_graph).serialize( - format=non_anot_mediatype, encoding="utf-8" - ) - ) + obj = io.BytesIO(graph.serialize(format=non_anot_mediatype, encoding="utf-8")) return StreamingResponse( content=obj, media_type=non_anot_mediatype, headers=profile_headers ) diff --git a/prez/routers/curie.py b/prez/routers/identifier.py similarity index 60% rename from prez/routers/curie.py rename to prez/routers/identifier.py index 8cff8c83..3e05f47e 100644 --- a/prez/routers/curie.py +++ b/prez/routers/identifier.py @@ -1,13 +1,43 @@ -from fastapi import APIRouter, HTTPException, status -from fastapi.responses import PlainTextResponse +from fastapi import APIRouter, HTTPException, status, Request +from fastapi.responses import PlainTextResponse, RedirectResponse from rdflib import URIRef from rdflib.term import _is_valid_uri from prez.services.curie_functions import get_uri_for_curie_id, get_curie_id_for_uri +from prez.queries.identifier import get_foaf_homepage_query +from prez.sparql.methods import sparql_query_non_async router = APIRouter(tags=["Identifier Resolution"]) +@router.get( + "/identifier/redirect", + summary="Get a redirect response to the resource landing page", + response_class=RedirectResponse, + responses={ + status.HTTP_404_NOT_FOUND: {"content": {"application/json": {}}}, + }, +) +def get_identifier_redirect_route(iri: str, request: Request): + """ + The `iri` query parameter is used to return a redirect response with the value from the `foaf:homepage` lookup. + If no value is found, a 404 HTTP response is returned. + """ + query = get_foaf_homepage_query(iri) + _, result = sparql_query_non_async(query) + url = None + for row in result: + url = row["url"]["value"] + + if url is None: + raise HTTPException( + status.HTTP_404_NOT_FOUND, f"No homepage found for IRI {iri}." + ) + + # Note: currently does not forward query parameters but we may want to implement this in the future. + return RedirectResponse(url, headers=request.headers) + + @router.get( "/identifier/curie/{iri:path}", summary="Get the IRI's CURIE identifier", diff --git a/prez/routers/object.py b/prez/routers/object.py index 8f9a941d..90176124 100644 --- a/prez/routers/object.py +++ b/prez/routers/object.py @@ -2,7 +2,7 @@ from starlette.responses import PlainTextResponse from prez.models import SpatialItem, VocabItem, CatalogItem -from prez.routers.curie import get_iri_route +from prez.routers.identifier import get_iri_route from prez.sparql.methods import sparql_query_non_async from prez.queries.object import object_inbound_query, object_outbound_query diff --git a/prez/routers/vocprez.py b/prez/routers/vocprez.py index 8b50d71c..a679cee2 100644 --- a/prez/routers/vocprez.py +++ b/prez/routers/vocprez.py @@ -29,7 +29,7 @@ get_concept_narrowers_query, ) from prez.response import StreamingTurtleAnnotatedResponse -from prez.routers.curie import get_iri_route +from prez.routers.identifier import get_iri_route router = APIRouter(tags=["VocPrez"]) diff --git a/tests/data/spaceprez/input/redirect-foaf-homepage.ttl b/tests/data/spaceprez/input/redirect-foaf-homepage.ttl new file mode 100644 index 00000000..1274566e --- /dev/null +++ b/tests/data/spaceprez/input/redirect-foaf-homepage.ttl @@ -0,0 +1,3 @@ +PREFIX foaf: + + foaf:homepage . diff --git a/tests/data/vocprez/expected_responses/beddingsurfacestructure_top_concepts.ttl b/tests/data/vocprez/expected_responses/beddingsurfacestructure_top_concepts.ttl new file mode 100644 index 00000000..8a27098b --- /dev/null +++ b/tests/data/vocprez/expected_responses/beddingsurfacestructure_top_concepts.ttl @@ -0,0 +1,255 @@ +PREFIX dcterms: +PREFIX ns1: +PREFIX ns2: +PREFIX rdfs: +PREFIX schema: +PREFIX skos: +PREFIX xsd: + + + a skos:ConceptScheme ; + ns2:status ; + skos:hasTopConcept + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + skos:prefLabel "BeddingSurfaceStructure"@en ; + ns1:childrenCount 21 ; +. + +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + +dcterms:identifier + rdfs:label "Identifier"@en ; + dcterms:description "Recommended practice is to identify the resource by means of a string conforming to an identification system. Examples include International Standard Book Number (ISBN), Digital Object Identifier (DOI), and Uniform Resource Name (URN). Persistent identifiers should be provided as HTTP URIs."@en ; +. + + + a skos:Concept ; + rdfs:label "Shrinkage (Desiccation) Cracks"@en ; + dcterms:identifier "bddngsrfcstrctr:CRACKDES"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Shrinkage (Desiccation) Cracks"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:CRACKDES" ; +. + + + a skos:Concept ; + rdfs:label "Synaeresis Cracks"@en ; + dcterms:identifier "bddngsrfcstrctr:CRACKSYN"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Synaeresis Cracks"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:CRACKSYN" ; +. + + + a skos:Concept ; + rdfs:label "Parting Lineation (Primary Current Lineation)"@en ; + dcterms:identifier "bddngsrfcstrctr:PART"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Parting Lineation (Primary Current Lineation)"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:PART" ; +. + + + a skos:Concept ; + rdfs:label "Rainspots"@en ; + dcterms:identifier "bddngsrfcstrctr:RAIN"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Rainspots"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RAIN" ; +. + + + a skos:Concept ; + rdfs:label "Ripples"@en ; + dcterms:identifier "bddngsrfcstrctr:RIP"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Ripples"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIP" ; +. + + + a skos:Concept ; + rdfs:label "Current Ripples"@en ; + dcterms:identifier "bddngsrfcstrctr:RIPCUR"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Current Ripples"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIPCUR" ; +. + + + a skos:Concept ; + rdfs:label "Linguoid Current Ripples"@en ; + dcterms:identifier "bddngsrfcstrctr:RIPCURLIN"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Linguoid Current Ripples"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIPCURLIN" ; +. + + + a skos:Concept ; + rdfs:label "Sinuous-Crested Current Rippled"@en ; + dcterms:identifier "bddngsrfcstrctr:RIPCURSIN"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Sinuous-Crested Current Rippled"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIPCURSIN" ; +. + + + a skos:Concept ; + rdfs:label "Straight-Crested Current Ripples"@en ; + dcterms:identifier "bddngsrfcstrctr:RIPCURSTR"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Straight-Crested Current Ripples"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIPCURSTR" ; +. + + + a skos:Concept ; + rdfs:label "Wave-Formed Ripples"@en ; + dcterms:identifier "bddngsrfcstrctr:RIPWAV"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Wave-Formed Ripples"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIPWAV" ; +. + + + a skos:Concept ; + rdfs:label "Interference Wave-Formed Ripples"@en ; + dcterms:identifier "bddngsrfcstrctr:RIPWAVINT"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Interference Wave-Formed Ripples"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIPWAVINT" ; +. + + + a skos:Concept ; + rdfs:label "Modified Wave-Formed Ripples"@en ; + dcterms:identifier "bddngsrfcstrctr:RIPWAVMOD"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Modified Wave-Formed Ripples"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:RIPWAVMOD" ; +. + + + a skos:Concept ; + rdfs:label "Trace Fossils"@en ; + dcterms:identifier "bddngsrfcstrctr:TF"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Trace Fossils"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TF" ; +. + + + a skos:Concept ; + rdfs:label "Crawling / Walking Tracks and Trails"@en ; + dcterms:identifier "bddngsrfcstrctr:TFCR"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Crawling / Walking Tracks and Trails"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TFCR" ; +. + + + a skos:Concept ; + rdfs:label "Foot Prints"@en ; + dcterms:identifier "bddngsrfcstrctr:TFCRFOOT"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Foot Prints"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TFCRFOOT" ; +. + + + a skos:Concept ; + rdfs:label "Grazing Traces"@en ; + dcterms:identifier "bddngsrfcstrctr:TFGRZ"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Grazing Traces"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TFGRZ" ; +. + + + a skos:Concept ; + rdfs:label "Coiled Grazing Traces"@en ; + dcterms:identifier "bddngsrfcstrctr:TFGRZCOIL"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Coiled Grazing Traces"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TFGRZCOIL" ; +. + + + a skos:Concept ; + rdfs:label "Meandering Grazing Traces"@en ; + dcterms:identifier "bddngsrfcstrctr:TFGRZMEAND"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Meandering Grazing Traces"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TFGRZMEAND" ; +. + + + a skos:Concept ; + rdfs:label "Radial Grazing Traces"@en ; + dcterms:identifier "bddngsrfcstrctr:TFGRZRAD"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Radial Grazing Traces"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TFGRZRAD" ; +. + + + a skos:Concept ; + rdfs:label "Resting Traces"@en ; + dcterms:identifier "bddngsrfcstrctr:TFREST"^^ns1:identifier ; + ns2:status ; + skos:prefLabel "Resting Traces"@en ; + ns1:childrenCount 0 ; + ns1:link "/v/vocab/ref:BeddingSurfaceStructure/bddngsrfcstrctr:TFREST" ; +. + + + skos:prefLabel "experimental"@en ; + schema:color "#eae72c" ; +. + + + skos:prefLabel "valid"@en ; + schema:color "#36a80d" ; +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/collection_listing_anot.ttl b/tests/data/vocprez/expected_responses/collection_listing_anot.ttl index 617a244e..3f2a822e 100644 --- a/tests/data/vocprez/expected_responses/collection_listing_anot.ttl +++ b/tests/data/vocprez/expected_responses/collection_listing_anot.ttl @@ -1,19 +1,35 @@ -@prefix dcterms: . -@prefix ns1: . -@prefix skos: . -@prefix xsd: . +PREFIX dcterms: +PREFIX ns1: +PREFIX rdfs: +PREFIX skos: +PREFIX xsd: - a skos:Collection ; + + a skos:Collection ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:definition "Borehole purposes applicable to regulatory notification forms."@en ; skos:prefLabel "PGGD selection"@en ; - ns1:link "/v/collection/brhl-prps:pggd" . + ns1:link "/v/collection/brhl-prps:pggd" ; +. - a skos:Collection ; +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + +dcterms:provenance + rdfs:label "Provenance"@en ; + dcterms:description "The statement may include a description of any changes successive custodians made to the resource."@en ; +. + + + a skos:Collection ; dcterms:provenance "this vocabulary" ; skos:definition "All Concepts in this vocabulary" ; skos:prefLabel "Contact Type - All Concepts"@en ; - ns1:link "/v/collection/cgi:contacttype" . - -skos:Collection ns1:count 2 . + ns1:link "/v/collection/cgi:contacttype" ; +. +skos:Collection + ns1:count 2 ; +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/collection_listing_item.ttl b/tests/data/vocprez/expected_responses/collection_listing_item.ttl index 921b20cc..47585167 100644 --- a/tests/data/vocprez/expected_responses/collection_listing_item.ttl +++ b/tests/data/vocprez/expected_responses/collection_listing_item.ttl @@ -1,197 +1,318 @@ -@prefix dcterms: . -@prefix ns1: . -@prefix rdfs: . -@prefix skos: . -@prefix xsd: . - -dcterms:identifier rdfs:label "Identifier"@en ; - dcterms:description "Recommended practice is to identify the resource by means of a string conforming to an identification system. Examples include International Standard Book Number (ISBN), Digital Object Identifier (DOI), and Uniform Resource Name (URN). Persistent identifiers should be provided as HTTP URIs."@en . - -dcterms:provenance rdfs:label "Provenance"@en ; - dcterms:description "The statement may include a description of any changes successive custodians made to the resource."@en . - - a skos:Collection ; +PREFIX dcterms: +PREFIX ns1: +PREFIX ns2: +PREFIX rdfs: +PREFIX skos: +PREFIX xsd: + +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + +dcterms:identifier + rdfs:label "Identifier"@en ; + dcterms:description "Recommended practice is to identify the resource by means of a string conforming to an identification system. Examples include International Standard Book Number (ISBN), Digital Object Identifier (DOI), and Uniform Resource Name (URN). Persistent identifiers should be provided as HTTP URIs."@en ; +. + +dcterms:provenance + rdfs:label "Provenance"@en ; + dcterms:description "The statement may include a description of any changes successive custodians made to the resource."@en ; +. + + + a skos:Collection ; dcterms:identifier "contacttype"^^xsd:token ; dcterms:provenance "this vocabulary" ; skos:definition "All Concepts in this vocabulary" ; - skos:member , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , + skos:member + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , ; - skos:prefLabel "Contact Type - All Concepts"@en . + skos:prefLabel "Contact Type - All Concepts"@en ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "alteration facies contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:alteration_facies_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:alteration_facies_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "angular unconformable contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:angular_unconformable_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:angular_unconformable_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "buttress unconformity"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:buttress_unconformity" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:buttress_unconformity" ; +. - dcterms:provenance "FGDC"@en ; + + dcterms:provenance "FGDC"@en ; + ns2:status ; skos:prefLabel "chronostratigraphic-zone contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:chronostratigraphic_zone_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:chronostratigraphic_zone_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "conductivity contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:conductivity_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:conductivity_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "conformable contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:conformable_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:conformable_contact" ; +. - dcterms:provenance "adapted from Jackson, 1997, page 137, NADM C1 2004"@en ; + + dcterms:provenance "adapted from Jackson, 1997, page 137, NADM C1 2004"@en ; + ns2:status ; skos:prefLabel "contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "deformation zone contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:deformation_zone_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:deformation_zone_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "density contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:density_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:density_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "depositional contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:depositional_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:depositional_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "disconformable contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:disconformable_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:disconformable_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "faulted contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:faulted_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:faulted_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "geologic province contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:geologic_province_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:geologic_province_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "geophysical contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:geophysical_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:geophysical_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "glacial stationary line"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:glacial_stationary_line" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:glacial_stationary_line" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "igneous intrusive contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:igneous_intrusive_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:igneous_intrusive_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "igneous phase contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:igneous_phase_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:igneous_phase_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "impact structure boundary"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:impact_structure_boundary" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:impact_structure_boundary" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "lithogenetic contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:lithogenetic_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:lithogenetic_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "magnetic contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetic_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetic_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "magnetic polarity contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetic_polarity_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetic_polarity_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "magnetic susceptiblity contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetic_susceptiblity_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetic_susceptiblity_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "magnetization contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetization_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:magnetization_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "metamorphic contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:metamorphic_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:metamorphic_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "metamorphic facies contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:metamorphic_facies_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:metamorphic_facies_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "metasomatic facies contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:metasomatic_facies_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:metasomatic_facies_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "mineralisation assemblage contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:mineralisation_assemblage_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:mineralisation_assemblage_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "nonconformable contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:nonconformable_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:nonconformable_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "paraconformable contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:paraconformable_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:paraconformable_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "radiometric contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:radiometric_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:radiometric_contact" ; +. - dcterms:provenance "base on Nichols, Gary, 1999, Sedimentology and stratigraphy, Blackwell, p. 62-63."@en ; + + dcterms:provenance "base on Nichols, Gary, 1999, Sedimentology and stratigraphy, Blackwell, p. 62-63."@en ; + ns2:status ; skos:prefLabel "sedimentary facies contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:sedimentary_facies_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:sedimentary_facies_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "sedimentary intrusive contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:sedimentary_intrusive_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:sedimentary_intrusive_contact" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "seismic contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:seismic_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:seismic_contact" ; +. - dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + + dcterms:provenance "Neuendorf, K.K.E, Mehl, J.P. & Jackson, J.A. (eds), 2005. Glossary of geology, 5th Edition. American Geological Institute, Alexandria, 779 p."@en ; + ns2:status ; skos:prefLabel "unconformable contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:unconformable_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:unconformable_contact" ; +. - dcterms:provenance "this vocabulary, concept to encompass boundary of caldron, caldera, or crater."@en ; + + dcterms:provenance "this vocabulary, concept to encompass boundary of caldron, caldera, or crater."@en ; + ns2:status ; skos:prefLabel "volcanic subsidence zone boundary"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:volcanic_subsidence_zone_boundary" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:volcanic_subsidence_zone_boundary" ; +. - dcterms:provenance "this vocabulary"@en ; + + dcterms:provenance "this vocabulary"@en ; + ns2:status ; skos:prefLabel "weathering contact"@en ; - ns1:link "/v/collection/cgi:contacttype/cntcttyp:weathering_contact" . + ns1:link "/v/collection/cgi:contacttype/cntcttyp:weathering_contact" ; +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/concept-coal.ttl b/tests/data/vocprez/expected_responses/concept-coal.ttl index 9bc5d8ce..2eb96cbf 100644 --- a/tests/data/vocprez/expected_responses/concept-coal.ttl +++ b/tests/data/vocprez/expected_responses/concept-coal.ttl @@ -1,20 +1,27 @@ PREFIX bhpur: PREFIX cs4: PREFIX dcterms: -PREFIX ns1: +PREFIX ns1: +PREFIX ns2: PREFIX rdfs: +PREFIX schema: PREFIX skos: bhpur:coal a skos:Concept ; - dcterms:identifier "brhl-prps:coal"^^ns1:identifier ; + dcterms:identifier "brhl-prps:coal"^^ns2:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; rdfs:isDefinedBy cs4: ; skos:definition "Wells and bores drilled to facilitate the mining of coal under permits governed by the Queensland Mineral Resources Act 1989"@en ; skos:inScheme cs4: ; skos:prefLabel "Coal"@en ; skos:topConceptOf cs4: ; - ns1:link "/v/vocab/df:borehole-purpose/brhl-prps:coal" ; + ns2:link "/v/vocab/df:borehole-purpose/brhl-prps:coal" ; +. + +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; . dcterms:identifier @@ -27,7 +34,13 @@ dcterms:provenance dcterms:description "The statement may include a description of any changes successive custodians made to the resource."@en ; . + + skos:prefLabel "stable"@en ; + schema:color "#2e8c09" ; +. + cs4: dcterms:provenance "Compiled by the Geological Survey of Queensland" ; + ns1:status ; skos:prefLabel "Borehole Purpose"@en ; -. +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/concept-open-cut-coal-mining.ttl b/tests/data/vocprez/expected_responses/concept-open-cut-coal-mining.ttl index b529b7b6..76b88c71 100644 --- a/tests/data/vocprez/expected_responses/concept-open-cut-coal-mining.ttl +++ b/tests/data/vocprez/expected_responses/concept-open-cut-coal-mining.ttl @@ -1,20 +1,27 @@ PREFIX bhpur: PREFIX cs4: PREFIX dcterms: -PREFIX ns1: +PREFIX ns1: +PREFIX ns2: PREFIX rdfs: +PREFIX schema: PREFIX skos: bhpur:open-cut-coal-mining a skos:Concept ; - dcterms:identifier "brhl-prps:open-cut-coal-mining"^^ns1:identifier ; + dcterms:identifier "brhl-prps:open-cut-coal-mining"^^ns2:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; rdfs:isDefinedBy cs4: ; skos:broader bhpur:coal ; skos:definition "Wells drilled for the purpose of assessing coal resources for an open cut coal mine."@en ; skos:inScheme cs4: ; skos:prefLabel "Open-Cut Coal Mining"@en ; - ns1:link "/v/vocab/df:borehole-purpose/brhl-prps:open-cut-coal-mining" ; + ns2:link "/v/vocab/df:borehole-purpose/brhl-prps:open-cut-coal-mining" ; +. + +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; . dcterms:identifier @@ -32,7 +39,13 @@ bhpur:coal skos:prefLabel "Coal"@en ; . + + skos:prefLabel "stable"@en ; + schema:color "#2e8c09" ; +. + cs4: dcterms:provenance "Compiled by the Geological Survey of Queensland" ; + ns1:status ; skos:prefLabel "Borehole Purpose"@en ; -. +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/concept-with-2-narrower-concepts.ttl b/tests/data/vocprez/expected_responses/concept-with-2-narrower-concepts.ttl index 34197ca2..ec1cb428 100644 --- a/tests/data/vocprez/expected_responses/concept-with-2-narrower-concepts.ttl +++ b/tests/data/vocprez/expected_responses/concept-with-2-narrower-concepts.ttl @@ -5,6 +5,7 @@ PREFIX skos: PREFIX xsd: + a skos:Concept ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:narrower , @@ -13,12 +14,23 @@ PREFIX xsd: ns1:childrenCount 2 ; . +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + dcterms:identifier rdfs:label "Identifier"@en ; dcterms:description "Recommended practice is to identify the resource by means of a string conforming to an identification system. Examples include International Standard Book Number (ISBN), Digital Object Identifier (DOI), and Uniform Resource Name (URN). Persistent identifiers should be provided as HTTP URIs."@en ; . +dcterms:provenance + rdfs:label "Provenance"@en ; + dcterms:description "The statement may include a description of any changes successive custodians made to the resource."@en ; +. + + a skos:Concept ; dcterms:identifier "brhl-prps:open-cut-coal-mining"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Open-Cut Coal Mining"@en ; @@ -27,9 +39,10 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:underground-coal-mining"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Underground Coal Mining"@en ; ns1:childrenCount 0 ; ns1:link "/v/vocab/def2:borehole-purpose/brhl-prps:underground-coal-mining" ; -. +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/concept_scheme_no_children.ttl b/tests/data/vocprez/expected_responses/concept_scheme_no_children.ttl index 27d246dd..824637d6 100644 --- a/tests/data/vocprez/expected_responses/concept_scheme_no_children.ttl +++ b/tests/data/vocprez/expected_responses/concept_scheme_no_children.ttl @@ -1,6 +1,6 @@ PREFIX dcterms: -PREFIX ns1: -PREFIX ns2: +PREFIX ns1: +PREFIX ns2: PREFIX owl: PREFIX prov: PREFIX rdfs: @@ -17,14 +17,14 @@ PREFIX xsd: dcterms:modified "2023-03-16"^^xsd:date ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; dcterms:publisher ; - ns2:status ; + ns1:status ; skos:definition "The primary purpose of a borehole based on the legislative State Act and/or the resources industry sector."@en ; skos:prefLabel "Borehole Purpose no children"@en ; prov:qualifiedDerivation [ prov:entity ; prov:hadRole ] ; - ns1:childrenCount 0 ; + ns2:childrenCount 0 ; . dcterms:created @@ -37,6 +37,11 @@ dcterms:creator dcterms:description "Recommended practice is to identify the creator with a URI. If this is not possible or feasible, a literal value that identifies the creator may be provided."@en ; . +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + dcterms:modified rdfs:label "Date Modified"@en ; dcterms:description "Recommended practice is to describe the date, date/time, or period of time as recommended for the property Date, of which this is a subproperty."@en ; @@ -54,4 +59,4 @@ dcterms:publisher skos:prefLabel "stable"@en ; schema:color "#2e8c09" ; -. +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/concept_scheme_top_concepts_with_children.ttl b/tests/data/vocprez/expected_responses/concept_scheme_top_concepts_with_children.ttl index 75b1de09..f800d098 100644 --- a/tests/data/vocprez/expected_responses/concept_scheme_top_concepts_with_children.ttl +++ b/tests/data/vocprez/expected_responses/concept_scheme_top_concepts_with_children.ttl @@ -1,11 +1,18 @@ PREFIX dcterms: PREFIX ns1: +PREFIX ns2: +PREFIX owl: PREFIX rdfs: +PREFIX schema: PREFIX skos: PREFIX xsd: + a + owl:Ontology , + skos:ConceptScheme ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; + ns2:status ; skos:hasTopConcept , , @@ -19,12 +26,23 @@ PREFIX xsd: ns1:childrenCount 8 ; . +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + dcterms:identifier rdfs:label "Identifier"@en ; dcterms:description "Recommended practice is to identify the resource by means of a string conforming to an identification system. Examples include International Standard Book Number (ISBN), Digital Object Identifier (DOI), and Uniform Resource Name (URN). Persistent identifiers should be provided as HTTP URIs."@en ; . +dcterms:provenance + rdfs:label "Provenance"@en ; + dcterms:description "The statement may include a description of any changes successive custodians made to the resource."@en ; +. + + a skos:Concept ; dcterms:identifier "brhl-prps:coal"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Coal"@en ; @@ -33,6 +51,7 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:geothermal"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Geothermal"@en ; @@ -41,6 +60,7 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:greenhouse-gas-storage"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Greenhouse Gas Storage"@en ; @@ -49,6 +69,7 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:mineral"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Mineral"@en ; @@ -57,6 +78,7 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:non-industry"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Non-Industry"@en ; @@ -65,6 +87,7 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:oil-shale"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Oil Shale"@en ; @@ -73,6 +96,7 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:petroleum"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Petroleum"@en ; @@ -81,9 +105,15 @@ dcterms:identifier . + a skos:Concept ; dcterms:identifier "brhl-prps:water"^^ns1:identifier ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; skos:prefLabel "Water"@en ; ns1:childrenCount 0 ; ns1:link "/v/vocab/def2:borehole-purpose/brhl-prps:water" ; . + + + skos:prefLabel "stable"@en ; + schema:color "#2e8c09" ; +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/concept_scheme_with_children.ttl b/tests/data/vocprez/expected_responses/concept_scheme_with_children.ttl index 86aadff0..012a004b 100644 --- a/tests/data/vocprez/expected_responses/concept_scheme_with_children.ttl +++ b/tests/data/vocprez/expected_responses/concept_scheme_with_children.ttl @@ -1,6 +1,6 @@ PREFIX dcterms: -PREFIX ns1: -PREFIX ns2: +PREFIX ns1: +PREFIX ns2: PREFIX owl: PREFIX prov: PREFIX rdfs: @@ -17,14 +17,14 @@ PREFIX xsd: dcterms:modified "2023-03-16"^^xsd:date ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; dcterms:publisher ; - ns1:status ; + ns2:status ; skos:definition "The primary purpose of a borehole based on the legislative State Act and/or the resources industry sector."@en ; skos:prefLabel "Borehole Purpose"@en ; prov:qualifiedDerivation [ prov:entity ; prov:hadRole ] ; - ns2:childrenCount 8 ; + ns1:childrenCount 8 ; . dcterms:created @@ -37,6 +37,11 @@ dcterms:creator dcterms:description "Recommended practice is to identify the creator with a URI. If this is not possible or feasible, a literal value that identifies the creator may be provided."@en ; . +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + dcterms:modified rdfs:label "Date Modified"@en ; dcterms:description "Recommended practice is to describe the date, date/time, or period of time as recommended for the property Date, of which this is a subproperty."@en ; @@ -54,4 +59,4 @@ dcterms:publisher skos:prefLabel "stable"@en ; schema:color "#2e8c09" ; -. +. \ No newline at end of file diff --git a/tests/data/vocprez/expected_responses/vocab_listing_anot.ttl b/tests/data/vocprez/expected_responses/vocab_listing_anot.ttl index db0eb520..ff6a8fa5 100644 --- a/tests/data/vocprez/expected_responses/vocab_listing_anot.ttl +++ b/tests/data/vocprez/expected_responses/vocab_listing_anot.ttl @@ -7,6 +7,13 @@ PREFIX schema: PREFIX skos: PREFIX xsd: + + a skos:ConceptScheme ; + ns1:status ; + skos:prefLabel "BeddingSurfaceStructure"@en ; + ns2:link "/v/vocab/ref:BeddingSurfaceStructure" ; +. + a skos:ConceptScheme ; dcterms:provenance "Compiled by the Geological Survey of Queensland" ; @@ -33,6 +40,16 @@ PREFIX xsd: ns2:link "/v/vocab/def2:borehole-purpose-no-children" ; . +dcterms:description + rdfs:label "Description"@en ; + dcterms:description "Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource."@en ; +. + +dcterms:provenance + rdfs:label "Provenance"@en ; + dcterms:description "The statement may include a description of any changes successive custodians made to the resource."@en ; +. + dcterms:publisher rdfs:label "Publisher"@en ; . @@ -68,11 +85,16 @@ dcterms:publisher ns2:link "/v/vocab/def:warox-alteration-types" ; . + + skos:prefLabel "experimental"@en ; + schema:color "#eae72c" ; +. + skos:prefLabel "stable"@en ; schema:color "#2e8c09" ; . skos:ConceptScheme - ns2:count 6 ; -. + ns2:count 7 ; +. \ No newline at end of file diff --git a/tests/data/vocprez/input/beddingsurfacestructure.ttl b/tests/data/vocprez/input/beddingsurfacestructure.ttl new file mode 100644 index 00000000..eeca1838 --- /dev/null +++ b/tests/data/vocprez/input/beddingsurfacestructure.ttl @@ -0,0 +1,177 @@ + . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + . + . + "A dictionary of bed surface structures, eg. ripples, dessication cracks."@en . + "Created for internal use in corporate BGS relational database"@en . + "BeddingSurfaceStructure"@en . + "2003-06-04"^^ . + "2003-06-04"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure"^^ . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + "Shrinkage (Desiccation) Cracks"@en . + "Synaeresis Cracks"@en . + "Parting Lineation (Primary Current Lineation)"@en . + "Rainspots"@en . + "Ripples"@en . + "Current Ripples"@en . + "Linguoid Current Ripples"@en . + "Sinuous-Crested Current Rippled"@en . + "Straight-Crested Current Ripples"@en . + "Wave-Formed Ripples"@en . + "Interference Wave-Formed Ripples"@en . + "Modified Wave-Formed Ripples"@en . + "Wind Ripples"@en . + "Trace Fossils"@en . + "Crawling / Walking Tracks and Trails"@en . + "Foot Prints"@en . + "Grazing Traces"@en . + "Coiled Grazing Traces"@en . + "Meandering Grazing Traces"@en . + "Radial Grazing Traces"@en . + "Resting Traces"@en . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + "SHRINKAGE (DESICCATION) CRACKS"@en . + "SYNAERESIS CRACKS"@en . + "PARTING LINEATION (PRIMARY CURRENT LINEATION)"@en . + "RAINSPOTS"@en . + "RIPPLES, TYPE UNDEFINED"@en . + "CURRENT RIPPLES"@en . + "LINGUOID CURRENT RIPPLES"@en . + "SINUOUS-CRESTED CURRENT RIPPLED"@en . + "STRAIGHT-CRESTED CURRENT RIPPLES"@en . + "WAVE-FORMED RIPPLES"@en . + "INTERFERENCE WAVE-FORMED RIPPLES"@en . + "MODIFIED WAVE-FORMED RIPPLES"@en . + "WIND RIPPLES"@en . + "TRACE FOSSILS, TYPE UNDEFINED"@en . + "CRAWLING / WALKING TRACKS AND TRAILS"@en . + "FOOT PRINTS"@en . + "GRAZING TRACES"@en . + "COILED GRAZING TRACES"@en . + "MEANDERING GRAZING TRACES"@en . + "RADIAL GRAZING TRACES"@en . + "RESTING TRACES"@en . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + . + "Shrinkage (Desiccation) Cracks"@en . + "Synaeresis Cracks"@en . + "Parting Lineation (Primary Current Lineation)"@en . + "Rainspots"@en . + "Ripples"@en . + "Current Ripples"@en . + "Linguoid Current Ripples"@en . + "Sinuous-Crested Current Rippled"@en . + "Straight-Crested Current Ripples"@en . + "Wave-Formed Ripples"@en . + "Interference Wave-Formed Ripples"@en . + "Modified Wave-Formed Ripples"@en . + "Wind Ripples"@en . + "Trace Fossils"@en . + "Crawling / Walking Tracks and Trails"@en . + "Foot Prints"@en . + "Grazing Traces"@en . + "Coiled Grazing Traces"@en . + "Meandering Grazing Traces"@en . + "Radial Grazing Traces"@en . + "Resting Traces"@en . diff --git a/tests/curies/conftest.py b/tests/identifier/conftest.py similarity index 100% rename from tests/curies/conftest.py rename to tests/identifier/conftest.py diff --git a/tests/curies/test_curie_endpoint.py b/tests/identifier/test_curie_endpoint.py similarity index 100% rename from tests/curies/test_curie_endpoint.py rename to tests/identifier/test_curie_endpoint.py diff --git a/tests/curies/test_curie_generation.py b/tests/identifier/test_curie_generation.py similarity index 100% rename from tests/curies/test_curie_generation.py rename to tests/identifier/test_curie_generation.py diff --git a/tests/identifier/test_redirect_endpoint.py b/tests/identifier/test_redirect_endpoint.py new file mode 100644 index 00000000..26ce540b --- /dev/null +++ b/tests/identifier/test_redirect_endpoint.py @@ -0,0 +1,72 @@ +import os +import subprocess +from time import sleep + +import pytest +from fastapi.testclient import TestClient + +PREZ_DIR = os.getenv("PREZ_DIR") +LOCAL_SPARQL_STORE = os.getenv("LOCAL_SPARQL_STORE") + + +@pytest.fixture(scope="module") +def test_client(request): + print("Run Local SPARQL Store") + p1 = subprocess.Popen(["python", str(LOCAL_SPARQL_STORE), "-p", "3032"]) + sleep(1) + + def teardown(): + print("\nDoing teardown") + p1.kill() + + request.addfinalizer(teardown) + + # must only import app after config.py has been altered above so config is retained + from prez.app import app + + return TestClient(app) + + +@pytest.mark.parametrize( + "iri, url, expected_response_code, accept_header_value", + [ + [ + "http://data.bgs.ac.uk/id/dataHolding/13603129", + "http://metadata.bgs.ac.uk/geonetwork/srv/eng/catalog.search#/metadata/9df8df53-2a1d-37a8-e044-0003ba9b0d98", + 307, + "", + ], + ["http://example.com/non-existent", None, 404, ""], + [ + "http://data.bgs.ac.uk/id/dataHolding/13603129", + "http://metadata.bgs.ac.uk/geonetwork/srv/eng/catalog.search#/metadata/9df8df53-2a1d-37a8-e044-0003ba9b0d98", + 307, + "text/turtle", + ], + ], +) +def test_redirect_endpoint( + test_client: TestClient, + iri: str, + url: str, + expected_response_code, + accept_header_value: str | None, +): + params = {"iri": iri} + headers = {"accept": accept_header_value} + response = test_client.get( + "/identifier/redirect", params=params, headers=headers, follow_redirects=False + ) + + if expected_response_code != 404: + assert response.status_code == expected_response_code + assert response.headers.get("location") == url + + if accept_header_value: + assert response.headers.get("accept") == accept_header_value + else: + assert response.status_code == expected_response_code + assert response.headers.get("content-type") == "application/json" + data = response.json() + assert data.get("status_code") == expected_response_code + assert data.get("detail") == f"No homepage found for IRI {iri}." diff --git a/tests/vocprez/test_endpoints_vocprez.py b/tests/vocprez/test_endpoints_vocprez.py index cd099809..b4a572fa 100644 --- a/tests/vocprez/test_endpoints_vocprez.py +++ b/tests/vocprez/test_endpoints_vocprez.py @@ -92,6 +92,11 @@ def test_concept_scheme( "empty.ttl", "Return concept scheme and a prez:childrenCount of 0", ], + [ + "http://data.bgs.ac.uk/ref/BeddingSurfaceStructure", + "beddingsurfacestructure_top_concepts.ttl", + "Top concepts have the correct annotation values for reg:status and color", + ], ], ) def test_concept_scheme_top_concepts(