Java tutorial
/*- * #%L * owncloud-spring-boot-starter * %% * Copyright (C) 2016 - 2017 by the original Authors * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ package software.coolstuff.springframework.owncloud.service.impl.local; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.junit.After; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestExecutionListeners; import software.coolstuff.springframework.owncloud.exception.resource.OwncloudLocalResourceChecksumServiceException; import software.coolstuff.springframework.owncloud.exception.resource.OwncloudLocalResourceException; import software.coolstuff.springframework.owncloud.exception.resource.OwncloudQuotaExceededException; import software.coolstuff.springframework.owncloud.model.OwncloudQuota; import software.coolstuff.springframework.owncloud.model.OwncloudResource; import software.coolstuff.springframework.owncloud.service.AbstractOwncloudResourceServiceTest; import software.coolstuff.springframework.owncloud.service.impl.OwncloudUtils; import software.coolstuff.springframework.owncloud.service.impl.local.OwncloudLocalProperties.ResourceServiceProperties; import java.io.*; import java.net.URI; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.List; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @ActiveProfiles("LOCAL-RESOURCE-SERVICE") @TestExecutionListeners({ OwncloudLocalResourceServiceEmptyDirectoryTestExecutionListener.class }) public class OwncloudLocalResourceServiceTest extends AbstractOwncloudResourceServiceTest { private final static String RANDOM_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @Autowired private OwncloudLocalProperties properties; @MockBean private OwncloudLocalResourceChecksumService checksumService; @Autowired private OwncloudLocalResourceService resourceService; @After public void tearDown() throws Exception { resourceService.resetAllUsedSpace(); } @Override protected OwncloudResource prepare_OwncloudTestResourceImpl_equalsTo_OwncloudResourceImpl( OwncloudResource expected) throws Exception { return OwncloudLocalResourceImpl.builder().eTag(expected.getETag()).href(expected.getHref()) .lastModifiedAt(expected.getLastModifiedAt()).mediaType(expected.getMediaType()) .name(expected.getName()).build(); } @Override protected void prepare_listRoot_OK(List<OwncloudTestResourceImpl> expectedResources) throws Exception { expectedResources.stream().forEach(this::createResource); expectedResources.stream().forEach(this::modifyResourceInformationBasedOnPathInformation); } private void createResource(OwncloudTestResourceImpl owncloudResource) { Path resourcePath = resolveRelativePath(Paths.get(owncloudResource.getHref().getPath())); try { Mockito.when(checksumService.getChecksum(resourcePath)) .thenReturn(Optional.ofNullable(owncloudResource.getBackendETag())); if (owncloudResource instanceof OwncloudTestFileResourceImpl) { Files.createDirectories(resourcePath.getParent()); createFile(resourcePath, (OwncloudTestFileResourceImpl) owncloudResource); } else { if (!Files.exists(resourcePath)) { Files.createDirectories(resourcePath); } else if (!Files.isDirectory(resourcePath)) { throw new IllegalStateException("Path " + resourcePath + " is not a Directory"); } } } catch (IOException e) { e.printStackTrace(System.err); throw new IllegalStateException( "Error while preparing Resource " + resourcePath + ". Cause: " + e.toString(), e); } } private Path resolveRelativePath(Path relativePath) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); ResourceServiceProperties resourceProperties = properties.getResourceService(); Path basePath = resourceProperties.getLocation().resolve(authentication.getName()); if (relativePath.isAbsolute()) { String relativizedPath = StringUtils.substring(relativePath.toString(), File.pathSeparator.length()); return basePath.resolve(relativizedPath); } return basePath.resolve(relativePath); } private void createFile(Path resourcePath, OwncloudTestFileResourceImpl owncloudFileResource) throws IOException { try (Writer writer = Files.newBufferedWriter(resourcePath)) { IOUtils.write(owncloudFileResource.getTestFileContent(), writer); } } private void modifyResourceInformationBasedOnPathInformation(OwncloudTestResourceImpl owncloudResource) { Path resourcePath = resolveRelativePath(Paths.get(owncloudResource.getHref().getPath())); try { LocalDateTime lastModifiedAt = LocalDateTime .ofInstant(Files.getLastModifiedTime(resourcePath).toInstant(), ZoneId.systemDefault()); owncloudResource.setLastModifiedAt(lastModifiedAt); } catch (IOException e) { e.printStackTrace(System.err); throw new IllegalStateException("Error while getting last modified time of Resource " + resourcePath, e); } } @Override protected void prepare_list_OK(URI searchPath, List<OwncloudTestResourceImpl> expectedResources) throws Exception { expectedResources.stream().forEach(this::createResource); expectedResources.stream().forEach(this::modifyResourceInformationBasedOnPathInformation); } @Override protected void prepare_findFile_OK(URI searchPath, OwncloudTestFileResourceImpl expectedResource) throws Exception { createResource(expectedResource); modifyResourceInformationBasedOnPathInformation(expectedResource); } @Override protected void prepare_findRootDirectory_OK(OwncloudTestResourceImpl expectedResource) throws Exception { createResource(expectedResource); modifyResourceInformationBasedOnPathInformation(expectedResource); } @Override protected void prepare_getInputStream_OK(OwncloudTestFileResourceImpl owncloudFileResource) throws Exception { createResource(owncloudFileResource); } @Override protected void check_getOutputStream_OK(OwncloudTestFileResourceImpl owncloudFileResource) throws Exception { Path resourcePath = resolveRelativePath(Paths.get(owncloudFileResource.getHref().getPath())); assertThat(resourcePath).exists(); try (InputStream input = Files.newInputStream(resourcePath)) { String actual = new String(IOUtils.toByteArray(input)); assertThat(actual).isEqualTo(owncloudFileResource.getTestFileContent()); } } @Override protected void prepare_getOutputStream_NOK_Unauthorized(OwncloudTestFileResourceImpl owncloudFileResource) throws Exception { Path resourcePath = resolveRelativePath(Paths.get(owncloudFileResource.getHref().getPath())); Mockito.doThrow(OwncloudLocalResourceException.class).when(checksumService) .recalculateChecksum(resourcePath); } @Override protected void prepare_getOutputStream_OK_CreateNewFile(URI href, MediaType mediaType, String testFileContent) throws Exception { OwncloudTestFileResourceImpl resource = OwncloudTestFileResourceImpl.fileBuilder() .owncloudResource(OwncloudTestResourceImpl.builder().href(href).mediaType(mediaType).build()) .testFileContent(testFileContent).build(); createResource(resource); } @Override protected void check_getOutputStream_OK_CreateNewFile(URI href, MediaType mediaType, String testFileContent) throws Exception { Path resourcePath = resolveRelativePath(Paths.get(href.getPath())); assertThat(resourcePath).exists(); assertThat(resourcePath).hasContent(testFileContent); } @Override protected void prepare_getOutputStream_NOK_ResourceIsDirectory(URI href) throws Exception { OwncloudTestResourceImpl resource = OwncloudTestResourceImpl.builder().href(href) .mediaType(OwncloudUtils.getDirectoryMediaType()).build(); createResource(resource); } @Override protected void check_getOutputStream_NOK_ResourceIsDirectory(URI href) throws Exception { Path resourcePath = resolveRelativePath(Paths.get(href.getPath())); assertThat(resourcePath).exists(); assertThat(resourcePath).isDirectory(); } @Override protected void prepare_getOutputStream_OK_OverwriteFile(URI href, MediaType mediaType, String testFileContent) throws Exception { OwncloudTestFileResourceImpl resource = OwncloudTestFileResourceImpl.fileBuilder() .owncloudResource(OwncloudTestResourceImpl.builder().href(href).mediaType(mediaType).build()) .testFileContent( "Here we have a very different Content that should be overwritten by the Test-Content") .build(); createResource(resource); } @Override protected void check_getOutputStream_OK_OverwriteFile(URI href, MediaType mediaType, String testFileContent) throws Exception { Path resourcePath = resolveRelativePath(Paths.get(href.getPath())); assertThat(resourcePath).exists(); assertThat(resourcePath).isRegularFile(); assertThat(resourcePath).hasContent(testFileContent); } @Override protected void prepare_deleteFile_OK(OwncloudTestFileResourceImpl owncloudFileResource) throws Exception { createResource(owncloudFileResource); Path resourcePath = resolveRelativePath(Paths.get(owncloudFileResource.getHref().getPath())); assertThat(resourcePath).exists(); } @Override protected void check_deleteFile_OK(OwncloudTestFileResourceImpl owncloudFileResource) throws Exception { Path resourcePath = resolveRelativePath(Paths.get(owncloudFileResource.getHref().getPath())); assertThat(resourcePath).doesNotExist(); } @Override protected void prepare_deleteFile_NOK_OtherError(OwncloudTestFileResourceImpl owncloudFileResource) throws Exception { createResource(owncloudFileResource); Path resourcePath = resolveRelativePath(Paths.get(owncloudFileResource.getHref().getPath())); Mockito.doThrow(OwncloudLocalResourceChecksumServiceException.class).when(checksumService) .recalculateChecksum(resourcePath); } @Override protected void prepare_deleteDirectory_OK(OwncloudTestResourceImpl owncloudResource) throws Exception { Path path = resolveRelativePath(Paths.get(owncloudResource.getHref().getPath())); Files.createDirectories(path); Files.createFile(path.resolve("someFile.txt")); Files.createFile(path.resolve("someOtherFile.txt")); Path subDirectory = Files.createDirectory(path.resolve("subDirectory")); Files.createFile(subDirectory.resolve("someFileInSubdirectory.txt")); Files.createFile(subDirectory.resolve("someOtherFileInSubdirectory.txt")); } @Override protected void check_deleteDirectory_OK(OwncloudTestResourceImpl owncloudResource) throws Exception { Path path = resolveRelativePath(Paths.get(owncloudResource.getHref().getPath())); assertThat(path).doesNotExist(); } @Override protected void prepare_createDirectory_OK(OwncloudTestResourceImpl expectedResource) throws Exception { Path path = resolveRelativePath(Paths.get(expectedResource.getHref().getPath())); Mockito.when(checksumService.getChecksum(path)) .thenReturn(Optional.ofNullable(expectedResource.getBackendETag())); } @Override protected void check_createDirectory_OK(OwncloudTestResourceImpl expectedResource) throws Exception { Path path = resolveRelativePath(Paths.get(expectedResource.getHref().getPath())); assertThat(path).exists(); assertThat(path).isDirectory(); } @Override protected void prepare_createDirectory_NOK_AlreadyExistsAsFile(URI uri) throws Exception { Path path = resolveRelativePath(Paths.get(uri.getPath())); Files.createDirectories(path.getParent()); Files.createFile(path); } @Override protected void prepare_createDirectory_OK_AlreadyExistsAsDirectory(OwncloudTestResourceImpl expected) throws Exception { createResource(expected); } @Test @WithMockUser(username = "user1", password = "s3cr3t") public void test_createBigFile_SecondFileFails_ModifyUserQuota_SecondFileWillBeWritten() throws Exception { MediaType mediaType = MediaType.TEXT_PLAIN; // check the quota (must be 1024) OwncloudQuota quota = resourceService.getQuota(); assertThat(quota.getTotal()).isEqualTo(1024); assertThat(quota.getUsed()).isEqualTo(0); // first create a File with a Length of 768 Bytes URI uriBigFile = URI.create("/bigFile.txt"); String bigFileContent = RandomStringUtils.random(768, RANDOM_CHARS.toCharArray()); try (OutputStream output = resourceService.getOutputStream(uriBigFile, mediaType)) { IOUtils.write(bigFileContent, output, Charset.forName("utf8")); } finally { Path pathBigFile = resolveRelativePath(Paths.get(uriBigFile.getPath())); assertThat(pathBigFile).exists().isRegularFile().hasContent(bigFileContent); } quota = resourceService.getQuota(); assertThat(quota.getUsed()).isEqualTo(768); // second try to create a File with a Length of 512 Bytes URI uriNotSoBigFile = URI.create("/notSoBigFile.txt"); String notSoBigFileContent = RandomStringUtils.random(512, RANDOM_CHARS.toCharArray()); OwncloudQuotaExceededException quotaExceeded = null; try (OutputStream output = resourceService.getOutputStream(uriNotSoBigFile, mediaType)) { IOUtils.write(notSoBigFileContent, output, Charset.forName("utf8")); } catch (OwncloudQuotaExceededException e) { quotaExceeded = e; } finally { Path pathNotSoBigFile = resolveRelativePath(Paths.get(uriNotSoBigFile.getPath())); assertThat(pathNotSoBigFile).doesNotExist(); } assertThat(quotaExceeded).isNotNull(); } }