Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,9 @@ public void query(String term, int page, Response<String> response) {
// Anything else the validator accepts is offered as a locally minted identifier
// (issue #652): typing "john-doe" mints it under the namespace of the
// nanopublication being published. It comes last, so that the known users the
// term matches keep the top of the list.
if (isLocalName(typedTerm) && !response.getResults().contains(typedTerm)) {
// term matches keep the top of the list. An external URI placeholder refers to an
// agent that exists outside this nanopublication, so it gets none (issue #676).
if (!template.isExternalUriPlaceholder(iri) && isLocalName(typedTerm) && !response.getResults().contains(typedTerm)) {
response.add(typedTerm);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,9 @@ public void query(String term, int page, Response<String> response) {
// a resource that has no identifier yet can be entered as well (issue #652): it is
// minted under the prefix of the field, or under the namespace of the
// nanopublication when the field has none. It comes last, so that the suggestions
// the term matches keep the top of the list.
if (Utils.isPlainName(typedTerm) && !response.getResults().contains(typedTerm)) {
// the term matches keep the top of the list. An external URI placeholder refers to
// something outside this nanopublication, so it gets no such name (issue #676).
if (!template.isExternalUriPlaceholder(iri) && Utils.isPlainName(typedTerm) && !response.getResults().contains(typedTerm)) {
response.add(typedTerm);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ public boolean isToBeMinted(IRI iri, String value) {
// The same rule processValue applies: a plain name (no colon, hash or space) gets the
// target namespace put in front of it. The colon also rules out anything that is a URI.
if (value == null || !value.matches("[^:# ]+")) return false;
// An external URI placeholder points at something that exists outside this
// nanopublication, so there is nothing to mint for it (issue #676).
if (template.isExternalUriPlaceholder(iri)) return false;
// A space-/namespace-dependent prefix mints the resource under the space or maintained
// resource instead, so it is not a local identifier of this nanopublication.
if (hasDynamicPrefix(iri)) return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ void tearDown() {
* initialized context for it.
*/
private TemplateContext agentContext() throws Exception {
return agentContext(false);
}

/**
* Builds a one-statement template whose object is an agent placeholder, optionally also typed
* as an external URI placeholder, and returns an initialized context for it.
*/
private TemplateContext agentContext(boolean external) throws Exception {
NanopubCreator creator = new NanopubCreator(NP_URI);
creator.addProvenanceStatement(vf.createStatement(creator.getAssertionUri(), RDFS.SEEALSO, creator.getAssertionUri()));
creator.addPubinfoStatement(vf.createStatement(creator.getNanopubUri(), RDFS.SEEALSO, creator.getNanopubUri()));
Expand All @@ -82,6 +90,9 @@ private TemplateContext agentContext() throws Exception {
creator.addAssertionStatement(st1, RDF.PREDICATE, vf.createIRI("http://example.com/hasAgent"));
creator.addAssertionStatement(st1, RDF.OBJECT, AGENT);
creator.addAssertionStatement(AGENT, RDF.TYPE, NTEMPLATE.AGENT_PLACEHOLDER);
if (external) {
creator.addAssertionStatement(AGENT, RDF.TYPE, NTEMPLATE.EXTERNAL_URI_PLACEHOLDER);
}
creator.addAssertionStatement(AGENT, RDFS.LABEL, vf.createLiteral("agent"));
Template template = TemplateTestUtil.parseTemplate(creator.finalizeNanopub());

Expand Down Expand Up @@ -158,6 +169,33 @@ void plainNameIsOfferedAsLocallyMintedIdentifier() throws Exception {
assertTrue(suggestionsFor(agentContext(), "john-doe").contains("john-doe"));
}

/**
* An agent placeholder that is also an external URI placeholder refers to an agent that exists
* outside this nanopublication, so no name to be minted is offered for it (issue #676).
*/
@Test
void externalAgentOffersNoPlainName() throws Exception {
assertFalse(suggestionsFor(agentContext(true), "john-doe").contains("john-doe"));
}

/**
* Only the minting is gone for an external agent placeholder: URIs and ORCIDs stay on offer.
*/
@Test
void externalAgentOffersUriAndOrcid() throws Exception {
assertTrue(suggestionsFor(agentContext(true), "did:plc:z72i7hdynmk6r22z27h6tvur").contains("did:plc:z72i7hdynmk6r22z27h6tvur"));
assertTrue(suggestionsFor(agentContext(true), "0000-0002-1267-0234").contains("https://orcid.org/0000-0002-1267-0234"));
}

/**
* Nothing is minted for an external agent placeholder, so a bare word held for it is not
* marked as a local identifier either (issue #676).
*/
@Test
void externalAgentNameIsNotShownAsMintedLocally() throws Exception {
assertEquals("john-doe", displayValueFor(agentContext(true), "john-doe"));
}

@Test
void termWithWhitespaceIsNotOffered() throws Exception {
// A name with a space cannot be minted into a well-formed IRI, so the validator would
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ void tearDown() {
* prefix (none if null), and returns an initialized context for it.
*/
private TemplateContext guidedContext(String prefix) throws Exception {
return guidedContext(prefix, false);
}

/**
* Builds a one-statement template whose object is a guided choice placeholder with the given
* prefix (none if null), optionally also typed as an external URI placeholder, and returns an
* initialized context for it.
*/
private TemplateContext guidedContext(String prefix, boolean external) throws Exception {
NanopubCreator creator = new NanopubCreator(NP_URI);
creator.addProvenanceStatement(vf.createStatement(creator.getAssertionUri(), RDFS.SEEALSO, creator.getAssertionUri()));
creator.addPubinfoStatement(vf.createStatement(creator.getNanopubUri(), RDFS.SEEALSO, creator.getNanopubUri()));
Expand All @@ -81,6 +90,9 @@ private TemplateContext guidedContext(String prefix) throws Exception {
creator.addAssertionStatement(st1, RDF.PREDICATE, vf.createIRI("http://example.com/hasThing"));
creator.addAssertionStatement(st1, RDF.OBJECT, THING);
creator.addAssertionStatement(THING, RDF.TYPE, NTEMPLATE.GUIDED_CHOICE_PLACEHOLDER);
if (external) {
creator.addAssertionStatement(THING, RDF.TYPE, NTEMPLATE.EXTERNAL_URI_PLACEHOLDER);
}
creator.addAssertionStatement(THING, RDFS.LABEL, vf.createLiteral("thing"));
if (prefix != null) {
creator.addAssertionStatement(THING, NTEMPLATE.HAS_PREFIX, vf.createLiteral(prefix));
Expand Down Expand Up @@ -147,6 +159,32 @@ void plainNameUnderAPrefixIsNotMintedLocally() throws Exception {
assertEquals("john", fieldOf(context).getProvider().getDisplayValue("john"));
}

/**
* A guided choice that is also an external URI placeholder refers to something outside the
* nanopublication, so a name that would have to be minted for it is not on offer (issue #676).
*/
@Test
void externalGuidedChoiceOffersNoPlainName() throws Exception {
assertFalse(suggestionsFor(guidedContext(null, true), "john").contains("john"));
}

/**
* A URI stays on offer for an external guided choice -- only the minting is gone.
*/
@Test
void externalGuidedChoiceOffersUri() throws Exception {
assertTrue(suggestionsFor(guidedContext(null, true), "https://example.com/thing").contains("https://example.com/thing"));
}

/**
* Nothing is minted for an external guided choice, so a bare word held for it is not marked as
* a local identifier either (issue #676).
*/
@Test
void externalGuidedChoiceIsNotShownAsMintedLocally() throws Exception {
assertEquals("john", fieldOf(guidedContext(null, true)).getProvider().getDisplayValue("john"));
}

/**
* A restricted choice is restricted: it must keep offering only what the template allows.
*/
Expand Down