package com.sinata.appointment.service;
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.mockito.Mockito.mock;
|
|
import com.sinata.appointment.config.LocalFileUploadProperties;
|
import com.sinata.appointment.mapper.MpStaffGroupMapper;
|
import com.sinata.appointment.mapper.MpStaffGroupMemberMapper;
|
import com.sinata.appointment.mapper.MpUserMapper;
|
import com.sinata.appointment.mapper.SysDeptMapper;
|
import java.io.ByteArrayInputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.nio.file.Files;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
import org.springframework.web.multipart.MultipartFile;
|
|
class UploadStreamCloseTest {
|
|
@Test
|
void localImageUploadClosesMultipartInputStream() throws Exception {
|
LocalFileUploadProperties properties = new LocalFileUploadProperties();
|
ReflectionTestUtils.setField(properties, "fileUploadPath", Files.createTempDirectory("image-upload").toString());
|
ReflectionTestUtils.setField(properties, "pictureServerAddress", "https://example.test/resources");
|
LocalImageUploadService service = new LocalImageUploadService(properties);
|
CloseTrackingMultipartFile file = new CloseTrackingMultipartFile("photo.png", "image/png");
|
|
service.uploadImage(file);
|
|
assertThat(file.lastStreamClosed()).isTrue();
|
}
|
|
@Test
|
void staffAvatarUploadClosesMultipartInputStream() throws Exception {
|
String previousUserDir = System.getProperty("user.dir");
|
System.setProperty("user.dir", Files.createTempDirectory("staff-avatar-upload").toString());
|
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(new MockHttpServletRequest()));
|
try {
|
StaffManageApplicationService service =
|
new StaffManageApplicationService(
|
mock(MpUserMapper.class),
|
mock(SysDeptMapper.class),
|
mock(MpStaffGroupMemberMapper.class),
|
mock(MpStaffGroupMapper.class));
|
CloseTrackingMultipartFile file = new CloseTrackingMultipartFile("avatar.jpg", "image/jpeg");
|
|
service.uploadAvatar(file);
|
|
assertThat(file.lastStreamClosed()).isTrue();
|
} finally {
|
RequestContextHolder.resetRequestAttributes();
|
System.setProperty("user.dir", previousUserDir);
|
}
|
}
|
|
private static final class CloseTrackingMultipartFile implements MultipartFile {
|
private final String originalFilename;
|
private final String contentType;
|
private CloseTrackingInputStream lastStream;
|
|
private CloseTrackingMultipartFile(String originalFilename, String contentType) {
|
this.originalFilename = originalFilename;
|
this.contentType = contentType;
|
}
|
|
boolean lastStreamClosed() {
|
return lastStream != null && lastStream.closed;
|
}
|
|
@Override
|
public String getName() {
|
return "file";
|
}
|
|
@Override
|
public String getOriginalFilename() {
|
return originalFilename;
|
}
|
|
@Override
|
public String getContentType() {
|
return contentType;
|
}
|
|
@Override
|
public boolean isEmpty() {
|
return false;
|
}
|
|
@Override
|
public long getSize() {
|
return 4;
|
}
|
|
@Override
|
public byte[] getBytes() {
|
return new byte[] {1, 2, 3, 4};
|
}
|
|
@Override
|
public InputStream getInputStream() {
|
lastStream = new CloseTrackingInputStream(getBytes());
|
return lastStream;
|
}
|
|
@Override
|
public void transferTo(java.io.File dest) throws IOException, IllegalStateException {
|
Files.write(dest.toPath(), getBytes());
|
}
|
}
|
|
private static final class CloseTrackingInputStream extends ByteArrayInputStream {
|
private boolean closed;
|
|
private CloseTrackingInputStream(byte[] buf) {
|
super(buf);
|
}
|
|
@Override
|
public void close() throws IOException {
|
closed = true;
|
super.close();
|
}
|
}
|
}
|