diff --git a/pom.xml b/pom.xml
index 497b7e92..e22ec5c3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
care.smith.top
top-backend
- 0.7.7
+ 0.8.0
jar
TOP Backend
diff --git a/src/main/java/care/smith/top/backend/api/CodeApiDelegateImpl.java b/src/main/java/care/smith/top/backend/api/CodeApiDelegateImpl.java
index 762495eb..56fbcb62 100644
--- a/src/main/java/care/smith/top/backend/api/CodeApiDelegateImpl.java
+++ b/src/main/java/care/smith/top/backend/api/CodeApiDelegateImpl.java
@@ -6,6 +6,8 @@
import care.smith.top.model.CodeScope;
import care.smith.top.model.CodeSystemPage;
import java.net.URI;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
@@ -21,7 +23,11 @@ public class CodeApiDelegateImpl implements CodeApiDelegate {
@Override
public ResponseEntity getCode(URI uri, String codeSystemId, CodeScope scope) {
- return ResponseEntity.ok(codeService.getCode(uri, codeSystemId, null));
+ return ResponseEntity.ok(
+ codeService.getCode(
+ URI.create(URLDecoder.decode(uri.toString(), Charset.defaultCharset())),
+ codeSystemId,
+ scope));
}
@Override
diff --git a/src/main/java/care/smith/top/backend/configuration/SecurityConfiguration.java b/src/main/java/care/smith/top/backend/configuration/SecurityConfiguration.java
index a588bc26..c0735711 100644
--- a/src/main/java/care/smith/top/backend/configuration/SecurityConfiguration.java
+++ b/src/main/java/care/smith/top/backend/configuration/SecurityConfiguration.java
@@ -10,6 +10,8 @@
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.firewall.HttpFirewall;
+import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@@ -22,6 +24,15 @@ public class SecurityConfiguration {
@Autowired private JwtAuthenticationProvider customAuthenticationProvider;
+ @Bean
+ public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
+ StrictHttpFirewall firewall = new StrictHttpFirewall();
+ firewall.setAllowUrlEncodedSlash(true);
+ firewall.setAllowUrlEncodedDoubleSlash(true);
+ firewall.setAllowUrlEncodedPercent(true);
+ return firewall;
+ }
+
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.sessionManagement()
diff --git a/src/main/java/care/smith/top/backend/model/jpa/CodeDao.java b/src/main/java/care/smith/top/backend/model/jpa/CodeDao.java
index a4c80fdc..c42d6f84 100644
--- a/src/main/java/care/smith/top/backend/model/jpa/CodeDao.java
+++ b/src/main/java/care/smith/top/backend/model/jpa/CodeDao.java
@@ -3,12 +3,29 @@
import care.smith.top.model.Code;
import care.smith.top.model.CodeSystem;
import java.net.URI;
-import javax.persistence.Column;
-import javax.persistence.Embeddable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import javax.persistence.*;
import javax.validation.constraints.NotNull;
-@Embeddable
+@Entity(name = "code")
public class CodeDao {
+
+ @Id @GeneratedValue private Long id;
+
+ @ManyToOne(optional = true)
+ @JoinColumn(name = "parent_id", referencedColumnName = "id")
+ private CodeDao parent;
+
+ @OrderColumn
+ @OneToMany(
+ cascade = {CascadeType.ALL},
+ orphanRemoval = true)
+ @JoinColumn(name = "parent_id")
+ private List children;
+
@Column(nullable = false)
private String code;
@@ -39,6 +56,10 @@ public CodeDao(@NotNull Code code) {
name = code.getName();
if (code.getUri() != null) uri = code.getUri().toString();
if (code.getCodeSystem() != null) codeSystemUri = code.getCodeSystem().getUri().toString();
+ this.children =
+ Optional.ofNullable(code.getChildren()).orElse(Collections.emptyList()).stream()
+ .map(this::deepTranslate)
+ .collect(Collectors.toList());
}
public Code toApiModel() {
@@ -46,29 +67,34 @@ public Code toApiModel() {
.code(code)
.uri(uri != null ? URI.create(uri) : null)
.name(name)
- .codeSystem(new CodeSystem().uri(URI.create(codeSystemUri)));
+ .codeSystem(new CodeSystem().uri(URI.create(codeSystemUri)))
+ .children(getChildren().stream().map(CodeDao::toApiModel).collect(Collectors.toList()))
+ .synonyms(Collections.emptyList());
}
- public String getCode() {
- return code;
+ public CodeDao id(@NotNull Long id) {
+ this.id = id;
+ return this;
}
- public CodeDao code(@NotNull String code) {
- this.code = code;
+ public CodeDao parent(@NotNull CodeDao parent) {
+ this.parent = parent;
return this;
}
- public String getName() {
- return name;
+ public CodeDao children(List children) {
+ this.children = children;
+ return this;
}
- public CodeDao name(String name) {
- this.name = name;
+ public CodeDao code(@NotNull String code) {
+ this.code = code;
return this;
}
- public String getUri() {
- return uri;
+ public CodeDao name(String name) {
+ this.name = name;
+ return this;
}
public CodeDao uri(String uri) {
@@ -76,10 +102,6 @@ public CodeDao uri(String uri) {
return this;
}
- public String getCodeSystemUri() {
- return codeSystemUri;
- }
-
public CodeDao codeSystemUri(@NotNull String codeSystemUri) {
this.codeSystemUri = codeSystemUri;
return this;
@@ -108,4 +130,40 @@ public int hashCode() {
result = 31 * result + getCodeSystemUri().hashCode();
return result;
}
+
+ public Long getId() {
+ return id;
+ }
+
+ public CodeDao getParent() {
+ return parent;
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public String getCodeSystemUri() {
+ return codeSystemUri;
+ }
+
+ private CodeDao deepTranslate(Code code) {
+ final CodeDao codeDao = new CodeDao(code);
+ return codeDao.children(
+ Optional.ofNullable(code.getChildren()).orElse(Collections.emptyList()).stream()
+ .map(childCode -> deepTranslate(childCode).parent(codeDao))
+ .collect(Collectors.toList()));
+ }
}
diff --git a/src/main/java/care/smith/top/backend/model/jpa/EntityVersionDao.java b/src/main/java/care/smith/top/backend/model/jpa/EntityVersionDao.java
index 4cfc4f43..1f9e0ffa 100644
--- a/src/main/java/care/smith/top/backend/model/jpa/EntityVersionDao.java
+++ b/src/main/java/care/smith/top/backend/model/jpa/EntityVersionDao.java
@@ -31,7 +31,9 @@ public class EntityVersionDao {
@ElementCollection @OrderColumn private List descriptions = null;
- @ElementCollection @OrderColumn private List codes = null;
+ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
+ @OrderColumn
+ private List codes = null;
@OneToOne private EntityVersionDao previousVersion;
diff --git a/src/main/java/care/smith/top/backend/repository/ols/CodeRepository.java b/src/main/java/care/smith/top/backend/repository/ols/CodeRepository.java
index 909b11e5..82d13585 100644
--- a/src/main/java/care/smith/top/backend/repository/ols/CodeRepository.java
+++ b/src/main/java/care/smith/top/backend/repository/ols/CodeRepository.java
@@ -1,16 +1,17 @@
package care.smith.top.backend.repository.ols;
-import care.smith.top.backend.service.ols.OLSSuggestResponse;
-import care.smith.top.backend.service.ols.OLSSuggestResponseBody;
-import care.smith.top.backend.service.ols.OLSTerm;
+import care.smith.top.backend.service.ols.*;
import care.smith.top.model.Code;
import care.smith.top.model.CodePage;
+import care.smith.top.model.CodeScope;
import care.smith.top.model.CodeSystem;
import java.net.URI;
import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
+import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
@@ -21,9 +22,14 @@
@Repository
public class CodeRepository extends OlsRepository {
- @Value("${spring.paging.page-size:10}")
+ private static final Logger log = LoggerFactory.getLogger(CodeRepository.class);
+
+ @Value("${coding.suggestions-page-size}")
private int suggestionsPageSize;
+ @Value("${coding.code-children-page-size}")
+ private int codeChildrenPageSize;
+
@Autowired private CodeSystemRepository codeSystemRepository;
/**
@@ -37,7 +43,7 @@ public static int toOlsPage(Integer page, int pageSize) {
return page == null ? 0 : (page - 1) * pageSize;
}
- public Code getCode(URI uri, String codeSystemId) {
+ public Code getCode(URI uri, String codeSystemId, CodeScope scope) {
CodeSystem codeSystem =
getCodeSystem(codeSystemId)
.orElseThrow(
@@ -54,9 +60,11 @@ public Code getCode(URI uri, String codeSystemId) {
// OLS requires that uri is double URL encoded, so we encode it once and
// additionally rely on uriBuilder encoding it for a second time
uriBuilder
- .path("/term")
.pathSegment(
- codeSystemId, URLEncoder.encode(uri.toString(), StandardCharsets.UTF_8))
+ "ontologies",
+ codeSystemId,
+ "terms",
+ URLEncoder.encode(uri.toString(), Charset.defaultCharset()))
.build())
.retrieve()
.bodyToMono(OLSTerm.class)
@@ -78,12 +86,147 @@ public Code getCode(URI uri, String codeSystemId) {
? term.getSynonyms().get(0)
: term.getLabel();
- return new Code()
- .code(term.getLabel())
- .name(primaryLabel)
- .uri(URI.create(term.getIri()))
- .codeSystem(codeSystem)
- .synonyms(term.getSynonyms());
+ Code result =
+ new Code()
+ .code(term.getLabel())
+ .name(primaryLabel)
+ .uri(URI.create(term.getIri()))
+ .codeSystem(codeSystem)
+ .synonyms(term.getSynonyms());
+
+ var childrenLink = term.get_links().getHierarchicalChildren();
+ if (childrenLink != null) {
+ fillInSubtree(result, scope);
+ }
+
+ if (result.getChildren() == null) {
+ result.setChildren(Collections.emptyList());
+ }
+ return result;
+ }
+
+ private void fillInSubtree(Code code, CodeScope scope) {
+ switch (scope) {
+ case LEAVES:
+ code.setChildren(collectLeaves(code, new HashSet<>()));
+ return;
+ case SUBTREE:
+ fillInSubtree(code, new HashSet<>());
+ return;
+ case SELF:
+ default:
+ }
+ }
+
+ private void fillInSubtree(Code code, Set tracker) {
+ // We need to keep track of which codes we have already encountered as ontologies might
+ // contain cycles, and we might end up in an infinite loop.
+ // This is not supposed to happen with TOP terminologies created by the
+ // TOP import pipeline. However, we have no control over what kind of ontologies are
+ // loaded into the OLS instance, so better safe than sorry.
+ if (tracker.contains(code.getUri())) return;
+ tracker.add(code.getUri());
+
+ var children = retrieveChildren(code);
+
+ code.setChildren(children);
+ children.forEach(
+ childCode -> {
+ fillInSubtree(childCode, tracker);
+ });
+ }
+
+ private List collectLeaves(Code code, Set tracker) {
+ if (tracker.contains(code.getUri())) return Collections.emptyList();
+ tracker.add(code.getUri());
+
+ var children = retrieveChildren(code);
+
+ if (children.isEmpty()) {
+ // code is a leaf.
+ return List.of(code);
+ }
+
+ return children.stream()
+ .flatMap(childCode -> collectLeaves(childCode, tracker).stream().distinct())
+ .collect(Collectors.toList());
+ }
+
+ class PageCounter {
+ private Integer page = 0;
+
+ Integer getPage() {
+ return page;
+ }
+
+ void increase() {
+ page++;
+ }
+ }
+
+ private List retrieveChildren(Code code) {
+ final PageCounter counter = new PageCounter();
+
+ final List result = new ArrayList<>();
+
+ while (true) {
+ OLSHierarchicalChildrenResponse response =
+ Objects.requireNonNull(
+ terminologyService
+ .get()
+ .uri(
+ uriBuilder ->
+ uriBuilder
+ .pathSegment(
+ "ontologies",
+ code.getCodeSystem().getExternalId(),
+ "terms",
+ URLEncoder.encode(
+ code.getUri().toString(), Charset.defaultCharset()),
+ "hierarchicalChildren")
+ .queryParam("page", counter.getPage())
+ .queryParam("size", codeChildrenPageSize)
+ .build())
+ .retrieve()
+ .bodyToMono(OLSHierarchicalChildrenResponse.class)
+ .onErrorResume(
+ WebClientResponseException.class,
+ e ->
+ e.getRawStatusCode() == HttpStatus.NOT_FOUND.value()
+ ? Mono.empty()
+ : Mono.error(e))
+ .block());
+
+ if (response.get_embedded() == null) {
+ return Collections.emptyList();
+ }
+ response
+ .get_embedded()
+ .getTerms()
+ .forEach(
+ term -> {
+ String primaryLabel =
+ term.getSynonyms() != null && term.getSynonyms().size() != 0
+ ? term.getSynonyms().get(0)
+ : term.getLabel();
+
+ result.add(
+ new Code()
+ .code(term.getLabel())
+ .name(primaryLabel)
+ .uri(URI.create(term.getIri()))
+ .codeSystem(code.getCodeSystem())
+ .synonyms(term.getSynonyms())
+ .children(Collections.emptyList()));
+ });
+
+ var paginationInfo = response.getPage();
+ if (paginationInfo.getNumber() + 1 == paginationInfo.getTotalPages()) {
+ break;
+ }
+ counter.increase();
+ }
+ return result;
}
public CodePage getCodes(
diff --git a/src/main/java/care/smith/top/backend/repository/ols/CodeSystemRepository.java b/src/main/java/care/smith/top/backend/repository/ols/CodeSystemRepository.java
index 8a863a70..b584a93b 100644
--- a/src/main/java/care/smith/top/backend/repository/ols/CodeSystemRepository.java
+++ b/src/main/java/care/smith/top/backend/repository/ols/CodeSystemRepository.java
@@ -3,10 +3,7 @@
import care.smith.top.backend.service.ols.OLSOntologiesResponse;
import care.smith.top.model.CodeSystem;
import java.net.URI;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
import java.util.function.Function;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -39,7 +36,9 @@ public Map getAllCodeSystems() {
ontology ->
new CodeSystem()
.externalId(ontology.getOntologyId())
- .uri(ontology.getConfig().getId())
+ .uri(
+ Optional.ofNullable(ontology.getConfig().getVersionId())
+ .orElse(ontology.getConfig().getId()))
.name(ontology.getConfig().getTitle())
.shortName(ontology.getConfig().getPreferredPrefix()))
.collect(
diff --git a/src/main/java/care/smith/top/backend/service/EntityService.java b/src/main/java/care/smith/top/backend/service/EntityService.java
index 4097c55f..74e03a79 100644
--- a/src/main/java/care/smith/top/backend/service/EntityService.java
+++ b/src/main/java/care/smith/top/backend/service/EntityService.java
@@ -12,6 +12,7 @@
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.validation.constraints.NotNull;
import org.reflections.Reflections;
import org.reflections.util.ConfigurationBuilder;
@@ -907,13 +908,15 @@ private Function populateWithCodeSystems() {
return e -> {
if (e.getCodes() == null) return e;
return e.codes(
- e.getCodes().stream()
- .peek(
- c ->
- codeRepository
- .getCodeSystem(c.getCodeSystem().getUri())
- .ifPresent(c::codeSystem))
- .collect(Collectors.toList()));
+ e.getCodes().stream().peek(this::populateWithCodeSystems).collect(Collectors.toList()));
};
}
+
+ private void populateWithCodeSystems(Code c) {
+ codeRepository.getCodeSystem(c.getCodeSystem().getUri()).ifPresent(c::codeSystem);
+ Optional.ofNullable(c.getChildren())
+ .map(Collection::stream)
+ .orElseGet(Stream::empty)
+ .forEach(this::populateWithCodeSystems);
+ }
}
diff --git a/src/main/java/care/smith/top/backend/service/OLSCodeService.java b/src/main/java/care/smith/top/backend/service/OLSCodeService.java
index 710ff275..46537db2 100644
--- a/src/main/java/care/smith/top/backend/service/OLSCodeService.java
+++ b/src/main/java/care/smith/top/backend/service/OLSCodeService.java
@@ -3,10 +3,7 @@
import care.smith.top.backend.repository.ols.CodeRepository;
import care.smith.top.backend.repository.ols.CodeSystemRepository;
import care.smith.top.backend.repository.ols.OlsRepository;
-import care.smith.top.model.Code;
-import care.smith.top.model.CodePage;
-import care.smith.top.model.CodeSystem;
-import care.smith.top.model.CodeSystemPage;
+import care.smith.top.model.*;
import java.net.URI;
import java.util.*;
import java.util.function.Predicate;
@@ -24,12 +21,12 @@
@Service
@Primary
public class OLSCodeService {
- @Value("${spring.paging.page-size:10}")
- private int ontologyPageSize;
-
@Autowired protected CodeSystemRepository codeSystemRepository;
@Autowired protected CodeRepository codeRepository;
+ @Value("${spring.paging.page-size:10}")
+ private int ontologyPageSize;
+
@NotNull
private static Predicate filterByName(String name) {
return cs ->
@@ -38,8 +35,8 @@ private static Predicate filterByName(String name) {
|| cs.getShortName() != null && StringUtils.containsIgnoreCase(cs.getShortName(), name);
}
- public Code getCode(URI uri, String codeSystemId, List include) {
- return codeRepository.getCode(uri, codeSystemId);
+ public Code getCode(URI uri, String codeSystemId, CodeScope scope) {
+ return codeRepository.getCode(uri, codeSystemId, scope);
}
public CodePage getCodes(
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSAutoSuggestion.java b/src/main/java/care/smith/top/backend/service/ols/OLSAutoSuggestion.java
index 032f3ece..c90ea99a 100644
--- a/src/main/java/care/smith/top/backend/service/ols/OLSAutoSuggestion.java
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSAutoSuggestion.java
@@ -1,5 +1,6 @@
package care.smith.top.backend.service.ols;
+import java.util.Collections;
import java.util.List;
/**
@@ -7,13 +8,13 @@
*/
public class OLSAutoSuggestion {
- private List label_autosuggest;
+ private List label_autosuggest = Collections.emptyList();
- private List label;
+ private List label = Collections.emptyList();
- private List synonym_autosuggest;
+ private List synonym_autosuggest = Collections.emptyList();
- private List synonym;
+ private List synonym = Collections.emptyList();
public List getLabel_autosuggest() {
return label_autosuggest;
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSHierarchicalChildrenEmbedded.java b/src/main/java/care/smith/top/backend/service/ols/OLSHierarchicalChildrenEmbedded.java
new file mode 100644
index 00000000..9fb0060d
--- /dev/null
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSHierarchicalChildrenEmbedded.java
@@ -0,0 +1,19 @@
+package care.smith.top.backend.service.ols;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Ralph Schäfermeier
+ */
+public class OLSHierarchicalChildrenEmbedded {
+ private List terms = Collections.emptyList();
+
+ public List getTerms() {
+ return terms;
+ }
+
+ public void setTerms(List terms) {
+ this.terms = terms;
+ }
+}
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSHierarchicalChildrenResponse.java b/src/main/java/care/smith/top/backend/service/ols/OLSHierarchicalChildrenResponse.java
new file mode 100644
index 00000000..854ade12
--- /dev/null
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSHierarchicalChildrenResponse.java
@@ -0,0 +1,25 @@
+package care.smith.top.backend.service.ols;
+
+/**
+ * @author Ralph Schäfermeier
+ */
+public class OLSHierarchicalChildrenResponse {
+ private OLSHierarchicalChildrenEmbedded _embedded;
+ private OLSPage page;
+
+ public OLSHierarchicalChildrenEmbedded get_embedded() {
+ return _embedded;
+ }
+
+ public void set_embedded(OLSHierarchicalChildrenEmbedded _embedded) {
+ this._embedded = _embedded;
+ }
+
+ public OLSPage getPage() {
+ return page;
+ }
+
+ public void setPage(OLSPage page) {
+ this.page = page;
+ }
+}
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSLink.java b/src/main/java/care/smith/top/backend/service/ols/OLSLink.java
new file mode 100644
index 00000000..3f33019e
--- /dev/null
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSLink.java
@@ -0,0 +1,16 @@
+package care.smith.top.backend.service.ols;
+
+/**
+ * @author Ralph Schäfermeier
+ */
+public class OLSLink {
+ private String href;
+
+ public String getHref() {
+ return href;
+ }
+
+ public void setHref(String href) {
+ this.href = href;
+ }
+}
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSLinks.java b/src/main/java/care/smith/top/backend/service/ols/OLSLinks.java
new file mode 100644
index 00000000..cb118a67
--- /dev/null
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSLinks.java
@@ -0,0 +1,16 @@
+package care.smith.top.backend.service.ols;
+
+/**
+ * @author Ralph Schäfermeier
+ */
+public class OLSLinks {
+ private OLSLink hierarchicalChildren;
+
+ public OLSLink getHierarchicalChildren() {
+ return hierarchicalChildren;
+ }
+
+ public void setHierarchicalChildren(OLSLink hierarchicalChildren) {
+ this.hierarchicalChildren = hierarchicalChildren;
+ }
+}
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSOntologyConfig.java b/src/main/java/care/smith/top/backend/service/ols/OLSOntologyConfig.java
index c38a7596..95279167 100644
--- a/src/main/java/care/smith/top/backend/service/ols/OLSOntologyConfig.java
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSOntologyConfig.java
@@ -7,6 +7,7 @@
*/
public class OLSOntologyConfig {
private URI id;
+ private URI versionId;
private String title;
private String description;
private String preferredPrefix;
@@ -19,6 +20,14 @@ public void setId(URI id) {
this.id = id;
}
+ public URI getVersionId() {
+ return versionId;
+ }
+
+ public void setVersionId(URI versionId) {
+ this.versionId = versionId;
+ }
+
public String getTitle() {
return title;
}
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSOntologyEmbedded.java b/src/main/java/care/smith/top/backend/service/ols/OLSOntologyEmbedded.java
index 87c79a71..2b3ff613 100644
--- a/src/main/java/care/smith/top/backend/service/ols/OLSOntologyEmbedded.java
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSOntologyEmbedded.java
@@ -4,7 +4,7 @@
* @author ralph
*/
public class OLSOntologyEmbedded {
- private OLSOntology[] ontologies;
+ private OLSOntology[] ontologies = new OLSOntology[] {};
public OLSOntology[] getOntologies() {
return ontologies;
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSTerm.java b/src/main/java/care/smith/top/backend/service/ols/OLSTerm.java
index d8dc9aa7..472193ab 100644
--- a/src/main/java/care/smith/top/backend/service/ols/OLSTerm.java
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSTerm.java
@@ -1,5 +1,6 @@
package care.smith.top.backend.service.ols;
+import java.util.Collections;
import java.util.List;
/**
@@ -9,11 +10,12 @@ public class OLSTerm {
private String iri;
private String short_form;
private String label;
- private String description;
+ private List description = Collections.emptyList();
private String ontology_name;
private String ontology_prefix;
private String ontology_iri;
- private List synonyms;
+ private List synonyms = Collections.emptyList();
+ private OLSLinks _links;
public String getIri() {
return iri;
@@ -39,11 +41,11 @@ public void setLabel(String label) {
this.label = label;
}
- public String getDescription() {
+ public List getDescription() {
return description;
}
- public void setDescription(String description) {
+ public void setDescription(List description) {
this.description = description;
}
@@ -78,4 +80,12 @@ public List getSynonyms() {
public void setSynonyms(List synonyms) {
this.synonyms = synonyms;
}
+
+ public OLSLinks get_links() {
+ return _links;
+ }
+
+ public void set_links(OLSLinks _links) {
+ this._links = _links;
+ }
}
diff --git a/src/main/java/care/smith/top/backend/service/ols/OLSTermsEmbedded.java b/src/main/java/care/smith/top/backend/service/ols/OLSTermsEmbedded.java
new file mode 100644
index 00000000..3290beca
--- /dev/null
+++ b/src/main/java/care/smith/top/backend/service/ols/OLSTermsEmbedded.java
@@ -0,0 +1,19 @@
+package care.smith.top.backend.service.ols;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Ralph Schäfermeier
+ */
+public class OLSTermsEmbedded {
+ private List terms = Collections.emptyList();
+
+ public List getTerms() {
+ return terms;
+ }
+
+ public void setTerms(List terms) {
+ this.terms = terms;
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index fea36894..3a3adf0e 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -81,3 +81,5 @@ top:
coding:
terminology-service: ${TERMINOLOGY_SERVICE_ENDPOINT:https://www.ebi.ac.uk/ols4/api}
+ suggestions-page-size: 1000
+ code-children-page-size: 500
diff --git a/src/main/resources/db/changelog/changesets/202407101044-add-subcodes.yaml b/src/main/resources/db/changelog/changesets/202407101044-add-subcodes.yaml
new file mode 100644
index 00000000..f4583004
--- /dev/null
+++ b/src/main/resources/db/changelog/changesets/202407101044-add-subcodes.yaml
@@ -0,0 +1,218 @@
+databaseChangeLog:
+ - changeSet:
+ id: 1720604582951-1
+ dbms: postgresql
+ author: Ralph Schäfermeier
+ changes:
+ - addColumn:
+ tableName: entity_version_codes
+ columns:
+ - column:
+ name: codes_id
+ type: BIGINT
+ defaultValueSequenceNext: hibernate_sequence
+ - changeSet:
+ id: 1720604582951-1-test
+ dbms: hsqldb
+ author: Ralph Schäfermeier
+ changes:
+ - addColumn:
+ tableName: entity_version_codes
+ columns:
+ - column:
+ name: codes_id
+ type: BIGINT
+ autoIncrement: true
+ - changeSet:
+ id: 1720604582951-2
+ dbms: postgresql
+ author: Ralph Schäfermeier
+ changes:
+ - dropDefaultValue:
+ tableName: entity_version_codes
+ columnName: codes_id
+ rollback:
+ - addDefaultValue:
+ tableName: entity_version_codes
+ columnName: codes_id
+ defaultValueSequenceNext: hibernate_sequence
+ - changeSet:
+ id: 1720604582951-2-test
+ dbms: hsqldb
+ author: Ralph Schäfermeier
+ changes:
+ - modifyDataType:
+ tableName: entity_version_codes
+ columnName: codes_id
+ newDataType: BIGINT
+ - changeSet:
+ id: 1720604582951-3
+ dbms: postgresql
+ author: Ralph Schäfermeier
+ changes:
+ - createTable:
+ tableName: code
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: codePK
+ name: id
+ type: BIGINT
+ defaultValueSequenceNext: hibernate_sequence
+ - column:
+ constraints:
+ nullable: false
+ name: code
+ type: VARCHAR(255)
+ - column:
+ constraints:
+ nullable: false
+ name: code_system_uri
+ type: VARCHAR(255)
+ - column:
+ name: name
+ type: VARCHAR(255)
+ - column:
+ name: uri
+ type: VARCHAR(255)
+ - column:
+ name: parent_id
+ type: BIGINT
+ - column:
+ name: children_order
+ type: INT
+ - changeSet:
+ id: 1720604582951-3-test
+ dbms: hsqldb
+ author: Ralph Schäfermeier
+ changes:
+ - createTable:
+ tableName: code
+ columns:
+ - column:
+ constraints:
+ nullable: false
+ primaryKey: true
+ primaryKeyName: codePK
+ name: id
+ type: BIGINT
+ autoIncrement: true
+ - column:
+ constraints:
+ nullable: false
+ name: code
+ type: VARCHAR(255)
+ - column:
+ constraints:
+ nullable: false
+ name: code_system_uri
+ type: VARCHAR(255)
+ - column:
+ name: name
+ type: VARCHAR(255)
+ - column:
+ name: uri
+ type: VARCHAR(255)
+ - column:
+ name: parent_id
+ type: BIGINT
+ - column:
+ name: children_order
+ type: INT
+ - changeSet:
+ id: 1720604582951-4
+ author: Ralph Schäfermeier (generated)
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: parent_id
+ baseTableName: code
+ constraintName: FK_code_parentid_code_id
+ deferrable: false
+ initiallyDeferred: false
+ referencedColumnNames: id
+ referencedTableName: code
+ validate: true
+ - changeSet:
+ id: 1720604582951-5
+ author: Ralph Schäfermeier
+ changes:
+ - sql: insert into code (id, code, code_system_uri, name, uri) select codes_id as id, code, code_system_uri, name, uri from entity_version_codes
+ rollback:
+ - delete:
+ tableName: code
+ - changeSet:
+ id: 1720604582951-6
+ author: Ralph Schäfermeier (generated)
+ changes:
+ - addForeignKeyConstraint:
+ baseColumnNames: codes_id
+ baseTableName: entity_version_codes
+ constraintName: FK_entityversioncodes_codesid_codes_id
+ deferrable: false
+ initiallyDeferred: false
+ referencedColumnNames: id
+ referencedTableName: code
+ validate: true
+ - changeSet:
+ id: 1720604582951-7
+ author: Ralph Schäfermeier (generated)
+ changes:
+ - dropColumn:
+ columnName: code
+ tableName: entity_version_codes
+ rollback:
+ - addColumn:
+ tableName: entity_version_codes
+ columns:
+ - column:
+ name: code
+ type: VARCHAR(255)
+ valueComputed: (select c.code from code c where c.id=codes_id)
+ - changeSet:
+ id: 1720604582951-8
+ author: Ralph Schäfermeier (generated)
+ changes:
+ - dropColumn:
+ columnName: code_system_uri
+ tableName: entity_version_codes
+ rollback:
+ - addColumn:
+ tableName: entity_version_codes
+ columns:
+ - column:
+ name: code_system_uri
+ type: VARCHAR(255)
+ valueComputed: (select c.code_system_uri from code c where c.id=codes_id)
+ - changeSet:
+ id: 1720604582951-9
+ author: Ralph Schäfermeier (generated)
+ changes:
+ - dropColumn:
+ columnName: name
+ tableName: entity_version_codes
+ rollback:
+ - addColumn:
+ tableName: entity_version_codes
+ columns:
+ - column:
+ name: name
+ type: VARCHAR(255)
+ valueComputed: (select c.name from code c where c.id=codes_id)
+ - changeSet:
+ id: 1720604582951-10
+ author: Ralph Schäfermeier (generated)
+ changes:
+ - dropColumn:
+ columnName: uri
+ tableName: entity_version_codes
+ rollback:
+ - addColumn:
+ tableName: entity_version_codes
+ columns:
+ - column:
+ name: uri
+ type: VARCHAR(255)
+ valueComputed: (select c.uri from code c where c.id=codes_id)
+
diff --git a/src/test/java/care/smith/top/backend/AbstractTest.java b/src/test/java/care/smith/top/backend/AbstractTest.java
index 26e4d42e..fe5a8e2a 100644
--- a/src/test/java/care/smith/top/backend/AbstractTest.java
+++ b/src/test/java/care/smith/top/backend/AbstractTest.java
@@ -18,9 +18,11 @@
import care.smith.top.backend.service.RepositoryService;
import care.smith.top.backend.service.UserService;
import care.smith.top.backend.util.ResourceHttpHandler;
+import care.smith.top.backend.util.ResourcePathHttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetSocketAddress;
+import java.nio.file.Path;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -56,6 +58,18 @@ static void initializeOLS() throws IOException {
olsServer.createContext(
"/api/ontologies", new ResourceHttpHandler("/ols4_fixtures/ontologies.json"));
olsServer.createContext("/api/select", new ResourceHttpHandler("/ols4_fixtures/select.json"));
+ olsServer.createContext(
+ "/api/ontologies/test/terms",
+ new ResourcePathHttpHandler(
+ path -> {
+ boolean hierarchicalChildren =
+ path.getFileName().toString().equals("hierarchicalChildren");
+ Path realPath = hierarchicalChildren ? path.getParent() : path;
+ Path resourceRootPath =
+ Path.of("/ols4_fixtures", hierarchicalChildren ? "terms_hierarchy" : "terms");
+ Path relativeUriPath = Path.of("/api/ontologies/test/terms").relativize(realPath);
+ return resourceRootPath.resolve(relativeUriPath.toString() + ".json");
+ }));
olsServer.start();
}
diff --git a/src/test/java/care/smith/top/backend/EnumTest.java b/src/test/java/care/smith/top/backend/EnumTest.java
index 9cdc2e55..7d86f1b5 100644
--- a/src/test/java/care/smith/top/backend/EnumTest.java
+++ b/src/test/java/care/smith/top/backend/EnumTest.java
@@ -82,5 +82,8 @@ void testEnumsDoNotHaveBreakingChanges() {
RestrictionOperator.GREATER_THAN,
RestrictionOperator.GREATER_THAN_OR_EQUAL_TO
});
+
+ assertThat(CodeScope.values())
+ .isEqualTo(new CodeScope[] {CodeScope.SELF, CodeScope.SUBTREE, CodeScope.LEAVES});
}
}
diff --git a/src/test/java/care/smith/top/backend/service/CodeServiceTest.java b/src/test/java/care/smith/top/backend/service/CodeServiceTest.java
index e21584f5..27c6d24c 100644
--- a/src/test/java/care/smith/top/backend/service/CodeServiceTest.java
+++ b/src/test/java/care/smith/top/backend/service/CodeServiceTest.java
@@ -3,15 +3,86 @@
import static org.assertj.core.api.Assertions.assertThat;
import care.smith.top.backend.AbstractTest;
-import care.smith.top.model.CodePage;
-import care.smith.top.model.CodeSystemPage;
-import java.util.Collections;
+import care.smith.top.backend.repository.ols.CodeRepository;
+import care.smith.top.backend.repository.ols.CodeSystemRepository;
+import care.smith.top.model.*;
+import java.net.URI;
+import java.util.*;
+import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class CodeServiceTest extends AbstractTest {
+
+ @Autowired private CodeSystemRepository codeSystemRepository;
+ @Autowired private CodeRepository codeRepository;
+
+ private static final class UriCodeScopeChildCountTuple {
+ URI uri;
+ Integer subtree;
+ Integer leaves;
+
+ UriCodeScopeChildCountTuple(URI uri, Integer subtree, Integer leaves) {
+ this.uri = uri;
+ this.subtree = subtree;
+ this.leaves = leaves;
+ }
+
+ static UriCodeScopeChildCountTuple of(URI uri, Integer subtree, Integer leaves) {
+ return new UriCodeScopeChildCountTuple(uri, subtree, leaves);
+ }
+
+ Integer value(CodeScope scope) {
+ switch (scope) {
+ case SELF:
+ return 0;
+ case SUBTREE:
+ return subtree;
+ case LEAVES:
+ return leaves;
+ default:
+ throw new AssertionError(scope.toString());
+ }
+ }
+ }
+
+ private static final Stream provideTestValuesForSubtrees() {
+ return Stream.of(
+ Arguments.of("test-1", 2, 1),
+ Arguments.of("test-11", 1, 1),
+ Arguments.of("test-2", 8, 5),
+ Arguments.of("test-21", 6, 4),
+ Arguments.of("test-211", 1, 1),
+ Arguments.of("test-212", 4, 3),
+ Arguments.of("test-2121", 1, 1),
+ Arguments.of("test-2122", 1, 1),
+ Arguments.of("test-2123", 1, 1),
+ Arguments.of("test-22", 1, 1),
+ Arguments.of("test-3", 7, 5),
+ Arguments.of("test-31", 4, 3),
+ Arguments.of("test-311", 1, 1),
+ Arguments.of("test-312", 1, 1),
+ Arguments.of("test-313", 1, 1),
+ Arguments.of("test-32", 1, 1),
+ Arguments.of("test-33", 1, 1),
+ Arguments.of("test-4", 5, 4),
+ Arguments.of("test-41", 1, 1),
+ Arguments.of("test-42", 1, 1),
+ Arguments.of("test-43", 1, 1),
+ Arguments.of("test-44", 1, 1),
+ Arguments.of("test-5", 6, 5),
+ Arguments.of("test-51", 1, 1),
+ Arguments.of("test-52", 1, 1),
+ Arguments.of("test-53", 1, 1),
+ Arguments.of("test-54", 1, 1),
+ Arguments.of("test-55", 1, 1));
+ }
+
@Autowired OLSCodeService codeService;
@Test
@@ -25,4 +96,83 @@ void getCodeSystems() {
CodeSystemPage codeSystems = codeService.getCodeSystems(null, null, null, 1);
assertThat(codeSystems).isNotNull().satisfies(cs -> assertThat(cs.getContent()).isNotEmpty());
}
+
+ @ParameterizedTest
+ @MethodSource("provideTestValuesForSubtrees")
+ void createCodesWithSubtrees(String codeName, int expectedSubtreeSize, int expectedLeafCount) {
+ Organisation organisation =
+ organisationService.createOrganisation(new Organisation().id("org"));
+ Repository repository =
+ repositoryService.createRepository(
+ organisation.getId(),
+ new Repository().id("repo").repositoryType(RepositoryType.PHENOTYPE_REPOSITORY),
+ null);
+
+ Arrays.stream(CodeScope.values())
+ .forEach(
+ scope -> {
+ Category category = new Category();
+ Code code =
+ codeService.getCode(
+ URI.create("http://top.smith.care/test/terminology#" + codeName),
+ "test",
+ scope);
+
+ category
+ .id(UUID.randomUUID().toString())
+ .entityType(EntityType.CATEGORY)
+ .addCodesItem(code);
+
+ assertThat(
+ entityService.createEntity(
+ organisation.getId(), repository.getId(), category))
+ .isNotNull()
+ .isInstanceOf(Category.class)
+ .satisfies(
+ c -> {
+ assertThat(c.getCodes()).size().isEqualTo(1);
+ Code codeEntity = c.getCodes().get(0);
+ fillInCodeSystems(codeEntity);
+
+ assertThat(codeEntity).isEqualTo(code);
+
+ switch (scope) {
+ case SUBTREE:
+ assertThat(nodeCount(code)).isEqualTo(expectedSubtreeSize);
+ assertThat(nodeCount(codeEntity)).isEqualTo(expectedSubtreeSize);
+ break;
+ case LEAVES:
+ assertThat(leafCount(code)).isEqualTo(expectedLeafCount);
+ assertThat(leafCount(codeEntity)).isEqualTo(expectedLeafCount);
+ break;
+ case SELF:
+ assertThat(leafCount(code)).isEqualTo(1);
+ assertThat(leafCount(codeEntity)).isEqualTo(1);
+ break;
+ }
+ });
+ });
+ }
+
+ private int nodeCount(Code c) {
+ return 1 + c.getChildren().stream().map(child -> nodeCount(child)).reduce(0, Integer::sum);
+ }
+
+ private int leafCount(Code c) {
+ return isLeaf(c)
+ ? 1
+ : c.getChildren().stream().map(child -> leafCount(child)).reduce(0, Integer::sum);
+ }
+
+ private boolean isLeaf(Code c) {
+ return c.getChildren() == null || c.getChildren().size() == 0;
+ }
+
+ private void fillInCodeSystems(Code code) {
+ codeRepository
+ .getCodeSystem(code.getCodeSystem().getUri())
+ .ifPresent(codeSystem -> code.setCodeSystem(codeSystem));
+ Optional.ofNullable(code.getChildren())
+ .ifPresent(children -> children.forEach(child -> fillInCodeSystems(child)));
+ }
}
diff --git a/src/test/java/care/smith/top/backend/util/ResourcePathHttpHandler.java b/src/test/java/care/smith/top/backend/util/ResourcePathHttpHandler.java
new file mode 100644
index 00000000..f5bd9440
--- /dev/null
+++ b/src/test/java/care/smith/top/backend/util/ResourcePathHttpHandler.java
@@ -0,0 +1,40 @@
+package care.smith.top.backend.util;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.nio.file.Path;
+
+public class ResourcePathHttpHandler implements HttpHandler {
+
+ @FunctionalInterface
+ public interface PathMapper {
+ Path map(Path path);
+ }
+
+ private final PathMapper mapper;
+
+ public ResourcePathHttpHandler(PathMapper mapper) {
+ this.mapper = mapper;
+ }
+
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ StringBuilder resourcePath = new StringBuilder();
+ mapper
+ .map(Path.of(exchange.getRequestURI().getRawPath()))
+ .iterator()
+ .forEachRemaining(p -> resourcePath.append("/").append(p.toString()));
+ try (InputStream resource =
+ ResourcePathHttpHandler.class.getResourceAsStream(resourcePath.toString())) {
+ assert resource != null;
+ byte[] response = resource.readAllBytes();
+ exchange.getResponseHeaders().set("Content-Type", "application/json");
+ exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
+ exchange.getResponseBody().write(response);
+ }
+ exchange.close();
+ }
+}
diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml
index 30b1080a..19b21ebc 100644
--- a/src/test/resources/application.yml
+++ b/src/test/resources/application.yml
@@ -67,3 +67,5 @@ top:
coding:
terminology-service: ${TERMINOLOGY_SERVICE_ENDPOINT:http://localhost:9000/api}
+ suggestions-page-size: 1000
+ code-children-page-size: 500
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1.json
new file mode 100644
index 00000000..f6a3b469
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1.json
@@ -0,0 +1,43 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-1",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : { },
+ "label" : "TEST_#test-1",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : true,
+ "short_form" : "TEST_#test-1",
+ "obo_id" : "TEST:#test-1",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1?lang=en"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11.json
new file mode 100644
index 00000000..187beddb
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-11",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-11" ]
+ },
+ "label" : "test-11",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-11",
+ "obo_id" : "TEST:#test-11",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2.json
new file mode 100644
index 00000000..cc6cabb0
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2.json
@@ -0,0 +1,43 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-2",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : { },
+ "label" : "TEST_#test-2",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : true,
+ "short_form" : "TEST_#test-2",
+ "obo_id" : "TEST:#test-2",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2?lang=en"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21.json
new file mode 100644
index 00000000..6ca61264
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21.json
@@ -0,0 +1,60 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-21",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-21" ]
+ },
+ "label" : "test-21",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : false,
+ "short_form" : "TEST_#test-21",
+ "obo_id" : "TEST:#test-21",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/jstree"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211.json
new file mode 100644
index 00000000..deb4db57
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-211",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-211" ]
+ },
+ "label" : "test-211",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-211",
+ "obo_id" : "TEST:#test-211",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212.json
new file mode 100644
index 00000000..f3dce6d9
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212.json
@@ -0,0 +1,60 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-212",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-212" ]
+ },
+ "label" : "test-212",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : false,
+ "short_form" : "TEST_#test-212",
+ "obo_id" : "TEST:#test-212",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/jstree"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121.json
new file mode 100644
index 00000000..d6b6c549
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-2121",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-2121" ]
+ },
+ "label" : "test-2121",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-2121",
+ "obo_id" : "TEST:#test-2121",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122.json
new file mode 100644
index 00000000..80729dc8
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-2122",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-2122" ]
+ },
+ "label" : "test-2122",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-2122",
+ "obo_id" : "TEST:#test-2122",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123.json
new file mode 100644
index 00000000..bdf8cc50
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-2123",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-2123" ]
+ },
+ "label" : "test-2123",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-2123",
+ "obo_id" : "TEST:#test-2123",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22.json
new file mode 100644
index 00000000..42d5d82b
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-22",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-22" ]
+ },
+ "label" : "test-22",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-22",
+ "obo_id" : "TEST:#test-22",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3.json
new file mode 100644
index 00000000..c0e3ffb1
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3.json
@@ -0,0 +1,43 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-3",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : { },
+ "label" : "TEST_#test-3",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : true,
+ "short_form" : "TEST_#test-3",
+ "obo_id" : "TEST:#test-3",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3?lang=en"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31.json
new file mode 100644
index 00000000..53dc0087
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31.json
@@ -0,0 +1,60 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-31",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-31" ]
+ },
+ "label" : "test-31",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : false,
+ "short_form" : "TEST_#test-31",
+ "obo_id" : "TEST:#test-31",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/jstree"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311.json
new file mode 100644
index 00000000..47d7f5c6
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-311",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-311" ]
+ },
+ "label" : "test-311",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-311",
+ "obo_id" : "TEST:#test-311",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312.json
new file mode 100644
index 00000000..0d68df9d
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-312",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-312" ]
+ },
+ "label" : "test-312",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-312",
+ "obo_id" : "TEST:#test-312",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313.json
new file mode 100644
index 00000000..e7f9fad8
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-313",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-313" ]
+ },
+ "label" : "test-313",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-313",
+ "obo_id" : "TEST:#test-313",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32.json
new file mode 100644
index 00000000..c19e833e
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-32",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-32" ]
+ },
+ "label" : "test-32",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-32",
+ "obo_id" : "TEST:#test-32",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33.json
new file mode 100644
index 00000000..c48b3d5d
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-33",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-33" ]
+ },
+ "label" : "test-33",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-33",
+ "obo_id" : "TEST:#test-33",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4.json
new file mode 100644
index 00000000..5820f298
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4.json
@@ -0,0 +1,43 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-4",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : { },
+ "label" : "TEST_#test-4",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : true,
+ "short_form" : "TEST_#test-4",
+ "obo_id" : "TEST:#test-4",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4?lang=en"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41.json
new file mode 100644
index 00000000..1a7d29f7
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-41",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-41" ]
+ },
+ "label" : "test-41",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-41",
+ "obo_id" : "TEST:#test-41",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42.json
new file mode 100644
index 00000000..30e90930
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-42",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-42" ]
+ },
+ "label" : "test-42",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-42",
+ "obo_id" : "TEST:#test-42",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43.json
new file mode 100644
index 00000000..045aa1b9
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-43",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-43" ]
+ },
+ "label" : "test-43",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-43",
+ "obo_id" : "TEST:#test-43",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44.json
new file mode 100644
index 00000000..39e8a4d4
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-44",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-44" ]
+ },
+ "label" : "test-44",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-44",
+ "obo_id" : "TEST:#test-44",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5.json
new file mode 100644
index 00000000..35f0599e
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5.json
@@ -0,0 +1,43 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-5",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : { },
+ "label" : "TEST_#test-5",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : true,
+ "short_form" : "TEST_#test-5",
+ "obo_id" : "TEST:#test-5",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5?lang=en"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51.json
new file mode 100644
index 00000000..7bedd727
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-51",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-51" ]
+ },
+ "label" : "test-51",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-51",
+ "obo_id" : "TEST:#test-51",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52.json
new file mode 100644
index 00000000..a8367f17
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-52",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-52" ]
+ },
+ "label" : "test-52",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-52",
+ "obo_id" : "TEST:#test-52",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53.json
new file mode 100644
index 00000000..a3314c1d
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-53",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-53" ]
+ },
+ "label" : "test-53",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-53",
+ "obo_id" : "TEST:#test-53",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54.json
new file mode 100644
index 00000000..44eff5cb
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-54",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-54" ]
+ },
+ "label" : "test-54",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-54",
+ "obo_id" : "TEST:#test-54",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55.json b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55.json
new file mode 100644
index 00000000..90824a9f
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms/http%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55.json
@@ -0,0 +1,48 @@
+{
+ "iri" : "https://top.smith.care/test/terminology#test-55",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-55" ]
+ },
+ "label" : "test-55",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-55",
+ "obo_id" : "TEST:#test-55",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/graph"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1.json
new file mode 100644
index 00000000..a3615862
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1.json
@@ -0,0 +1,63 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-11",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-11" ]
+ },
+ "label" : "test-11",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-11",
+ "obo_id" : "TEST:#test-11",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-1/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 1,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11.json
new file mode 100644
index 00000000..f2626ffc
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-11/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2.json
new file mode 100644
index 00000000..7e98c078
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2.json
@@ -0,0 +1,122 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-22",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-22" ]
+ },
+ "label" : "test-22",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-22",
+ "obo_id" : "TEST:#test-22",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-21",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-21" ]
+ },
+ "label" : "test-21",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : false,
+ "short_form" : "TEST_#test-21",
+ "obo_id" : "TEST:#test-21",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/jstree"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 2,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21.json
new file mode 100644
index 00000000..6636e2d5
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21.json
@@ -0,0 +1,122 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-212",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-212" ]
+ },
+ "label" : "test-212",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : false,
+ "short_form" : "TEST_#test-212",
+ "obo_id" : "TEST:#test-212",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/jstree"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-211",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-211" ]
+ },
+ "label" : "test-211",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-211",
+ "obo_id" : "TEST:#test-211",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-21/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 2,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211.json
new file mode 100644
index 00000000..28cccdfc
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-211/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212.json
new file mode 100644
index 00000000..c12d558b
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212.json
@@ -0,0 +1,157 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-2123",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-2123" ]
+ },
+ "label" : "test-2123",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-2123",
+ "obo_id" : "TEST:#test-2123",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-2122",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-2122" ]
+ },
+ "label" : "test-2122",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-2122",
+ "obo_id" : "TEST:#test-2122",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-2121",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-2121" ]
+ },
+ "label" : "test-2121",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-2121",
+ "obo_id" : "TEST:#test-2121",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-212/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 3,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121.json
new file mode 100644
index 00000000..aa499bbd
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2121/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122.json
new file mode 100644
index 00000000..7f836b56
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2122/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123.json
new file mode 100644
index 00000000..94116d80
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-2123/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22.json
new file mode 100644
index 00000000..18b2b19e
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-22/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3.json
new file mode 100644
index 00000000..423260ee
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3.json
@@ -0,0 +1,169 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-33",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-33" ]
+ },
+ "label" : "test-33",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-33",
+ "obo_id" : "TEST:#test-33",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-32",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-32" ]
+ },
+ "label" : "test-32",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-32",
+ "obo_id" : "TEST:#test-32",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-31",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-31" ]
+ },
+ "label" : "test-31",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : true,
+ "is_root" : false,
+ "short_form" : "TEST_#test-31",
+ "obo_id" : "TEST:#test-31",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/jstree"
+ },
+ "children" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/children"
+ },
+ "descendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/descendants"
+ },
+ "hierarchicalChildren" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalChildren"
+ },
+ "hierarchicalDescendants" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalDescendants"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-3/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 3,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31.json
new file mode 100644
index 00000000..8fde8d82
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31.json
@@ -0,0 +1,157 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-313",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-313" ]
+ },
+ "label" : "test-313",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-313",
+ "obo_id" : "TEST:#test-313",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-312",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-312" ]
+ },
+ "label" : "test-312",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-312",
+ "obo_id" : "TEST:#test-312",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-311",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-311" ]
+ },
+ "label" : "test-311",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-311",
+ "obo_id" : "TEST:#test-311",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-31/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 3,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311.json
new file mode 100644
index 00000000..95b2a75c
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-311/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312.json
new file mode 100644
index 00000000..96bb47dc
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-312/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313.json
new file mode 100644
index 00000000..f2771b2e
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-313/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32.json
new file mode 100644
index 00000000..e52b686b
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-32/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33.json
new file mode 100644
index 00000000..276fc27f
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-33/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4.json
new file mode 100644
index 00000000..c428048c
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4.json
@@ -0,0 +1,204 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-44",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-44" ]
+ },
+ "label" : "test-44",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-44",
+ "obo_id" : "TEST:#test-44",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-43",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-43" ]
+ },
+ "label" : "test-43",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-43",
+ "obo_id" : "TEST:#test-43",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-42",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-42" ]
+ },
+ "label" : "test-42",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-42",
+ "obo_id" : "TEST:#test-42",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-41",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-41" ]
+ },
+ "label" : "test-41",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-41",
+ "obo_id" : "TEST:#test-41",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-4/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 4,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41.json
new file mode 100644
index 00000000..dd383e84
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-41/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42.json
new file mode 100644
index 00000000..2dbe082d
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-42/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43.json
new file mode 100644
index 00000000..813945e8
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-43/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44.json
new file mode 100644
index 00000000..e1f5a564
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-44/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5.json
new file mode 100644
index 00000000..b1196efe
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5.json
@@ -0,0 +1,251 @@
+{
+ "_embedded" : {
+ "terms" : [ {
+ "iri" : "https://top.smith.care/test/terminology#test-55",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-55" ]
+ },
+ "label" : "test-55",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-55",
+ "obo_id" : "TEST:#test-55",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-54",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-54" ]
+ },
+ "label" : "test-54",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-54",
+ "obo_id" : "TEST:#test-54",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-53",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-53" ]
+ },
+ "label" : "test-53",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-53",
+ "obo_id" : "TEST:#test-53",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-52",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-52" ]
+ },
+ "label" : "test-52",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-52",
+ "obo_id" : "TEST:#test-52",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/graph"
+ }
+ }
+ }, {
+ "iri" : "https://top.smith.care/test/terminology#test-51",
+ "lang" : "en",
+ "description" : [ ],
+ "synonyms" : [ ],
+ "annotation" : {
+ "prefLabel" : [ "test-51" ]
+ },
+ "label" : "test-51",
+ "ontology_name" : "test",
+ "ontology_prefix" : "TEST",
+ "ontology_iri" : "https://top.smith.care/test/terminology",
+ "is_obsolete" : false,
+ "term_replaced_by" : null,
+ "is_defining_ontology" : true,
+ "has_children" : false,
+ "is_root" : false,
+ "short_form" : "TEST_#test-51",
+ "obo_id" : "TEST:#test-51",
+ "in_subset" : null,
+ "obo_definition_citation" : null,
+ "obo_xref" : null,
+ "obo_synonym" : null,
+ "is_preferred_root" : false,
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51?lang=en"
+ },
+ "parents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/parents"
+ },
+ "ancestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/ancestors"
+ },
+ "hierarchicalParents" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/hierarchicalParents"
+ },
+ "hierarchicalAncestors" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/hierarchicalAncestors"
+ },
+ "jstree" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/jstree"
+ },
+ "graph" : {
+ "href" : "http://localhost:9000/api/ontologies/test/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/graph"
+ }
+ }
+ } ]
+ },
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-5/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 5,
+ "totalPages" : 1,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51.json
new file mode 100644
index 00000000..6fb1ca09
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-51/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52.json
new file mode 100644
index 00000000..697294b5
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-52/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53.json
new file mode 100644
index 00000000..da7f2842
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-53/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54.json
new file mode 100644
index 00000000..2a6798e7
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-54/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55.json b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55.json
new file mode 100644
index 00000000..c6bd5b7d
--- /dev/null
+++ b/src/test/resources/ols4_fixtures/terms_hierarchy/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55.json
@@ -0,0 +1,13 @@
+{
+ "_links" : {
+ "self" : {
+ "href" : "http://localhost:9000/api/ontologies/TEST/terms/https%253A%252F%252Ftop.smith.care%252Ftest%252Fterminology%2523test-55/hierarchicalChildren?page=0&size=500"
+ }
+ },
+ "page" : {
+ "size" : 500,
+ "totalElements" : 0,
+ "totalPages" : 0,
+ "number" : 0
+ }
+}
\ No newline at end of file