@@ -63,8 +63,6 @@ private static Stream<Arguments> customUserAgentValues() {
6363 );
6464 }
6565
66- // ========== Default Behavior Tests ==========
67-
6866 private static Stream <Arguments > customUserAgentListValues () {
6967 return Stream .of (
7068 Arguments .of (Arrays .asList ("Agent1" )),
@@ -73,13 +71,13 @@ private static Stream<Arguments> customUserAgentListValues() {
7371 );
7472 }
7573
76- // ========== Custom User-Agent Preservation Tests ==========
77-
7874 @ BeforeEach
7975 void setUp () {
8076 interceptor = new CapturingInterceptor ();
8177 }
8278
79+ // ========== Default Behavior Tests ==========
80+
8381 @ Test
8482 void executeRequest_withoutCustomUserAgent_shouldAddSdkDefaultUserAgent () {
8583 RestJsonEndpointProvidersClient client = defaultClientBuilder ().build ();
@@ -88,7 +86,7 @@ void executeRequest_withoutCustomUserAgent_shouldAddSdkDefaultUserAgent() {
8886 assertUserAgentContains (SDK_USER_AGENT_PREFIX );
8987 }
9088
91- // ========== API Name Handling Tests ==========
89+ // ========== Custom User-Agent Preservation Tests ==========
9290
9391 @ ParameterizedTest (name = "Custom User-Agent ''{0}'' should be preserved without SDK prefix" )
9492 @ MethodSource ("customUserAgentValues" )
@@ -112,6 +110,69 @@ void executeRequest_withCustomUserAgentList_shouldPreserveAllValues(List<String>
112110 assertThat (userAgentList ).isEqualTo (customUserAgentList );
113111 }
114112
113+ // ========== Request-Level User-Agent Tests ==========
114+
115+ @ ParameterizedTest (name = "Request-level User-Agent ''{0}'' should be preserved" )
116+ @ MethodSource ("customUserAgentValues" )
117+ void executeRequest_withRequestLevelCustomUserAgent_shouldPreserveAndNotOverwrite (String customUserAgent ) {
118+ RestJsonEndpointProvidersClient client = defaultClientBuilder ().build ();
119+
120+ assertThatThrownBy (() -> client .allTypes (r -> r
121+ .overrideConfiguration (o -> o .putHeader (USER_AGENT_HEADER , customUserAgent ))))
122+ .hasMessageContaining (INTERCEPTOR_STOP_MESSAGE );
123+
124+ String userAgent = getCapturedUserAgent ();
125+ assertThat (userAgent )
126+ .isEqualTo (customUserAgent )
127+ .doesNotContain (SDK_USER_AGENT_PREFIX );
128+ }
129+
130+ @ ParameterizedTest (name = "Request-level User-Agent list {0} should be preserved" )
131+ @ MethodSource ("customUserAgentListValues" )
132+ void executeRequest_withRequestLevelCustomUserAgentList_shouldPreserveAllValues (List <String > customUserAgentList ) {
133+ RestJsonEndpointProvidersClient client = defaultClientBuilder ().build ();
134+
135+ assertThatThrownBy (() -> client .allTypes (r -> r
136+ .overrideConfiguration (o -> o .putHeader (USER_AGENT_HEADER , customUserAgentList ))))
137+ .hasMessageContaining (INTERCEPTOR_STOP_MESSAGE );
138+
139+ List <String > userAgentList = getCapturedUserAgentList ();
140+ assertThat (userAgentList ).isEqualTo (customUserAgentList );
141+ }
142+
143+ @ Test
144+ void executeRequest_withRequestLevelCustomUserAgentAndApiName_shouldNotAppendApiName () {
145+ String customUserAgent = "CustomUserAgentHeaderValue" ;
146+ RestJsonEndpointProvidersClient client = defaultClientBuilder ().build ();
147+
148+ assertThatThrownBy (() -> client .allTypes (r -> r
149+ .overrideConfiguration (o -> o
150+ .addApiName (api -> api .name (TEST_API_NAME ).version (TEST_API_VERSION ))
151+ .putHeader (USER_AGENT_HEADER , customUserAgent ))))
152+ .hasMessageContaining (INTERCEPTOR_STOP_MESSAGE );
153+
154+ String userAgent = getCapturedUserAgent ();
155+ assertThat (userAgent )
156+ .isEqualTo (customUserAgent )
157+ .doesNotContain (TEST_API_NAME );
158+ }
159+
160+ @ ParameterizedTest (name = "Request-level User-Agent list {0} with API name should not append API name" )
161+ @ MethodSource ("customUserAgentListValues" )
162+ void executeRequest_withRequestLevelCustomUserAgentListAndApiName_shouldNotAppendApiName (List <String > customUserAgentList ) {
163+ RestJsonEndpointProvidersClient client = defaultClientBuilder ().build ();
164+
165+ assertThatThrownBy (() -> client .allTypes (r -> r
166+ .overrideConfiguration (o -> o
167+ .addApiName (api -> api .name (TEST_API_NAME ).version (TEST_API_VERSION ))
168+ .putHeader (USER_AGENT_HEADER , customUserAgentList ))))
169+ .hasMessageContaining (INTERCEPTOR_STOP_MESSAGE );
170+
171+ List <String > userAgentList = getCapturedUserAgentList ();
172+ assertThat (userAgentList ).isEqualTo (customUserAgentList );
173+ assertThat (String .join (" " , userAgentList )).doesNotContain (TEST_API_NAME );
174+ }
175+
115176 // ========== Header via Interceptors ==========
116177
117178 @ Test
@@ -133,7 +194,7 @@ public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
133194 assertUserAgentContains (SDK_USER_AGENT_PREFIX );
134195 }
135196
136- // ========== Edge Case Tests ==========
197+ // ========== API Name Handling Tests ==========
137198
138199 @ Test
139200 void executeRequest_withCustomUserAgentAndApiName_shouldNotAppendApiName () {
@@ -155,12 +216,8 @@ void executeRequest_withoutCustomUserAgentAndWithApiName_shouldAppendApiName() {
155216 assertUserAgentContains (TEST_API_NAME + "/" + TEST_API_VERSION );
156217 }
157218
158- /**
159- * Verifies that null User-Agent list throws NullPointerException.
160- *
161- * <p>This ensures the SDK fails fast with clear error rather than allowing
162- * invalid configuration.
163- */
219+ // ========== Edge Case Tests ==========
220+
164221 @ Test
165222 void buildClient_withNullListUserAgent_shouldThrowNullPointerException () {
166223 assertThatThrownBy (() -> clientWithCustomUserAgentList (null ))
@@ -195,17 +252,40 @@ void executeRequest_withNullStringUserAgent_shouldStoreAsSdkUserAgent() {
195252 .hasSize (1 )
196253 .allSatisfy (ua -> {
197254 assertThat (ua ).isNull ();
198-
199255 });
200256 }
201257
258+ @ Test
259+ void executeRequest_withRequestLevelEmptyCustomUserAgent_shouldStoreEmptyUserAgent () {
260+ RestJsonEndpointProvidersClient client = defaultClientBuilder ().build ();
261+
262+ assertThatThrownBy (() -> client .allTypes (r -> r
263+ .overrideConfiguration (o -> o .putHeader (USER_AGENT_HEADER , "" ))))
264+ .hasMessageContaining (INTERCEPTOR_STOP_MESSAGE );
265+
266+ assertUserAgentContains ("" );
267+ }
268+
269+ @ Test
270+ void executeRequest_withRequestLevelEmptyListUserAgent_shouldResultInNoUserAgent () {
271+ RestJsonEndpointProvidersClient client = defaultClientBuilder ().build ();
272+
273+ assertThatThrownBy (() -> client .allTypes (r -> r
274+ .overrideConfiguration (o -> o .putHeader (USER_AGENT_HEADER , Collections .emptyList ()))))
275+ .hasMessageContaining (INTERCEPTOR_STOP_MESSAGE );
276+
277+ List <String > userAgentList = getCapturedUserAgentList ();
278+ assertThat (userAgentList ).isNull ();
279+ }
280+
281+ // ========== Helper Methods ==========
282+
202283 private void assertUserAgentContains (String expected ) {
203284 assertThat (getCapturedUserAgent ()).contains (expected );
204285 }
205286
206287 private void executeRequestExpectingInterception (RestJsonEndpointProvidersClient client ) {
207- assertThatThrownBy (() -> client .allTypes (r -> {
208- }))
288+ assertThatThrownBy (() -> client .allTypes (r -> {}))
209289 .hasMessageContaining (INTERCEPTOR_STOP_MESSAGE );
210290 }
211291
0 commit comments