1 package de.dlr.shepard.context.semantic.services;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertNotNull;
5 import static org.junit.jupiter.api.Assertions.assertThrows;
6 import static org.junit.jupiter.api.Assertions.assertTrue;
7 import static org.mockito.ArgumentMatchers.eq;
8
9 import de.dlr.shepard.RandomGenerator;
10 import de.dlr.shepard.auth.security.AuthenticationContext;
11 import de.dlr.shepard.auth.users.entities.User;
12 import de.dlr.shepard.auth.users.services.UserService;
13 import de.dlr.shepard.common.exceptions.InvalidPathException;
14 import de.dlr.shepard.context.semantic.SemanticRepositoryType;
15 import de.dlr.shepard.context.semantic.daos.SemanticRepositoryDAO;
16 import de.dlr.shepard.context.semantic.entities.SemanticRepository;
17 import de.dlr.shepard.context.semantic.io.SemanticAnnotationIO;
18 import de.dlr.shepard.data.timeseries.daos.TimeseriesContainerDAO;
19 import de.dlr.shepard.data.timeseries.model.TimeseriesContainer;
20 import de.dlr.shepard.data.timeseries.services.TimeseriesService;
21 import io.quarkus.test.InjectMock;
22 import io.quarkus.test.junit.QuarkusTest;
23 import jakarta.enterprise.context.control.ActivateRequestContext;
24 import jakarta.inject.Inject;
25 import jakarta.transaction.Transactional;
26 import jakarta.ws.rs.NotFoundException;
27 import org.junit.jupiter.api.AfterAll;
28 import org.junit.jupiter.api.BeforeAll;
29 import org.junit.jupiter.api.BeforeEach;
30 import org.junit.jupiter.api.Test;
31 import org.junit.jupiter.api.TestInstance;
32 import org.mockito.Mockito;
33
34 @QuarkusTest
35 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
36 @ActivateRequestContext
37 public class AnnotatableTimeseriesServiceTest {
38
39 @InjectMock
40 SemanticAnnotationService semanticAnnotationService;
41
42 @InjectMock
43 TimeseriesService timeseriesService;
44
45 @InjectMock
46 UserService userService;
47
48 @InjectMock
49 AuthenticationContext authenticationContext;
50
51 @Inject
52 TimeseriesContainerDAO timeseriesContainerDao;
53
54 @Inject
55 SemanticRepositoryDAO semanticRepositoryDao;
56
57 @Inject
58 AnnotatableTimeseriesService service;
59
60 private final User user = new User("Testuser");
61
62 private TimeseriesContainer container;
63 private SemanticRepository semanticRepository;
64 private final String iri = "http://purl.obolibrary.org/obo/uo.owl";
65
66 private final int nonExistingTimeseriesId = 9999999;
67 private final long nonExistingAnnotationId = 9999999L;
68
69 @BeforeAll
70 @Transactional
71 public void setup() {
72 var timeseriesContainer = new TimeseriesContainer();
73 timeseriesContainer.setName("ttc-" + RandomGenerator.generateString(10));
74 container = timeseriesContainerDao.createOrUpdate(timeseriesContainer);
75
76 semanticRepository = new SemanticRepository();
77 semanticRepository.setName("ontobee test repository");
78 semanticRepository.setEndpoint("https://sparql.hegroup.org/sparql/");
79 semanticRepository.setType(SemanticRepositoryType.SPARQL);
80 semanticRepositoryDao.createOrUpdate(semanticRepository);
81
82 Mockito.when(userService.getCurrentUser()).thenReturn(user);
83 Mockito.when(authenticationContext.getCurrentUserName()).thenReturn(user.getUsername());
84 }
85
86 @BeforeEach
87 public void setupEach() {
88 Mockito.when(semanticAnnotationService.validateTerm(semanticRepository, iri)).thenReturn("prop", "value");
89 Mockito.when(timeseriesService.getTimeseriesById(eq(container.getId()), eq(nonExistingTimeseriesId))).thenThrow(
90 new InvalidPathException()
91 );
92 }
93
94 @AfterAll
95 @Transactional
96 public void cleanup() {}
97
98 @Test
99 public void createAnnotation_NothingExists_AnnotatableTimeseriesAndAnnotationAreCreated() {
100 int timeseriesId = 1;
101 SemanticAnnotationIO annotationIO = new SemanticAnnotationIO();
102 annotationIO.setPropertyRepositoryId(semanticRepository.getId());
103 annotationIO.setPropertyIRI(iri);
104 annotationIO.setValueRepositoryId(semanticRepository.getId());
105 annotationIO.setValueIRI(iri);
106
107 var actual = service.createAnnotation(container.getId(), timeseriesId, annotationIO);
108
109 assertTrue(actual.getId() > 0);
110 assertEquals("prop::value", actual.getName());
111 assertEquals(iri, actual.getPropertyIRI());
112 assertEquals(iri, actual.getValueIRI());
113 assertEquals(semanticRepository, actual.getPropertyRepository());
114 assertEquals(semanticRepository, actual.getValueRepository());
115 }
116
117 @Test
118 public void createAnnotation_TimeseriesIdDoesNotExist_throwNotFoundException() {
119 assertThrows(InvalidPathException.class, () ->
120 service.createAnnotation(container.getId(), nonExistingTimeseriesId, null)
121 );
122 }
123
124 @Test
125 public void getAnnotations_AnnotatableTimeseriesWithTwoAnnotationsExist_returnsTwoAnnotations() {
126 int timeseriesId = 2;
127
128 var firstAnnotation = new SemanticAnnotationIO();
129 firstAnnotation.setPropertyRepositoryId(semanticRepository.getId());
130 firstAnnotation.setPropertyIRI(iri);
131 firstAnnotation.setValueRepositoryId(semanticRepository.getId());
132 firstAnnotation.setValueIRI(iri);
133 service.createAnnotation(container.getId(), timeseriesId, firstAnnotation);
134
135 var secondAnnotation = new SemanticAnnotationIO();
136 secondAnnotation.setPropertyRepositoryId(semanticRepository.getId());
137 secondAnnotation.setPropertyIRI(iri);
138 secondAnnotation.setValueRepositoryId(semanticRepository.getId());
139 secondAnnotation.setValueIRI(iri);
140 service.createAnnotation(container.getId(), timeseriesId, secondAnnotation);
141
142 service.clearSession();
143 var actual = service.getAnnotations(container.getId(), timeseriesId);
144
145 assertEquals(2, actual.size());
146 assertNotNull(actual.get(0).getPropertyRepository(), "Property repository is null");
147 assertNotNull(actual.get(0).getValueRepository(), "Value repository is null");
148 }
149
150 @Test
151 public void getAnnotations_TimeseriesDoesNotExist_throwsInvalidPathException() {
152 assertThrows(InvalidPathException.class, () -> service.getAnnotations(container.getId(), nonExistingTimeseriesId));
153 }
154
155 @Test
156 public void getAnnotationById_AnnotatableTimeseriesDoesExist_returnsAnnotatableTimeseriesWithAnnotation() {
157 var timeseriesId = 4;
158 SemanticAnnotationIO annotationIO = new SemanticAnnotationIO();
159 annotationIO.setPropertyRepositoryId(semanticRepository.getId());
160 annotationIO.setPropertyIRI(iri);
161 annotationIO.setValueRepositoryId(semanticRepository.getId());
162 annotationIO.setValueIRI(iri);
163
164 var storedEntity = service.createAnnotation(container.getId(), timeseriesId, annotationIO);
165 service.clearSession();
166 var actual = service.getAnnotationById(container.getId(), timeseriesId, storedEntity.getId());
167
168 assertNotNull(actual);
169 assertEquals("prop::value", actual.getName());
170 assertEquals(annotationIO.getPropertyIRI(), actual.getPropertyIRI());
171 assertEquals(annotationIO.getValueIRI(), actual.getValueIRI());
172 assertEquals(semanticRepository.getId(), actual.getPropertyRepository().getId());
173 assertEquals(semanticRepository.getId(), actual.getValueRepository().getId());
174 assertEquals(storedEntity.getId(), actual.getId());
175 }
176
177 @Test
178 public void getAnnotationById_AnnotationDoesNotExist_throwsNotFoundException() {
179 var timeseriesId = 5;
180
181 assertThrows(NotFoundException.class, () ->
182 service.getAnnotationById(container.getId(), timeseriesId, nonExistingAnnotationId)
183 );
184 }
185
186 @Test
187 public void delete_AnnotatableTimeseriesDoesExist_entityIsDeleted() {
188 var timeseriesId = 5;
189 SemanticAnnotationIO annotationIO = new SemanticAnnotationIO();
190 annotationIO.setPropertyRepositoryId(semanticRepository.getId());
191 annotationIO.setPropertyIRI(iri);
192 annotationIO.setValueRepositoryId(semanticRepository.getId());
193 annotationIO.setValueIRI(iri);
194
195 var storedEntity = service.createAnnotation(container.getId(), timeseriesId, annotationIO);
196
197 service.clearSession();
198 service.deleteAnnotation(container.getId(), timeseriesId, storedEntity.getId());
199
200 service.clearSession();
201 assertThrows(NotFoundException.class, () ->
202 service.getAnnotationById(container.getId(), timeseriesId, storedEntity.getId())
203 );
204 }
205
206 @Test
207 public void getAnnotations_TimeseriesWithoutAnnotations_returnsEmptyList() {
208 int timeseriesId = 6;
209 var actual = service.getAnnotations(container.getId(), timeseriesId);
210 assertEquals(0, actual.size());
211 }
212 }