1 package de.dlr.shepard.data.structureddata.services;
2
3 import static com.mongodb.client.model.Filters.eq;
4 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5 import static org.junit.jupiter.api.Assertions.assertEquals;
6 import static org.junit.jupiter.api.Assertions.assertThrows;
7 import static org.mockito.ArgumentMatchers.any;
8 import static org.mockito.Mockito.doAnswer;
9 import static org.mockito.Mockito.doThrow;
10 import static org.mockito.Mockito.never;
11 import static org.mockito.Mockito.verify;
12 import static org.mockito.Mockito.when;
13
14 import com.mongodb.MongoException;
15 import com.mongodb.client.FindIterable;
16 import com.mongodb.client.MongoCollection;
17 import com.mongodb.client.MongoDatabase;
18 import com.mongodb.client.model.Filters;
19 import de.dlr.shepard.BaseTestCase;
20 import de.dlr.shepard.common.exceptions.InvalidBodyException;
21 import de.dlr.shepard.common.util.DateHelper;
22 import de.dlr.shepard.data.structureddata.entities.StructuredData;
23 import de.dlr.shepard.data.structureddata.entities.StructuredDataPayload;
24 import io.quarkus.test.InjectMock;
25 import io.quarkus.test.component.QuarkusComponentTest;
26 import jakarta.inject.Inject;
27 import jakarta.inject.Named;
28 import jakarta.ws.rs.InternalServerErrorException;
29 import jakarta.ws.rs.NotFoundException;
30 import java.util.Date;
31 import org.bson.Document;
32 import org.bson.types.ObjectId;
33 import org.junit.jupiter.api.Test;
34 import org.mockito.ArgumentCaptor;
35 import org.mockito.Captor;
36 import org.mockito.invocation.InvocationOnMock;
37 import org.mockito.stubbing.Answer;
38
39 @QuarkusComponentTest
40 public class StructuredDataServiceTest extends BaseTestCase {
41
42 @InjectMock
43 DateHelper dateHelper;
44
45 @InjectMock
46 FindIterable<Document> result;
47
48 @InjectMock
49 MongoCollection<Document> collection;
50
51 @Inject
52 StructuredDataService service;
53
54 @Captor
55 private ArgumentCaptor<String> collectionName;
56
57 @InjectMock
58 @Named("mongoDatabase")
59 MongoDatabase mongoDatabase;
60
61 @Test
62 public void createStructuredDataContainerTest() {
63 var actual = service.createStructuredDataContainer();
64 verify(mongoDatabase).createCollection(collectionName.capture());
65 assertEquals(collectionName.getValue(), actual);
66 }
67
68 @Test
69 public void createStructuredDataTest() {
70 String payload = "{\"a\":\"b\", \"c\":\"d\"}";
71 Date date = new Date();
72 ObjectId oid = new ObjectId();
73 StructuredData data = new StructuredData("name", date);
74 Document toInsert = Document.parse(payload);
75 toInsert.append("_meta", data);
76
77 when(dateHelper.getDate()).thenReturn(date);
78 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
79 doAnswer(
80 new Answer<Void>() {
81 @Override
82 public Void answer(InvocationOnMock invocation) throws Throwable {
83 Object[] args = invocation.getArguments();
84 ((Document) args[0]).append("_id", oid);
85 return null;
86 }
87 }
88 )
89 .when(collection)
90 .insertOne(toInsert);
91
92 var expectedData = new StructuredData();
93 expectedData.setName("name");
94 var actual = service.createStructuredData("collection", new StructuredDataPayload(expectedData, payload));
95 assertEquals(new StructuredData(oid.toHexString(), date, "name"), actual);
96 }
97
98 @Test
99 public void createStructuredDataTest_forbiddenKeys() {
100 String payload = "{\"_a\":\"b\", \"c\":\"d\"}";
101 String payloadCleaned = "{\"c\":\"d\"}";
102 Date date = new Date();
103 ObjectId oid = new ObjectId();
104 StructuredData data = new StructuredData("name", date);
105 Document toInsert = Document.parse(payloadCleaned);
106 toInsert.append("_meta", data);
107
108 when(dateHelper.getDate()).thenReturn(date);
109 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
110 doAnswer(
111 new Answer<Void>() {
112 @Override
113 public Void answer(InvocationOnMock invocation) throws Throwable {
114 Object[] args = invocation.getArguments();
115 ((Document) args[0]).append("_id", oid);
116 return null;
117 }
118 }
119 )
120 .when(collection)
121 .insertOne(toInsert);
122
123 var expectedData = new StructuredData();
124 expectedData.setName("name");
125 var actual = service.createStructuredData("collection", new StructuredDataPayload(expectedData, payload));
126 assertEquals(new StructuredData(oid.toHexString(), date, "name"), actual);
127 }
128
129 @Test
130 public void createStructuredDataTest_noStructuredData() {
131 String payload = "{\"a\":\"b\", \"c\":\"d\"}";
132 Date date = new Date();
133 ObjectId oid = new ObjectId();
134 StructuredData data = new StructuredData(null, date);
135 Document toInsert = Document.parse(payload);
136 toInsert.append("_meta", data);
137
138 when(dateHelper.getDate()).thenReturn(date);
139 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
140 doAnswer(
141 new Answer<Void>() {
142 @Override
143 public Void answer(InvocationOnMock invocation) throws Throwable {
144 Object[] args = invocation.getArguments();
145 ((Document) args[0]).append("_id", oid);
146 return null;
147 }
148 }
149 )
150 .when(collection)
151 .insertOne(toInsert);
152
153 var actual = service.createStructuredData("collection", new StructuredDataPayload(null, payload));
154 assertEquals(new StructuredData(oid.toHexString(), date, null), actual);
155 }
156
157 @Test
158 public void createStructuredDataTest_mongoError() {
159 String payload = "{\"a\":\"b\", \"c\":\"d\"}";
160
161 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
162 doThrow(new MongoException("message")).when(collection).insertOne(any(Document.class));
163
164 var expectedData = new StructuredData();
165 expectedData.setName("name");
166
167 assertThrows(InternalServerErrorException.class, () ->
168 service.createStructuredData("collection", new StructuredDataPayload(expectedData, payload))
169 );
170 }
171
172 @Test
173 public void createStructuredDataTest_collectionIsNull() {
174 String payload = "{\"a\":\"b\", \"c\":\"d\"}";
175 String mongoId = "collection";
176
177 var expectedData = new StructuredData();
178 expectedData.setName("name");
179
180 doThrow(new IllegalArgumentException()).when(mongoDatabase).getCollection(mongoId);
181
182 assertThrows(NotFoundException.class, () ->
183 service.createStructuredData(mongoId, new StructuredDataPayload(expectedData, payload))
184 );
185
186 verify(collection, never()).insertOne(any(Document.class));
187 }
188
189 @Test
190 public void createStructuredDataTest_invalidJson() {
191 String payload = "invalid";
192
193 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
194
195 var expectedData = new StructuredData();
196 expectedData.setName("name");
197 var newStrData = new StructuredDataPayload(expectedData, payload);
198 assertThrows(InvalidBodyException.class, () -> service.createStructuredData("collection", newStrData));
199 verify(collection, never()).insertOne(any(Document.class));
200 }
201
202 @Test
203 public void deleteStructuredDataTest() {
204 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
205
206 assertDoesNotThrow(() -> service.deleteStructuredDataContainer("collection"));
207 }
208
209 @Test
210 public void deleteStructuredDataTest_collectionIsNull() {
211 doThrow(new IllegalArgumentException()).when(mongoDatabase).getCollection("collection");
212
213 assertThrows(NotFoundException.class, () -> service.deleteStructuredDataContainer("collection"));
214 }
215
216 @Test
217 public void getPayloadTest() {
218 Date date = new Date();
219 StructuredData data = new StructuredData(null, date, "name");
220 ObjectId oid = new ObjectId();
221 Document doc = new Document("_id", oid);
222 doc.append("a", "b");
223 Document sd = new Document();
224 sd.append("name", data.getName());
225 sd.append("createdAt", data.getCreatedAt());
226 doc.append("_meta", sd);
227
228 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
229 when(collection.find(eq("_id", oid))).thenReturn(result);
230 when(result.first()).thenReturn(doc);
231
232 var actual = service.getPayload("collection", oid.toHexString());
233 assertEquals(new StructuredDataPayload(new StructuredData(oid.toHexString(), date, "name"), doc.toJson()), actual);
234 }
235
236 @Test
237 public void getPayloadTest_noMeta() {
238 ObjectId oid = new ObjectId();
239 Document doc = new Document("_id", oid);
240 doc.append("a", "b");
241
242 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
243 when(collection.find(eq("_id", oid))).thenReturn(result);
244 when(result.first()).thenReturn(doc);
245
246 var actual = service.getPayload("collection", oid.toHexString());
247 assertEquals(new StructuredDataPayload(new StructuredData(oid.toHexString(), null, null), doc.toJson()), actual);
248 }
249
250 @Test
251 public void getPayloadTest_collectionIsNull() {
252 ObjectId oid = new ObjectId();
253
254 doThrow(new IllegalArgumentException()).when(mongoDatabase).getCollection("collection");
255
256 assertThrows(NotFoundException.class, () -> service.getPayload("collection", oid.toHexString()));
257 }
258
259 @Test
260 public void getPayloadTest_payloadIsNull() {
261 ObjectId oid = new ObjectId();
262
263 when(mongoDatabase.getCollection("collection")).thenReturn(collection);
264 when(collection.find(eq("_id", oid))).thenReturn(result);
265 when(result.first()).thenReturn(null);
266
267 assertThrows(NotFoundException.class, () -> service.getPayload("collection", oid.toHexString()));
268 }
269
270 @Test
271 public void deletePayloadTest() {
272 String mongoOid = "60b73212cfa45d2d5baa795b";
273 ObjectId oid = new ObjectId("60b73212cfa45d2d5baa795c");
274
275 when(mongoDatabase.getCollection(mongoOid)).thenReturn(collection);
276 when(collection.findOneAndDelete(Filters.eq("_id", oid))).thenReturn(new Document());
277
278 assertDoesNotThrow(() -> service.deletePayload(mongoOid, oid.toHexString()));
279 }
280
281 @Test
282 public void deletePayloadTest_collectionIsNull() {
283 String mongoOid = "60b73212cfa45d2d5baa795b";
284 ObjectId oid = new ObjectId("60b73212cfa45d2d5baa795c");
285
286 doThrow(new IllegalArgumentException()).when(mongoDatabase).getCollection(mongoOid);
287
288 assertThrows(NotFoundException.class, () -> service.deletePayload(mongoOid, oid.toHexString()));
289 }
290
291 @Test
292 public void deletePayloadTest_notFound() {
293 String mongoOid = "60b73212cfa45d2d5baa795b";
294 ObjectId oid = new ObjectId("60b73212cfa45d2d5baa795c");
295
296 when(mongoDatabase.getCollection(mongoOid)).thenReturn(collection);
297 when(collection.findOneAndDelete(Filters.eq("_id", oid))).thenReturn(null);
298
299 assertThrows(NotFoundException.class, () -> service.deletePayload(mongoOid, oid.toHexString()));
300 }
301 }