From 360ee5c1ab82ad4d5de9c7781d0c57a33b1fbd26 Mon Sep 17 00:00:00 2001 From: jolov Date: Wed, 18 Mar 2026 21:18:15 -0700 Subject: [PATCH 1/3] Fix authenticationPolicy not used in internal ctor and skip settings for internal clients Bug 1: When no auth is configured, the internal constructor accepted an authenticationPolicy parameter but never included it in the pipeline policies. Fixed by checking only authPolicyParam != null instead of requiring authFields != null too. Bug 2: When ClientOptions is internal, skip generating ClientSettings entirely rather than generating a settings class with accessibility mismatches. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/Providers/ClientProvider.cs | 7 +++++-- .../MultiServiceClient_GeneratesExpectedClient.cs | 2 +- ...viceClient_WithThreeServices_GeneratesExpectedClient.cs | 2 +- .../MultiServiceCombinedClient_GeneratesExpectedClient.cs | 2 +- ...inedClient_WithThreeServices_GeneratesExpectedClient.cs | 2 +- ...uctors_PrimaryConstructor(WithDefault,False,False,0).cs | 2 +- ...ctors_PrimaryConstructor(WithRequired,False,False,0).cs | 2 +- .../ValidateConstructorsWhenUnsupportedAuth.cs | 2 +- .../TestData/ClientProviderTests/XmlDocsAreWritten.cs | 4 ++-- 9 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs index a296420f62f..1319fbeb9d6 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs @@ -105,7 +105,10 @@ public ClientProvider(InputClient inputClient) _publicCtorDescription = $"Initializes a new instance of {Name}."; ClientOptions = _inputClient.Parent is null ? ClientOptionsProvider.CreateClientOptionsProvider(_inputClient, this) : null; ClientOptionsParameter = ClientOptions != null ? ScmKnownParameters.ClientOptions(ClientOptions.Type) : null; - ClientSettings = ClientOptions != null ? new ClientSettingsProvider(_inputClient, this) : null; + ClientSettings = ClientOptions != null + && DeclarationModifiers.HasFlag(TypeSignatureModifiers.Public) + && !ClientOptions.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Internal) + ? new ClientSettingsProvider(_inputClient, this) : null; IsMultiServiceClient = _inputClient.IsMultiServiceClient; var apiKey = _inputAuth?.ApiKey; @@ -916,7 +919,7 @@ private MethodBodyStatement[] BuildPrimaryConstructorBody(IReadOnlyList(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); + Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); _serviceAApiVersion = options.ServiceAApiVersion; _serviceBApiVersion = options.ServiceBApiVersion; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceClient_WithThreeServices_GeneratesExpectedClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceClient_WithThreeServices_GeneratesExpectedClient.cs index 54206fc6ffb..818e21ea570 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceClient_WithThreeServices_GeneratesExpectedClient.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceClient_WithThreeServices_GeneratesExpectedClient.cs @@ -39,7 +39,7 @@ internal TestClient(global::System.ClientModel.Primitives.AuthenticationPolicy a _endpoint = endpoint; _subscriptionId = subscriptionId; - Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); + Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); _serviceComputeApiVersion = options.ServiceComputeApiVersion; _serviceKeyVaultApiVersion = options.ServiceKeyVaultApiVersion; _serviceStorageApiVersion = options.ServiceStorageApiVersion; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_GeneratesExpectedClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_GeneratesExpectedClient.cs index 1bd204e71e8..9e13afc14ea 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_GeneratesExpectedClient.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_GeneratesExpectedClient.cs @@ -31,7 +31,7 @@ internal TestClient(global::System.ClientModel.Primitives.AuthenticationPolicy a options ??= new global::Sample.TestClientOptions(); _endpoint = endpoint; - Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); + Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); _serviceAApiVersion = options.ServiceAApiVersion; _serviceBApiVersion = options.ServiceBApiVersion; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_WithThreeServices_GeneratesExpectedClient.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_WithThreeServices_GeneratesExpectedClient.cs index a5520eb71c1..eac8c763bd9 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_WithThreeServices_GeneratesExpectedClient.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/MultiServiceCombinedClient_WithThreeServices_GeneratesExpectedClient.cs @@ -32,7 +32,7 @@ internal TestClient(global::System.ClientModel.Primitives.AuthenticationPolicy a options ??= new global::Sample.TestClientOptions(); _endpoint = endpoint; - Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); + Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); _serviceComputeApiVersion = options.ServiceComputeApiVersion; _serviceKeyVaultApiVersion = options.ServiceKeyVaultApiVersion; _serviceStorageApiVersion = options.ServiceStorageApiVersion; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithDefault,False,False,0).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithDefault,False,False,0).cs index bc5bbc28eac..579690c23a0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithDefault,False,False,0).cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithDefault,False,False,0).cs @@ -3,4 +3,4 @@ options ??= new global::Sample.TestClientOptions(); _endpoint = endpoint; -Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); +Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithRequired,False,False,0).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithRequired,False,False,0).cs index bc5bbc28eac..579690c23a0 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithRequired,False,False,0).cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/TestBuildConstructors_PrimaryConstructor(WithRequired,False,False,0).cs @@ -3,4 +3,4 @@ options ??= new global::Sample.TestClientOptions(); _endpoint = endpoint; -Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); +Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/ValidateConstructorsWhenUnsupportedAuth.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/ValidateConstructorsWhenUnsupportedAuth.cs index 60e6d68058d..a9933b7eedf 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/ValidateConstructorsWhenUnsupportedAuth.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/ValidateConstructorsWhenUnsupportedAuth.cs @@ -20,7 +20,7 @@ internal TestClient(global::System.ClientModel.Primitives.AuthenticationPolicy a options ??= new global::Sample.TestClientOptions(); _endpoint = endpoint; - Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); + Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); } internal TestClient(global::System.Uri endpoint, global::Sample.TestClientOptions options) : this(null, endpoint, options) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/XmlDocsAreWritten.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/XmlDocsAreWritten.cs index 5e455f24f4c..ade621ea51e 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/XmlDocsAreWritten.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/TestData/ClientProviderTests/XmlDocsAreWritten.cs @@ -1,4 +1,4 @@ -// +// #nullable disable @@ -44,7 +44,7 @@ internal TestClient(global::System.ClientModel.Primitives.AuthenticationPolicy a _endpoint = endpoint; _queryParam = queryParam; - Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly) }, Array.Empty()); + Pipeline = global::System.ClientModel.Primitives.ClientPipeline.Create(options, Array.Empty(), new global::System.ClientModel.Primitives.PipelinePolicy[] { new global::System.ClientModel.Primitives.UserAgentPolicy(typeof(global::Sample.TestClient).Assembly), authenticationPolicy }, Array.Empty()); } /// Initializes a new instance of TestClient. From d2e5946b944210627e33fc9b93ace423ac0f85d1 Mon Sep 17 00:00:00 2001 From: jolov Date: Thu, 19 Mar 2026 09:08:22 -0700 Subject: [PATCH 2/3] Remove redundant ClientOptions internal check The client-level public check is sufficient; if the client is internal, settings are already skipped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/Providers/ClientProvider.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs index fa3b7b4051b..0904a1205bd 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ClientProvider.cs @@ -109,7 +109,6 @@ public ClientProvider(InputClient inputClient) bool isIndividuallyInitialized = (_inputClient.InitializedBy & InputClientInitializedBy.Individually) != 0; ClientSettings = isIndividuallyInitialized && DeclarationModifiers.HasFlag(TypeSignatureModifiers.Public) - && (ClientOptions == null || !ClientOptions.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Internal)) ? new ClientSettingsProvider(_inputClient, this) : null; IsMultiServiceClient = _inputClient.IsMultiServiceClient; From 661af11bb34a8a6e5fdd543b89f1cad21805084a Mon Sep 17 00:00:00 2001 From: jolov Date: Thu, 19 Mar 2026 09:10:54 -0700 Subject: [PATCH 3/3] Add test assertions for ClientSettings not generated on internal clients Verify that ClientSettings is null when the client is customized to be internal, in both CanChangeClientAccessibility and CanChangeClientOptionsAccessibility tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../ClientProviders/ClientProviderCustomizationTests.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderCustomizationTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderCustomizationTests.cs index c7d924e8747..0b8620ee7ab 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderCustomizationTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/ClientProviders/ClientProviderCustomizationTests.cs @@ -228,6 +228,10 @@ public async Task CanChangeClientAccessibility() // The client options were not customized Assert.IsTrue(clientOptionsProvider!.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Public)); + // ClientSettings should not be generated for internal clients + Assert.IsNull(((ClientProvider)clientProvider).ClientSettings, + "Internal client should not have ClientSettings generated"); + // The docs should be generated even when then methods is internal foreach (var method in clientProvider.Methods) { @@ -265,6 +269,10 @@ public async Task CanChangeClientOptionsAccessibility() // The client options were not customized Assert.IsTrue(clientOptionsProvider!.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Internal)); + // ClientSettings should not be generated for internal clients + Assert.IsNull(((ClientProvider)clientProvider).ClientSettings, + "Internal client should not have ClientSettings generated"); + // The docs should be generated even when then methods is internal foreach (var method in clientProvider.Methods) {