diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 69c31cd49..000000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1c..000000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/CHANGELOG.md b/CHANGELOG.md index c5d51b58f..ec0e89ce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [UNRELEASED] - TBD +### Added +- Added more test coverage +### Removed +- Eclipse Config Files + + ## [3.2.0] - 2023-11-15 ### Added - Added latest Checkstyle version, diff --git a/src/main/java/com/smartsheet/api/Trace.java b/src/main/java/com/smartsheet/api/Trace.java index 2490a6417..1290f21cd 100644 --- a/src/main/java/com/smartsheet/api/Trace.java +++ b/src/main/java/com/smartsheet/api/Trace.java @@ -74,6 +74,6 @@ public static Set parse(String traces) { LoggerFactory.getLogger(Trace.class).warn("invalid trace in parse() - '{}'", part); } } - return results.size() > 0 ? results : Collections.emptySet(); + return !results.isEmpty() ? results : Collections.emptySet(); } } diff --git a/src/main/java/com/smartsheet/api/internal/oauth/OAuthFlowImpl.java b/src/main/java/com/smartsheet/api/internal/oauth/OAuthFlowImpl.java index 5d16f4a30..4e2d96da1 100644 --- a/src/main/java/com/smartsheet/api/internal/oauth/OAuthFlowImpl.java +++ b/src/main/java/com/smartsheet/api/internal/oauth/OAuthFlowImpl.java @@ -123,8 +123,15 @@ public class OAuthFlowImpl implements OAuthFlow { * @param jsonSerializer the json serializer * @throws IllegalArgumentException If any argument is null, or empty string. */ - public OAuthFlowImpl(String clientId, String clientSecret, String redirectURL, String authorizationURL, - String tokenURL, HttpClient httpClient, JsonSerializer jsonSerializer) { + public OAuthFlowImpl( + String clientId, + String clientSecret, + String redirectURL, + String authorizationURL, + String tokenURL, + HttpClient httpClient, + JsonSerializer jsonSerializer + ) { Util.throwIfNull(clientId, clientSecret, redirectURL, authorizationURL, tokenURL, httpClient, jsonSerializer); Util.throwIfEmpty(clientId, clientSecret, redirectURL, authorizationURL, tokenURL); diff --git a/src/main/java/com/smartsheet/api/internal/util/StreamUtil.java b/src/main/java/com/smartsheet/api/internal/util/StreamUtil.java index 3b9c2334f..ea1e8e1f8 100644 --- a/src/main/java/com/smartsheet/api/internal/util/StreamUtil.java +++ b/src/main/java/com/smartsheet/api/internal/util/StreamUtil.java @@ -29,6 +29,10 @@ * a collection of Stream-oriented utility methods */ public class StreamUtil { + private StreamUtil() { + // Empty private constructor since every method in this class is static + } + public static final int ONE_MB = 1 << 20; public static final int ONE_KB = 1 << 10; public static final int TEN_KB = 10 * ONE_KB; diff --git a/src/test/java/com/smartsheet/api/SmartsheetFactoryTest.java b/src/test/java/com/smartsheet/api/SmartsheetFactoryTest.java new file mode 100644 index 000000000..d63fe4ee7 --- /dev/null +++ b/src/test/java/com/smartsheet/api/SmartsheetFactoryTest.java @@ -0,0 +1,50 @@ +/* +* Copyright (C) 2024 Smartsheet + * + * 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 com.smartsheet.api; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SmartsheetFactoryTest { + @Test + void testStaticStrings() { + assertThat(SmartsheetFactory.DEFAULT_BASE_URI).isEqualTo("https://api.smartsheet.com/2.0/"); + assertThat(SmartsheetFactory.GOV_BASE_URI).isEqualTo("https://api.smartsheetgov.com/2.0/"); + } + + @Nested + class CreateDefaultClientTests { + } + + @Nested + class CreateDefaultGovAccountClientTests { + } + + @Nested + class CustomTests { + @Test + void custom() { + // Act + SmartsheetBuilder result = SmartsheetFactory.custom(); + + // Assert + assertThat(result).isInstanceOf(SmartsheetBuilder.class); + } + } +} diff --git a/src/test/java/com/smartsheet/api/TraceTest.java b/src/test/java/com/smartsheet/api/TraceTest.java new file mode 100644 index 000000000..4ec6d78b6 --- /dev/null +++ b/src/test/java/com/smartsheet/api/TraceTest.java @@ -0,0 +1,291 @@ +/* +* Copyright (C) 2024 Smartsheet + * + * 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 com.smartsheet.api; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class TraceTest { + + @Test + void testEnumValues() { + assertThat(Trace.valueOf("RequestHeaders")).isNotNull(); + assertThat(Trace.valueOf("RequestBody")).isNotNull(); + assertThat(Trace.valueOf("RequestBodySummary")).isNotNull(); + assertThat(Trace.valueOf("ResponseHeaders")).isNotNull(); + assertThat(Trace.valueOf("ResponseBody")).isNotNull(); + assertThat(Trace.valueOf("ResponseBodySummary")).isNotNull(); + assertThat(Trace.valueOf("Request")).isNotNull(); + assertThat(Trace.valueOf("Response")).isNotNull(); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + + @Nested + class AddReplacementsTests { + + @Nested + class DefaultAddReplacementsTests { + @ParameterizedTest + @ValueSource(strings = { + "RequestHeaders", + "RequestBody", + "RequestBodySummary", + "ResponseHeaders", + "ResponseBody", + "ResponseBodySummary" + }) + void addReplacements_default_withSetReturnsFalse(String traceInput) { + // Arrange + Set input = Set.of(Trace.RequestBodySummary, Trace.RequestBody); + Trace trace = Trace.valueOf(traceInput); + + // Act + boolean result = trace.addReplacements(input); + + // Assert + assertThat(result).isFalse(); + assertThat(input).isEqualTo(Set.of(Trace.RequestBodySummary, Trace.RequestBody)); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + + @ParameterizedTest + @ValueSource(strings = { + "RequestHeaders", + "RequestBody", + "RequestBodySummary", + "ResponseHeaders", + "ResponseBody", + "ResponseBodySummary" + }) + void addReplacements_default_emptyInputReturnsFalse(String traceInput) { + // Arrange + Set input = Collections.emptySet(); + Trace trace = Trace.valueOf(traceInput); + + // Act + boolean result = trace.addReplacements(input); + + // Assert + assertThat(result).isFalse(); + assertThat(input).isEmpty(); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + + @ParameterizedTest + @ValueSource(strings = { + "RequestHeaders", + "RequestBody", + "RequestBodySummary", + "ResponseHeaders", + "ResponseBody", + "ResponseBodySummary" + }) + void addReplacements_default_nullInputReturnsFalse(String traceInput) { + // Arrange + Trace trace = Trace.valueOf(traceInput); + + // Act + boolean result = trace.addReplacements(null); + + // Assert + assertThat(result).isFalse(); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + } + + @Nested + class CustomAddReplacementsTests { + + @Test + void addReplacements_custom_requestWithSetReturnsFalse() { + // Arrange + Set input = new HashSet<>(Set.of(Trace.RequestBody, Trace.ResponseBody)); + + // Act + boolean result = Trace.Request.addReplacements(input); + + // Assert + assertThat(result).isTrue(); + Set expectedSet = Set.of( + Trace.RequestBody, + Trace.ResponseBody, + Trace.RequestHeaders, + Trace.RequestBodySummary + ); + assertThat(input).containsExactlyInAnyOrderElementsOf(expectedSet); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + + @Test + void addReplacements_custom_responseWithSetReturnsFalse() { + // Arrange + Set input = new HashSet<>(Set.of(Trace.RequestBody, Trace.ResponseBody)); + + // Act + boolean result = Trace.Response.addReplacements(input); + + // Assert + assertThat(result).isTrue(); + Set expectedSet = Set.of( + Trace.RequestBody, + Trace.ResponseBody, + Trace.ResponseHeaders, + Trace.ResponseBodySummary + ); + assertThat(input).containsExactlyInAnyOrderElementsOf(expectedSet); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + + @Test + void addReplacements_custom_requestEmptyInputReturnsFalse() { + // Arrange + Set input = new HashSet<>(); + + // Act + boolean result = Trace.Request.addReplacements(input); + + // Assert + assertThat(result).isTrue(); + assertThat(input).containsExactlyInAnyOrderElementsOf(Set.of(Trace.RequestHeaders, Trace.RequestBodySummary)); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + + @Test + void addReplacements_custom_responseEmptyInputReturnsFalse() { + // Arrange + Set input = new HashSet<>(); + + // Act + boolean result = Trace.Response.addReplacements(input); + + // Assert + assertThat(result).isTrue(); + assertThat(input).containsExactlyInAnyOrderElementsOf(Set.of(Trace.ResponseHeaders, Trace.ResponseBodySummary)); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + + @ParameterizedTest + @ValueSource(strings = {"Request", "Response"}) + void addReplacements_custom_nullInputThrowsNpe(String traceInput) { + // Arrange + Trace trace = Trace.valueOf(traceInput); + + // Act & Assert + assertThatThrownBy(() -> trace.addReplacements(null)) + .isInstanceOf(NullPointerException.class); + + // This will cause the test to fail if we ever add a new value. + // Please remember to add the new value in these tests + assertThat(Trace.values()).hasSize(8); + } + } + } + + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @Nested + class ParseTests { + + private Stream parseBaseCasesArguments() { + return Stream.of( + Arguments.of(null, Collections.emptySet()), + Arguments.of("", Collections.emptySet()), + Arguments.of(" ", Collections.emptySet()), + Arguments.of("RequestBodySummary", Set.of(Trace.RequestBodySummary)), + Arguments.of( + "RequestBodySummary,ResponseBodySummary", + Set.of(Trace.RequestBodySummary, Trace.ResponseBodySummary) + ), + Arguments.of( + "RequestBodySummary, ResponseBodySummary", + Set.of(Trace.RequestBodySummary, Trace.ResponseBodySummary) + ), + Arguments.of( + "Request", + Set.of(Trace.RequestHeaders, Trace.RequestBodySummary) + ), + Arguments.of( + "Response", + Set.of(Trace.ResponseHeaders, Trace.ResponseBodySummary) + ), + // Partial Error Cases + Arguments.of("RequestBodySummary,invalid", Set.of(Trace.RequestBodySummary)), + Arguments.of("invalid,RequestBodySummary", Set.of(Trace.RequestBodySummary)), + Arguments.of("RequestBodySummary,", Set.of(Trace.RequestBodySummary)) + + ); + } + + @ParameterizedTest + @MethodSource("parseBaseCasesArguments") + void parse_baseCases(String input, Set expectedSet) { + // Act + Set result = Trace.parse(input); + + // Assert + assertThat(result) + .hasSameSizeAs(expectedSet) + .containsExactlyInAnyOrderElementsOf(expectedSet); + } + + @ParameterizedTest + @ValueSource(strings = {",", ",,", " , ", "invalid"}) + void parse_baseCases(String input) { + // Act + Set result = Trace.parse(input); + + // Assert + assertThat(result).isEmpty(); + } + } +} diff --git a/src/test/java/com/smartsheet/api/integrationtest/RowResourcesIT.java b/src/test/java/com/smartsheet/api/integrationtest/RowResourcesIT.java index f7e8924c4..84299f152 100644 --- a/src/test/java/com/smartsheet/api/integrationtest/RowResourcesIT.java +++ b/src/test/java/com/smartsheet/api/integrationtest/RowResourcesIT.java @@ -47,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat; -public class RowResourcesIT extends ITResourcesImpl { +class RowResourcesIT extends ITResourcesImpl { Smartsheet smartsheet; Sheet sheet; List newRows; @@ -333,7 +333,7 @@ void testPartialUpdateRows() throws SmartsheetException, IOException { assertThat(result.getResult()) .isNotNull() .hasSize(2); - assertThat(result.getFailedItems()).isNull(); + assertThat(result.getFailedItems()).isNullOrEmpty(); deleteSheet(sheet.getId()); } diff --git a/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java index 3e18d6b54..48a5c6708 100644 --- a/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java @@ -22,6 +22,7 @@ import com.smartsheet.api.models.PagedResult; import com.smartsheet.api.models.PaginationParameters; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.io.File; @@ -38,19 +39,48 @@ public void setUp() throws Exception { new DefaultHttpClient(), serializer)); } - @Test - void testGetContact() throws SmartsheetException, IOException { - server.setResponseBody(new File("src/test/resources/getContact.json")); - Contact contact = contactResources.getContact("xyz"); - assertThat(contact.getName()).isEqualTo("David Davidson"); + @Nested + class GetContactTests { + @Test + void getContact() throws SmartsheetException, IOException { + // Arrange + server.setResponseBody(new File("src/test/resources/getContact.json")); + + // Act + Contact contact = contactResources.getContact("xyz"); + + // Assert + assertThat(contact.getName()).isEqualTo("David Davidson"); + } } - @Test - void testListContacts() throws SmartsheetException, IOException { - server.setResponseBody(new File("src/test/resources/listContacts.json")); - PaginationParameters paginationParameters = new PaginationParameters.PaginationParametersBuilder().setIncludeAll(true).build(); - PagedResult contacts = contactResources.listContacts(paginationParameters); - assertThat(contacts.getData().get(0).getName()).isEqualTo("David Davidson"); - assertThat(contacts.getTotalCount()).isEqualTo(2); + @Nested + class ListContactsTests { + @Test + void listContacts_withParameters() throws SmartsheetException, IOException { + // Arrange + server.setResponseBody(new File("src/test/resources/listContacts.json")); + PaginationParameters paginationParameters = new PaginationParameters.PaginationParametersBuilder().setIncludeAll(true).build(); + + // Act + PagedResult contacts = contactResources.listContacts(paginationParameters); + + // Assert + assertThat(contacts.getData().get(0).getName()).isEqualTo("David Davidson"); + assertThat(contacts.getTotalCount()).isEqualTo(2); + } + + @Test + void listContacts_nullParameters() throws SmartsheetException, IOException { + // Arrange + server.setResponseBody(new File("src/test/resources/listContacts.json")); + + // Act + PagedResult contacts = contactResources.listContacts(null); + + // Assert + assertThat(contacts.getData().get(0).getName()).isEqualTo("David Davidson"); + assertThat(contacts.getTotalCount()).isEqualTo(2); + } } } diff --git a/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java index 2a78290c1..bf5a23bf1 100644 --- a/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java @@ -22,6 +22,7 @@ import com.smartsheet.api.models.PagedResult; import com.smartsheet.api.models.PaginationParameters; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.io.File; @@ -39,13 +40,25 @@ public void setUp() throws Exception { "accessToken", new DefaultHttpClient(), serializer)); } - @Test - void testGetAttachments() throws SmartsheetException, IOException { - server.setResponseBody(new File("src/test/resources/listAssociatedAttachments.json")); - PaginationParameters parameters = new PaginationParameters(false, 1, 1); + @Nested + class GetAttachmentsTests { + @Test + void getAttachments_withParameters() throws SmartsheetException, IOException { + server.setResponseBody(new File("src/test/resources/listAssociatedAttachments.json")); + PaginationParameters parameters = new PaginationParameters(false, 1, 1); - PagedResult attachments = discussionAttachmentResources.getAttachments(1234L, 456L, parameters); - assertThat(attachments.getTotalCount()).isEqualTo(2); - assertThat(attachments.getData().get(0).getId()).isEqualTo(4583173393803140L); + PagedResult attachments = discussionAttachmentResources.getAttachments(1234L, 456L, parameters); + assertThat(attachments.getTotalCount()).isEqualTo(2); + assertThat(attachments.getData().get(0).getId()).isEqualTo(4583173393803140L); + } + + @Test + void getAttachments_nullParameters() throws SmartsheetException, IOException { + server.setResponseBody(new File("src/test/resources/listAssociatedAttachments.json")); + + PagedResult attachments = discussionAttachmentResources.getAttachments(1234L, 456L, null); + assertThat(attachments.getTotalCount()).isEqualTo(2); + assertThat(attachments.getData().get(0).getId()).isEqualTo(4583173393803140L); + } } } diff --git a/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java index 4744c216a..4671b3dba 100644 --- a/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java @@ -22,6 +22,7 @@ import com.smartsheet.api.models.PagedResult; import com.smartsheet.api.models.PaginationParameters; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.io.File; @@ -39,27 +40,45 @@ public void setUp() throws Exception { "accessToken", new DefaultHttpClient(), serializer)); } - @Test - void testListFolders() throws SmartsheetException, IOException { - server.setResponseBody(new File("src/test/resources/listFolders.json")); + @Nested + class ListFoldersTests { + @Test + void listFolders_withParameters() throws SmartsheetException, IOException { + server.setResponseBody(new File("src/test/resources/listFolders.json")); - PaginationParameters parameters = new PaginationParameters(true, null, null); - PagedResult foldersWrapper = homeFolderResources.listFolders(parameters); + PaginationParameters parameters = new PaginationParameters(true, null, null); + PagedResult foldersWrapper = homeFolderResources.listFolders(parameters); - assertThat(foldersWrapper.getPageSize()).isEqualTo(100); - assertThat(foldersWrapper.getData().get(0).getName()).isEqualTo("Folder 1"); - assertThat(foldersWrapper.getData().get(1).getName()).isEqualTo("Folder 2"); - assertThat(foldersWrapper.getData().get(0).getId()).isEqualTo(7116448184199044L); + assertThat(foldersWrapper.getPageSize()).isEqualTo(100); + assertThat(foldersWrapper.getData().get(0).getName()).isEqualTo("Folder 1"); + assertThat(foldersWrapper.getData().get(1).getName()).isEqualTo("Folder 2"); + assertThat(foldersWrapper.getData().get(0).getId()).isEqualTo(7116448184199044L); + } + + @Test + void listFolders_nullParameters() throws SmartsheetException, IOException { + server.setResponseBody(new File("src/test/resources/listFolders.json")); + + PagedResult foldersWrapper = homeFolderResources.listFolders(null); + + assertThat(foldersWrapper.getPageSize()).isEqualTo(100); + assertThat(foldersWrapper.getData().get(0).getName()).isEqualTo("Folder 1"); + assertThat(foldersWrapper.getData().get(1).getName()).isEqualTo("Folder 2"); + assertThat(foldersWrapper.getData().get(0).getId()).isEqualTo(7116448184199044L); + } } - @Test - void testCreateFolder() throws IOException, SmartsheetException { - server.setResponseBody(new File("src/test/resources/createFolders.json")); + @Nested + class CreateFolderTests { + @Test + void createFolder() throws IOException, SmartsheetException { + server.setResponseBody(new File("src/test/resources/createFolders.json")); - Folder folder = new Folder.CreateFolderBuilder().setName("Hello World").build(); + Folder folder = new Folder.CreateFolderBuilder().setName("Hello World").build(); - Folder newFolder = homeFolderResources.createFolder(folder); - assertThat(newFolder.getId()).isEqualTo(6821399500220292L); - assertThat(newFolder.getName()).isEqualTo("hello world"); + Folder newFolder = homeFolderResources.createFolder(folder); + assertThat(newFolder.getId()).isEqualTo(6821399500220292L); + assertThat(newFolder.getName()).isEqualTo("hello world"); + } } } diff --git a/src/test/java/com/smartsheet/api/internal/util/StreamUtilTest.java b/src/test/java/com/smartsheet/api/internal/util/StreamUtilTest.java index e2ad26ca9..f07b7ff99 100644 --- a/src/test/java/com/smartsheet/api/internal/util/StreamUtilTest.java +++ b/src/test/java/com/smartsheet/api/internal/util/StreamUtilTest.java @@ -17,74 +17,166 @@ package com.smartsheet.api.internal.util; import org.apache.commons.io.input.CharSequenceInputStream; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; class StreamUtilTest { @Test - void testReadBytesFromStream() throws Exception { - final String testString = "fuzzy wuzzy was a bear; fuzzy wuzzy had no hair..."; - final byte[] testBytes = testString.getBytes(StandardCharsets.UTF_8); - final InputStream inputStream = new CharSequenceInputStream(testString, StandardCharsets.UTF_8); - final ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); - - // this takes what was in inputStream, copies it into copyStream, and either resets inputStream (if supported) - // or returns a new stream around the bytes read - final InputStream backupStream = StreamUtil.cloneContent(inputStream, StreamUtil.ONE_MB, copyStream); - if (backupStream == inputStream) { - System.out.println("same stream returned (reset)"); - // verify readBytesFromStream gets everything from the inputStream (it also verifies cloneContent resets the source) - byte[] streamBytes = StreamUtil.readBytesFromStream(inputStream); - // it's all US-ASCII so it should match UTF-8 bytes - assertThat(streamBytes).containsExactly(testBytes); - } else { - System.out.println("new stream returned"); - byte[] backupBytes = StreamUtil.readBytesFromStream(backupStream); - assertThat(backupBytes).containsExactly(testBytes); - } - - assertThat(copyStream.toByteArray()).containsExactly(testBytes); + void testPublicVariableValues() { + assertThat(StreamUtil.ONE_MB).isEqualTo(1048576); + assertThat(StreamUtil.ONE_KB).isEqualTo(1024); + assertThat(StreamUtil.TEN_KB).isEqualTo(10240); } - @Test - void testReadBytesFromStream_NullInputSource() throws Exception { - final ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); - assertThat(StreamUtil.cloneContent(null, StreamUtil.ONE_MB, copyStream)).isNull(); - } + @Nested + class ReadBytesFromStreamTests { + @Test + void readBytesFromStream() throws Exception { + final String testString = "fuzzy wuzzy was a bear; fuzzy wuzzy had no hair..."; + final byte[] testBytes = testString.getBytes(StandardCharsets.UTF_8); + final InputStream inputStream = new CharSequenceInputStream(testString, StandardCharsets.UTF_8); + final ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); - @Test - void testToUtf8StringOrHex_MaxLength_EmptyUtf8String() { - final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - String result = StreamUtil.toUtf8StringOrHex(byteStream, -1); - assertThat(result).isEmpty(); + // this takes what was in inputStream, copies it into copyStream, and either resets inputStream (if supported) + // or returns a new stream around the bytes read + final InputStream backupStream = StreamUtil.cloneContent(inputStream, StreamUtil.ONE_MB, copyStream); + if (backupStream == inputStream) { + System.out.println("same stream returned (reset)"); + // verify readBytesFromStream gets everything from the inputStream (it also verifies cloneContent resets the source) + byte[] streamBytes = StreamUtil.readBytesFromStream(inputStream); + // it's all US-ASCII so it should match UTF-8 bytes + assertThat(streamBytes).containsExactly(testBytes); + } else { + System.out.println("new stream returned"); + byte[] backupBytes = StreamUtil.readBytesFromStream(backupStream); + assertThat(backupBytes).containsExactly(testBytes); + } + + assertThat(copyStream.toByteArray()).containsExactly(testBytes); + } } - @Test - void testToUtf8StringOrHex_MaxLength_NonEmptyUtf8String() throws IOException { - String data = "This is a line of text. "; - final byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8); - final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - byteStream.writeBytes(dataBytes); - byteStream.close(); - String result = StreamUtil.toUtf8StringOrHex(byteStream, -1); - assertThat(result).isEqualTo(data); + @Nested + class CloneContentTests { + @Test + void cloneContent_NullInputSource() throws Exception { + // Arrange + final ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); + + // Act + InputStream result = StreamUtil.cloneContent(null, StreamUtil.ONE_MB, copyStream); + + // Assert + assertThat(result).isNull(); + } + + @Test + void cloneContent_sourceMarkNotSupported() throws Exception { + // Arrange + final ByteArrayOutputStream copyStream = new ByteArrayOutputStream(); + InputStream inputStream = mock(InputStream.class); + when(inputStream.markSupported()).thenReturn(false); + when(inputStream.read(any())).thenReturn(-1); + + // Act + InputStream result = StreamUtil.cloneContent(inputStream, StreamUtil.ONE_MB, copyStream); + + // Assert + assertThat(result).isNotNull().isEmpty(); + } } - @Test - void testToUtf8StringOrHex_LengthSpecified_NonEmptyUtf8String() throws IOException { - String data = "This is a line of text. "; - final byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8); - final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - byteStream.writeBytes(dataBytes); - byteStream.close(); - String result = StreamUtil.toUtf8StringOrHex(byteStream, 10); - assertThat(result).isEqualTo("This is a ..."); + @Nested + class ToUtf8StringOrHexTests { + @Test + void toUtf8StringOrHex_MaxLength_EmptyUtf8String() { + // Arrange + final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + + // Act + String result = StreamUtil.toUtf8StringOrHex(byteStream, -1); + + // Assert + assertThat(result).isEmpty(); + } + + @Test + void toUtf8StringOrHex_MaxLength_NonEmptyUtf8String() throws IOException { + // Arrange + String data = "This is a line of text. "; + final byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8); + final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + byteStream.writeBytes(dataBytes); + byteStream.close(); + + // Act + String result = StreamUtil.toUtf8StringOrHex(byteStream, -1); + + // Assert + assertThat(result).isEqualTo(data); + } + + @Test + void toUtf8StringOrHex_LengthSpecified_NonEmptyUtf8String() throws IOException { + // Arrange + String data = "This is a line of text. "; + final byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8); + final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + byteStream.writeBytes(dataBytes); + byteStream.close(); + + // Act + String result = StreamUtil.toUtf8StringOrHex(byteStream, 10); + + // Assert + assertThat(result).isEqualTo("This is a ..."); + } + + @Test + void toUtf8StringOrHex_LengthSpecified_nullByteStream() throws IOException { + // Arrange + ByteArrayOutputStream byteArrayOutputStream = mock(ByteArrayOutputStream.class); + when(byteArrayOutputStream.toString(anyString())).thenReturn(null); + + // Act + String result = StreamUtil.toUtf8StringOrHex(byteArrayOutputStream, 10); + + // Assert + assertThat(result) + .isNotNull() + .isEmpty(); + } + + @Test + void toUtf8StringOrHex_LengthSpecified_notUtf8() throws IOException { + ByteArrayOutputStream byteArrayOutputStream = mock(ByteArrayOutputStream.class); + doThrow(new RuntimeException("bad!")).when(byteArrayOutputStream).toString(any(Charset.class)); + + String data = Integer.toHexString(0); + final byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8); + when(byteArrayOutputStream.toByteArray()).thenReturn(dataBytes); + + // Act + String result = StreamUtil.toUtf8StringOrHex(byteArrayOutputStream, 10); + + // Assert + assertThat(result) + .isNotNull() + .isEqualTo("30"); + } } }