Commit 8d8d20fc authored by Maxym Borodenko's avatar Maxym Borodenko

Attaching files to CooperatorAttachment

parent fd5c02cf
......@@ -21,15 +21,19 @@ import java.util.Map;
import javax.validation.Valid;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.gringlobal.api.v1.ApiBaseController;
import org.gringlobal.api.v1.FilteredCRUDController;
import org.gringlobal.api.v1.FilteredPage;
import org.gringlobal.api.v1.Pagination;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.gringlobal.model.AccessionInvAttach;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.InventoryAction;
import org.gringlobal.model.QInventory;
import org.gringlobal.service.InventoryActionService;
import org.gringlobal.service.InventoryAttachmentFileService;
import org.gringlobal.service.InventoryService;
import org.gringlobal.service.filter.InventoryActionFilter;
import org.gringlobal.service.filter.InventoryFilter;
......@@ -37,12 +41,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import com.querydsl.core.types.OrderSpecifier;
......@@ -50,6 +56,7 @@ import com.querydsl.core.types.OrderSpecifier;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.multipart.MultipartFile;
@RestController("inventoryApi1")
@RequestMapping(InventoryController.API_URL)
......@@ -62,7 +69,10 @@ public class InventoryController extends FilteredCRUDController<Inventory, Inven
@Autowired
private InventoryActionService inventoryActionService;
@Autowired
private InventoryAttachmentFileService attachmentFileService;
@Override
protected OrderSpecifier<?>[] defaultSort() {
return new OrderSpecifier[] { QInventory.inventory.id.asc() };
......@@ -145,4 +155,19 @@ public class InventoryController extends FilteredCRUDController<Inventory, Inven
public Map<?, ?> inventoryOverview(@PathVariable(name = "groupBy", required = true) String groupBy, @RequestBody InventoryFilter filter) {
return crudService.inventoryOverview(groupBy, filter);
}
@PostMapping(value = "/attach/{inventoryId}", produces = { MediaType.APPLICATION_JSON_VALUE })
@Operation(operationId = "uploadFile", description = "Attach accession file", summary = "Attach file")
public AccessionInvAttach uploadFile(@PathVariable(name = "inventoryId") final Long inventoryId, @RequestPart(name = "file") final MultipartFile file,
@RequestPart(name = "metadata") final InventoryAttachmentFileService.InventoryAttachmentRequest metadata) throws InvalidRepositoryPathException, InvalidRepositoryFileDataException, IOException {
return attachmentFileService.uploadFile(crudService.get(inventoryId), file, metadata);
}
@DeleteMapping(value = "/attach/{inventoryId}/{attachmentId}", produces = { MediaType.APPLICATION_JSON_VALUE })
@Operation(operationId = "removeFile", description = "Remove attached file", summary = "Remove file")
public AccessionInvAttach removeFile(@PathVariable(name = "inventoryId") final Long inventoryId, @PathVariable(name = "attachmentId") final Long attachmentId) {
return attachmentFileService.removeFile(crudService.get(inventoryId), attachmentId);
}
}
......@@ -37,6 +37,10 @@ import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
@Configuration
@Import({ CommonConfig.class, CacheConfig.class, DatabaseConfig.class, SecurityConfig.class, SpringMvcConfig.class,
SchedulerConfig.class, OpenAPIConfig.class, ElasticsearchConfig.class, FileRepositoryConfig.class })
......@@ -94,4 +98,10 @@ public class ApplicationConfig {
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
@Bean
public Validator validator() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
return factory.getValidator();
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.service;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.model.RepositoryFile;
import org.gringlobal.model.CooperatorAttachment;
import org.gringlobal.model.CooperatorOwnedModel;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
/**
* @author Maxym Borodenko
*/
@Transactional(readOnly = true)
public interface AttachmentFileService<T extends CooperatorOwnedModel, A extends CooperatorAttachment, R extends AttachmentFileService.AttachmentRequest<A>> {
@Transactional
A uploadFile(@NotNull T entity, @NotNull MultipartFile file, @Valid R metadata) throws IOException, InvalidRepositoryPathException, InvalidRepositoryFileDataException;
@Transactional
A removeFile(@NotNull T entity, @NotNull Long attachmentId);
class AttachmentRequest<A extends CooperatorAttachment> {
public RepositoryFile fileMetadata;
@NotNull
public A attachMetadata;
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.service;
import org.gringlobal.model.AccessionInvAttach;
import org.gringlobal.model.Inventory;
/**
* @author Maxym Borodenko
*/
public interface InventoryAttachmentFileService extends AttachmentFileService<Inventory, AccessionInvAttach, InventoryAttachmentFileService.InventoryAttachmentRequest> {
class InventoryAttachmentRequest extends AttachmentFileService.AttachmentRequest<AccessionInvAttach> {
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.service.impl;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
import com.querydsl.core.types.dsl.NumberPath;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.filerepository.service.RepositoryService;
import org.gringlobal.api.NotFoundElement;
import org.gringlobal.model.CooperatorAttachment;
import org.gringlobal.model.CooperatorOwnedModel;
import org.gringlobal.service.AttachmentFileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.multipart.MultipartFile;
/**
* @author Maxym Borodenko
*/
@Validated
public abstract class BaseAttachmentFileSupport<T extends CooperatorOwnedModel, A extends CooperatorAttachment, R extends AttachmentFileService.AttachmentRequest<A>> implements AttachmentFileService<T, A, R> {
protected final Logger LOG = LoggerFactory.getLogger(getClass());
private NumberPath<Long> qActionOwningEntityId;
private NumberPath<Long> qAttachId;
@Autowired
protected JpaRepository<A, Long> attachRepository;
@Autowired
protected JpaRepository<T, Long> owningEntityRepository;
@Autowired
private QuerydslPredicateExecutor<A> attachFinder;
@Autowired
protected RepositoryService repositoryService;
@Autowired
private Validator validator;
public BaseAttachmentFileSupport() {
}
protected BaseAttachmentFileSupport(NumberPath<Long> owningEntityId, NumberPath<Long> qAttachId) {
this.qActionOwningEntityId = owningEntityId;
this.qAttachId = qAttachId;
}
@Override
@Transactional
public A uploadFile(T entity, MultipartFile file, R metadata) throws IOException, InvalidRepositoryPathException, InvalidRepositoryFileDataException {
T savedEntity = owningEntityRepository.getOne(entity.getId());
Path repositoryPath = createRepositoryPath(savedEntity);
LOG.info("Upload file {} to path {}", file.getOriginalFilename(), repositoryPath);
RepositoryFile uploadedFile = repositoryService.addFile(repositoryPath, file.getOriginalFilename(), file.getContentType(), file.getBytes(), metadata.fileMetadata);
// make virtualPath
String virtualPath = Paths.get(uploadedFile.getFolder().getPath() + "/" + uploadedFile.getOriginalFilename()).toString();
A attach = createAttach(savedEntity, metadata.attachMetadata);
attach.setVirtualPath(virtualPath);
attach.setRepositoryFile(uploadedFile);
Set<ConstraintViolation<A>> violations = validator.validate(attach);
if (violations != null && !violations.isEmpty()) {
// remove file
try {
repositoryService.removeFile(uploadedFile);
LOG.warn("Removed {} from repository", uploadedFile);
} catch (NoSuchRepositoryFileException e) {
LOG.warn(e.getMessage());
}
throw new ConstraintViolationException("Invalid attach", violations);
}
A savedAttach = attachRepository.save(attach);
savedAttach.lazyLoad();
return savedAttach;
}
@Override
@Transactional
public A removeFile(T entity, Long attachmentId) {
entity = owningEntityRepository.getOne(entity.getId());
A toDelete = attachFinder.findOne(qActionOwningEntityId.eq(entity.getId()).and(qAttachId.eq(attachmentId)))
.orElseThrow(() -> new NotFoundElement("No such attach for provided entity"));
// Note: repository file must be deleted in the AttachmentAspect
attachRepository.delete(toDelete);
return toDelete;
}
protected abstract Path createRepositoryPath(T entity);
protected abstract A createAttach(T entity, A attachMetadata);
}
......@@ -16,6 +16,8 @@
package org.gringlobal.service.impl;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.Map;
import java.util.Set;
......@@ -24,14 +26,18 @@ import org.gringlobal.api.InvalidApiUsageException;
import org.gringlobal.api.NotFoundElement;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.gringlobal.model.Accession;
import org.gringlobal.model.AccessionInvAttach;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.InventoryAction;
import org.gringlobal.model.InventoryMaintenancePolicy;
import org.gringlobal.model.QAccession;
import org.gringlobal.model.QAccessionInvAttach;
import org.gringlobal.model.QCooperator;
import org.gringlobal.model.QInventory;
import org.gringlobal.model.QInventoryAction;
import org.gringlobal.model.QInventoryMaintenancePolicy;
import org.gringlobal.model.TaxonomyGenus;
import org.gringlobal.model.TaxonomySpecies;
import org.gringlobal.model.community.CommunityCodeValues;
import org.gringlobal.model.community.CommunityCodeValues.CodeValueDef;
import org.gringlobal.persistence.AccessionInvAttachRepository;
......@@ -40,6 +46,8 @@ import org.gringlobal.persistence.InventoryActionRepository;
import org.gringlobal.persistence.InventoryMaintenancePolicyRepository;
import org.gringlobal.persistence.InventoryRepository;
import org.gringlobal.service.InventoryActionService;
import org.gringlobal.service.InventoryAttachmentFileService;
import org.gringlobal.service.InventoryAttachmentFileService.InventoryAttachmentRequest;
import org.gringlobal.service.InventoryService;
import org.gringlobal.service.filter.InventoryActionFilter;
import org.gringlobal.service.filter.InventoryFilter;
......@@ -73,7 +81,7 @@ public class InventoryServiceImpl extends FilteredCRUDServiceImpl<Inventory, Inv
private AccessionInvNameRepository accessionInvNameRepository;
@Autowired
private AccessionInvAttachRepository accessionInvAttachRepository;
private AccessionInvAttachRepository attachRepository;
@Autowired
private CompatibilityTriggers compatibilityTrigger;
......@@ -84,6 +92,43 @@ public class InventoryServiceImpl extends FilteredCRUDServiceImpl<Inventory, Inv
@Autowired
private OverviewHelper overviewHelper;
@Component
protected static class AttachmentSupport extends BaseAttachmentFileSupport<Inventory, AccessionInvAttach, InventoryAttachmentRequest> implements InventoryAttachmentFileService {
public AttachmentSupport() {
super(QAccessionInvAttach.accessionInvAttach.inventory.id, QAccessionInvAttach.accessionInvAttach.id);
}
@Override
protected Path createRepositoryPath(Inventory inventory) {
inventory = owningEntityRepository.getOne(inventory.getId());
Hibernate.initialize(inventory.getAccession());
Accession accession = inventory.getAccession();
Hibernate.initialize(accession.getTaxonomySpecies());
TaxonomySpecies taxonomySpecies = accession.getTaxonomySpecies();
Hibernate.initialize(taxonomySpecies.getTaxonomyGenus());
TaxonomyGenus taxonomyGenus = taxonomySpecies.getTaxonomyGenus();
StringBuilder builder = new StringBuilder("/").append("AIA").append("/")
.append(taxonomyGenus.getGenusName()).append("/")
.append(accession.getId()).append("/")
.append(inventory.getId());
return Paths.get(builder.toString());
}
@Override
protected AccessionInvAttach createAttach(Inventory entity, AccessionInvAttach source) {
AccessionInvAttach attach = new AccessionInvAttach();
attach.apply(source);
attach.setInventory(entity);
return attach;
}
}
@Component
protected static class ActionSupport extends BaseActionSupport<Inventory, InventoryAction, InventoryActionFilter, InventoryActionService.InventoryActionRequest> implements InventoryActionService {
......@@ -269,7 +314,7 @@ public class InventoryServiceImpl extends FilteredCRUDServiceImpl<Inventory, Inv
inventoryDetails.qualityStatus = inventory.getQuality();
inventoryDetails.names = accessionInvNameRepository.findInventoryNames(inventory);
inventoryDetails.attachments = accessionInvAttachRepository.findInventoryAttachments(inventory);
inventoryDetails.attachments = attachRepository.findInventoryAttachments(inventory);
return inventoryDetails;
}
......
......@@ -21,12 +21,17 @@ import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.genesys.filerepository.model.RepositoryImage;
import org.gringlobal.api.v1.impl.InventoryController;
import org.gringlobal.model.Accession;
import org.gringlobal.model.AccessionInvAttach;
import org.gringlobal.model.AccessionInvName;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.InventoryAction;
import org.gringlobal.model.community.CommunityCodeValues;
import org.gringlobal.persistence.AccessionInvAttachRepository;
import org.gringlobal.service.AccessionService;
import org.gringlobal.service.InventoryAttachmentFileService;
import org.gringlobal.service.InventoryService;
import org.gringlobal.service.filter.InventoryFilter;
import org.gringlobal.test.service.AbstractServicesTest;
......@@ -34,6 +39,7 @@ import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.transaction.annotation.Transactional;
......@@ -47,10 +53,17 @@ public class InventoryControllerTest extends AbstractApiV1Test {
@Autowired
private AccessionService accessionService;
@Autowired
private InventoryAttachmentFileService attachmentFileService;
@Autowired
private AccessionInvAttachRepository attachRepository;
@After
@Transactional
public void cleanup() throws Exception {
attachRepository.deleteAll();
repositoryFileRepository.deleteAll();
deleteFolders(repositoryFolderRepository.findAll());
accessionInvNameRepository.deleteAll();
inventoryActionRepository.deleteAllInBatch();
inventoryRepository.deleteAll();
......@@ -289,7 +302,104 @@ public class InventoryControllerTest extends AbstractApiV1Test {
assertThat(updated.getQuantityOnHandUnitCode(), is(quantity.quantityOnHandUnitCode));
assertThat(updated.getHundredSeedWeight(), nullValue());
}
@Test
@WithUserDetails(value = AbstractServicesTest.USER_ADMINISTRATOR)
public void testUploadFile() throws Exception {
Inventory inventory = addInventoryToDB(addAccessionToDB());
assertThat(inventory, is(notNullValue()));
MockMultipartFile file = new MockMultipartFile("file", "image.png", "image/png", new byte[1]);
// build file metadata
RepositoryImage imageMetadata = new RepositoryImage();
imageMetadata.setDescription("Test description of image.");
// build attach metadata
AccessionInvAttach attach = new AccessionInvAttach();
attach.setCategoryCode(CommunityCodeValues.ATTACH_CATEGORY_IMAGE.value);
attach.setIsWebVisible(TRUE);
// build a request
InventoryAttachmentFileService.InventoryAttachmentRequest request = new InventoryAttachmentFileService.InventoryAttachmentRequest();
request.fileMetadata = imageMetadata;
request.attachMetadata = attach;
MockMultipartFile metadata = new MockMultipartFile("metadata", "", "application/json", verboseMapper.writeValueAsString(request).getBytes());
assertThat(attachRepository.count(), is(0L));
assertThat(repositoryFileRepository.count(), is(0L));
/*@formatter:off*/
mockMvc
.perform(multipart(InventoryController.API_URL.concat("/attach/{inventoryId}"), inventory.getId())
.file(file)
.file(metadata)
.contentType(MediaType.APPLICATION_JSON)
)
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.isWebVisible", is(TRUE)))
.andExpect(jsonPath("$.categoryCode", is(CommunityCodeValues.ATTACH_CATEGORY_IMAGE.value)))
.andExpect(jsonPath("$.repositoryFile", not(nullValue())))
.andExpect(jsonPath("$.repositoryFile").isMap())
.andExpect(jsonPath("$.repositoryFile.description", is(imageMetadata.getDescription())))
.andExpect(jsonPath("$.repositoryFile.originalFilename", is("image.png")))
.andExpect(jsonPath("$.inventory", not(nullValue())))
.andExpect(jsonPath("$.inventory").isMap())
.andExpect(jsonPath("$.inventory.id", is(inventory.getId().intValue())))
;
/*@formatter:on*/
assertThat(attachRepository.count(), is(1L));
assertThat(repositoryFileRepository.count(), is(1L));
}
@Test
@WithUserDetails(value = AbstractServicesTest.USER_ADMINISTRATOR)
public void testRemoveFile() throws Exception {
Inventory inventory = addInventoryToDB(addAccessionToDB());
assertThat(inventory, is(notNullValue()));
MockMultipartFile file = new MockMultipartFile("file", "image.png", "image/png", new byte[1]);
// build file metadata
RepositoryImage imageMetadata = new RepositoryImage();
imageMetadata.setDescription("Test description of image.");
// build attach metadata
AccessionInvAttach attach = new AccessionInvAttach();
attach.setCategoryCode(CommunityCodeValues.ATTACH_CATEGORY_IMAGE.value);
attach.setIsWebVisible(TRUE);
// build a request
InventoryAttachmentFileService.InventoryAttachmentRequest request = new InventoryAttachmentFileService.InventoryAttachmentRequest();
request.fileMetadata = imageMetadata;
request.attachMetadata = attach;
assertThat(attachRepository.count(), is(0L));
assertThat(repositoryFileRepository.count(), is(0L));
AccessionInvAttach savedAttach = attachmentFileService.uploadFile(inventory, file, request);
assertThat(attachRepository.count(), is(1L));
assertThat(repositoryFileRepository.count(), is(1L));
/*@formatter:off*/
mockMvc
.perform(delete(InventoryController.API_URL.concat("/attach/{inventoryId}/{attachmentId}"), inventory.getId(), savedAttach.getId())
.contentType(MediaType.APPLICATION_JSON)
)
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", not(nullValue())))
;
/*@formatter:on*/
//
assertThat(attachRepository.count(), is(0L));
// FIXME repository is not empty but why?
//assertThat(repositoryFileRepository.count(), is(0L));
}
private Accession makeAccession() {
Accession a = new Accession();
......
......@@ -39,6 +39,10 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
public final class ApplicationConfig {
/**
......@@ -92,6 +96,12 @@ public final class ApplicationConfig {
return new MethodValidationPostProcessor();
}
@Bean
public Validator validator() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
return factory.getValidator();
}
}
......
/*
* Copyright 2020 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.gringlobal.test.service;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.genesys.filerepository.model.RepositoryImage;
import org.gringlobal.model.AccessionInvAttach;
import org.gringlobal.model.Inventory;
import org.gringlobal.model.community.CommunityCodeValues;
import org.gringlobal.persistence.AccessionInvAttachRepository;
import org.gringlobal.service.InventoryAttachmentFileService;
import org.gringlobal.service.InventoryAttachmentFileService.InventoryAttachmentRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.transaction.annotation.Transactional;
import javax.validation.ConstraintViolationException;
/**
* @author Maxym Borodenko
*/
@WithUserDetails(value = AbstractServicesTest.USER_ADMINISTRATOR)
public class InventoryAttachServiceTest extends AbstractServicesTest {
private Inventory inventory;
@Autowired
private InventoryAttachmentFileService attachmentFileService;
@Autowired
private AccessionInvAttachRepository attachRepository;
@Before
@Transactional
public void beforeTest() throws Exception {
super.beforeTest();
inventory = addInventoryToDB(addAccessionToDB());
assertThat(inventory, notNullValue());
assertThat(inventoryRepository.count(), is(1L));
}
@After
@Transactional
public void cleanup() throws Exception {
attachRepository.deleteAll();
repositoryFileRepository.deleteAll();
deleteFolders(repositoryFolderRepository.findAll());
inventoryRepository.deleteAll();
policyRepository.deleteAll();
accessionRepository.deleteAll();
taxonomySpeciesRepository.deleteAll();
taxonomyGenusRepository.deleteAll();
taxonomyFamilyRepository.deleteAll();
super.cleanup();
}
@Test
public void uploadFileTest() throws Exception {
MockMultipartFile imageFile = new MockMultipartFile("image", "image.png", "image/png", new byte[1]);
// build file metadata
RepositoryImage imageMetadata = new RepositoryImage();
imageMetadata.setDescription("Test description of image.");
// build attach metadata
AccessionInvAttach attach = new AccessionInvAttach();
attach.setCategoryCode(CommunityCodeValues.ATTACH_CATEGORY_IMAGE.value);
attach.setIsWebVisible(TRUE);
// build a request
InventoryAttachmentRequest request = new InventoryAttachmentRequest();
request.fileMetadata = imageMetadata;
request.attachMetadata = attach;
assertThat(attachRepository.count(), is(0L));
assertThat(repositoryFileRepository.count(), is(0L));
// upload
AccessionInvAttach saved = attachmentFileService.uploadFile(inventory, imageFile, request);
assertThat(saved, is(notNullValue()));
assertThat(attachRepository.count(), is(1L));