View Javadoc
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; // void method, so 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; // void method, so 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; // void method, so 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 }