Skip to content

Commit

Permalink
#323 - Extended referencedCriteria and Valueset Search
Browse files Browse the repository at this point in the history
- add integration test for CodeableConceptService
  • Loading branch information
michael-82 committed Aug 19, 2024
1 parent 7ffcf7f commit c420e6c
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public CcSearchResult performCodeableConceptSearchWithRepoAndPaging(String keywo
if (valueSets != null && !valueSets.isEmpty()) {
searchHitPage = repo
.findByNameOrTermcodeMultiMatch1Filter(keyword,
"valuesets",
"value_sets",
valueSets,
PageRequest.of(page, pageSize));
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package de.numcodex.feasibility_gui_backend.terminology.es;

import de.numcodex.feasibility_gui_backend.terminology.es.repository.CodeableConceptEsRepository;
import de.numcodex.feasibility_gui_backend.terminology.es.repository.OntologyItemNotFoundException;
import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.elasticsearch.DataElasticsearchTest;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
import org.testcontainers.images.PullPolicy;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.io.IOException;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertThrows;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@Tag("terminology")
@Tag("elasticsearch")
@Import({CodeableConceptService.class})
@Testcontainers
@DataElasticsearchTest( properties = {
"app.elastic.filter=context,terminology"
})
public class CodeableConceptServiceIT {

@Autowired
private ElasticsearchOperations operations;

@Autowired
private CodeableConceptEsRepository repo;

@Autowired
private CodeableConceptService codeableConceptService;

@Container
public static ElasticsearchContainer elastic = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.15.0")
.withEnv("discovery.type", "single-node")
.withEnv("xpack.security.enabled", "false")
.withExposedPorts(9200)
.withStartupAttempts(3)
.withImagePullPolicy(PullPolicy.alwaysPull())
.waitingFor(Wait.forHttp("/health").forStatusCodeMatching(c -> c >= 200 && c <= 500));

@DynamicPropertySource
static void esProperties(DynamicPropertyRegistry registry) {
registry.add("spring.elasticsearch.uris", elastic::getHttpHostAddress);
}

@BeforeAll
static void setUp() throws IOException {
elastic.start();
System.out.println(elastic.getHttpHostAddress());
WebClient webClient = WebClient.builder().baseUrl("http://" + elastic.getHttpHostAddress()).build();
webClient.put()
.uri("/codeable_concept")
.body(BodyInserters.fromResource(new ClassPathResource("codeable_concept.json", CodeableConceptServiceIT.class)))
.retrieve()
.toBodilessEntity()
.block();

webClient.post()
.uri("/codeable_concept/_bulk")
.body(BodyInserters.fromResource(new ClassPathResource("cc_testdata.json", CodeableConceptServiceIT.class)))
.retrieve()
.toBodilessEntity()
.block();
}

@AfterAll
static void tearDown() {
elastic.stop();
}

@Test
void testPerformCodeableConceptSearchWithRepoAndPaging_findsOne() {
var page = assertDoesNotThrow (() -> codeableConceptService.performCodeableConceptSearchWithRepoAndPaging("foo", List.of(), 20, 0));

assertNotNull(page);
assertThat(page.getTotalHits()).isOne();
Assertions.assertEquals("A1.0", page.getResults().get(0).code());
}

@Test
void testPerformCodeableConceptSearchWithRepoAndPaging_findsNone() {
var page = assertDoesNotThrow (() -> codeableConceptService.performCodeableConceptSearchWithRepoAndPaging("something-not-found", List.of(), 20, 0));

assertNotNull(page);
assertThat(page.getTotalHits()).isZero();
}

@Test
void testPerformCodeableConceptSearchWithRepoAndPaging_findsTwoOrOneDependingOnFilter() {
var pageNoFilter = assertDoesNotThrow (() -> codeableConceptService.performCodeableConceptSearchWithRepoAndPaging("ba", List.of(), 20, 0));
var pageOneFilter = assertDoesNotThrow (() -> codeableConceptService.performCodeableConceptSearchWithRepoAndPaging("ba", List.of("some-value-set"), 20, 0));

assertNotNull(pageNoFilter);
assertNotNull(pageOneFilter);
Assertions.assertEquals(2, pageNoFilter.getTotalHits());
Assertions.assertEquals(1, pageOneFilter.getTotalHits());
}

@Test
void testGetSearchResultEntryByCode_succeeds() {
var result = assertDoesNotThrow(() -> codeableConceptService.getSearchResultEntryByCode("A1.1"));

assertNotNull(result);
Assertions.assertEquals("bar", result.display());
Assertions.assertEquals("A1.1", result.code());
Assertions.assertEquals("2012", result.version());
Assertions.assertEquals("another-system", result.system());
}

@Test
void testGetSearchResultEntryByCode_throwsOnNotFound() {
assertThrows(OntologyItemNotFoundException.class, () -> codeableConceptService.getSearchResultEntryByCode("something-not-found"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static void setUp() throws IOException {

webClient.post()
.uri("/ontology/_bulk")
.body(BodyInserters.fromResource(new ClassPathResource("testData.json", TerminologyEsServiceIT.class)))
.body(BodyInserters.fromResource(new ClassPathResource("ontology_testdata.json", TerminologyEsServiceIT.class)))
.retrieve()
.toBodilessEntity()
.block();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{"index": {"_index": "codeable_concept", "_id": "A1.0"}}
{"termcode": {"code": "A1.0", "display": "foo", "system": "some-system", "version": 2010}, "value_sets": []}
{"index": {"_index": "codeable_concept", "_id": "A1.1"}}
{"termcode": {"code": "A1.1", "display": "bar", "system": "another-system", "version": 2012}, "value_sets": ["some-value-set"]}
{"index": {"_index": "codeable_concept", "_id": "A2.0"}}
{"termcode": {"code": "A2.0", "display": "baz", "system": "some-system", "version": 2023}, "value_sets": []}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"settings": {
"analysis": {
"tokenizer": {
"edge_ngram_tokenizer": {
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 20,
"token_chars": [
"letter",
"digit"
]
}
},
"analyzer": {
"edge_ngram_analyzer": {
"type": "custom",
"tokenizer": "edge_ngram_tokenizer",
"filter": [
"lowercase"
]
},
"lowercase_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"properties": {
"termcode": {
"properties": {
"code": {
"type": "text",
"analyzer": "edge_ngram_analyzer",
"search_analyzer": "lowercase_analyzer"
},
"display": {
"type": "text",
"analyzer": "edge_ngram_analyzer",
"search_analyzer": "lowercase_analyzer"
},
"system": {
"type": "text",
"index": false
},
"version": {
"type": "long",
"index": false
}
}
},
"value_sets": {
"type": "keyword"
}
}
}
}

0 comments on commit c420e6c

Please sign in to comment.