View Javadoc
1   package de.dlr.shepard.data.file.services;
2   
3   import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
4   import static org.junit.jupiter.api.Assertions.assertEquals;
5   import static org.junit.jupiter.api.Assertions.assertThrows;
6   import static org.mockito.Mockito.doThrow;
7   import static org.mockito.Mockito.never;
8   import static org.mockito.Mockito.verify;
9   import static org.mockito.Mockito.when;
10  
11  import de.dlr.shepard.auth.permission.services.PermissionsService;
12  import de.dlr.shepard.auth.security.AuthenticationContext;
13  import de.dlr.shepard.auth.users.entities.User;
14  import de.dlr.shepard.auth.users.services.UserService;
15  import de.dlr.shepard.common.exceptions.InvalidPathException;
16  import de.dlr.shepard.common.mongoDB.NamedInputStream;
17  import de.dlr.shepard.common.util.AccessType;
18  import de.dlr.shepard.common.util.DateHelper;
19  import de.dlr.shepard.common.util.PermissionType;
20  import de.dlr.shepard.data.file.daos.FileContainerDAO;
21  import de.dlr.shepard.data.file.entities.FileContainer;
22  import de.dlr.shepard.data.file.entities.ShepardFile;
23  import de.dlr.shepard.data.file.io.FileContainerIO;
24  import io.quarkus.test.InjectMock;
25  import io.quarkus.test.component.QuarkusComponentTest;
26  import jakarta.inject.Inject;
27  import jakarta.ws.rs.InternalServerErrorException;
28  import jakarta.ws.rs.NotFoundException;
29  import java.text.SimpleDateFormat;
30  import java.util.Date;
31  import java.util.List;
32  import org.junit.jupiter.api.Test;
33  
34  @QuarkusComponentTest
35  public class FileContainerServiceTest {
36  
37    @InjectMock
38    FileContainerDAO dao;
39  
40    @InjectMock
41    PermissionsService permissionsService;
42  
43    @InjectMock
44    FileService fileService;
45  
46    @InjectMock
47    UserService userService;
48  
49    @InjectMock
50    DateHelper dateHelper;
51  
52    @InjectMock
53    AuthenticationContext authenticationContext;
54  
55    @Inject
56    FileContainerService service;
57  
58    private final User defaultUser = new User("Anna");
59  
60    @Test
61    public void getFileContainerTest_successful() {
62      FileContainer container = new FileContainer(1L);
63  
64      when(dao.findByNeo4jId(1L)).thenReturn(container);
65      when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
66      when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
67        true
68      );
69  
70      FileContainer actual = service.getContainer(1L);
71      assertEquals(container, actual);
72    }
73  
74    @Test
75    public void getFileContainerTest_isNull() {
76      when(dao.findByNeo4jId(1L)).thenReturn(null);
77      when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
78      when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
79        true
80      );
81      assertThrows(InvalidPathException.class, () -> service.getContainer(1L));
82    }
83  
84    @Test
85    public void getFileContainerTest_isDeleted() {
86      FileContainer container = new FileContainer(1L);
87      container.setDeleted(true);
88  
89      when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
90      when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
91        true
92      );
93      when(dao.findByNeo4jId(1L)).thenReturn(container);
94  
95      assertThrows(InvalidPathException.class, () -> service.getContainer(1L));
96    }
97  
98    @Test
99    public void getAllFileContainerTest_successful() {
100     var container1 = new FileContainer(1L);
101     var container2 = new FileContainer(2L);
102 
103     when(userService.getCurrentUser()).thenReturn(defaultUser);
104     when(dao.findAllFileContainers(null, defaultUser.getUsername())).thenReturn(List.of(container1, container2));
105 
106     var actual = service.getAllContainers(null);
107     assertEquals(List.of(container1, container2), actual);
108   }
109 
110   @Test
111   public void createFileContainerTest() {
112     var date = new Date(32);
113 
114     var input = new FileContainerIO() {
115       {
116         setName("Name");
117       }
118     };
119 
120     var toCreate = new FileContainer() {
121       {
122         setCreatedAt(date);
123         setCreatedBy(defaultUser);
124         setMongoId("collection");
125         setName("Name");
126       }
127     };
128 
129     var created = new FileContainer() {
130       {
131         setCreatedAt(date);
132         setCreatedBy(defaultUser);
133         setMongoId("database");
134         setName("Name");
135         setId(1L);
136       }
137     };
138 
139     when(fileService.createFileContainer()).thenReturn("collection");
140     when(dateHelper.getDate()).thenReturn(date);
141     when(userService.getCurrentUser()).thenReturn(defaultUser);
142     when(dao.createOrUpdate(toCreate)).thenReturn(created);
143 
144     var actual = service.createContainer(input);
145     assertEquals(created, actual);
146     verify(permissionsService).createPermissions(created, defaultUser, PermissionType.Private);
147   }
148 
149   @Test
150   public void deleteFileContainerServiceTest() {
151     var date = new Date(23);
152     var old = new FileContainer(1L);
153     old.setMongoId("XYZ");
154 
155     var expected = new FileContainer(1L) {
156       {
157         setUpdatedAt(date);
158         setUpdatedBy(defaultUser);
159         setDeleted(true);
160       }
161     };
162 
163     when(userService.getCurrentUser()).thenReturn(defaultUser);
164     when(dateHelper.getDate()).thenReturn(date);
165     when(dao.findByNeo4jId(1L)).thenReturn(old);
166     when(dao.createOrUpdate(expected)).thenReturn(expected);
167     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
168     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
169       true
170     );
171     when(permissionsService.isCurrentUserOwner(1L)).thenReturn(true);
172 
173     assertDoesNotThrow(() -> service.deleteContainer(1L));
174   }
175 
176   @Test
177   public void deleteFileContainerServiceTest_isNull() {
178     var date = new Date(23);
179 
180     when(userService.getCurrentUser()).thenReturn(defaultUser);
181     when(dateHelper.getDate()).thenReturn(date);
182     when(dao.findByNeo4jId(1L)).thenReturn(null);
183 
184     assertThrows(InvalidPathException.class, () -> service.deleteContainer(1L));
185   }
186 
187   @Test
188   public void createFileTest() {
189     FileContainer container = new FileContainer(1L);
190     container.setMongoId("mongoId");
191     ShepardFile file = new ShepardFile("oid", new Date(), "name", "md5");
192 
193     FileContainer updated = new FileContainer(1L);
194     updated.setMongoId("mongoId");
195     updated.addFile(file);
196 
197     when(dao.findByNeo4jId(1L)).thenReturn(container);
198     when(fileService.createFile("mongoId", "filename", null)).thenReturn(file);
199     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
200     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
201       true
202     );
203     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Write, defaultUser.getUsername())).thenReturn(
204       true
205     );
206 
207     ShepardFile actual = service.createFile(1L, "filename", null);
208 
209     assertEquals(file, actual);
210     verify(dao).createOrUpdate(updated);
211   }
212 
213   @Test
214   public void createFileTest_filenameIsNull() {
215     var container = new FileContainer(1L);
216     container.setMongoId("mongoId");
217     var file = new ShepardFile("oid", new Date(), "name", "md5");
218 
219     var date = new Date();
220     when(dateHelper.getDate()).thenReturn(date);
221     var sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
222     var dateStr = sdf.format(dateHelper.getDate());
223     var fileName = "shepard-file-" + dateStr;
224 
225     var updated = new FileContainer(1L);
226     updated.setMongoId("mongoId");
227     updated.addFile(file);
228 
229     when(dao.findByNeo4jId(1L)).thenReturn(container);
230     when(fileService.createFile("mongoId", fileName, null)).thenReturn(file);
231     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
232     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
233       true
234     );
235     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Write, defaultUser.getUsername())).thenReturn(
236       true
237     );
238 
239     var actual = service.createFile(1L, null, null);
240 
241     assertEquals(file, actual);
242     verify(dao).createOrUpdate(updated);
243   }
244 
245   @Test
246   public void createFileTest_filenameIsBlank() {
247     var container = new FileContainer(1L);
248     container.setMongoId("mongoId");
249     var file = new ShepardFile("oid", new Date(), "name", "md5");
250 
251     var date = new Date();
252     when(dateHelper.getDate()).thenReturn(date);
253     var sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");
254     var dateStr = sdf.format(dateHelper.getDate());
255     var fileName = "shepard-file-" + dateStr;
256 
257     var updated = new FileContainer(1L);
258     updated.setMongoId("mongoId");
259     updated.addFile(file);
260 
261     when(dao.findByNeo4jId(1L)).thenReturn(container);
262     when(fileService.createFile("mongoId", fileName, null)).thenReturn(file);
263     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
264     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
265       true
266     );
267     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Write, defaultUser.getUsername())).thenReturn(
268       true
269     );
270     var actual = service.createFile(1L, "", null);
271 
272     assertEquals(file, actual);
273     verify(dao).createOrUpdate(updated);
274   }
275 
276   @Test
277   public void createFileTest_containerIsNull() {
278     when(dao.findByNeo4jId(1L)).thenReturn(null);
279     var ex = assertThrows(InvalidPathException.class, () -> service.createFile(1L, "filename", null));
280     assertEquals(ex.getMessage(), "ID ERROR - File Container with id 1 is null or deleted");
281   }
282 
283   @Test
284   public void createFileTest_containerIsDeleted() {
285     var container = new FileContainer(1L);
286     container.setMongoId("mongoId");
287     container.setDeleted(true);
288 
289     when(dao.findByNeo4jId(1L)).thenReturn(container);
290 
291     var ex = assertThrows(InvalidPathException.class, () -> service.createFile(1L, "filename", null));
292     assertEquals("ID ERROR - File Container with id 1 is null or deleted", ex.getMessage());
293   }
294 
295   @Test
296   public void createFileTest_mongoError() {
297     var container = new FileContainer(1L);
298     container.setMongoId("mongoId");
299 
300     when(dao.findByNeo4jId(1L)).thenReturn(container);
301     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
302     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
303       true
304     );
305     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Write, defaultUser.getUsername())).thenReturn(
306       true
307     );
308     when(fileService.createFile("mongoId", "filename", null)).thenThrow(InternalServerErrorException.class);
309     //TODO: this unit test does not really test anything, we need to implement partial mocking on the FileService to simulate the MongoError
310 
311     assertThrows(InternalServerErrorException.class, () -> service.createFile(1L, "filename", null));
312   }
313 
314   @Test
315   public void getFileTest() {
316     FileContainer container = new FileContainer(1L);
317     container.setMongoId("mongoId");
318 
319     NamedInputStream result = new NamedInputStream("oid", null, "name", 123L);
320 
321     when(dao.findByNeo4jId(1L)).thenReturn(container);
322     when(fileService.getPayload("mongoId", "oid")).thenReturn(result);
323     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
324     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
325       true
326     );
327     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Write, defaultUser.getUsername())).thenReturn(
328       true
329     );
330 
331     var actual = service.getFile(1L, "oid");
332     assertEquals(result, actual);
333   }
334 
335   @Test
336   public void getFileTest_containerIsNull() {
337     when(dao.findByNeo4jId(1L)).thenReturn(null);
338 
339     var ex = assertThrows(InvalidPathException.class, () -> service.getFile(1L, "oid"));
340     assertEquals(ex.getMessage(), "ID ERROR - File Container with id 1 is null or deleted");
341   }
342 
343   @Test
344   public void getFileTest_containerIsDeleted() {
345     var container = new FileContainer(1L);
346     container.setMongoId("mongoId");
347     container.setDeleted(true);
348 
349     when(dao.findLightByNeo4jId(1L)).thenReturn(container);
350 
351     var ex = assertThrows(InvalidPathException.class, () -> service.getFile(1L, "oid"));
352     assertEquals(ex.getMessage(), "ID ERROR - File Container with id 1 is null or deleted");
353   }
354 
355   @Test
356   public void deleteFileTest() {
357     var file1 = new ShepardFile("abc", new Date(), "name", "md5");
358     var file2 = new ShepardFile("123", new Date(), "name", "md5");
359 
360     var container = new FileContainer(1L);
361     container.setMongoId("mongoId");
362     container.setFiles(List.of(file1, file2));
363 
364     var updated = new FileContainer(1L);
365     updated.setMongoId("mongoId");
366     updated.setFiles(List.of(file2));
367 
368     when(dao.findByNeo4jId(1L)).thenReturn(container);
369     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
370     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
371       true
372     );
373     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Write, defaultUser.getUsername())).thenReturn(
374       true
375     );
376 
377     assertDoesNotThrow(() -> service.deleteFile(1L, "abc"));
378     verify(dao).createOrUpdate(updated);
379   }
380 
381   @Test
382   public void deleteFileTest_deletedFalse() {
383     ShepardFile file1 = new ShepardFile("abc", new Date(), "name", "md5");
384     ShepardFile file2 = new ShepardFile("123", new Date(), "name", "md5");
385 
386     FileContainer container = new FileContainer(1L);
387     container.setMongoId("mongoId");
388     container.setFiles(List.of(file1, file2));
389 
390     FileContainer updated = new FileContainer(1L);
391     updated.setMongoId("mongoId");
392     updated.setFiles(List.of(file2));
393 
394     when(dao.findByNeo4jId(1L)).thenReturn(container);
395 
396     doThrow(new NotFoundException("Could not find and delete file with oid: abc"))
397       .when(fileService)
398       .deleteFile("mongoId", "abc");
399     when(authenticationContext.getCurrentUserName()).thenReturn(defaultUser.getUsername());
400     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Read, defaultUser.getUsername())).thenReturn(
401       true
402     );
403     when(permissionsService.isAccessTypeAllowedForUser(1L, AccessType.Write, defaultUser.getUsername())).thenReturn(
404       true
405     );
406 
407     assertThrows(NotFoundException.class, () -> service.deleteFile(1L, "abc"));
408 
409     verify(dao, never()).createOrUpdate(updated);
410   }
411 
412   @Test
413   public void deleteFileTest_containerIsNull() {
414     when(dao.findByNeo4jId(1L)).thenReturn(null);
415 
416     assertThrows(InvalidPathException.class, () -> service.deleteFile(1L, "oid"));
417   }
418 
419   @Test
420   public void deleteFileTest_containerIsDeleted() {
421     var container = new FileContainer(1L);
422     container.setMongoId("mongoId");
423     container.setDeleted(true);
424 
425     when(dao.findByNeo4jId(1L)).thenReturn(container);
426 
427     assertThrows(InvalidPathException.class, () -> service.deleteFile(1L, "oid"));
428   }
429 }