ProjectController { @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/projects/{projectId}/attachments", method = RequestMethod.POST) public Attachment addProjectAttachment(@PathVariable("projectId") String projectId, @RequestParam("file") MultipartFile file, Principal principal) { if (file.isEmpty()) { throw InvalidRequestException.fileMustNotBeEmpty(); } if (!contentTypeAllowed(file.getContentType())) { throw InvalidRequestException.filetypeNotAllowed(); } try ( InputStream inputStream = file.getInputStream() ) { Attachment attachment = Attachment.asCreationCommand(file.getOriginalFilename(), file.getContentType(), inputStream); return projectService.addProjectAttachment(projectId, attachment, userByPrincipal(principal)); } catch (IOException e) { log.warn("Couldn' process file input, due to stream threw IOException; ProjectId: {}", projectId, e); throw new RuntimeException("Internal error, couldn't process file stream", e); } }  @Secured({Roles.ROLE_USER}) @RequestMapping(value = "/projects", method = RequestMethod.GET) @JsonView(Project.ProjectSummaryView.class) List<Project> getProjects(Authentication auth); @Secured({Roles.ROLE_USER}) @RequestMapping(value = "/project/{projectId}", method = RequestMethod.GET) Project getProject(@PathVariable String projectId, Authentication auth); @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.CREATED) @RequestMapping(value = "/project", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) Project addProject(@RequestBody @Valid Project project, Principal principal); @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.CREATED) @RequestMapping(value = "/project/{projectId}/pledges", method = RequestMethod.POST) void pledgeProject(@PathVariable String projectId, @RequestBody @Valid Pledge pledge, Principal principal); @Secured(Roles.ROLE_ADMIN) @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/project/{projectId}/status", method = RequestMethod.PATCH) Project modifyProjectStatus(@PathVariable("projectId") String projectId, @RequestBody @Valid @NotNull ProjectStatusUpdate newStatus, Principal principal); @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/project/{projectId}", method = RequestMethod.PUT) Project modifyProjectMasterdata(@PathVariable("projectId") String projectId, @RequestBody @Valid @NotNull Project modifiedProject, Principal principal); @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/projects/{projectId}/likes", method = RequestMethod.POST) void likeProject(@PathVariable("projectId") String projectId, Principal principal); @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/projects/{projectId}/likes", method = RequestMethod.DELETE) void unlikeProject(@PathVariable("projectId") String projectId, Principal principal); @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.OK) @RequestMapping(value = "/projects/{projectId}/attachments", method = RequestMethod.POST) Attachment addProjectAttachment(@PathVariable("projectId") String projectId, @RequestParam("file") MultipartFile file, Principal principal); @Secured({Roles.ROLE_TRUSTED_ANONYMOUS, Roles.ROLE_USER}) @RequestMapping(value = "/projects/{projectId}/attachments/{fileReference}", method = RequestMethod.GET) ResponseEntity<InputStreamResource> serveProjectAttachment(@PathVariable("projectId") String projectId, @PathVariable("fileReference") String fileReference); @Secured(Roles.ROLE_USER) @ResponseStatus(HttpStatus.NO_CONTENT) @RequestMapping(value = "/projects/{projectId}/attachments/{fileReference}", method = RequestMethod.DELETE) void deleteProjectAttachment(@PathVariable("projectId") String projectId, @PathVariable("fileReference") String fileReference, Principal principal);  }
@Test public void addProjectAttachment_shouldDelegateToProjectService() throws Exception { final String email = "some@mail.com"; final UserEntity user = userEntity(email, Roles.ROLE_USER, Roles.ROLE_ADMIN); final Attachment expectedAttachment = anExpectedAttachment(aPersistedProjectEntity()); MockMultipartFile content = mockedMultipart("somecontent", "test_filename", "text/plain"); MediaType mediaType = mediaType(); when(projectService.addProjectAttachment(eq("some_id"), eq(Attachment.asCreationCommand("test_filename", "text/plain", content.getInputStream())), eq(user))) .thenReturn(expectedAttachment); MvcResult mvcRes = mockMvc.perform(fileUpload("/projects/{projectId}/attachments", "some_id") .file(content) .principal(authentication(user)) .contentType(mediaType)) .andExpect(status().isOk()) .andReturn(); Attachment res = mapper.readValue(mvcRes.getResponse().getContentAsString(), Attachment.class); assertAttachmentsEqual(expectedAttachment, res); }
@Test public void addProjectAttachment_shouldCloseInputStream() throws Exception { final String email = "some@mail.com"; final UserEntity user = userEntity(email, Roles.ROLE_USER, Roles.ROLE_ADMIN); final Attachment expectedAttachment = anExpectedAttachment(aPersistedProjectEntity()); MockMultipartFile content = new MockedInputStreamMultipartFile("file", "test_filename", "text/plain"); final InputStream mockedInputStream = content.getInputStream(); MediaType mediaType = mediaType(); when(projectService.addProjectAttachment(eq("some_id"), eq(Attachment.asCreationCommand("test_filename", "text/plain", content.getInputStream())), eq(user))) .thenReturn(expectedAttachment); MvcResult mvcRes = mockMvc.perform(fileUpload("/projects/{projectId}/attachments", "some_id") .file(content) .principal(authentication(user)) .contentType(mediaType)) .andExpect(status().isOk()) .andReturn(); Attachment res = mapper.readValue(mvcRes.getResponse().getContentAsString(), Attachment.class); assertAttachmentsEqual(expectedAttachment, res); verify(mockedInputStream).close(); }