From 10d0927961d36e1e2325dc5b1497661e6e038daa Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Tue, 12 Aug 2025 13:57:34 +0300 Subject: [PATCH 01/12] Introduce Smartsheet integration Source header --- .../java/com/smartsheet/api/Smartsheet.java | 7 ++++++ .../api/internal/AbstractResources.java | 3 +++ .../api/internal/SmartsheetImpl.java | 22 +++++++++++++++++++ .../api/internal/AbstractResourcesTest.java | 3 +++ .../api/internal/SmartsheetImplTest.java | 4 ++++ 5 files changed, 39 insertions(+) diff --git a/src/main/java/com/smartsheet/api/Smartsheet.java b/src/main/java/com/smartsheet/api/Smartsheet.java index 8411cfbbf..4d2913475 100644 --- a/src/main/java/com/smartsheet/api/Smartsheet.java +++ b/src/main/java/com/smartsheet/api/Smartsheet.java @@ -77,6 +77,13 @@ public interface Smartsheet { */ void setMaxRetryTimeMillis(long maxRetryTimeMillis); + /** + *

Sets the custom integration source identifier.

+ * + * @param smartsheetIntegrationSource the integration source header value + */ + void setSmartsheetIntegrationSource(String smartsheetIntegrationSource); + /** *

Returns the HomeResources instance that provides access to Home resources.

* diff --git a/src/main/java/com/smartsheet/api/internal/AbstractResources.java b/src/main/java/com/smartsheet/api/internal/AbstractResources.java index 496e6981b..febbbf621 100644 --- a/src/main/java/com/smartsheet/api/internal/AbstractResources.java +++ b/src/main/java/com/smartsheet/api/internal/AbstractResources.java @@ -1076,6 +1076,9 @@ Map createHeaders() { if (smartsheet.getUserAgent() != null) { headers.put("User-Agent", smartsheet.getUserAgent()); } + if (smartsheet.getSmartsheetIntegrationSource() != null) { + headers.put("Smartsheet-Integration-Source", smartsheet.getSmartsheetIntegrationSource()); + } return headers; } diff --git a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java index 97570fd03..8d8a8eae1 100644 --- a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java +++ b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java @@ -282,6 +282,11 @@ public class SmartsheetImpl implements Smartsheet { */ private final AtomicReference assetShares; + /** + * Represents the AtomicReference for the smartsheet integration source header + */ + private final AtomicReference smartsheetIntegrationSource; + private static final String INVALID_OPERATION_FOR_CLASS = "Invalid operation for class "; /** @@ -341,6 +346,7 @@ public SmartsheetImpl(String baseURI, String accessToken, HttpClient httpClient, this.passthrough = new AtomicReference<>(); this.events = new AtomicReference<>(); this.assetShares = new AtomicReference<>(); + this.smartsheetIntegrationSource = new AtomicReference<>(); } /** @@ -484,6 +490,22 @@ public void setTracePrettyPrint(boolean pretty) { } } + /** + * Gets the custom integration source identifier. + * + * This value is intended to be sent as a header in API requests for tracking and analytics purposes, + * helping to identify which specific integration or application is making the API call. + * + * @return the integration source string, or null if it has not been set. + */ + public String getSmartsheetIntegrationSource() { + return smartsheetIntegrationSource.get(); + } + + public void setSmartsheetIntegrationSource(String smartsheetIntegrationSource) { + this.smartsheetIntegrationSource.set(smartsheetIntegrationSource); + } + /** * Returns the HomeResources instance that provides access to Home resources. * diff --git a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java index 67ae9cabb..9f889f369 100644 --- a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java +++ b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java @@ -33,18 +33,21 @@ class AbstractResourcesTest { private final String tokenValue = "somevalue"; private final String changeAgent = "mychangeagent"; + private final String smartsheetIntegrationSource = "integrationsourcevalue"; @Test void testHeaders() { SmartsheetImpl smartsheet = new SmartsheetImpl("doesnt/matter", tokenValue, new DefaultHttpClient(), null); smartsheet.setChangeAgent(changeAgent); + smartsheet.setSmartsheetIntegrationSource(smartsheetIntegrationSource); AbstractResources resources = new AbstractResources(smartsheet) { }; Map headers = resources.createHeaders(); assertThat(headers) .containsEntry("Authorization", "Bearer " + tokenValue) + .containsEntry("Smartsheet-Integration-Source", smartsheetIntegrationSource) .containsEntry("Smartsheet-Change-Agent", changeAgent); } diff --git a/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java b/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java index 26a3fda5c..355adec3b 100644 --- a/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java @@ -121,4 +121,8 @@ void testSights() { assertThat(smartsheet.sightResources()).isNotNull(); } + @Test + void testGetSmartsheetIntegrationSource() { + assertThat(smartsheet.getSmartsheetIntegrationSource()).isNull(); + } } From df4f5d77bfba8256f8251612bb23ae2530f52b81 Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Tue, 12 Aug 2025 17:52:17 +0300 Subject: [PATCH 02/12] Updated Java doc --- src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java index 8d8a8eae1..9ab5014d1 100644 --- a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java +++ b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java @@ -493,8 +493,7 @@ public void setTracePrettyPrint(boolean pretty) { /** * Gets the custom integration source identifier. * - * This value is intended to be sent as a header in API requests for tracking and analytics purposes, - * helping to identify which specific integration or application is making the API call. + * This value is intended to be sent as a header in API requests for integration purposes * * @return the integration source string, or null if it has not been set. */ From bed7beeb016180c0e371ebb11d1352e5dc1c5788 Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Wed, 13 Aug 2025 13:40:03 +0300 Subject: [PATCH 03/12] Enhanced JavaDoc for smartsheetIntegrationSource and updated the test with a valid value --- .../java/com/smartsheet/api/internal/SmartsheetImpl.java | 7 +++++++ .../com/smartsheet/api/internal/AbstractResourcesTest.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java index 9ab5014d1..45fddf457 100644 --- a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java +++ b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java @@ -284,6 +284,13 @@ public class SmartsheetImpl implements Smartsheet { /** * Represents the AtomicReference for the smartsheet integration source header + * + * Format: $TYPE,$ORG_NAME,$INTEGRATOR_NAME + * (NB: Comma is used as a delimiter and is required if value is missing) + * + * $INTEGRATION-TYPE - Required, the type of the integrator (e.g. AI, SCRIPT, APPLICATION) + * $SMAR-ORGANIZATION-NAME - Optional (but COMMA is required), organization name (e.g. Microsoft, Google, OpenAI, etc.) + * $INTEGRATOR-NAME - Required, the name of the integrator (e.g. Claude, Copilot, ChatGPT, DeepSeek, etc.) */ private final AtomicReference smartsheetIntegrationSource; diff --git a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java index 9f889f369..66bc0515e 100644 --- a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java +++ b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java @@ -33,7 +33,7 @@ class AbstractResourcesTest { private final String tokenValue = "somevalue"; private final String changeAgent = "mychangeagent"; - private final String smartsheetIntegrationSource = "integrationsourcevalue"; + private final String smartsheetIntegrationSource = "AI,OpenAI,ChatGPT"; @Test void testHeaders() { From 870919bc24adc6da661d261fb1ce1480ae3cfe8e Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Wed, 13 Aug 2025 14:47:10 +0300 Subject: [PATCH 04/12] Use more generic integration source value in AbstractResourcesTest --- .../java/com/smartsheet/api/internal/AbstractResourcesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java index 66bc0515e..658374d99 100644 --- a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java +++ b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java @@ -33,7 +33,7 @@ class AbstractResourcesTest { private final String tokenValue = "somevalue"; private final String changeAgent = "mychangeagent"; - private final String smartsheetIntegrationSource = "AI,OpenAI,ChatGPT"; + private final String smartsheetIntegrationSource = "AI,MyCompany,MyGPT"; @Test void testHeaders() { From 1536b5693e5bd9cd7f742c2f70ca29879f74a058 Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Thu, 14 Aug 2025 12:16:02 +0300 Subject: [PATCH 05/12] Add smartsheetIntegrationSource in SmartsheetBuilder --- .../com/smartsheet/api/SmartsheetBuilder.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java index ae4c5382f..a22881d9d 100644 --- a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java +++ b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java @@ -76,6 +76,14 @@ public class SmartsheetBuilder { */ private String changeAgent; + /** + *

Represents the smartsheet integration source.

+ * + *

It can be set using corresponding setter.

+ */ + private String smartsheetIntegrationSource; + + /** URI to prod-us API endpoints */ public static final String US_BASE_URI = "https://api.smartsheet.com/2.0/"; /** URI to prod-eu API endpoints */ @@ -180,6 +188,11 @@ public SmartsheetBuilder setChangeAgent(String changeAgent) { return this; } + public SmartsheetBuilder setSmartsheetIntegrationSource(String smartsheetIntegrationSource) { + this.smartsheetIntegrationSource = smartsheetIntegrationSource; + return this; + } + /** *

Gets the http client.

* @@ -243,6 +256,15 @@ public String getChangeAgent() { return changeAgent; } + /** + *

Gets the Smartsheet-Integration-Source

+ * + * @return the smartsheet integration source + */ + public String getSmartsheetIntegrationSource() { + return smartsheetIntegrationSource; + } + /** *

Build the Smartsheet instance.

* @@ -263,6 +285,9 @@ public Smartsheet build() { if (changeAgent != null) { smartsheet.setChangeAgent(changeAgent); } + if (smartsheetIntegrationSource != null) { + smartsheet.setSmartsheetIntegrationSource(smartsheetIntegrationSource); + } if (assumedUser != null) { smartsheet.setAssumedUser(assumedUser); } From 928bfebe8f12f634fd422337ddc0ac8c7a921ecf Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Thu, 14 Aug 2025 12:30:20 +0300 Subject: [PATCH 06/12] Added info in CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62c864d13..1e9d12c85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [x.x.x] - unreleased +## [3.6.0] - 2025-08-14 +### Added + - Added support for the `Smartsheet-Integration-Source` header. This can be configured using the `SmartsheetBuilder` or set directly on the `Smartsheet` client. + ## [3.5.0] - 2025-08-08 ### Added - Added support for token-based pagination in WorkspaceResources.listWorkspaces() method From 0c69c0eca0468175ad6f06d6eebfd7b5f71fe934 Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Fri, 15 Aug 2025 14:48:34 +0300 Subject: [PATCH 07/12] Increment SDK version in build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 901b8295b..f1623baf2 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ plugins { // The group name. This dictates the prefix our dependency will have once it's published. group = 'com.smartsheet' // The version. This will be added to the end of the Jar and all other resources that are created during the build. -version = '3.5.0' +version = '3.6.0' // The Java version: sourceCompatibility = '11' From 95ccf1b8c91aa8a56d2c89564459f1d930f4c98b Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Tue, 26 Aug 2025 17:15:18 +0300 Subject: [PATCH 08/12] Make Smartsheet-Integration-Source mandatory header and add validator to check the format in SmartsheetIntegrationSourceValidator --- CHANGELOG.md | 10 +++ .../java/com/smartsheet/api/Smartsheet.java | 2 +- .../com/smartsheet/api/SmartsheetBuilder.java | 27 ++++++-- .../api/internal/AbstractResources.java | 8 ++- .../api/internal/SmartsheetImpl.java | 33 +++------ .../SmartsheetIntegrationSourceValidator.java | 61 +++++++++++++++++ .../SmartsheetIntegrationSourceType.java | 19 ++++++ .../smartsheet/api/SmartsheetBuilderTest.java | 11 ++- ...tsheetIntegrationSourceValidatorTests.java | 68 +++++++++++++++++++ .../api/integrationtest/ITResourcesImpl.java | 2 +- .../api/internal/AbstractResourcesTest.java | 3 +- .../internal/AssetShareResourcesImplTest.java | 3 +- ...AttachmentVersioningResourcesImplTest.java | 6 -- .../CommentAttachmentResourcesImplTest.java | 3 +- .../internal/ContactResourcesImplTest.java | 3 +- ...DiscussionAttachmentResourcesImplTest.java | 3 +- .../DiscussionCommentResourcesImplTest.java | 3 +- .../internal/DiscussionResourcesImplTest.java | 3 +- .../api/internal/EventResourcesImplTest.java | 3 +- .../internal/FavoriteResourcesImplTest.java | 3 +- .../api/internal/FolderResourcesImplTest.java | 3 +- .../api/internal/GroupResourcesImplTest.java | 3 +- .../internal/HomeFolderResourcesImplTest.java | 3 +- .../api/internal/HomeResourcesImplTest.java | 3 +- .../internal/ImageUrlResourcesImplTest.java | 3 +- .../PassthroughResourcesImplTest.java | 3 +- .../api/internal/ReportResourcesImplTest.java | 3 +- .../api/internal/ResourcesImplBase.java | 9 +++ .../RowAttachmentResourcesImplTest.java | 3 +- .../internal/RowColumnResourcesImplTest.java | 3 +- .../RowDiscussionResourcesImplTest.java | 3 +- .../api/internal/SearchResourcesImplTest.java | 3 +- .../internal/ServerInfoResourcesImplTest.java | 3 +- .../api/internal/ShareResourcesImplTest.java | 3 +- .../SheetAttachmentResourcesImplTest.java | 3 +- .../SheetColumnResourcesImplTest.java | 3 +- .../SheetCommentResourcesImplTest.java | 3 +- .../SheetDiscussionResourcesImplTest.java | 3 +- .../api/internal/SheetResourcesImplTest.java | 3 +- .../internal/SheetRowResourcesImplTest.java | 3 +- .../api/internal/SightResourcesImplTest.java | 6 -- .../internal/TemplateResourcesImplTest.java | 3 +- .../api/internal/TokenResourcesImplTest.java | 3 +- .../api/internal/UserResourcesImplTest.java | 3 +- .../internal/WebhookResourcesImplTest.java | 3 +- .../WorkspaceFolderResourcesImplTest.java | 3 +- .../internal/WorkspaceResourcesImplTest.java | 3 +- .../com/smartsheet/api/logging/LoggingIT.java | 8 +-- .../api/sdktest/HelperFunctions.java | 4 +- .../com/smartsheet/api/sdktest/RowTest.java | 10 +-- .../com/smartsheet/api/sdktest/SheetTest.java | 2 +- 51 files changed, 257 insertions(+), 131 deletions(-) create mode 100644 src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java create mode 100644 src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java create mode 100644 src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e9d12c85..bb29d62e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [3.6.0] - 2025-08-14 ### Added - Added support for the `Smartsheet-Integration-Source` header. This can be configured using the `SmartsheetBuilder` or set directly on the `Smartsheet` client. + This header is mandatory and has to follow the format: + + `INTEGRATION-TYPE, ORGANIZATION_NAME, INTEGRATOR_NAME` + (NB: Comma is used as a delimiter and is required if the value is missing) + + `INTEGRATION-TYPE - Required, the type of the integrator (e.g. AI, SCRIPT, APPLICATION)` + + `ORGANIZATION_NAME - Optional (but COMMA is required), organization name (e.g. Microsoft, Google, OpenAI, etc.)` + + `INTEGRATOR-NAME - Required, the name of the integrator (e.g. Claude, Copilot, ChatGPT, DeepSeek, etc.)` ## [3.5.0] - 2025-08-08 ### Added diff --git a/src/main/java/com/smartsheet/api/Smartsheet.java b/src/main/java/com/smartsheet/api/Smartsheet.java index 4d2913475..3e7cd012d 100644 --- a/src/main/java/com/smartsheet/api/Smartsheet.java +++ b/src/main/java/com/smartsheet/api/Smartsheet.java @@ -82,7 +82,7 @@ public interface Smartsheet { * * @param smartsheetIntegrationSource the integration source header value */ - void setSmartsheetIntegrationSource(String smartsheetIntegrationSource); + void setSmartsheetIntegrationSource(String smartsheetIntegrationSource) throws SmartsheetException; /** *

Returns the HomeResources instance that provides access to Home resources.

diff --git a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java index a22881d9d..0349e39d0 100644 --- a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java +++ b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java @@ -19,6 +19,7 @@ import com.smartsheet.api.internal.SmartsheetImpl; import com.smartsheet.api.internal.http.HttpClient; import com.smartsheet.api.internal.json.JsonSerializer; +import com.smartsheet.api.internal.util.SmartsheetIntegrationSourceValidator; /** *

A convenience class to help create a {@link Smartsheet} instance with the appropriate fields.

@@ -188,8 +189,23 @@ public SmartsheetBuilder setChangeAgent(String changeAgent) { return this; } - public SmartsheetBuilder setSmartsheetIntegrationSource(String smartsheetIntegrationSource) { - this.smartsheetIntegrationSource = smartsheetIntegrationSource; + /** + *

Set the smartsheet integration source.

+ * + * Format: $TYPE,$ORG_NAME,$INTEGRATOR_NAME + * (NB: Comma is used as a delimiter and is required if the value is missing) + * + * $INTEGRATION-TYPE - Required, the type of the integrator (e.g. AI, SCRIPT, APPLICATION) + * $SMAR-ORGANIZATION-NAME - Optional (but COMMA is required), organization name (e.g. Microsoft, Google, OpenAI, etc.) + * $INTEGRATOR-NAME - Required, the name of the integrator (e.g. Claude, Copilot, ChatGPT, DeepSeek, etc.) + * + * @param smartsheetIntegrationSource the identifier to include in requests to determine the source of request maker + * @return the smartsheet builder + */ + public SmartsheetBuilder setSmartsheetIntegrationSource(String smartsheetIntegrationSource) throws SmartsheetException { + if (SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)) { + this.smartsheetIntegrationSource = smartsheetIntegrationSource; + } return this; } @@ -271,7 +287,7 @@ public String getSmartsheetIntegrationSource() { * @return the Smartsheet instance * @throws IllegalStateException if accessToken isn't set yet. */ - public Smartsheet build() { + public Smartsheet build() throws SmartsheetException { if (baseURI == null) { baseURI = DEFAULT_BASE_URI; } @@ -285,7 +301,10 @@ public Smartsheet build() { if (changeAgent != null) { smartsheet.setChangeAgent(changeAgent); } - if (smartsheetIntegrationSource != null) { + if (smartsheetIntegrationSource == null) { + throw new SmartsheetException("SmartsheetIntegrationSource cannot be null"); + } + else { smartsheet.setSmartsheetIntegrationSource(smartsheetIntegrationSource); } if (assumedUser != null) { diff --git a/src/main/java/com/smartsheet/api/internal/AbstractResources.java b/src/main/java/com/smartsheet/api/internal/AbstractResources.java index febbbf621..257b4450d 100644 --- a/src/main/java/com/smartsheet/api/internal/AbstractResources.java +++ b/src/main/java/com/smartsheet/api/internal/AbstractResources.java @@ -850,7 +850,7 @@ protected List putAndReceiveList(String path, T objectToPut, Class * @param method the HttpMethod * @return the http request */ - protected HttpRequest createHttpRequest(URI uri, HttpMethod method) { + protected HttpRequest createHttpRequest(URI uri, HttpMethod method) throws SmartsheetException { HttpRequest request = new HttpRequest(); request.setUri(uri); request.setMethod(method); @@ -861,7 +861,7 @@ protected HttpRequest createHttpRequest(URI uri, HttpMethod method) { return request; } - protected HttpPost createHttpPost(URI uri) { + protected HttpPost createHttpPost(URI uri) throws SmartsheetException { HttpPost httpPost = new HttpPost(uri); Map headers = createHeaders(); for (Map.Entry entry : headers.entrySet()) { @@ -1061,7 +1061,7 @@ private static void copyStream(InputStream input, OutputStream output) throws IO /** * @return a map of headers to be used when making requests. */ - Map createHeaders() { + Map createHeaders() throws SmartsheetException { Map headers = new HashMap<>(); headers.put("Authorization", "Bearer " + smartsheet.getAccessToken()); headers.put(HEADER_CONTENT_TYPE, JSON_CONTENT_TYPE); @@ -1078,6 +1078,8 @@ Map createHeaders() { } if (smartsheet.getSmartsheetIntegrationSource() != null) { headers.put("Smartsheet-Integration-Source", smartsheet.getSmartsheetIntegrationSource()); + } else { + throw new SmartsheetException("Smartsheet integration source cannot be null"); } return headers; } diff --git a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java index 45fddf457..ae48041c5 100644 --- a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java +++ b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java @@ -16,27 +16,7 @@ package com.smartsheet.api.internal; -import com.smartsheet.api.AssetShareResources; -import com.smartsheet.api.ContactResources; -import com.smartsheet.api.EventResources; -import com.smartsheet.api.FavoriteResources; -import com.smartsheet.api.FolderResources; -import com.smartsheet.api.GroupResources; -import com.smartsheet.api.HomeResources; -import com.smartsheet.api.ImageUrlResources; -import com.smartsheet.api.PassthroughResources; -import com.smartsheet.api.ReportResources; -import com.smartsheet.api.SearchResources; -import com.smartsheet.api.ServerInfoResources; -import com.smartsheet.api.SheetResources; -import com.smartsheet.api.SightResources; -import com.smartsheet.api.Smartsheet; -import com.smartsheet.api.TemplateResources; -import com.smartsheet.api.TokenResources; -import com.smartsheet.api.Trace; -import com.smartsheet.api.UserResources; -import com.smartsheet.api.WebhookResources; -import com.smartsheet.api.WorkspaceResources; +import com.smartsheet.api.*; import com.smartsheet.api.internal.http.AndroidHttpClient; import com.smartsheet.api.internal.http.DefaultHttpClient; import com.smartsheet.api.internal.http.HttpClient; @@ -44,6 +24,7 @@ import com.smartsheet.api.internal.json.JsonSerializer; import com.smartsheet.api.internal.util.CleanerUtil; import com.smartsheet.api.internal.util.Util; +import com.smartsheet.api.internal.util.SmartsheetIntegrationSourceValidator; import org.apache.http.impl.client.HttpClients; import java.io.IOException; @@ -502,14 +483,16 @@ public void setTracePrettyPrint(boolean pretty) { * * This value is intended to be sent as a header in API requests for integration purposes * - * @return the integration source string, or null if it has not been set. + * @return the integration source string. */ - public String getSmartsheetIntegrationSource() { + String getSmartsheetIntegrationSource() { return smartsheetIntegrationSource.get(); } - public void setSmartsheetIntegrationSource(String smartsheetIntegrationSource) { - this.smartsheetIntegrationSource.set(smartsheetIntegrationSource); + public void setSmartsheetIntegrationSource(String smartsheetIntegrationSource) throws SmartsheetException { + if (SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)) { + this.smartsheetIntegrationSource.set(smartsheetIntegrationSource); + } } /** diff --git a/src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java b/src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java new file mode 100644 index 000000000..a2ae49e10 --- /dev/null +++ b/src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java @@ -0,0 +1,61 @@ +package com.smartsheet.api.internal.util; + +import com.smartsheet.api.SmartsheetException; +import com.smartsheet.api.models.enums.SmartsheetIntegrationSourceType; + +import java.util.Arrays; + +public class SmartsheetIntegrationSourceValidator { + + /** + * Validates a smartsheet integration source string in the format: + * type, organisation name, integrator name + * + * - type: must be one of the enum values + * - organisation name: optional (can be empty) + * - integrator name: non-empty + */ + public static boolean isValidFormat(String input) throws SmartsheetException { + if (input == null) { + throw new SmartsheetException("Smartsheet integration source cannot be null"); + } + + String[] parts = input.split(",", -1); // -1 keeps empty slots + if (parts.length != 3) { + throw new SmartsheetException("Invalid smartsheet integration source format"); + } + + String integrationType = parts[0]; + String integratorName = parts[2]; + + // The First slot (integration type) must match enum + if (!isValidType(integrationType)) { + throw new SmartsheetException("Invalid smartsheet integration source format. " + + "The integration type has to be one of the following: " + + Arrays.toString(SmartsheetIntegrationSourceType.values())); + } + + // Integrator name must be non-empty + if (integratorName.isEmpty()) { + throw new SmartsheetException("Invalid smartsheet integration source format. " + + "The integrator name cannot be empty."); + } + + return true; + } + + /** + * Checks if the integration type matches one of the enum values + */ + private static boolean isValidType(String integrationTypeValue) { + if (integrationTypeValue == null || integrationTypeValue.isEmpty()) { + return false; + } + for (SmartsheetIntegrationSourceType sourceType : SmartsheetIntegrationSourceType.values()) { + if (sourceType.name().equalsIgnoreCase(integrationTypeValue)) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java b/src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java new file mode 100644 index 000000000..8dda54818 --- /dev/null +++ b/src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java @@ -0,0 +1,19 @@ +package com.smartsheet.api.models.enums; + +/** + * Represents Smartsheet integration source types + */ +public enum SmartsheetIntegrationSourceType { + /** + * Represents the AI integration source type. + */ + AI, + /** + * Represents the SCRIPT integration source type. + */ + SCRIPT, + /** + * Represents the APPLICATION integration source type. + */ + APPLICATION; +} diff --git a/src/test/java/com/smartsheet/api/SmartsheetBuilderTest.java b/src/test/java/com/smartsheet/api/SmartsheetBuilderTest.java index 80b929204..5b5e66308 100644 --- a/src/test/java/com/smartsheet/api/SmartsheetBuilderTest.java +++ b/src/test/java/com/smartsheet/api/SmartsheetBuilderTest.java @@ -26,13 +26,10 @@ class SmartsheetBuilderTest { @Test - void testBuild() { - Smartsheet smartsheet = new SmartsheetBuilder().build(); + void testBuild() throws SmartsheetException { + Smartsheet smartsheet = new SmartsheetBuilder().setBaseURI("a").setAccessToken("b").setHttpClient( + new DefaultHttpClient()).setJsonSerializer(new JacksonJsonSerializer()).setAssumedUser("user") + .setSmartsheetIntegrationSource("AI,MyCompany,MyGPT").build(); assertThat(smartsheet).isInstanceOf(SmartsheetImpl.class); - - Smartsheet ss = new SmartsheetBuilder().setBaseURI("a").setAccessToken("b").setHttpClient( - new DefaultHttpClient()).setJsonSerializer(new JacksonJsonSerializer()).setAssumedUser("user").build(); - ss.getClass(); } - } diff --git a/src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java b/src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java new file mode 100644 index 000000000..5fd81b79a --- /dev/null +++ b/src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java @@ -0,0 +1,68 @@ +package com.smartsheet.api; + +import com.smartsheet.api.internal.util.SmartsheetIntegrationSourceValidator; +import com.smartsheet.api.models.enums.SmartsheetIntegrationSourceType; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +public class SmartsheetIntegrationSourceValidatorTests { + + @Test + void testBuildWithSmartsheetIntegrationSource_allThreeStrings_success() throws SmartsheetException { + String smartsheetIntegrationSource = "AI,MyOrg,MyGPT"; + + assertTrue(SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); + } + + @Test + void testBuildWithSmartsheetIntegrationSource_twoStringsSeparatedByOneComma_fail() { + String smartsheetIntegrationSource = "AI,MyGPT"; + + Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); + assertEquals("Invalid smartsheet integration source format", exception.getMessage()); + } + + @Test + void testBuildWithSmartsheetIntegrationSource_twoStringsSeparatedByTwoCommas_success() throws SmartsheetException { + String smartsheetIntegrationSource = "AI,,MyGPT"; + + assertTrue(SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); + } + + @Test + void testBuildWithSmartsheetIntegrationSource_moreThanThreeStrings_fail() { + String smartsheetIntegrationSource = "AI,MyOrg,MyGPT,MyDivision"; + + Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); + assertEquals("Invalid smartsheet integration source format", exception.getMessage()); + } + + @Test + void testBuildWithSmartsheetIntegrationSource_moreThanTwoCommas_fail() { + String smartsheetIntegrationSource = "AI,MyOrg,,,MyGPT"; + + Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); + assertEquals("Invalid smartsheet integration source format", exception.getMessage()); + } + + @Test + void testBuildWithSmartsheetIntegrationSource_integratorTypeNotValidEnum_fail() { + String smartsheetIntegrationSource = "MyInvalidIntegratorType,MyOrg,MyGPT"; + + Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); + assertEquals("Invalid smartsheet integration source format. " + + "The integration type has to be one of the following: " + Arrays.toString(SmartsheetIntegrationSourceType.values()), exception.getMessage()); + } + + @Test + void testBuildWithSmartsheetIntegrationSource_integratorNameMissing_fail() { + String smartsheetIntegrationSource = "AI,MyOrg,"; + + Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); + assertEquals("Invalid smartsheet integration source format. " + + "The integrator name cannot be empty.", exception.getMessage()); + } +} diff --git a/src/test/java/com/smartsheet/api/integrationtest/ITResourcesImpl.java b/src/test/java/com/smartsheet/api/integrationtest/ITResourcesImpl.java index ff0a2ab48..a488c1014 100644 --- a/src/test/java/com/smartsheet/api/integrationtest/ITResourcesImpl.java +++ b/src/test/java/com/smartsheet/api/integrationtest/ITResourcesImpl.java @@ -44,7 +44,7 @@ public class ITResourcesImpl { public Smartsheet createAuthentication() throws SmartsheetException { // will pull the access token from the environment SMARTSHEET_ACCESS_TOKEN since not provided here. - smartsheet = new SmartsheetBuilder().build(); + smartsheet = new SmartsheetBuilder().setSmartsheetIntegrationSource("AI,MyCompany,MyGPT").build(); return smartsheet; } diff --git a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java index 658374d99..c4a97e3f5 100644 --- a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java +++ b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java @@ -17,6 +17,7 @@ package com.smartsheet.api.internal; import com.smartsheet.api.SmartsheetBuilder; +import com.smartsheet.api.SmartsheetException; import com.smartsheet.api.internal.http.DefaultHttpClient; import com.smartsheet.api.models.Home; import org.junit.jupiter.api.Test; @@ -36,7 +37,7 @@ class AbstractResourcesTest { private final String smartsheetIntegrationSource = "AI,MyCompany,MyGPT"; @Test - void testHeaders() { + void testHeaders() throws SmartsheetException { SmartsheetImpl smartsheet = new SmartsheetImpl("doesnt/matter", tokenValue, new DefaultHttpClient(), null); smartsheet.setChangeAgent(changeAgent); diff --git a/src/test/java/com/smartsheet/api/internal/AssetShareResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/AssetShareResourcesImplTest.java index e154ba0cd..6867fd1d2 100644 --- a/src/test/java/com/smartsheet/api/internal/AssetShareResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/AssetShareResourcesImplTest.java @@ -41,8 +41,7 @@ class AssetShareResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - assetShareResourcesImpl = new AssetShareResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer)); + assetShareResourcesImpl = new AssetShareResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/AttachmentVersioningResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/AttachmentVersioningResourcesImplTest.java index 0ac12a4cf..4c20df355 100644 --- a/src/test/java/com/smartsheet/api/internal/AttachmentVersioningResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/AttachmentVersioningResourcesImplTest.java @@ -37,12 +37,6 @@ class AttachmentVersioningResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - SmartsheetImpl smartsheetImpl = new SmartsheetImpl( - "http://localhost:9090/1.1/", - "accessToken", - new DefaultHttpClient(), - serializer - ); attachmentVersioningResources = new AttachmentVersioningResourcesImpl(smartsheetImpl); } diff --git a/src/test/java/com/smartsheet/api/internal/CommentAttachmentResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/CommentAttachmentResourcesImplTest.java index 43ee88439..ff4edac8f 100644 --- a/src/test/java/com/smartsheet/api/internal/CommentAttachmentResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/CommentAttachmentResourcesImplTest.java @@ -38,8 +38,7 @@ class CommentAttachmentResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - commentAttachmentResources = new CommentAttachmentResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + commentAttachmentResources = new CommentAttachmentResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java index 6e8060fd6..30ff1d912 100644 --- a/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/ContactResourcesImplTest.java @@ -35,8 +35,7 @@ class ContactResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - contactResources = new ContactResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer)); + contactResources = new ContactResourcesImpl(smartsheetImpl); } @Nested diff --git a/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java index 6e698b75b..a27362ab5 100644 --- a/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesImplTest.java @@ -36,8 +36,7 @@ class DiscussionAttachmentResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - discussionAttachmentResources = new DiscussionAttachmentResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + discussionAttachmentResources = new DiscussionAttachmentResourcesImpl(smartsheetImpl); } @Nested diff --git a/src/test/java/com/smartsheet/api/internal/DiscussionCommentResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/DiscussionCommentResourcesImplTest.java index 530aabe55..2bbb19856 100644 --- a/src/test/java/com/smartsheet/api/internal/DiscussionCommentResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/DiscussionCommentResourcesImplTest.java @@ -33,8 +33,7 @@ class DiscussionCommentResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - discussionCommentResources = new DiscussionCommentResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + discussionCommentResources = new DiscussionCommentResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/DiscussionResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/DiscussionResourcesImplTest.java index 8a4c501f9..c8019277e 100644 --- a/src/test/java/com/smartsheet/api/internal/DiscussionResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/DiscussionResourcesImplTest.java @@ -33,8 +33,7 @@ class DiscussionResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - discussionResources = new DiscussionResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + discussionResources = new DiscussionResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/EventResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/EventResourcesImplTest.java index 317f41edd..53ff63e4e 100644 --- a/src/test/java/com/smartsheet/api/internal/EventResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/EventResourcesImplTest.java @@ -37,8 +37,7 @@ class EventResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - eventResources = new EventResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + eventResources = new EventResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/FavoriteResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/FavoriteResourcesImplTest.java index 845407aba..4145b9dcd 100644 --- a/src/test/java/com/smartsheet/api/internal/FavoriteResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/FavoriteResourcesImplTest.java @@ -37,8 +37,7 @@ class FavoriteResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - favoriteResources = new FavoriteResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + favoriteResources = new FavoriteResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/FolderResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/FolderResourcesImplTest.java index 1d15021c9..b640c6468 100644 --- a/src/test/java/com/smartsheet/api/internal/FolderResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/FolderResourcesImplTest.java @@ -39,8 +39,7 @@ class FolderResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() { // Create a folder resource - folderResource = new FolderResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer)); + folderResource = new FolderResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/GroupResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/GroupResourcesImplTest.java index 0c058e560..4b46cbf87 100644 --- a/src/test/java/com/smartsheet/api/internal/GroupResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/GroupResourcesImplTest.java @@ -41,8 +41,7 @@ class GroupResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - groupResources = new GroupResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + groupResources = new GroupResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java index 188d9aeed..f6289a4fc 100644 --- a/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/HomeFolderResourcesImplTest.java @@ -36,8 +36,7 @@ class HomeFolderResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - homeFolderResources = new HomeFolderResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + homeFolderResources = new HomeFolderResourcesImpl(smartsheetImpl); } @Nested diff --git a/src/test/java/com/smartsheet/api/internal/HomeResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/HomeResourcesImplTest.java index 4bb9769ff..86f24469c 100644 --- a/src/test/java/com/smartsheet/api/internal/HomeResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/HomeResourcesImplTest.java @@ -39,8 +39,7 @@ class HomeResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - homeResources = new HomeResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + homeResources = new HomeResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/ImageUrlResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/ImageUrlResourcesImplTest.java index 7aaed8285..5e952bee8 100644 --- a/src/test/java/com/smartsheet/api/internal/ImageUrlResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/ImageUrlResourcesImplTest.java @@ -38,8 +38,7 @@ class ImageUrlResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() { // Create a folder resource - imageUrlResources = new ImageUrlResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer)); + imageUrlResources = new ImageUrlResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/PassthroughResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/PassthroughResourcesImplTest.java index dc7fc0b7c..42ed96f55 100644 --- a/src/test/java/com/smartsheet/api/internal/PassthroughResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/PassthroughResourcesImplTest.java @@ -34,8 +34,7 @@ class PassthroughResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - passthroughResources = new PassthroughResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + passthroughResources = new PassthroughResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/ReportResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/ReportResourcesImplTest.java index b417003e2..6f9be6a8c 100644 --- a/src/test/java/com/smartsheet/api/internal/ReportResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/ReportResourcesImplTest.java @@ -50,8 +50,7 @@ class ReportResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - reportResources = new ReportResourcesImpl(new SmartsheetImpl("http://localhost:9090/2.0/", - "accessToken", new DefaultHttpClient(), serializer)); + reportResources = new ReportResourcesImpl(smartsheetImpl); } diff --git a/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java b/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java index 71acf9679..67782a8b7 100644 --- a/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java +++ b/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java @@ -17,6 +17,7 @@ package com.smartsheet.api.internal; import com.smartsheet.api.HttpTestServer; +import com.smartsheet.api.internal.http.DefaultHttpClient; import com.smartsheet.api.internal.json.JacksonJsonSerializer; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -26,6 +27,7 @@ public class ResourcesImplBase { HttpTestServer server; FolderResourcesImpl folderResource; JacksonJsonSerializer serializer; + SmartsheetImpl smartsheetImpl; @BeforeEach public void baseSetUp() throws Exception { @@ -36,6 +38,13 @@ public void baseSetUp() throws Exception { // Setup the serializer JacksonJsonSerializer.setFailOnUnknownProperties(true); + smartsheetImpl = new SmartsheetImpl( + "http://localhost:9090/1.1/", + "accessToken", + new DefaultHttpClient(), + serializer + ); + smartsheetImpl.setSmartsheetIntegrationSource("AI,MyCompany,MyGPT"); } @AfterEach diff --git a/src/test/java/com/smartsheet/api/internal/RowAttachmentResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/RowAttachmentResourcesImplTest.java index 224865f4d..2800b4dee 100644 --- a/src/test/java/com/smartsheet/api/internal/RowAttachmentResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/RowAttachmentResourcesImplTest.java @@ -41,8 +41,7 @@ class RowAttachmentResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - rowAttachmentResources = new RowAttachmentResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + rowAttachmentResources = new RowAttachmentResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/RowColumnResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/RowColumnResourcesImplTest.java index d7ee73d5e..26f12a166 100644 --- a/src/test/java/com/smartsheet/api/internal/RowColumnResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/RowColumnResourcesImplTest.java @@ -36,8 +36,7 @@ class RowColumnResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - rowColumnResources = new RowColumnResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer)); + rowColumnResources = new RowColumnResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/RowDiscussionResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/RowDiscussionResourcesImplTest.java index da6c2a6e6..162d7f84e 100644 --- a/src/test/java/com/smartsheet/api/internal/RowDiscussionResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/RowDiscussionResourcesImplTest.java @@ -37,8 +37,7 @@ class RowDiscussionResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - discussionRowResources = new RowDiscussionResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + discussionRowResources = new RowDiscussionResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SearchResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SearchResourcesImplTest.java index 106c8aa3e..00f984980 100644 --- a/src/test/java/com/smartsheet/api/internal/SearchResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SearchResourcesImplTest.java @@ -36,8 +36,7 @@ class SearchResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - searchResources = new SearchResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + searchResources = new SearchResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/ServerInfoResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/ServerInfoResourcesImplTest.java index 8512b11fa..26fc4ce4c 100644 --- a/src/test/java/com/smartsheet/api/internal/ServerInfoResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/ServerInfoResourcesImplTest.java @@ -32,8 +32,7 @@ class ServerInfoResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - serverInfoResources = new ServerInfoResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + serverInfoResources = new ServerInfoResourcesImpl(smartsheetImpl); } diff --git a/src/test/java/com/smartsheet/api/internal/ShareResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/ShareResourcesImplTest.java index 485fe1ae3..e98683a29 100644 --- a/src/test/java/com/smartsheet/api/internal/ShareResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/ShareResourcesImplTest.java @@ -39,8 +39,7 @@ class ShareResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - shareResourcesImpl = new ShareResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer), "sheets"); + shareResourcesImpl = new ShareResourcesImpl(smartsheetImpl, "sheets"); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SheetAttachmentResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SheetAttachmentResourcesImplTest.java index 468615cb2..58834245e 100644 --- a/src/test/java/com/smartsheet/api/internal/SheetAttachmentResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SheetAttachmentResourcesImplTest.java @@ -41,8 +41,7 @@ class SheetAttachmentResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - sheetAttachmentResources = new SheetAttachmentResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + sheetAttachmentResources = new SheetAttachmentResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SheetColumnResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SheetColumnResourcesImplTest.java index 75fa58feb..4e1b34443 100644 --- a/src/test/java/com/smartsheet/api/internal/SheetColumnResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SheetColumnResourcesImplTest.java @@ -41,8 +41,7 @@ class SheetColumnResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - sheetColumnResourcesImpl = new SheetColumnResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + sheetColumnResourcesImpl = new SheetColumnResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SheetCommentResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SheetCommentResourcesImplTest.java index 57e4f85d5..41223ae20 100644 --- a/src/test/java/com/smartsheet/api/internal/SheetCommentResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SheetCommentResourcesImplTest.java @@ -32,8 +32,7 @@ class SheetCommentResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - sheetCommentResources = new SheetCommentResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + sheetCommentResources = new SheetCommentResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SheetDiscussionResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SheetDiscussionResourcesImplTest.java index ce21beaf6..ca552ce16 100644 --- a/src/test/java/com/smartsheet/api/internal/SheetDiscussionResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SheetDiscussionResourcesImplTest.java @@ -43,8 +43,7 @@ class SheetDiscussionResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - sheetDiscussionResources = new SheetDiscussionResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + sheetDiscussionResources = new SheetDiscussionResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SheetResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SheetResourcesImplTest.java index 4ada2ffd6..95b84193b 100644 --- a/src/test/java/com/smartsheet/api/internal/SheetResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SheetResourcesImplTest.java @@ -68,8 +68,7 @@ class SheetResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { // Create a folder resource - sheetResource = new SheetResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer)); + sheetResource = new SheetResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SheetRowResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SheetRowResourcesImplTest.java index ba3b6a96d..9637500a9 100644 --- a/src/test/java/com/smartsheet/api/internal/SheetRowResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SheetRowResourcesImplTest.java @@ -52,8 +52,7 @@ class SheetRowResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - sheetRowResource = new SheetRowResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", "accessToken", - new DefaultHttpClient(), serializer)); + sheetRowResource = new SheetRowResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/SightResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/SightResourcesImplTest.java index 31f126db6..a07fa1ba0 100644 --- a/src/test/java/com/smartsheet/api/internal/SightResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SightResourcesImplTest.java @@ -41,12 +41,6 @@ class SightResourcesImplTest extends ResourcesImplBase { @BeforeEach public void before() { - SmartsheetImpl smartsheetImpl = new SmartsheetImpl( - "http://localhost:9090/1.1/", - "accessToken", - new DefaultHttpClient(), - serializer - ); sightResourcesImpl = new SightResourcesImpl(smartsheetImpl); } diff --git a/src/test/java/com/smartsheet/api/internal/TemplateResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/TemplateResourcesImplTest.java index 3fcf1c94f..af0418db1 100644 --- a/src/test/java/com/smartsheet/api/internal/TemplateResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/TemplateResourcesImplTest.java @@ -36,8 +36,7 @@ class TemplateResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - templateResources = new TemplateResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + templateResources = new TemplateResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/TokenResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/TokenResourcesImplTest.java index 12e9ac331..422df73f5 100644 --- a/src/test/java/com/smartsheet/api/internal/TokenResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/TokenResourcesImplTest.java @@ -29,8 +29,7 @@ class TokenResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - tokenResources = new TokenResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + tokenResources = new TokenResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/UserResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/UserResourcesImplTest.java index 096de4666..f8f236a5a 100644 --- a/src/test/java/com/smartsheet/api/internal/UserResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/UserResourcesImplTest.java @@ -53,8 +53,7 @@ class UserResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - userResources = new UserResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + userResources = new UserResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/WebhookResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/WebhookResourcesImplTest.java index de531aeba..add9c856e 100644 --- a/src/test/java/com/smartsheet/api/internal/WebhookResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/WebhookResourcesImplTest.java @@ -41,8 +41,7 @@ class WebhookResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - webhookResources = new WebhookResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + webhookResources = new WebhookResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/WorkspaceFolderResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/WorkspaceFolderResourcesImplTest.java index 1f2485b7e..42b26feb9 100644 --- a/src/test/java/com/smartsheet/api/internal/WorkspaceFolderResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/WorkspaceFolderResourcesImplTest.java @@ -35,8 +35,7 @@ class WorkspaceFolderResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - workspaceFolderResources = new WorkspaceFolderResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + workspaceFolderResources = new WorkspaceFolderResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/WorkspaceResourcesImplTest.java b/src/test/java/com/smartsheet/api/internal/WorkspaceResourcesImplTest.java index 2da1ba16c..0f04ee8f0 100644 --- a/src/test/java/com/smartsheet/api/internal/WorkspaceResourcesImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/WorkspaceResourcesImplTest.java @@ -44,8 +44,7 @@ class WorkspaceResourcesImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { - workspaceResources = new WorkspaceResourcesImpl(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + workspaceResources = new WorkspaceResourcesImpl(smartsheetImpl); } @Test diff --git a/src/test/java/com/smartsheet/api/logging/LoggingIT.java b/src/test/java/com/smartsheet/api/logging/LoggingIT.java index 89045ca40..548d8f102 100644 --- a/src/test/java/com/smartsheet/api/logging/LoggingIT.java +++ b/src/test/java/com/smartsheet/api/logging/LoggingIT.java @@ -31,10 +31,10 @@ // Note this is an IT test because at least one of the tests requires an internet connection class LoggingIT { @Test - void testConsoleLogging() { + void testConsoleLogging() throws SmartsheetException { ByteArrayOutputStream traceStream = new ByteArrayOutputStream(); DefaultHttpClient.setTraceStream(traceStream); - Smartsheet client = new SmartsheetBuilder().setAccessToken("null").build(); + Smartsheet client = new SmartsheetBuilder().setAccessToken("null").setSmartsheetIntegrationSource("AI,MyCompany,MyGPT").build(); // should log entire request and response client.setTraces(Trace.Request, Trace.Response); @@ -51,11 +51,11 @@ void testConsoleLogging() { } @Test - void testCustomLogging() { + void testCustomLogging() throws SmartsheetException { ByteArrayOutputStream traceStream = new ByteArrayOutputStream(); DefaultHttpClient.setTraceStream(traceStream); // using "null" as token results in NPE - Smartsheet client = new SmartsheetBuilder().setAccessToken("just_a_random_dummy_token").build(); + Smartsheet client = new SmartsheetBuilder().setAccessToken("just_a_random_dummy_token").setSmartsheetIntegrationSource("AI,MyCompany,MyGPT").build(); // should log entire request and response client.setTraces(Trace.Request, Trace.Response); diff --git a/src/test/java/com/smartsheet/api/sdktest/HelperFunctions.java b/src/test/java/com/smartsheet/api/sdktest/HelperFunctions.java index a9587b17a..2e095f2d1 100644 --- a/src/test/java/com/smartsheet/api/sdktest/HelperFunctions.java +++ b/src/test/java/com/smartsheet/api/sdktest/HelperFunctions.java @@ -18,13 +18,15 @@ import com.smartsheet.api.Smartsheet; import com.smartsheet.api.SmartsheetBuilder; +import com.smartsheet.api.SmartsheetException; class HelperFunctions { - public static Smartsheet SetupClient(String apiScenario) { + public static Smartsheet SetupClient(String apiScenario) throws SmartsheetException { TestHttpClient testHttpClient = new TestHttpClient(apiScenario); Smartsheet ss = new SmartsheetBuilder() .setBaseURI("http://localhost:8082/") .setAccessToken("aaaaaaaaaaaaaaaaaaaaaaaaaa") + .setSmartsheetIntegrationSource("AI,MyCompany,MyGPT") .setHttpClient(testHttpClient) .build(); diff --git a/src/test/java/com/smartsheet/api/sdktest/RowTest.java b/src/test/java/com/smartsheet/api/sdktest/RowTest.java index 3ffa0e8a3..549e45535 100644 --- a/src/test/java/com/smartsheet/api/sdktest/RowTest.java +++ b/src/test/java/com/smartsheet/api/sdktest/RowTest.java @@ -196,7 +196,7 @@ void addRows_AssignValues_HyperlinkReportID() throws SmartsheetException { } @Test - void addRows_Invalid_AssignHyperlinkUrlAndSheetId() { + void addRows_Invalid_AssignHyperlinkUrlAndSheetId() throws SmartsheetException { Smartsheet ss = HelperFunctions.SetupClient("Add Rows - Invalid - Assign Hyperlink URL and SheetId"); Cell cell1 = new Cell() @@ -213,7 +213,7 @@ void addRows_Invalid_AssignHyperlinkUrlAndSheetId() { } @Test - void addRows_Invalid_AssignValueAndFormulae() { + void addRows_Invalid_AssignValueAndFormulae() throws SmartsheetException { Smartsheet ss = HelperFunctions.SetupClient("Add Rows - Invalid - Assign Value and Formulae"); Cell cell1 = new Cell().setColumnId(101L).setFormula("=SUM([Column2]3, [Column2]4)*2").setValue("20"); @@ -371,7 +371,7 @@ void updateRows_AssignValues_HyperlinkReportID() throws SmartsheetException { } @Test - void updateRows_Invalid_AssignHyperlinkUrlAndSheetId() { + void updateRows_Invalid_AssignHyperlinkUrlAndSheetId() throws SmartsheetException { Smartsheet ss = HelperFunctions.SetupClient("Update Rows - Invalid - Assign Hyperlink URL and SheetId"); Hyperlink hyperlink1 = new Hyperlink().setUrl("http://google.com").setSheetId(2L); @@ -387,7 +387,7 @@ void updateRows_Invalid_AssignHyperlinkUrlAndSheetId() { } @Test - void updateRows_Invalid_AssignValueAndFormulae() { + void updateRows_Invalid_AssignValueAndFormulae() throws SmartsheetException { Smartsheet ss = HelperFunctions.SetupClient("Update Rows - Invalid - Assign Value and Formulae"); Cell cell1 = new Cell().setColumnId(101L).setFormula("=SUM([Column2]3, [Column2]4)*2").setValue("20"); @@ -457,7 +457,7 @@ void updateRows_ClearValue_CellLink() throws SmartsheetException { } @Test - void updateRows_Invalid_AssignHyperlinkAndCellLink() { + void updateRows_Invalid_AssignHyperlinkAndCellLink() throws SmartsheetException { Smartsheet ss = HelperFunctions.SetupClient("Update Rows - Invalid - Assign Hyperlink and Cell Link"); Hyperlink hyperlink = new Hyperlink().setUrl("www.google.com"); diff --git a/src/test/java/com/smartsheet/api/sdktest/SheetTest.java b/src/test/java/com/smartsheet/api/sdktest/SheetTest.java index 7a88ef4e9..405638580 100644 --- a/src/test/java/com/smartsheet/api/sdktest/SheetTest.java +++ b/src/test/java/com/smartsheet/api/sdktest/SheetTest.java @@ -46,7 +46,7 @@ void listSheets_IncludeOwnerInfo() throws SmartsheetException { } @Test - void createSheet__Invalid_NoColumns() { + void createSheet__Invalid_NoColumns() throws SmartsheetException { Smartsheet ss = HelperFunctions.SetupClient("Create Sheet - Invalid - No Columns"); Sheet sheetA = new Sheet().setSheetName("New Sheet").setColumns(new ArrayList<>()); From 33df0042364784e62c8574d21beeee471d4eb8fb Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Mon, 1 Sep 2025 11:54:39 +0300 Subject: [PATCH 09/12] Make smartsheet-integration-source mandatory in the constructor of SmartsheetImpl --- .../com/smartsheet/api/SmartsheetBuilder.java | 12 +++++------- .../com/smartsheet/api/SmartsheetFactory.java | 18 ++++++++++-------- .../api/internal/SmartsheetImpl.java | 11 +++++++---- .../api/internal/AbstractResourcesTest.java | 8 ++++---- .../DiscussionAttachmentResourcesTest.java | 2 +- .../api/internal/ResourcesImplBase.java | 5 +++-- .../api/internal/SmartsheetImplTest.java | 4 ++-- 7 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java index 0349e39d0..1ecf9593e 100644 --- a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java +++ b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java @@ -296,16 +296,14 @@ public Smartsheet build() throws SmartsheetException { accessToken = System.getenv("SMARTSHEET_ACCESS_TOKEN"); } - SmartsheetImpl smartsheet = new SmartsheetImpl(baseURI, accessToken, httpClient, jsonSerializer); - - if (changeAgent != null) { - smartsheet.setChangeAgent(changeAgent); - } if (smartsheetIntegrationSource == null) { throw new SmartsheetException("SmartsheetIntegrationSource cannot be null"); } - else { - smartsheet.setSmartsheetIntegrationSource(smartsheetIntegrationSource); + + SmartsheetImpl smartsheet = new SmartsheetImpl(baseURI, accessToken, httpClient, jsonSerializer, smartsheetIntegrationSource); + + if (changeAgent != null) { + smartsheet.setChangeAgent(changeAgent); } if (assumedUser != null) { smartsheet.setAssumedUser(assumedUser); diff --git a/src/main/java/com/smartsheet/api/SmartsheetFactory.java b/src/main/java/com/smartsheet/api/SmartsheetFactory.java index 42206faa0..3d3158fad 100644 --- a/src/main/java/com/smartsheet/api/SmartsheetFactory.java +++ b/src/main/java/com/smartsheet/api/SmartsheetFactory.java @@ -39,9 +39,10 @@ public class SmartsheetFactory { * * @return the Smartsheet client */ - public static Smartsheet createDefaultClient() { + public static Smartsheet createDefaultClient() throws SmartsheetException { String accessToken = System.getenv("SMARTSHEET_ACCESS_TOKEN"); - SmartsheetImpl smartsheet = new SmartsheetImpl(DEFAULT_BASE_URI, accessToken); + String smartsheetIntegrationSource = System.getenv("SMARTSHEET_INTEGRATION_SOURCE"); + SmartsheetImpl smartsheet = new SmartsheetImpl(DEFAULT_BASE_URI, accessToken, smartsheetIntegrationSource); return smartsheet; } @@ -50,8 +51,8 @@ public static Smartsheet createDefaultClient() { * * @return the Smartsheet client */ - public static Smartsheet createDefaultClient(String accessToken) { - SmartsheetImpl smartsheet = new SmartsheetImpl(DEFAULT_BASE_URI, accessToken); + public static Smartsheet createDefaultClient(String accessToken, String smartsheetIntegrationSource) throws SmartsheetException { + SmartsheetImpl smartsheet = new SmartsheetImpl(DEFAULT_BASE_URI, accessToken, smartsheetIntegrationSource); return smartsheet; } @@ -61,9 +62,10 @@ public static Smartsheet createDefaultClient(String accessToken) { * * @return the Smartsheet client */ - public static Smartsheet createDefaultGovAccountClient() { + public static Smartsheet createDefaultGovAccountClient() throws SmartsheetException { String accessToken = System.getenv("SMARTSHEET_ACCESS_TOKEN"); - SmartsheetImpl smartsheet = new SmartsheetImpl(GOV_BASE_URI, accessToken); + String smartsheetIntegrationSource = System.getenv("SMARTSHEET_INTEGRATION_SOURCE"); + SmartsheetImpl smartsheet = new SmartsheetImpl(GOV_BASE_URI, accessToken, smartsheetIntegrationSource); return smartsheet; } @@ -72,8 +74,8 @@ public static Smartsheet createDefaultGovAccountClient() { * * @return the Smartsheet client */ - public static Smartsheet createDefaultGovAccountClient(String accessToken) { - SmartsheetImpl smartsheet = new SmartsheetImpl(GOV_BASE_URI, accessToken); + public static Smartsheet createDefaultGovAccountClient(String accessToken, String smartsheetIntegrationSource) throws SmartsheetException { + SmartsheetImpl smartsheet = new SmartsheetImpl(GOV_BASE_URI, accessToken, smartsheetIntegrationSource); return smartsheet; } diff --git a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java index ae48041c5..8164d791c 100644 --- a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java +++ b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java @@ -284,9 +284,10 @@ public class SmartsheetImpl implements Smartsheet { * * @param baseURI the server uri * @param accessToken the access token + * @param smartsheetIntegrationSource integration source identifier */ - public SmartsheetImpl(String baseURI, String accessToken) { - this(baseURI, accessToken, null, null); + public SmartsheetImpl(String baseURI, String accessToken, String smartsheetIntegrationSource) throws SmartsheetException { + this(baseURI, accessToken, null, null, smartsheetIntegrationSource); } /** @@ -299,7 +300,8 @@ public SmartsheetImpl(String baseURI, String accessToken) { * @param httpClient the http client (optional) * @param jsonSerializer the json serializer (optional) */ - public SmartsheetImpl(String baseURI, String accessToken, HttpClient httpClient, JsonSerializer jsonSerializer) { + public SmartsheetImpl(String baseURI, String accessToken, HttpClient httpClient, JsonSerializer jsonSerializer, + String smartsheetIntegrationSource) throws SmartsheetException { Util.throwIfNull(baseURI); Util.throwIfEmpty(baseURI); @@ -334,7 +336,8 @@ public SmartsheetImpl(String baseURI, String accessToken, HttpClient httpClient, this.passthrough = new AtomicReference<>(); this.events = new AtomicReference<>(); this.assetShares = new AtomicReference<>(); - this.smartsheetIntegrationSource = new AtomicReference<>(); + SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource); + this.smartsheetIntegrationSource = new AtomicReference<>(smartsheetIntegrationSource); } /** diff --git a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java index c4a97e3f5..51e843e95 100644 --- a/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java +++ b/src/test/java/com/smartsheet/api/internal/AbstractResourcesTest.java @@ -39,9 +39,8 @@ class AbstractResourcesTest { @Test void testHeaders() throws SmartsheetException { - SmartsheetImpl smartsheet = new SmartsheetImpl("doesnt/matter", tokenValue, new DefaultHttpClient(), null); + SmartsheetImpl smartsheet = new SmartsheetImpl("doesnt/matter", tokenValue, new DefaultHttpClient(), null, smartsheetIntegrationSource); smartsheet.setChangeAgent(changeAgent); - smartsheet.setSmartsheetIntegrationSource(smartsheetIntegrationSource); AbstractResources resources = new AbstractResources(smartsheet) { }; @@ -53,12 +52,13 @@ void testHeaders() throws SmartsheetException { } @Test - void createResourceWithObjectClassNull() { + void createResourceWithObjectClassNull() throws SmartsheetException { SmartsheetImpl smartsheetImpl = new SmartsheetImpl( SmartsheetBuilder.DEFAULT_BASE_URI, tokenValue, new DefaultHttpClient(), - null + null, + smartsheetIntegrationSource ); AbstractResources resources = new AbstractResources(smartsheetImpl) { }; diff --git a/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesTest.java b/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesTest.java index 620a208cd..c8ad58486 100644 --- a/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesTest.java +++ b/src/test/java/com/smartsheet/api/internal/DiscussionAttachmentResourcesTest.java @@ -32,7 +32,7 @@ class DiscussionAttachmentResourcesTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { discussionAttachmentResources = new DiscussionAttachmentResources(new SmartsheetImpl("http://localhost:9090/1.1/", - "accessToken", new DefaultHttpClient(), serializer)); + "accessToken", new DefaultHttpClient(), serializer, smartsheetIntegrationSource)); } @Test diff --git a/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java b/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java index 67782a8b7..c34520f9a 100644 --- a/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java +++ b/src/test/java/com/smartsheet/api/internal/ResourcesImplBase.java @@ -28,6 +28,7 @@ public class ResourcesImplBase { FolderResourcesImpl folderResource; JacksonJsonSerializer serializer; SmartsheetImpl smartsheetImpl; + String smartsheetIntegrationSource = "AI,MyCompany,MyGPT"; @BeforeEach public void baseSetUp() throws Exception { @@ -42,9 +43,9 @@ public void baseSetUp() throws Exception { "http://localhost:9090/1.1/", "accessToken", new DefaultHttpClient(), - serializer + serializer, + smartsheetIntegrationSource ); - smartsheetImpl.setSmartsheetIntegrationSource("AI,MyCompany,MyGPT"); } @AfterEach diff --git a/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java b/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java index 355adec3b..b9386b607 100644 --- a/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java +++ b/src/test/java/com/smartsheet/api/internal/SmartsheetImplTest.java @@ -33,7 +33,7 @@ class SmartsheetImplTest extends ResourcesImplBase { @BeforeEach public void setUp() throws Exception { httpClient = new DefaultHttpClient(); - smartsheet = new SmartsheetImpl(baseURI, accessToken, httpClient, serializer); + smartsheet = new SmartsheetImpl(baseURI, accessToken, httpClient, serializer, smartsheetIntegrationSource); } @Test @@ -123,6 +123,6 @@ void testSights() { @Test void testGetSmartsheetIntegrationSource() { - assertThat(smartsheet.getSmartsheetIntegrationSource()).isNull(); + assertThat(smartsheet.getSmartsheetIntegrationSource()).isNotNull(); } } From 1518b1357b3ed42f48d319c7f5e9d319ca1ce47d Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Mon, 1 Sep 2025 14:11:14 +0300 Subject: [PATCH 10/12] Remove unnecessary check for null smartsheetIntegrationSource in the builder which is checked in the validator --- src/main/java/com/smartsheet/api/SmartsheetBuilder.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java index 1ecf9593e..5440847f4 100644 --- a/src/main/java/com/smartsheet/api/SmartsheetBuilder.java +++ b/src/main/java/com/smartsheet/api/SmartsheetBuilder.java @@ -296,10 +296,6 @@ public Smartsheet build() throws SmartsheetException { accessToken = System.getenv("SMARTSHEET_ACCESS_TOKEN"); } - if (smartsheetIntegrationSource == null) { - throw new SmartsheetException("SmartsheetIntegrationSource cannot be null"); - } - SmartsheetImpl smartsheet = new SmartsheetImpl(baseURI, accessToken, httpClient, jsonSerializer, smartsheetIntegrationSource); if (changeAgent != null) { From 02c54ef976488b7554cecb4595bda338dc033d2d Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Mon, 1 Sep 2025 15:10:08 +0300 Subject: [PATCH 11/12] Update Java doc to include SMARTSHEET_INTEGRATION_SOURCE --- src/main/java/com/smartsheet/api/SmartsheetFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/smartsheet/api/SmartsheetFactory.java b/src/main/java/com/smartsheet/api/SmartsheetFactory.java index 3d3158fad..c877c8074 100644 --- a/src/main/java/com/smartsheet/api/SmartsheetFactory.java +++ b/src/main/java/com/smartsheet/api/SmartsheetFactory.java @@ -35,6 +35,7 @@ public class SmartsheetFactory { /** *

Creates a Smartsheet client with default parameters. SMARTSHEET_ACCESS_TOKEN + * and SMARTSHEET_INTEGRATION_SOURCE * must be set in the environment.

* * @return the Smartsheet client @@ -58,7 +59,7 @@ public static Smartsheet createDefaultClient(String accessToken, String smartshe /** *

Creates a Smartsheet client with default parameters using the Smartsheetgov URI. - * SMARTSHEET_ACCESS_TOKEN must be set in the environment.

+ * SMARTSHEET_ACCESS_TOKEN and SMARTSHEET_INTEGRATION_SOURCE must be set in the environment.

* * @return the Smartsheet client */ From 5c84b405f673337ba40079151cb791197ae9bf79 Mon Sep 17 00:00:00 2001 From: Ahmed Ahmed Date: Wed, 3 Sep 2025 14:45:02 +0300 Subject: [PATCH 12/12] Make validator messages more verbose and add link to the public documentation of the http headers --- .../api/internal/SmartsheetImpl.java | 1 + .../SmartsheetIntegrationSourceValidator.java | 88 ++++++++++--------- .../SmartsheetIntegrationSourceType.java | 6 +- ...tsheetIntegrationSourceValidatorTests.java | 15 +++- 4 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java index 8164d791c..b38669847 100644 --- a/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java +++ b/src/main/java/com/smartsheet/api/internal/SmartsheetImpl.java @@ -299,6 +299,7 @@ public SmartsheetImpl(String baseURI, String accessToken, String smartsheetInteg * @param accessToken the access token * @param httpClient the http client (optional) * @param jsonSerializer the json serializer (optional) + * @param smartsheetIntegrationSource integration source identifier */ public SmartsheetImpl(String baseURI, String accessToken, HttpClient httpClient, JsonSerializer jsonSerializer, String smartsheetIntegrationSource) throws SmartsheetException { diff --git a/src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java b/src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java index a2ae49e10..9cd717d3e 100644 --- a/src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java +++ b/src/main/java/com/smartsheet/api/internal/util/SmartsheetIntegrationSourceValidator.java @@ -7,55 +7,59 @@ public class SmartsheetIntegrationSourceValidator { - /** - * Validates a smartsheet integration source string in the format: - * type, organisation name, integrator name - * - * - type: must be one of the enum values - * - organisation name: optional (can be empty) - * - integrator name: non-empty - */ - public static boolean isValidFormat(String input) throws SmartsheetException { - if (input == null) { - throw new SmartsheetException("Smartsheet integration source cannot be null"); - } + private static final String documentationLink = "https://developers.smartsheet.com/api/smartsheet/guides/basics/http-and-rest#http-headers"; - String[] parts = input.split(",", -1); // -1 keeps empty slots - if (parts.length != 3) { - throw new SmartsheetException("Invalid smartsheet integration source format"); - } + /** + * Validates a smartsheet integration source string in the format: + * type, organisation name, integrator name + * + * - type: must be one of the enum values + * - organisation name: optional (can be empty) + * - integrator name: non-empty + */ + public static boolean isValidFormat(String input) throws SmartsheetException { + if (input == null) { + throw new SmartsheetException("Smartsheet integration source cannot be null"); + } - String integrationType = parts[0]; - String integratorName = parts[2]; + String[] parts = input.split(",", -1); // -1 keeps empty slots + if (parts.length != 3) { + throw new SmartsheetException("Invalid smartsheet integration source format. " + + "Expected format: 'TYPE,ORGANIZATION,INTEGRATOR. " + documentationLink); + } - // The First slot (integration type) must match enum - if (!isValidType(integrationType)) { - throw new SmartsheetException("Invalid smartsheet integration source format. " + - "The integration type has to be one of the following: " - + Arrays.toString(SmartsheetIntegrationSourceType.values())); - } + String integrationType = parts[0]; + String integratorName = parts[2]; - // Integrator name must be non-empty - if (integratorName.isEmpty()) { - throw new SmartsheetException("Invalid smartsheet integration source format. " + - "The integrator name cannot be empty."); - } + // The First slot (integration type) must match enum + if (!isValidType(integrationType)) { + throw new SmartsheetException("Invalid smartsheet integration source format. " + + "The integration type has to be one of the following: " + + Arrays.toString(SmartsheetIntegrationSourceType.values()) + + ". Invalid integration type: " + integrationType + " " + documentationLink); + } - return true; + // Integrator name must be non-empty + if (integratorName.isEmpty()) { + throw new SmartsheetException("Invalid smartsheet integration source format. " + + "The integrator name cannot be empty."); } - /** - * Checks if the integration type matches one of the enum values - */ - private static boolean isValidType(String integrationTypeValue) { - if (integrationTypeValue == null || integrationTypeValue.isEmpty()) { - return false; - } - for (SmartsheetIntegrationSourceType sourceType : SmartsheetIntegrationSourceType.values()) { - if (sourceType.name().equalsIgnoreCase(integrationTypeValue)) { - return true; - } - } + return true; + } + + /** + * Checks if the integration type matches one of the enum values + */ + private static boolean isValidType(String integrationTypeValue) { + if (integrationTypeValue == null || integrationTypeValue.isEmpty()) { return false; } + for (SmartsheetIntegrationSourceType sourceType : SmartsheetIntegrationSourceType.values()) { + if (sourceType.name().equalsIgnoreCase(integrationTypeValue)) { + return true; + } + } + return false; + } } diff --git a/src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java b/src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java index 8dda54818..5c0e568ff 100644 --- a/src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java +++ b/src/main/java/com/smartsheet/api/models/enums/SmartsheetIntegrationSourceType.java @@ -15,5 +15,9 @@ public enum SmartsheetIntegrationSourceType { /** * Represents the APPLICATION integration source type. */ - APPLICATION; + APPLICATION, + /** + * Represents the PERSONAL_ACCOUNT integration source type. + */ + PERSONAL_ACCOUNT } diff --git a/src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java b/src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java index 5fd81b79a..abab3e815 100644 --- a/src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java +++ b/src/test/java/com/smartsheet/api/SmartsheetIntegrationSourceValidatorTests.java @@ -10,6 +10,8 @@ public class SmartsheetIntegrationSourceValidatorTests { + private static final String documentationLink = "https://developers.smartsheet.com/api/smartsheet/guides/basics/http-and-rest#http-headers"; + @Test void testBuildWithSmartsheetIntegrationSource_allThreeStrings_success() throws SmartsheetException { String smartsheetIntegrationSource = "AI,MyOrg,MyGPT"; @@ -22,7 +24,8 @@ void testBuildWithSmartsheetIntegrationSource_twoStringsSeparatedByOneComma_fail String smartsheetIntegrationSource = "AI,MyGPT"; Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); - assertEquals("Invalid smartsheet integration source format", exception.getMessage()); + assertEquals("Invalid smartsheet integration source format. " + + "Expected format: 'TYPE,ORGANIZATION,INTEGRATOR. " + documentationLink, exception.getMessage()); } @Test @@ -37,7 +40,8 @@ void testBuildWithSmartsheetIntegrationSource_moreThanThreeStrings_fail() { String smartsheetIntegrationSource = "AI,MyOrg,MyGPT,MyDivision"; Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); - assertEquals("Invalid smartsheet integration source format", exception.getMessage()); + assertEquals("Invalid smartsheet integration source format. " + + "Expected format: 'TYPE,ORGANIZATION,INTEGRATOR. " + documentationLink, exception.getMessage()); } @Test @@ -45,7 +49,8 @@ void testBuildWithSmartsheetIntegrationSource_moreThanTwoCommas_fail() { String smartsheetIntegrationSource = "AI,MyOrg,,,MyGPT"; Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); - assertEquals("Invalid smartsheet integration source format", exception.getMessage()); + assertEquals("Invalid smartsheet integration source format. " + + "Expected format: 'TYPE,ORGANIZATION,INTEGRATOR. " + documentationLink, exception.getMessage()); } @Test @@ -54,7 +59,9 @@ void testBuildWithSmartsheetIntegrationSource_integratorTypeNotValidEnum_fail() Exception exception = assertThrows(SmartsheetException.class, () -> SmartsheetIntegrationSourceValidator.isValidFormat(smartsheetIntegrationSource)); assertEquals("Invalid smartsheet integration source format. " + - "The integration type has to be one of the following: " + Arrays.toString(SmartsheetIntegrationSourceType.values()), exception.getMessage()); + "The integration type has to be one of the following: " + + Arrays.toString(SmartsheetIntegrationSourceType.values()) + + ". Invalid integration type: " + "MyInvalidIntegratorType" + " " + documentationLink, exception.getMessage()); } @Test