diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c2ff4300..e2a418592b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a bug where the hash alias in typescript wasn't being generated uniformly for similar interfaces [microsoftgraph/msgraph-beta-sdk-typescript#84](https://github.com/microsoftgraph/msgraph-beta-sdk-typescript/issues/84) - Fixes a bug where name collisions would occur in the Typescript refiner if model name also exists with the `Interface` suffix [#4382](https://github.com/microsoft/kiota/issues/4382) - Fixes a bug where paths without operationIds would not be included in the generated plugins and ensured operationIds are cleaned up [#4642](https://github.com/microsoft/kiota/issues/4642) +- Fixes a bug where models would be duplicated in some allOf scenarios [#4191](https://github.com/microsoft/kiota/issues/4191) - Fixes a bug where CLI Generation does not handle path parameters of type "string" and format "date", "date-time", "time", etc. [#4615](https://github.com/microsoft/kiota/issues/4615) ## [1.14.0] - 2024-05-02 diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index fc1c9caac9..0275f5bd50 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -1595,12 +1595,6 @@ private CodeClass CreateInheritedModelDeclaration(OpenApiUrlTreeNode currentNode { var flattenedAllOfs = schema.AllOf.FlattenSchemaIfRequired(static x => x.AllOf).ToArray(); var referenceId = schema.Reference?.Id; - var className = (schema.GetSchemaName(true) is string cName && !string.IsNullOrEmpty(cName) ? - cName : - (!string.IsNullOrEmpty(typeNameForInlineSchema) ? - typeNameForInlineSchema : - currentNode.GetClassName(config.StructuredMimeTypes, operation: operation, suffix: classNameSuffix, schema: schema, requestBody: isRequestBody))) - .CleanupSymbolName(); var shortestNamespaceName = GetModelsNamespaceNameFromReferenceId(referenceId); var codeNamespaceFromParent = GetShortestNamespace(codeNamespace, schema); if (rootNamespace is null) @@ -1609,6 +1603,12 @@ private CodeClass CreateInheritedModelDeclaration(OpenApiUrlTreeNode currentNode var inlineSchema = Array.Find(flattenedAllOfs, static x => !x.IsReferencedSchema()); var referencedSchema = Array.Find(flattenedAllOfs, static x => x.IsReferencedSchema()); var rootSchemaHasProperties = schema.HasAnyProperty(); + var className = (schema.GetSchemaName(schema.IsSemanticallyMeaningful()) is string cName && !string.IsNullOrEmpty(cName) ? + cName : + (!string.IsNullOrEmpty(typeNameForInlineSchema) ? + typeNameForInlineSchema : + currentNode.GetClassName(config.StructuredMimeTypes, operation: operation, suffix: classNameSuffix, schema: schema, requestBody: isRequestBody))) + .CleanupSymbolName(); var codeDeclaration = (rootSchemaHasProperties, inlineSchema, referencedSchema) switch { // greatest parent type diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 1032c91c52..1229f61547 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -7400,6 +7400,85 @@ public async Task InheritanceWithAllOfInBaseType() Assert.NotNull(codeModel.FindChildByName("Group")); } [Fact] + public async Task InlineSchemaWithSingleAllOfReference() + { + var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + await using var fs = await GetDocumentStream(@"openapi: 3.0.1 +info: + title: OData Service for namespace microsoft.graph + description: This OData service is located at https://graph.microsoft.com/v1.0 + version: 1.0.1 +servers: + - url: https://graph.microsoft.com/v1.0 +paths: + /user: + get: + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/microsoft.graph.user' + /group/members: + get: + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/microsoft.graph.member' +components: + schemas: + microsoft.graph.directoryObject: + required: ['@odata.type'] + properties: + '@odata.type': + type: 'string' + default: '#microsoft.graph.directoryObject' + discriminator: + propertyName: '@odata.type' + mapping: + '#microsoft.graph.group': '#/components/schemas/microsoft.graph.group' + microsoft.graph.group: + allOf: + - '$ref': '#/components/schemas/microsoft.graph.directoryObject' + - title: 'group' + type: 'object' + properties: + groupprop: + type: 'string' + microsoft.graph.member: + type: 'object' + properties: + group: + allOf: + - '$ref': '#/components/schemas/microsoft.graph.group' + microsoft.graph.user: + properties: + groups: + type: array + items: + - '$ref': '#/components/schemas/microsoft.graph.group'"); + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient); + var document = await builder.CreateOpenApiDocumentAsync(fs); + var node = builder.CreateUriSpace(document); + var codeModel = builder.CreateSourceModel(node); + var memberClass = codeModel.FindChildByName("member"); + Assert.NotNull(memberClass); + Assert.Equal(2, memberClass.Properties.Count());// single prop plus additionalData + Assert.Null(memberClass.StartBlock.Inherits);//no base + var userClass = codeModel.FindChildByName("user"); + Assert.NotNull(userClass); + Assert.Equal(2, userClass.Properties.Count());// single prop plus additionalData + Assert.Null(userClass.StartBlock.Inherits);//no base + var inlinedClassThatIsDuplicate = codeModel.FindChildByName("member_group"); + Assert.Null(inlinedClassThatIsDuplicate);//no duplicate + var modelsNamespace = codeModel.FindChildByName("ApiSdk.models.microsoft.graph"); + Assert.NotNull(modelsNamespace); + Assert.Equal(4, modelsNamespace.Classes.Count());// only 4 classes for user, member, group and directoryObject + } + [Fact] public async Task InheritanceWithAllOfWith3Parts3SchemaChildClass() { var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());