diff --git a/hiero-enterprise-base/src/main/java/com/openelements/hiero/base/implementation/FileClientImpl.java b/hiero-enterprise-base/src/main/java/com/openelements/hiero/base/implementation/FileClientImpl.java index 6f5c2fe2..cde3ff92 100644 --- a/hiero-enterprise-base/src/main/java/com/openelements/hiero/base/implementation/FileClientImpl.java +++ b/hiero-enterprise-base/src/main/java/com/openelements/hiero/base/implementation/FileClientImpl.java @@ -44,7 +44,7 @@ public FileId createFile(@NonNull final byte[] contents, @NonNull final Instant private FileId createFileImpl(@NonNull final byte[] contents, @Nullable final Instant expirationTime) throws HieroException { - Objects.requireNonNull(contents, "fileId must not be null"); + Objects.requireNonNull(contents, "contents must not be null"); if (contents.length > FileCreateRequest.FILE_MAX_SIZE) { throw new HieroException("File contents must be less than " + FileCreateRequest.FILE_MAX_SIZE + " bytes"); } diff --git a/hiero-enterprise-base/src/test/java/com/openelements/hiero/base/test/FileClientImplTest.java b/hiero-enterprise-base/src/test/java/com/openelements/hiero/base/test/FileClientImplTest.java index 16afc7c1..a8ba70bf 100644 --- a/hiero-enterprise-base/src/test/java/com/openelements/hiero/base/test/FileClientImplTest.java +++ b/hiero-enterprise-base/src/test/java/com/openelements/hiero/base/test/FileClientImplTest.java @@ -3,6 +3,10 @@ import com.hedera.hashgraph.sdk.FileId; import com.openelements.hiero.base.HieroException; import com.openelements.hiero.base.implementation.FileClientImpl; +import com.openelements.hiero.base.protocol.FileCreateResult; +import com.openelements.hiero.base.protocol.FileCreateRequest; +import com.openelements.hiero.base.protocol.FileAppendRequest; +import com.openelements.hiero.base.protocol.FileAppendResult; import com.openelements.hiero.base.protocol.FileInfoRequest; import com.openelements.hiero.base.protocol.FileInfoResponse; import com.openelements.hiero.base.protocol.ProtocolLayerClient; @@ -11,8 +15,12 @@ import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import java.time.Instant; + import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.times; public class FileClientImplTest { ProtocolLayerClient protocolLayerClient; @@ -24,6 +32,94 @@ void setup() { fileClientImpl = new FileClientImpl(protocolLayerClient); } + @Test + void testCreateFile() throws HieroException { + // mock + final FileId fileId = FileId.fromString("1.2.3"); + final FileCreateResult fileCreateResult = Mockito.mock(FileCreateResult.class); + + // given + final byte[] content = "Hello Hiero!".getBytes(); + + //then + when(protocolLayerClient.executeFileCreateTransaction(any(FileCreateRequest.class))) + .thenReturn(fileCreateResult); + when(fileCreateResult.fileId()).thenReturn(fileId); + + final FileId result = fileClientImpl.createFile(content); + + verify(protocolLayerClient, times(1)) + .executeFileCreateTransaction(any(FileCreateRequest.class)); + verify(fileCreateResult, times(1)).fileId(); + Assertions.assertEquals(fileId, result); + } + + @Test + void testCreateFileForSizeGreaterThanFileCreateMaxSize() throws HieroException { + // mock + final FileId fileId = FileId.fromString("1.2.3"); + final FileCreateResult fileCreateResult = Mockito.mock(FileCreateResult.class); + final FileAppendResult fileAppendResult = Mockito.mock(FileAppendResult.class); + + // given + final byte[] content = new byte[FileCreateRequest.FILE_CREATE_MAX_SIZE * 2]; + // -1 because 1 for executeFileCreateTransaction() + final int appendCount = Math.floorDiv(content.length, FileCreateRequest.FILE_CREATE_MAX_SIZE) - 1; + + //then + when(protocolLayerClient.executeFileCreateTransaction(any(FileCreateRequest.class))) + .thenReturn(fileCreateResult); + when(fileCreateResult.fileId()).thenReturn(fileId); + when(protocolLayerClient.executeFileAppendRequestTransaction(any(FileAppendRequest.class))) + .thenReturn(fileAppendResult); + + final FileId result = fileClientImpl.createFile(content); + + verify(protocolLayerClient, times(1)) + .executeFileCreateTransaction(any(FileCreateRequest.class)); + verify(fileCreateResult, times(1)).fileId(); + verify(protocolLayerClient, times(appendCount)) + .executeFileAppendRequestTransaction(any(FileAppendRequest.class)); + Assertions.assertEquals(fileId, result); + } + + @Test + void testCreateFileThrowsExceptionForSizeGreaterThanMaxFileSize() { + final String message = "File contents must be less than " + FileCreateRequest.FILE_MAX_SIZE + " bytes"; + // given + final byte[] contents = new byte[FileCreateRequest.FILE_MAX_SIZE + 1]; + + // then + final HieroException exception = Assertions.assertThrows( + HieroException.class, () -> fileClientImpl.createFile(contents) + ); + Assertions.assertTrue(exception.getMessage().contains(message)); + } + + @Test + void testCreateFileThrowsExceptionForExpirationTimeBeforeNow() { + final String message = "Expiration time must be in the future"; + // given + final byte[] contents = "Hello Hiero!".getBytes(); + final Instant expiration = Instant.now().minusSeconds(1); + + // then + final IllegalArgumentException exception =Assertions.assertThrows( + IllegalArgumentException.class, () -> fileClientImpl.createFile(contents, expiration) + ); + Assertions.assertTrue(exception.getMessage().contains(message)); + } + + @Test + void testCreateFileThrowsExceptionForNullContent() { + final String message = "contents must not be null"; + + final NullPointerException exception = Assertions.assertThrows( + NullPointerException.class, () -> fileClientImpl.createFile(null) + ); + Assertions.assertTrue(exception.getMessage().contains(message)); + } + @Test void testGetFileSize() throws HieroException { // mocks @@ -60,6 +156,11 @@ void testGetFileSizeThrowsExceptionForInvalidId() throws HieroException { @Test void testGetFileSizeThrowsExceptionForNullId() { - Assertions.assertThrows(NullPointerException.class, () -> fileClientImpl.getSize(null)); + final String message = "fileId must not be null"; + + final NullPointerException exception = Assertions.assertThrows( + NullPointerException.class, () -> fileClientImpl.getSize(null) + ); + Assertions.assertTrue(exception.getMessage().contains(message)); } } diff --git a/hiero-enterprise-spring/src/test/java/com/openelements/hiero/spring/test/FileClientTests.java b/hiero-enterprise-spring/src/test/java/com/openelements/hiero/spring/test/FileClientTests.java index aa2b0d13..84bcb429 100644 --- a/hiero-enterprise-spring/src/test/java/com/openelements/hiero/spring/test/FileClientTests.java +++ b/hiero-enterprise-spring/src/test/java/com/openelements/hiero/spring/test/FileClientTests.java @@ -7,6 +7,8 @@ import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.stream.IntStream; + +import com.openelements.hiero.base.protocol.FileCreateRequest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -45,7 +47,7 @@ void testCreateEmptyFile() throws Exception { @Test void testCreateSmallFile() throws Exception { //given - final byte[] contents = "Hello, Hedera!".getBytes(); + final byte[] contents = "Hello, Hiero!".getBytes(); //when final FileId fileId = fileClient.createFile(contents); @@ -57,7 +59,7 @@ void testCreateSmallFile() throws Exception { @Test void testCreateLargeFile() throws Exception { //given - final byte[] contents = IntStream.range(0, 500).mapToObj(i -> "Hello, Hedera!") + final byte[] contents = IntStream.range(0, 500).mapToObj(i -> "Hello, Hiero!") .reduce((a, b) -> a + b) .get() .getBytes(); @@ -69,6 +71,27 @@ void testCreateLargeFile() throws Exception { Assertions.assertNotNull(fileId); } + @Test + void testCreateFileThrowExceptionIfExceedMaxFileSize() { + // given + final byte[] contents = new byte[FileCreateRequest.FILE_MAX_SIZE + 1]; + + // then + Assertions.assertThrows(HieroException.class, () -> fileClient.createFile(contents)); + } + + @Test + void testCreateFileThrowExceptionIfExpirationTimeBeforeNow() { + // given + final byte[] contents = "Hello Hiero!".getBytes(); + final Instant definedExpirationTime = Instant.now().minusSeconds(60); + + // then + Assertions.assertThrows( + IllegalArgumentException.class, () -> fileClient.createFile(contents, definedExpirationTime) + ); + } + @Test void testReadFileByFileId() throws Exception { //given