From 2960f2b9f103dc990545e8727ccc080bd1195137 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 3 Dec 2024 08:24:43 -0500 Subject: [PATCH 01/45] chore/tasks linting (#2176) * chore: removes extraneous project * chore: aligns task usage * chore: additional tasks linting Signed-off-by: Vincent Biret * fix: lock implementation for cache access Signed-off-by: Vincent Biret * fix: converts uri matching service to net8 * fix: wrong dependency for tasks analysis * feat: adds analyzers to test projects * Refactor: Combine async function call and await into one line for improved readability * fix: bad merge version regression * add analyser dependency. * use async lazy to alleviate network async failures. * use async overloads for the lazy * chore: fixes timeouts in PS generation. updates dependencies and cleans up PR --------- Signed-off-by: Vincent Biret Co-authored-by: Millicent Achieng Co-authored-by: Andrew Omondi --- .../CodeSnippetsPipeline.Test.csproj | 4 + .../CodeSnippetsReflection.App.csproj | 4 + CodeSnippetsReflection.App/Program.cs | 47 ++- .../CodeSnippetsReflection.OData.Test.csproj | 4 + .../CommonGeneratorShould.cs | 56 ++- .../JavascriptGeneratorShould.cs | 19 +- .../SnippetsModelShould.cs | 58 ++- .../CodeSnippetsReflection.OData.csproj | 5 + .../LanguageGenerators/CommonGenerator.cs | 4 +- .../ODataSnippetsGenerator.cs | 46 ++- CodeSnippetsReflection.OData/SnippetModel.cs | 1 - .../CSharpGeneratorTests.cs | 308 +++++++++------- ...CodeSnippetsReflection.OpenAPI.Test.csproj | 4 + .../GoGeneratorTests.cs | 211 ++++++----- .../GraphCliGeneratorTests.cs | 119 ++++--- .../JavaGeneratorTests.cs | 295 +++++++++------ .../OpenApiSnippetGeneratorTestBase.cs | 24 +- .../OpenApiSnippetsGeneratortTests.cs | 13 +- .../PhpGeneratorTests.cs | 215 ++++++----- .../PhpImportGeneratorTests.cs | 15 +- .../PowerShellGeneratorTests.cs | 237 ++++++++----- .../PythonGeneratorTests.cs | 335 +++++++++++------- .../PythonImportGeneratorTests.cs | 30 +- .../SimpleLazyTest.cs | 67 ---- .../SnippetCodeGraphTests.cs | 128 ++++--- .../SnippetImportTests.cs | 15 +- .../SnippetModelTests.cs | 28 +- .../TypeScriptGeneratorTest.cs | 120 ++++--- .../CodeSnippetsReflection.OpenAPI.csproj | 7 +- .../LanguageGenerators/PhpGenerator.cs | 3 +- .../LanguageGenerators/PowerShellGenerator.cs | 22 +- .../LanguageGenerators/PythonGenerator.cs | 3 +- .../ModelGraph/SnippetCodeGraph.cs | 2 - .../OpenAPISnippetsGenerator.cs | 51 ++- .../PowerShellCommandInfo.cs | 2 +- CodeSnippetsReflection.OpenAPI/SimpleLazy.cs | 40 --- .../SnippetModel.cs | 1 - .../CodeSnippetsReflection.csproj | 7 + CodeSnippetsReflection/ISnippetsGenerator.cs | 5 +- CodeSnippetsReflection/SnippetBaseModel.cs | 11 +- .../ExceptionMiddleware.Test.csproj | 4 + .../ExceptionMiddlewareShould.cs | 24 +- FileService.Test/FileService.Test.csproj | 4 + FileService.Test/HttpClientUtilityShould.cs | 4 +- FileService/FileService.csproj | 4 + FileService/Interfaces/IFileUtility.cs | 4 +- .../Services/AzureBlobStorageUtility.cs | 4 +- FileService/Services/DiskFileUtility.cs | 4 +- .../Controllers/KnownIssuesController.cs | 2 +- GraphWebApi/Controllers/OpenApiController.cs | 10 +- .../Controllers/PermissionsController.cs | 4 +- GraphWebApi/Controllers/SnippetsController.cs | 4 +- GraphWebApi/GraphWebApi.csproj | 8 +- GraphWebApi/Program.cs | 2 +- .../KnownIssuesService.Test.csproj | 10 +- .../KnownIssuesServiceShould.cs | 6 +- KnownIssuesService/KnownIssuesService.csproj | 4 + MockTestUtility/FileUtilityMock.cs | 6 +- MockTestUtility/MockTestUtility.csproj | 10 +- .../OpenAPIService.Test.csproj | 8 +- OpenAPIService.Test/OpenAPIServiceShould.cs | 9 +- OpenAPIService/Interfaces/IOpenApiService.cs | 2 +- OpenAPIService/OpenAPIService.csproj | 8 +- OpenAPIService/OpenApiService.cs | 4 +- .../PermissionsService.Test.csproj | 4 + .../PermissionsStoreShould.cs | 36 +- PermissionsService/PermissionsService.csproj | 7 +- .../Services/PermissionsStore.cs | 150 ++++---- .../SamplesService.Test.csproj | 6 +- SamplesService.Test/SamplesStoreShould.cs | 8 +- SamplesService/SamplesService.csproj | 5 + SamplesService/Services/SamplesStore.cs | 69 ++-- .../CustomPIIFilterShould.cs | 28 +- .../TelemetrySanitizerService.Test.csproj | 4 + TelemetryService/CustomPIIFilter.cs | 15 +- .../TelemetrySanitizerService.csproj | 4 + .../UriMatchingService.Test.csproj | 4 + UriMatchService/UriMatchService.csproj | 7 - UriMatchService/UriMatchingService.csproj | 9 +- .../UtilityService.Test.csproj | 4 + UtilityService/UtilityService.csproj | 4 + apidoctor | 2 +- 82 files changed, 1773 insertions(+), 1308 deletions(-) delete mode 100644 CodeSnippetsReflection.OpenAPI.Test/SimpleLazyTest.cs delete mode 100644 CodeSnippetsReflection.OpenAPI/SimpleLazy.cs delete mode 100644 UriMatchService/UriMatchService.csproj diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index f9cbc609d..4b609e19f 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -10,6 +10,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj b/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj index 59556c480..70bb3e625 100644 --- a/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj +++ b/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj @@ -8,6 +8,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/CodeSnippetsReflection.App/Program.cs b/CodeSnippetsReflection.App/Program.cs index 7741111bc..544271aea 100644 --- a/CodeSnippetsReflection.App/Program.cs +++ b/CodeSnippetsReflection.App/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Text; @@ -24,7 +25,7 @@ namespace CodeSnippetsReflection.App /// class Program { - static void Main(string[] args) + static async Task Main(string[] args) { IConfiguration config = new ConfigurationBuilder() .AddCommandLine(args) @@ -36,7 +37,7 @@ static void Main(string[] args) var generationArg = config.GetSection("Generation"); if (!snippetsPathArg.Exists() || !languagesArg.Exists()) { - Console.Error.WriteLine("Http snippets directory and languages should be specified"); + await Console.Error.WriteLineAsync("Http snippets directory and languages should be specified"); Console.WriteLine(@"Example usage: .\CodeSnippetReflection.App.exe --SnippetsPath C:\snippets --Languages c#,javascript --Generation odata|openapi"); return; @@ -45,13 +46,13 @@ static void Main(string[] args) var httpSnippetsDir = snippetsPathArg.Value; if (!Directory.Exists(httpSnippetsDir)) { - Console.Error.WriteLine($@"Directory {httpSnippetsDir} does not exist!"); + await Console.Error.WriteLineAsync($@"Directory {httpSnippetsDir} does not exist!"); return; } if (customMetadataPathArg.Exists() && !File.Exists(customMetadataPathArg.Value)) { - Console.Error.WriteLine($@"Metadata file {customMetadataPathArg.Value} does not exist!"); + await Console.Error.WriteLineAsync($@"Metadata file {customMetadataPathArg.Value} does not exist!"); return; } @@ -67,12 +68,12 @@ static void Main(string[] args) .GroupBy(l => ODataSnippetsGenerator.SupportedLanguages.Contains(l) || OpenApiSnippetsGenerator.SupportedLanguages.Contains(l)) .ToDictionary(g => g.Key, g => g.ToList()); - var supportedLanguages = languageGroups.ContainsKey(true) ? languageGroups[true] : null; - var unsupportedLanguages = languageGroups.ContainsKey(false) ? languageGroups[false] : null; + var supportedLanguages = languageGroups.GetValueOrDefault(true, null); + var unsupportedLanguages = languageGroups.GetValueOrDefault(false, null); if (supportedLanguages == null) { - Console.Error.WriteLine($"None of the given languages are supported. Supported languages: {string.Join(" ", ODataSnippetsGenerator.SupportedLanguages)}"); + await Console.Error.WriteLineAsync($"None of the given languages are supported. Supported languages: {string.Join(" ", ODataSnippetsGenerator.SupportedLanguages)}"); return; } @@ -94,18 +95,15 @@ static void Main(string[] args) // cache the generators by generation rather than creating a new one on each generation to avoid multiple loads of the metadata. var snippetGenerators = new ConcurrentDictionary(); - Parallel.ForEach(supportedLanguages, language => + await Task.WhenAll(supportedLanguages.Select(language => { //Generation will still be originalGeneration if language is java since it is not stable //Remove the condition when java is stable generation = (OpenApiSnippetsGenerator.SupportedLanguages.Contains(language)) ? "openapi" : originalGeneration; var generator = snippetGenerators.GetOrAdd(generation, generationKey => GetSnippetsGenerator(generationKey, customMetadataPathArg)); - Parallel.ForEach(files, file => - { - ProcessFile(generator, language, file); - }); - }); + return files.Select(file => ProcessFileAsync(generator, language, file)); + }).SelectMany(static t => t)); Console.WriteLine($"Processed {files.Count()} files."); } @@ -118,43 +116,38 @@ private static ISnippetsGenerator GetSnippetsGenerator(string generation, IConfi }; } - private static void ProcessFile(ISnippetsGenerator generator, string language, string file) + private static async Task ProcessFileAsync(ISnippetsGenerator generator, string language, string file) { // convert http request into a type that works with SnippetGenerator.ProcessPayloadRequest() // we are not altering the types as it should continue serving the HTTP endpoint as well - using var streamContent = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(File.ReadAllText(file)))); + using var streamContent = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes(await File.ReadAllTextAsync(file)))); streamContent.Headers.Add("Content-Type", "application/http;msgtype=request"); string snippet; var filePath = file.Replace("-httpSnippet", $"---{language.ToLowerInvariant()}"); try { - // This is a very fast operation, it is fine to make is synchronuous. - // With the parallel foreach in the main method, processing all snippets for C# in both Beta and V1 takes about 7 seconds. - // As of this writing, the code was processing 2650 snippets - // Using async-await is costlier as this operation is all in-memory and task creation and scheduling overhead is high for that. - // With async-await, the same operation takes 1 minute 7 seconds. - using var message = streamContent.ReadAsHttpRequestMessageAsync().Result; - snippet = generator.ProcessPayloadRequest(message, language); + using var message = await streamContent.ReadAsHttpRequestMessageAsync(); + snippet = await generator.ProcessPayloadRequestAsync(message, language); } catch (Exception e) { var message = $"Exception while processing {file}.{Environment.NewLine}{e.Message}{Environment.NewLine}{e.StackTrace}"; - Console.Error.WriteLine(message); - File.WriteAllText(filePath + "-error", message); + await Console.Error.WriteLineAsync(message); + await File.WriteAllTextAsync(filePath + "-error", message); return; } if (!string.IsNullOrWhiteSpace(snippet)) { Console.WriteLine($"Writing snippet: {filePath}"); - File.WriteAllText(filePath, snippet); + await File.WriteAllTextAsync(filePath, snippet); } else { var message = $"Failed to generate {language} snippets for {file}."; - File.WriteAllText(filePath + "-error", message); - Console.Error.WriteLine(message); + await File.WriteAllTextAsync(filePath + "-error", message); + await Console.Error.WriteLineAsync(message); } } } diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index fb17ed9b0..44308bafa 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -13,6 +13,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/CodeSnippetsReflection.OData.Test/CommonGeneratorShould.cs b/CodeSnippetsReflection.OData.Test/CommonGeneratorShould.cs index 627dc506f..4c708b276 100644 --- a/CodeSnippetsReflection.OData.Test/CommonGeneratorShould.cs +++ b/CodeSnippetsReflection.OData.Test/CommonGeneratorShould.cs @@ -7,6 +7,7 @@ using System.Xml; using Microsoft.OData.UriParser; using Xunit; +using System.Threading.Tasks; namespace CodeSnippetsReflection.Test { @@ -19,13 +20,14 @@ public class CommonGeneratorShould #region Test GenerateQuerySection [Fact] - public void GenerateQuerySection_ShouldReturnEmptyStringIfQueryListIsEmpty() + public async Task GenerateQuerySection_ShouldReturnEmptyStringIfQueryListIsEmptyAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); //no query present var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/drive/root"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -35,13 +37,14 @@ public void GenerateQuerySection_ShouldReturnEmptyStringIfQueryListIsEmpty() } [Fact] - public void GenerateQuerySection_ShouldReturnAppropriateJavascriptSelectExpression() + public async Task GenerateQuerySection_ShouldReturnAppropriateJavascriptSelectExpressionAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); //no query present var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/users/{id}?$select=displayName,givenName,postalCode"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -51,13 +54,14 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptSelectExpressi } [Fact] - public void GenerateQuerySection_ShouldReturnAppropriateJavascriptFilterExpression() + public async Task GenerateQuerySection_ShouldReturnAppropriateJavascriptFilterExpressionAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); //no query present var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/users?$filter=startswith(givenName, 'J')"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -67,13 +71,14 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptFilterExpressi } [Fact] - public void GenerateQuerySection_ShouldReturnAppropriateJavascriptSearchExpression() + public async Task GenerateQuerySection_ShouldReturnAppropriateJavascriptSearchExpressionAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); //no query present var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/people/?$search=\"Irene McGowen\""); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -83,13 +88,14 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptSearchExpressi } [Fact] - public void GenerateQuerySection_ShouldReturnAppropriateJavascriptSkipExpression() + public async Task GenerateQuerySection_ShouldReturnAppropriateJavascriptSkipExpressionAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); //no query present var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/events?$skip=20"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -99,13 +105,14 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptSkipExpression } [Fact] - public void GenerateQuerySection_ShouldReturnAppropriateJavascriptTopExpression() + public async Task GenerateQuerySection_ShouldReturnAppropriateJavascriptTopExpressionAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); //no query present var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/events?$top=5"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -115,7 +122,7 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptTopExpression( } [Fact] - public void GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderExpression() + public async Task GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderExpressionAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -124,6 +131,7 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderE requestPayload.Headers.Add("Prefer", "kenya-timezone"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -133,7 +141,7 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderE } [Fact] - public void GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderExpressionWithEscapedDoubleQuotes() + public async Task GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderExpressionWithEscapedDoubleQuotesAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -142,6 +150,7 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderE requestPayload.Headers.Add("Prefer", "outlook.timezone=\"Pacific Standard Time\""); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var result = CommonGenerator.GenerateQuerySection(snippetModel, expressions); @@ -154,7 +163,7 @@ public void GenerateQuerySection_ShouldReturnAppropriateJavascriptRequestHeaderE #region Test GetEdmTypeFromIdentifier [Fact] - public void GetClassNameFromIdentifier_ShouldReturnRootIdentifierOnFirstSearch() + public async Task GetClassNameFromIdentifier_ShouldReturnRootIdentifierOnFirstSearchAsync() { //Arrange List path = new List @@ -164,6 +173,7 @@ public void GetClassNameFromIdentifier_ShouldReturnRootIdentifierOnFirstSearch() var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/people"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var commonGenerator = new CommonGenerator(_edmModel); @@ -174,7 +184,7 @@ public void GetClassNameFromIdentifier_ShouldReturnRootIdentifierOnFirstSearch() } [Fact] - public void GetClassNameFromIdentifier_ShouldReturnParameterTypeForActionOrFunction() + public async Task GetClassNameFromIdentifier_ShouldReturnParameterTypeForActionOrFunctionAsync() { //Arrange List path = new List @@ -184,6 +194,7 @@ public void GetClassNameFromIdentifier_ShouldReturnParameterTypeForActionOrFunct var requestPayload = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/me/sendMail"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var commonGenerator = new CommonGenerator(_edmModel); @@ -194,7 +205,7 @@ public void GetClassNameFromIdentifier_ShouldReturnParameterTypeForActionOrFunct } [Fact] - public void GetClassNameFromIdentifier_ShouldSearchForOneLevelNestedType() + public async Task GetClassNameFromIdentifier_ShouldSearchForOneLevelNestedTypeAsync() { //Arrange List path = new List @@ -205,6 +216,7 @@ public void GetClassNameFromIdentifier_ShouldSearchForOneLevelNestedType() var requestPayload = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/me/messages"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var commonGenerator = new CommonGenerator(_edmModel); @@ -235,7 +247,7 @@ public void GetClassNameFromIdentifier_ShouldFindSubclassProperties() } [Fact] - public void GetClassNameFromIdentifier_ShouldSearchForOneLevelNestedType_2() + public async Task GetClassNameFromIdentifier_ShouldSearchForOneLevelNestedType_2Async() { //Arrange List path = new List @@ -246,6 +258,7 @@ public void GetClassNameFromIdentifier_ShouldSearchForOneLevelNestedType_2() var requestPayload = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/me/messages"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var commonGenerator = new CommonGenerator(_edmModel); @@ -257,7 +270,7 @@ public void GetClassNameFromIdentifier_ShouldSearchForOneLevelNestedType_2() } [Fact] - public void GetClassNameFromIdentifier_ShouldSearchForTwoLevelNestedType() + public async Task GetClassNameFromIdentifier_ShouldSearchForTwoLevelNestedTypeAsync() { //Arrange List path = new List @@ -269,6 +282,7 @@ public void GetClassNameFromIdentifier_ShouldSearchForTwoLevelNestedType() var requestPayload = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/me/messages"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var commonGenerator = new CommonGenerator(_edmModel); @@ -279,7 +293,7 @@ public void GetClassNameFromIdentifier_ShouldSearchForTwoLevelNestedType() } [Fact] - public void GetClassNameFromIdentifier_ShouldSearchForTwoLevelNestedType_2() + public async Task GetClassNameFromIdentifier_ShouldSearchForTwoLevelNestedType_2Async() { //Arrange List path = new List @@ -291,6 +305,7 @@ public void GetClassNameFromIdentifier_ShouldSearchForTwoLevelNestedType_2() var requestPayload = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/me/events"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act var commonGenerator = new CommonGenerator(_edmModel); @@ -314,17 +329,17 @@ public void EnsureVariableNameIsNotReserved_AppendsUnderscoreOnJavascriptKeyword //Assert Assert.Equal("_transient", result); } - #endregion #region Test GetParameterListFromOperationSegment [Fact] - public void GetParameterListFromOperationSegment_ShouldReturnStringWithDoubleQuotesForOdataActionParameter() + public async Task GetParameterListFromOperationSegment_ShouldReturnStringWithDoubleQuotesForOdataActionParameterAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/drive/items/{id}/workbook/worksheets/{id|name}/range(address='A1:B2')"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); var operationSegment = snippetModel.Segments.Last() as OperationSegment; //Act @@ -335,7 +350,7 @@ public void GetParameterListFromOperationSegment_ShouldReturnStringWithDoubleQuo } [Fact] - public void GetParameterListFromOperationSegment_ShouldReturnParameterListOrderedByOptionality() + public async Task GetParameterListFromOperationSegment_ShouldReturnParameterListOrderedByOptionalityAsync() { //Arrange const string jsonObject = "{\r\n " + @@ -347,6 +362,7 @@ public void GetParameterListFromOperationSegment_ShouldReturnParameterListOrdere Content = new StringContent(jsonObject) }; var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); var operationSegment = snippetModel.Segments.Last() as OperationSegment; //Act @@ -358,7 +374,7 @@ public void GetParameterListFromOperationSegment_ShouldReturnParameterListOrdere } [Fact] - public void GetParameterListFromOperationSegment_ShouldReturnParameterListOrderedByMetadataReference() + public async Task GetParameterListFromOperationSegment_ShouldReturnParameterListOrderedByMetadataReferenceAsync() { //Arrange const string jsonObject = "{\r\n " + @@ -370,6 +386,7 @@ public void GetParameterListFromOperationSegment_ShouldReturnParameterListOrdere Content = new StringContent(jsonObject) }; var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); var operationSegment = snippetModel.Segments.Last() as OperationSegment; //Act @@ -381,7 +398,7 @@ public void GetParameterListFromOperationSegment_ShouldReturnParameterListOrdere } [Fact] - public void GetParameterListFromOperationSegment_ShouldSetOptionalUnprovidedParameterToNull() + public async Task GetParameterListFromOperationSegment_ShouldSetOptionalUnprovidedParameterToNullAsync() { //Arrange const string jsonObject = "{\r\n " + @@ -392,6 +409,7 @@ public void GetParameterListFromOperationSegment_ShouldSetOptionalUnprovidedPara Content = new StringContent(jsonObject) }; var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); var operationSegment = snippetModel.Segments.Last() as OperationSegment; //Act diff --git a/CodeSnippetsReflection.OData.Test/JavascriptGeneratorShould.cs b/CodeSnippetsReflection.OData.Test/JavascriptGeneratorShould.cs index 2bb4b5a9b..53cdb4db4 100644 --- a/CodeSnippetsReflection.OData.Test/JavascriptGeneratorShould.cs +++ b/CodeSnippetsReflection.OData.Test/JavascriptGeneratorShould.cs @@ -1,4 +1,5 @@ using System.Net.Http; +using System.Threading.Tasks; using System.Xml; using CodeSnippetsReflection.OData.LanguageGenerators; using Microsoft.OData.Edm; @@ -15,7 +16,7 @@ public class JavascriptGeneratorShould [Fact] //This tests asserts that we can generate snippets from json objects with nested objects inside them. - public void GeneratesCorrectCreateCalendarEventJavascriptSnippet() + public async Task GeneratesCorrectCreateCalendarEventJavascriptSnippetAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -52,6 +53,7 @@ public void GeneratesCorrectCreateCalendarEventJavascriptSnippet() Content = new StringContent(userJsonObject) }; var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act by generating the code snippet var result = JavaScriptGenerator.GenerateCodeSnippet(snippetModel, expressions); @@ -94,7 +96,7 @@ public void GeneratesCorrectCreateCalendarEventJavascriptSnippet() [Fact] //This tests asserts that we can generate snippets from json objects with nested objects inside them. - public void GeneratesPostRequestSnippetFromJsonObject() + public async Task GeneratesPostRequestSnippetFromJsonObjectAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -110,6 +112,7 @@ public void GeneratesPostRequestSnippetFromJsonObject() Content = new StringContent(userJsonObject) }; var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act by generating the code snippet var result = JavaScriptGenerator.GenerateCodeSnippet(snippetModel, expressions); @@ -135,7 +138,7 @@ public void GeneratesPostRequestSnippetFromJsonObject() [Fact] //This tests asserts that we can generate snippets from json objects with nested arrays inside them. - public void GeneratesPatchRequestSnippetFromJsonObject() + public async Task GeneratesPatchRequestSnippetFromJsonObjectAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -149,6 +152,7 @@ public void GeneratesPatchRequestSnippetFromJsonObject() Content = new StringContent(userJsonObject) }; var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act by generating the code snippet var result = JavaScriptGenerator.GenerateCodeSnippet(snippetModel, expressions); @@ -170,7 +174,7 @@ public void GeneratesPatchRequestSnippetFromJsonObject() [Fact] //This tests asserts that we can generate snippets with query options present - public void GeneratesSnippetsWithQueryOptions() + public async Task GeneratesSnippetsWithQueryOptionsAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -178,6 +182,7 @@ public void GeneratesSnippetsWithQueryOptions() var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2017-01-01T19:00:00.0000000&endDateTime=2017-01-07T19:00:00.0000000"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act by generating the code snippet var result = JavaScriptGenerator.GenerateCodeSnippet(snippetModel, expressions); @@ -191,7 +196,7 @@ public void GeneratesSnippetsWithQueryOptions() [Fact] // This test asserts that we can generate snippets with @odata properties - public void GenerateSnippetsWithOdataProperties() + public async Task GenerateSnippetsWithOdataPropertiesAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -205,6 +210,7 @@ public void GenerateSnippetsWithOdataProperties() }; var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act by generating the code snippet var result = JavaScriptGenerator.GenerateCodeSnippet(snippetModel, expressions); @@ -223,7 +229,7 @@ public void GenerateSnippetsWithOdataProperties() [Fact] // This test asserts that single quotes inside strings are escaped - public void GenerateSnippetsWithSingleQuotesInsideString() + public async Task GenerateSnippetsWithSingleQuotesInsideStringAsync() { //Arrange LanguageExpressions expressions = new JavascriptExpressions(); @@ -254,6 +260,7 @@ public void GenerateSnippetsWithSingleQuotesInsideString() var betaServiceRootUrl = "https://graph.microsoft.com/beta"; var betaEdmModel = CsdlReader.Parse(XmlReader.Create(CommonGeneratorShould.CleanBetaMetadata)); var snippetModel = new SnippetModel(requestPayload, betaServiceRootUrl, betaEdmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Act by generating the code snippet var result = JavaScriptGenerator.GenerateCodeSnippet(snippetModel, expressions); diff --git a/CodeSnippetsReflection.OData.Test/SnippetsModelShould.cs b/CodeSnippetsReflection.OData.Test/SnippetsModelShould.cs index 4dacf2563..67825e343 100644 --- a/CodeSnippetsReflection.OData.Test/SnippetsModelShould.cs +++ b/CodeSnippetsReflection.OData.Test/SnippetsModelShould.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Net.Http; +using System.Threading.Tasks; using System.Xml; using Microsoft.OData.Edm; using Microsoft.OData.Edm.Csdl; @@ -13,39 +14,42 @@ public class SnippetsModelShould private readonly IEdmModel _edmModel = CsdlReader.Parse(XmlReader.Create(CommonGeneratorShould.CleanV1Metadata)); [Fact] - public void PopulateExpandFieldExpression() + public async Task PopulateExpandFieldExpressionAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/drive/root?$expand=children"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("children", snippetModel.ExpandFieldExpression); } [Fact] - public void PopulateExpandFieldExpressionWithNestedQuery() + public async Task PopulateExpandFieldExpressionWithNestedQueryAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/drive/root?$expand=children($select=id,name)"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("children($select=id,name)", snippetModel.ExpandFieldExpression); } [Fact] - public void PopulateExpandFieldExpressionFromMultipleQueryString() + public async Task PopulateExpandFieldExpressionFromMultipleQueryStringAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/users?$select=id,displayName,mail&$expand=extensions"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("extensions", snippetModel.ExpandFieldExpression); @@ -53,7 +57,7 @@ public void PopulateExpandFieldExpressionFromMultipleQueryString() } [Fact] - public void PopulateExpandFieldExpressionFromReversedMultipleQueryString() + public async Task PopulateExpandFieldExpressionFromReversedMultipleQueryStringAsync() { //Reverse the query structure should still work //Arrange @@ -61,45 +65,49 @@ public void PopulateExpandFieldExpressionFromReversedMultipleQueryString() //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("extensions", snippetModel.ExpandFieldExpression); } [Fact] - public void PopulateFilterListField() + public async Task PopulateFilterListFieldAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/users?$filter=startswith(displayName,'J')"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("startswith(displayName,'J')", snippetModel.FilterFieldList.First()); } [Fact] - public void PopulateOrderByListField() + public async Task PopulateOrderByListFieldAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/users?$orderby=displayName"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("displayName", snippetModel.OrderByFieldList.First()); } [Fact] - public void PopulateSelectListField() + public async Task PopulateSelectListFieldAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/messages?$select=from,subject"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("from", snippetModel.SelectFieldList[0]); @@ -107,20 +115,21 @@ public void PopulateSelectListField() } [Fact] - public void PopulateSearchExpression() + public async Task PopulateSearchExpressionAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/people/?$search=\"Irene McGowen\""); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("Irene McGowen", snippetModel.SearchExpression); } [Fact] - public void PopulateHeadersCollection() + public async Task PopulateHeadersCollectionAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/people/?$search=\"Irene McGowen\""); @@ -128,6 +137,7 @@ public void PopulateHeadersCollection() //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert Assert.Equal("Irene McGowen", snippetModel.SearchExpression); @@ -136,7 +146,7 @@ public void PopulateHeadersCollection() } [Fact] - public void PopulateRequestBody() + public async Task PopulateRequestBodyAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/people/") @@ -146,32 +156,35 @@ public void PopulateRequestBody() //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the request body is empty Assert.Equal("This is just a test", snippetModel.RequestBody); } [Fact] - public void PopulateEmptyStringOnEmptyRequestBody() + public async Task PopulateEmptyStringOnEmptyRequestBodyAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/people/"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the request body is empty Assert.Equal("",snippetModel.RequestBody); } [Fact] - public void PopulatesCustomQueryOptions() + public async Task PopulatesCustomQueryOptionsAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2017-01-01T19:00:00.0000000&endDateTime=2017-01-07T19:00:00.0000000"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the keys and values are as expected Assert.Equal("startDateTime", snippetModel.CustomQueryOptions.First().Key); @@ -182,26 +195,28 @@ public void PopulatesCustomQueryOptions() #region Test ResponseVariableNames [Fact] - public void SetAppropriateVariableNameForPeopleEntity() + public async Task SetAppropriateVariableNameForPeopleEntityAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/people/"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the variable name is "people" for a collection Assert.Equal("people", snippetModel.ResponseVariableName); } [Fact] - public void SetAppropriateVariableNameForUsersList() + public async Task SetAppropriateVariableNameForUsersListAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/users"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the variable name is "users" for the users collection Assert.Equal("users", snippetModel.ResponseVariableName); @@ -209,13 +224,14 @@ public void SetAppropriateVariableNameForUsersList() [Fact] - public void SetAppropriateVariableNameForSingleUser() + public async Task SetAppropriateVariableNameForSingleUserAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/users/{id|userPrincipalName}"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the variable name is "user" for the single user. Assert.Equal("user", snippetModel.ResponseVariableName); @@ -223,52 +239,56 @@ public void SetAppropriateVariableNameForSingleUser() } [Fact] - public void SetAppropriateVariableNameForChildrenItemsInDrive() + public async Task SetAppropriateVariableNameForChildrenItemsInDriveAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0//drives/{drive-id}/items/{item-id}/children"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the variable name is "children" for the collection returned Assert.Equal("children", snippetModel.ResponseVariableName); } [Fact] - public void SetAppropriateVariableNameForCalendarGroups() + public async Task SetAppropriateVariableNameForCalendarGroupsAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me/calendarGroups"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the variable name is "calendarGroups" for the collection returned Assert.Equal("calendarGroups", snippetModel.ResponseVariableName); } [Fact] - public void SetAppropriateVariableNameForEventCreate() + public async Task SetAppropriateVariableNameForEventCreateAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/me/events"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the variable name is "event" (singular) as we are making a post call to create an entity Assert.Equal("event", snippetModel.ResponseVariableName); } [Fact] - public void SetsAppropriateVariableNameForEventUpdate() + public async Task SetsAppropriateVariableNameForEventUpdateAsync() { //Arrange var requestPayload = new HttpRequestMessage(HttpMethod.Patch, "https://graph.microsoft.com/v1.0/groups/{id}/events/{id}"); //Act var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, _edmModel); + await snippetModel.InitializeModelAsync(requestPayload); //Assert that the variable name is "event" for an event update Assert.Equal("event", snippetModel.ResponseVariableName); diff --git a/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj b/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj index 9c4291cfc..739b2db13 100644 --- a/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj +++ b/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj @@ -7,6 +7,11 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/CodeSnippetsReflection.OData/LanguageGenerators/CommonGenerator.cs b/CodeSnippetsReflection.OData/LanguageGenerators/CommonGenerator.cs index 02b9c66e4..2259efb2b 100644 --- a/CodeSnippetsReflection.OData/LanguageGenerators/CommonGenerator.cs +++ b/CodeSnippetsReflection.OData/LanguageGenerators/CommonGenerator.cs @@ -140,7 +140,7 @@ public bool CanGetServiceCollectionNavigationPropertyForProperty(NavigationPrope // Check if its defined directly in an the entitySet var isDirectlyInEntitySet = model.EntityContainer.EntitySets() - .Any(entitySet => entitySet.EntityType().FullName().Equals(navigationPropertyLinkSegment.NavigationProperty.ToEntityType().FullName(), StringComparison.OrdinalIgnoreCase)); + .Any(entitySet => entitySet.EntityType.FullName().Equals(navigationPropertyLinkSegment.NavigationProperty.ToEntityType().FullName(), StringComparison.OrdinalIgnoreCase)); if (isDirectlyInEntitySet) return true; @@ -148,7 +148,7 @@ public bool CanGetServiceCollectionNavigationPropertyForProperty(NavigationPrope // check the navBindings/nav Properties on singletons var isImplicitFromSingleton = model.EntityContainer.Singletons() .SelectMany(singleton => singleton.NavigationPropertyBindings.Select(navPropertyBindings => navPropertyBindings.NavigationProperty)// get the nav propertyBinding from the singleton - .Concat(singleton.EntityType().NavigationProperties())) // Append the nav properties from the singleton type + .Concat(singleton.EntityType.NavigationProperties())) // Append the nav properties from the singleton type .Any(property => property.ContainsTarget && property.ToEntityType().FullName().Equals(navigationPropertyLinkSegment.NavigationProperty.ToEntityType().FullName(), StringComparison.OrdinalIgnoreCase)); return isImplicitFromSingleton; diff --git a/CodeSnippetsReflection.OData/ODataSnippetsGenerator.cs b/CodeSnippetsReflection.OData/ODataSnippetsGenerator.cs index ec10aea99..fcf7751ae 100644 --- a/CodeSnippetsReflection.OData/ODataSnippetsGenerator.cs +++ b/CodeSnippetsReflection.OData/ODataSnippetsGenerator.cs @@ -11,6 +11,8 @@ using UtilityService; using System.Diagnostics.CodeAnalysis; using System.Threading; +using System.Threading.Tasks; +using Microsoft.VisualStudio.Threading; namespace CodeSnippetsReflection.OData { @@ -24,13 +26,18 @@ public class ODataSnippetsGenerator : IODataSnippetsGenerator private readonly Dictionary _snippetsTraceProperties = new() { { UtilityConstants.TelemetryPropertyKey_Snippets, nameof(ODataSnippetsGenerator) } }; - private Lazy IedmModelV1 { get; set; } - private Lazy IedmModelBeta { get; set; } + private static readonly JoinableTaskFactory _joinableTaskFactory = new(new JoinableTaskContext()); + private AsyncLazy IedmModelV1 { get; set; } + private AsyncLazy IedmModelBeta { get; set; } + private static readonly HttpClient HttpClient = new () + { + Timeout = TimeSpan.FromMinutes(5) + }; /// /// initialized only if custom metadata path is specified in constructor /// - private Lazy CustomEdmModel { get; set; } + private AsyncLazy CustomEdmModel { get; set; } private Uri ServiceRootV1 { get; set; } private Uri ServiceRootBeta { get; set; } @@ -62,9 +69,8 @@ private void LoadGraphMetadata(string customMetadataPath) ServiceRootBeta = new Uri(UtilityConstants.ServiceRootBeta); // use clean metadata - IedmModelV1 = new Lazy(() => CsdlReader.Parse(XmlReader.Create(UtilityConstants.CleanV1Metadata)), LazyThreadSafetyMode.PublicationOnly); - IedmModelBeta = new Lazy(() => CsdlReader.Parse(XmlReader.Create(UtilityConstants.CleanBetaMetadata)), LazyThreadSafetyMode.PublicationOnly); - + IedmModelV1 = new AsyncLazy(() => GetEdmModelAsync(UtilityConstants.CleanV1Metadata), _joinableTaskFactory); + IedmModelBeta = new AsyncLazy(() => GetEdmModelAsync(UtilityConstants.CleanBetaMetadata), _joinableTaskFactory); if (customMetadataPath == null) { return; @@ -74,24 +80,28 @@ private void LoadGraphMetadata(string customMetadataPath) { throw new FileNotFoundException("Metadata file is not found in the specified path!", nameof(customMetadataPath)); } - - CustomEdmModel = new Lazy(() => - { - using var reader = File.OpenText(customMetadataPath); - return CsdlReader.Parse(XmlReader.Create(reader)); - }); + CustomEdmModel = new AsyncLazy(() => GetEdmModelAsync(customMetadataPath), _joinableTaskFactory); + } + private static async Task GetEdmModelAsync(string url) { + Stream stream; + if(url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { + stream = await HttpClient.GetStreamAsync(url); + } else { + stream = File.OpenRead(url); + } + return CsdlReader.Parse(XmlReader.Create(stream)) ; } - /// /// Entry point to generate snippets from the payload /// /// /// /// String of snippet generated - public string ProcessPayloadRequest(HttpRequestMessage requestPayload, string language) + public async Task ProcessPayloadRequestAsync(HttpRequestMessage requestPayload, string language) { - var (edmModel, serviceRootUri) = GetModelAndServiceUriTuple(requestPayload.RequestUri); + var (edmModel, serviceRootUri) = await GetModelAndServiceUriTupleAsync(requestPayload.RequestUri); var snippetModel = new SnippetModel(requestPayload, serviceRootUri.AbsoluteUri, edmModel); + await snippetModel.InitializeModelAsync(requestPayload); _telemetryClient?.TrackTrace($"Generating code snippet for '{language}' from the request payload", SeverityLevel.Information, @@ -111,12 +121,12 @@ public string ProcessPayloadRequest(HttpRequestMessage requestPayload, string la /// /// The URI of the service requested /// Tuple of the Edm model and the URI of the service root - private (IEdmModel, Uri) GetModelAndServiceUriTuple(Uri requestUri) + private async Task<(IEdmModel, Uri)> GetModelAndServiceUriTupleAsync(Uri requestUri) { return requestUri.Segments[1] switch { - "v1.0/" => ((CustomEdmModel ?? IedmModelV1).Value, ServiceRootV1), - "beta/" => ((CustomEdmModel ?? IedmModelBeta).Value, ServiceRootBeta), + "v1.0/" => (await (CustomEdmModel ?? IedmModelV1).GetValueAsync(), ServiceRootV1), + "beta/" => (await (CustomEdmModel ?? IedmModelBeta).GetValueAsync(), ServiceRootBeta), _ => throw new ArgumentOutOfRangeException(nameof(requestUri), "Unsupported Graph version in url"), }; } diff --git a/CodeSnippetsReflection.OData/SnippetModel.cs b/CodeSnippetsReflection.OData/SnippetModel.cs index 4b92ca976..c8a8dc884 100644 --- a/CodeSnippetsReflection.OData/SnippetModel.cs +++ b/CodeSnippetsReflection.OData/SnippetModel.cs @@ -29,7 +29,6 @@ public SnippetModel(HttpRequestMessage requestPayload, string serviceRootUrl, IE this.ODataUri = ODataUriParser.ParseUri(); this.CustomQueryOptions = ODataUriParser.CustomQueryOptions; this.Segments = ODataUri.Path.ToList(); - InitializeModel(requestPayload); } /// diff --git a/CodeSnippetsReflection.OpenAPI.Test/CSharpGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/CSharpGeneratorTests.cs index dc918abef..f0e8e30db 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CSharpGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/CSharpGeneratorTests.cs @@ -11,75 +11,84 @@ public class CSharpGeneratorTests : OpenApiSnippetGeneratorTestBase private readonly CSharpGenerator _generator = new(); [Fact] - public async Task GeneratesTheCorrectFluentApiPath() { + public async Task GeneratesTheCorrectFluentApiPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".Me.Messages", result); } [Fact] - public async Task GeneratesTheCorrectFluentApiPath_2() + public async Task GeneratesTheCorrectFluentApiPath_2Async() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/identityGovernance/lifecycleWorkflows/workflows/{{workflowId}}/versions/{{workflowVersion-versionNumber}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Versions[2]", result); } [Fact] - public async Task GeneratesTheCorrectFluentApiPathForIndexedCollections() { + public async Task GeneratesTheCorrectFluentApiPathForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".Me.Messages[\"{message-id}\"]", result); } [Fact] - public async Task GeneratesTheSnippetHeader() { + public async Task GeneratesTheSnippetHeaderAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.DoesNotContain("var graphClient = new GraphServiceClient(requestAdapter)", result); // no initialization statement present Assert.Contains("// Code snippets are only available for the latest version. Current version is", result);// ensure version comment is present Assert.Contains("// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client", result);// ensure initialization guidance is present } [Fact] - public async Task GeneratesTheGetMethodCall() { + public async Task GeneratesTheGetMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("GetAsync", result); Assert.Contains("await", result); } [Fact] - public async Task GeneratesThePostMethodCall() { + public async Task GeneratesThePostMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("PostAsync", result); } [Fact] - public async Task GeneratesThePatchMethodCall() { + public async Task GeneratesThePatchMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("PatchAsync", result); } [Fact] - public async Task GeneratesThePutMethodCall() { + public async Task GeneratesThePutMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("PutAsync", result); } [Fact] - public async Task GeneratesTheDeleteMethodCall() { + public async Task GeneratesTheDeleteMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("DeleteAsync", result); Assert.DoesNotContain("var result =", result); } [Fact] - public async Task WritesTheRequestPayload() { + public async Task WritesTheRequestPayloadAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + "\"mailNickname\": \"mailNickname-value\",\r\n " + @@ -90,7 +99,8 @@ public async Task WritesTheRequestPayload() { { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new User", result); Assert.Contains("AccountEnabled = true,", result); @@ -98,121 +108,133 @@ public async Task WritesTheRequestPayload() { Assert.Contains("DisplayName = \"displayName-value\"", result); } [Fact] - public async Task WritesALongAndFindsAnAction() { + public async Task WritesALongAndFindsAnActionAsync() { const string userJsonObject = "{\r\n \"chainId\": 10\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/teams/{{team-id}}/sendActivityNotification") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("10L", result); Assert.Contains("SendActivityNotificationPostRequestBody", result); Assert.DoesNotContain("microsoft.graph", result); } [Fact] - public async Task WritesADouble() { + public async Task WritesADoubleAsync() { const string userJsonObject = "{\r\n \"minimumAttendeePercentage\": 10\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("10d", result); } [Fact] - public async Task GeneratesABinaryPayload() { + public async Task GeneratesABinaryPayloadAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo") { Content = new ByteArrayContent(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }) }; requestPayload.Content.Headers.ContentType = new ("application/octet-stream"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new MemoryStream", result); } [Fact] - public async Task GeneratesABase64UrlPayload() { + public async Task GeneratesABase64UrlPayloadAsync() { const string userJsonObject = "{\r\n \"contentBytes\": \"wiubviuwbegviwubiu\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/chats/{{chat-id}}/messages/{{chatMessage-id}}/hostedContents") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Convert.FromBase64String", result); } [Fact] - public async Task GeneratesADateTimeOffsetPayload() { + public async Task GeneratesADateTimeOffsetPayloadAsync() { const string userJsonObject = "{\r\n \"receivedDateTime\": \"2021-08-30T20:00:00:00Z\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("DateTimeOffset.Parse", result); } [Fact] - public async Task GeneratesAnArrayPayloadInAdditionalData() { + public async Task GeneratesAnArrayPayloadInAdditionalDataAsync() { const string userJsonObject = "{\r\n \"members@odata.bind\": [\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\"\r\n ]\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/groups/{{group-id}}") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new List", result); Assert.Contains("AdditionalData", result); Assert.Contains("members", result); // property name hasn't been changed } [Fact] - public async Task GeneratesSelectQueryParameters() { + public async Task GeneratesSelectQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me?$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("displayName", result); Assert.Contains("(requestConfiguration) =>", result); Assert.Contains("requestConfiguration.QueryParameters.Select", result); } [Fact] - public async Task GeneratesCountBooleanQueryParameters() { + public async Task GeneratesCountBooleanQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("displayName", result); Assert.DoesNotContain("\"true\"", result); Assert.Contains("true", result); } [Fact] - public async Task GeneratesSkipQueryParameters() { + public async Task GeneratesSkipQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$skip=10"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.DoesNotContain("\"10\"", result); Assert.Contains("10", result); } [Fact] - public async Task GeneratesSelectExpandQueryParameters() { + public async Task GeneratesSelectExpandQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members($select=id,displayName)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Expand", result); Assert.Contains("members($select=id,displayName)", result); Assert.DoesNotContain("Select", result); } [Fact] - public async Task GeneratesRequestHeaders() { + public async Task GeneratesRequestHeadersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.Headers.Add(\"ConsistencyLevel\", \"eventual\");", result); Assert.Contains("(requestConfiguration) =>", result); } [Fact] - public async Task GeneratesFilterParameters() { + public async Task GeneratesFilterParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$filter=Department eq 'Finance'&$orderBy=displayName&$select=id,displayName,department"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.QueryParameters.Count", result); Assert.Contains("requestConfiguration.QueryParameters.Filter", result); @@ -220,37 +242,41 @@ public async Task GeneratesFilterParameters() { Assert.Contains("requestConfiguration.QueryParameters.Orderby", result); } [Fact] - public async Task GeneratesFilterParametersWithSpecialCharacters() { + public async Task GeneratesFilterParametersWithSpecialCharactersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$filter=imAddresses/any(i:i eq 'admin@contoso.com')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.QueryParameters.Filter", result); Assert.Contains("imAddresses/any(i:i eq 'admin@contoso.com')", result); } [Fact] - public async Task GeneratesSnippetForRequestWithDeltaAndSkipToken() + public async Task GeneratesSnippetForRequestWithDeltaAndSkipTokenAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/calendarView/delta?$skiptoken=R0usmcCM996atia_s"); requestPayload.Headers.Add("Prefer", "odata.maxpagesize=2"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("var result = await graphClient.Me.CalendarView.Delta.WithUrl(\"", result); Assert.Contains("requestConfiguration.Headers.Add(\"Prefer\", \"odata.maxpagesize=2\");", result); } [Fact] - public async Task GeneratesSnippetForRequestWithIndexerDeltaAndSkipToken() + public async Task GeneratesSnippetForRequestWithIndexerDeltaAndSkipTokenAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/education/classes/72a7baec-c3e9-4213-a850-f62de0adad5f/assignments/delta?$skiptoken=U43TyYWKlRvJ6wWxZOfJvkp22nMqShRw9f-GxBtG2FDy9b1hMDaAJGdLb7n2fh1IdHoweKQs1czM4Ry1LVsNqwIFXftTcRHvgSCbcszvbJHEWDCO3QO7K7zwCM8DdXNepZOa1gqldecjIUM0NFRbGQoQ5yR6RmGnMgtko8TDMOyMH_yg1my82PTXA_t4Nj-DhMDZWvuNTd_lbLeTngc7mIJPMCR2gHN9CSKsW_kw850.UM9tUqwOu5Ln1pnxaP6KdMmfJHszGqY3EKPlQkOiyGs"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("var result = await graphClient.Education.Classes[\"{educationClass-id}\"].Assignments.Delta.WithUrl(\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjunction() + public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjunctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$search=\"displayName:di\" AND \"displayName:al\""); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.QueryParameters.Search", result); Assert.Contains("requestConfiguration.QueryParameters.Search = \"\\\"displayName:di\\\" AND \\\"displayName:al\\\"\";", result); @@ -262,13 +288,14 @@ public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalC [InlineData("/me/photos/48x48/$value","Content.GetAsync(")] public async Task ObsoleteGetAsyncReplacedWithGetAsLastNodeNameGetResponseAsync(string inputPath, string expectedSuffix, string method = "") { using var requestPayload = new HttpRequestMessage(string.IsNullOrEmpty(method) ? HttpMethod.Get : new HttpMethod(method), $"{ServiceRootUrl}{inputPath}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(expectedSuffix, result); } [Fact] - public async Task HandlesOdataTypeWhenGenerating() { + public async Task HandlesOdataTypeWhenGeneratingAsync() { var sampleJson = @" { ""@odata.type"": ""#microsoft.graph.socialIdentityProvider"", @@ -281,13 +308,14 @@ public async Task HandlesOdataTypeWhenGenerating() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/identity/identityProviders"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("OdataType = \"#microsoft.graph.socialIdentityProvider\",", result); Assert.Contains("new SocialIdentityProvider", result);// ensure the derived type is used } [Fact] - public async Task HandlesOdataReferenceSegmentsInUrl() { + public async Task HandlesOdataReferenceSegmentsInUrlAsync() { var sampleJson = @" { ""@odata.id"": ""https://graph.microsoft.com/beta/users/alexd@contoso.com"" @@ -296,12 +324,13 @@ public async Task HandlesOdataReferenceSegmentsInUrl() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/groups/id/acceptedSenders/$ref"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".AcceptedSenders.Ref.PostAsync(requestBody);", result); } [Fact] - public async Task GenerateSnippetsWithArrayNesting() + public async Task GenerateSnippetsWithArrayNestingAsync() { var eventData = @" { @@ -342,7 +371,8 @@ public async Task GenerateSnippetsWithArrayNesting() { Content = new StringContent(eventData, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("ContentType = BodyType.Html", result); @@ -351,7 +381,7 @@ public async Task GenerateSnippetsWithArrayNesting() Assert.Contains("DisplayName = null,", result); } [Fact] - public async Task GenerateFindMeetingTime() + public async Task GenerateFindMeetingTimeAsync() { var bodyContent = @" { @@ -395,7 +425,8 @@ public async Task GenerateFindMeetingTime() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("MeetingDuration = TimeSpan.Parse(\"PT1H\")", result); Assert.Contains("IsRequired = false,", result); @@ -405,7 +436,7 @@ public async Task GenerateFindMeetingTime() [Theory] [InlineData("sendMail")] [InlineData("microsoft.graph.sendMail")] - public async Task FullyQualifiesActionRequestBodyType(string sendMailString) + public async Task FullyQualifiesActionRequestBodyTypeAsync(string sendMailString) { var bodyContent = @"{ ""message"": { @@ -436,7 +467,8 @@ public async Task FullyQualifiesActionRequestBodyType(string sendMailString) { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.Users[\"{user-id}\"].SendMail.PostAsync(requestBody);", result); @@ -446,7 +478,7 @@ public async Task FullyQualifiesActionRequestBodyType(string sendMailString) } [Fact] - public async Task TypeArgumentsForListArePlacedCorrectly() + public async Task TypeArgumentsForListArePlacedCorrectlyAsync() { var bodyContent = @"{ ""businessPhones"": [ @@ -459,14 +491,15 @@ public async Task TypeArgumentsForListArePlacedCorrectly() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new List", result); } [Fact] - public async Task ModelsInNestedNamespacesAreDisambiguated() + public async Task ModelsInNestedNamespacesAreDisambiguatedAsync() { var bodyContent = @"{ ""id"": ""1431b9c38ee647f6a"", @@ -477,7 +510,8 @@ public async Task ModelsInNestedNamespacesAreDisambiguated() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new Identity", result); @@ -487,10 +521,11 @@ public async Task ModelsInNestedNamespacesAreDisambiguated() } [Fact] - public async Task ReplacesReservedTypeNames() + public async Task ReplacesReservedTypeNamesAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/directory/administrativeUnits/8a07f5a8-edc9-4847-bbf2-dde106594bf4/scopedRoleMembers"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); // Assert `Directory` is replaced with `DirectoryObject` @@ -498,7 +533,7 @@ public async Task ReplacesReservedTypeNames() } [Fact] - public async Task CorrectlyGeneratesEnumMember() + public async Task CorrectlyGeneratesEnumMemberAsync() { var bodyContent = @"{ ""id"": ""SHPR_eeab4fb1-20e5-48ca-ad9b-98119d94bee7"", @@ -524,7 +559,8 @@ public async Task CorrectlyGeneratesEnumMember() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Type = RecurrencePatternType.Weekly,", result); @@ -532,7 +568,7 @@ public async Task CorrectlyGeneratesEnumMember() } [Fact] - public async Task CorrectlyGeneratesMultipleFlagsEnumMembers() + public async Task CorrectlyGeneratesMultipleFlagsEnumMembersAsync() { var bodyContent = @"{ ""clientContext"": ""clientContext-value"", @@ -543,24 +579,26 @@ public async Task CorrectlyGeneratesMultipleFlagsEnumMembers() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Status = RecordingStatus.NotRecording | RecordingStatus.Recording | RecordingStatus.Failed", result); } [Fact] - public async Task CorrectlyOptionalRequestBodyParameter() + public async Task CorrectlyOptionalRequestBodyParameterAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/teams/{{id}}/archive"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.Teams[\"{team-id}\"].Archive.PostAsync(null);", result); } [Fact] - public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() + public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameterAsync() { var bodyContent = @"{ ""subject"": ""Let's go for lunch"", @@ -576,7 +614,8 @@ public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("StartDate = new Date(DateTime.Parse(\"2017-09-04\")),", result); @@ -584,7 +623,7 @@ public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() } [Fact] - public async Task CorrectlyEvaluatesOdataActionRequestBodyParameter() + public async Task CorrectlyEvaluatesOdataActionRequestBodyParameterAsync() { var bodyContent = @"{ ""keyCredential"": { @@ -599,14 +638,15 @@ public async Task CorrectlyEvaluatesOdataActionRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("var requestBody = new AddKeyPostRequestBody", result); Assert.Contains("using Microsoft.Graph.Applications.Item.AddKey;", result); } [Fact] - public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() + public async Task CorrectlyEvaluatesGuidInRequestBodyParameterAsync() { var bodyContent = @"{ ""principalId"": ""cde330e5-2150-4c11-9c5b-14bfdc948c79"", @@ -617,7 +657,8 @@ public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Guid.Parse(\"cde330e5-2150-4c11-9c5b-14bfdc948c79\")", result); @@ -625,7 +666,7 @@ public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() Assert.Contains("Guid.Parse(\"00000000-0000-0000-0000-000000000000\")", result); } [Fact] - public async Task DefaultsEnumIfNoneProvided() + public async Task DefaultsEnumIfNoneProvidedAsync() { var bodyContent = @"{ ""subject"": ""subject-value"", @@ -639,12 +680,13 @@ public async Task DefaultsEnumIfNoneProvided() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("ContentType = BodyType.Text,", result); } [Fact] - public async Task HandlesEmptyCollection() + public async Task HandlesEmptyCollectionAsync() { var bodyContent = @"{ ""defaultUserRolePermissions"": { @@ -655,15 +697,17 @@ public async Task HandlesEmptyCollection() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("PermissionGrantPoliciesAssigned = new List", result); } [Fact] - public async Task CorrectlyHandlesOdataFunction() + public async Task CorrectlyHandlesOdataFunctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/delta?$select=displayName,jobTitle,mobilePhone"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.Users.Delta.GetAsDeltaGetResponseAsync", result); @@ -671,53 +715,58 @@ public async Task CorrectlyHandlesOdataFunction() } [Fact] - public async Task CorrectlyHandlesDateTimeOffsetInUrl() + public async Task CorrectlyHandlesDateTimeOffsetInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/reports/getUserArchivedPrintJobs(userId='{{id}}',startDateTime=,endDateTime=)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.Reports.GetUserArchivedPrintJobsWithUserIdWithStartDateTimeWithEndDateTime(DateTimeOffset.Parse(\"{endDateTime}\"),DateTimeOffset.Parse(\"{startDateTime}\"),\"{userId}\").GetAsGetUserArchivedPrintJobsWithUserIdWithStartDateTimeWithEndDateTimeGetResponseAsync()", result); } [Fact] - public async Task CorrectlyHandlesNumberInUrl() + public async Task CorrectlyHandlesNumberInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/worksheets/{{id|name}}/cell(row=,column=)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.Drives[\"{drive-id}\"].Items[\"{driveItem-id}\"].Workbook.Worksheets[\"{workbookWorksheet-id}\"].CellWithRowWithColumn(1,1).GetAsync();",result); } [Fact] - public async Task CorrectlyHandlesDateInUrl() + public async Task CorrectlyHandlesDateInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/reports/getYammerGroupsActivityDetail(date='2018-03-05')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.Reports.GetYammerGroupsActivityDetailWithDate(new Date(DateTime.Parse(\"{date}\"))).GetAsync();", result); } [Fact] - public async Task CorrectlyHandlesDateInUrl2() + public async Task CorrectlyHandlesDateInUrl2Async() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/communications/callRecords/getPstnCalls(fromDateTime=2019-11-01,toDateTime=2019-12-01)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.Communications.CallRecords.MicrosoftGraphCallRecordsGetPstnCallsWithFromDateTimeWithToDateTime(DateTimeOffset.Parse(\"{fromDateTime}\"),DateTimeOffset.Parse(\"{toDateTime}\")).GetAsGetPstnCallsWithFromDateTimeWithToDateTimeGetResponseAsync()", result); } [Fact] - public async Task CorrectlyHandlesEnumInUrl() + public async Task CorrectlyHandlesEnumInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/identityGovernance/appConsent/appConsentRequests/filterByCurrentUser(on='reviewer')?$filter=userConsentRequests/any(u:u/status eq 'InProgress')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.IdentityGovernance.AppConsent.AppConsentRequests.FilterByCurrentUserWithOn(\"reviewer\").GetAsFilterByCurrentUserWithOnGetResponseAsync", result); } [Fact] - public async Task GeneratesObjectsInArray() { + public async Task GeneratesObjectsInArrayAsync() { var sampleJson = @" { ""addLicenses"": [ @@ -732,7 +781,8 @@ public async Task GeneratesObjectsInArray() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/assignLicense"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("var requestBody = new AssignLicensePostRequestBody", result); Assert.Contains("using Microsoft.Graph.Me.AssignLicense;", result); @@ -741,7 +791,7 @@ public async Task GeneratesObjectsInArray() { Assert.Contains("Guid.Parse(\"bea13e0c-3828-4daa-a392-28af7ff61a0f\"),", result); } [Fact] - public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() { + public async Task GeneratesCorrectCollectionTypeAndDerivedInstancesAsync() { var sampleJson = @"{ ""message"": { ""subject"": ""Meet for lunch?"", @@ -769,7 +819,8 @@ public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/sendMail"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("var requestBody = new SendMailPostRequestBody", result); Assert.Contains("using Microsoft.Graph.Me.SendMail;", result); @@ -778,7 +829,7 @@ public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() { Assert.Contains("ContentBytes = Convert.FromBase64String(\"SGVsbG8gV29ybGQh\"),", result); } [Fact] - public async Task GenerateUntypedTypesInstancesInAdditionalData() { + public async Task GenerateUntypedTypesInstancesInAdditionalDataAsync() { var sampleJson = @"{ ""customSecurityAttributes"": { @@ -792,7 +843,8 @@ public async Task GenerateUntypedTypesInstancesInAdditionalData() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/users/{{id}}"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("using Microsoft.Kiota.Abstractions.Serialization;", result);//verify import @@ -800,7 +852,7 @@ public async Task GenerateUntypedTypesInstancesInAdditionalData() { } [Fact] - public async Task GenerateUntypedTypesInstancesInAdditionalData2() + public async Task GenerateUntypedTypesInstancesInAdditionalData2Async() { var sampleJson = @"{ ""allowedValues@delta"": [ @@ -818,7 +870,8 @@ public async Task GenerateUntypedTypesInstancesInAdditionalData2() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("using Microsoft.Kiota.Abstractions.Serialization;", result);//verify import @@ -827,7 +880,7 @@ public async Task GenerateUntypedTypesInstancesInAdditionalData2() Assert.Contains("\"id\", new UntypedString(\"Skagit\")", result); } [Fact] - public async Task GeneratesCorrectTypesInstancesInAdditionalData() { + public async Task GeneratesCorrectTypesInstancesInAdditionalDataAsync() { var sampleJson = @"{ ""transferTarget"": { ""endpointType"": ""default"", @@ -845,12 +898,13 @@ public async Task GeneratesCorrectTypesInstancesInAdditionalData() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/communications/calls/{{id}}/transfer"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("\"phone\" , new Identity", result);//phone should be initialized with specified type. } [Fact] - public async Task GeneratesPropertiesWithSpecialCharacters() { + public async Task GeneratesPropertiesWithSpecialCharactersAsync() { var sampleJson = @"{ ""@odata.type"": ""#microsoft.graph.managedIOSLobApp"", ""displayName"": ""Display Name value"", @@ -907,14 +961,15 @@ public async Task GeneratesPropertiesWithSpecialCharacters() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootBetaUrl}/deviceAppManagement/mobileApps/{{mobileAppId}}"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("MinimumSupportedOperatingSystem = new IosMinimumOperatingSystem", result); Assert.Contains("V80 = true,", result);//Assert that the property was pascal cased } [Fact] - public async Task GeneratesCorrectTypeInCollectionInitializer() { + public async Task GeneratesCorrectTypeInCollectionInitializerAsync() { var sampleJson = @"{ ""workflow"":{ ""category"": ""joiner"", @@ -957,41 +1012,45 @@ public async Task GeneratesCorrectTypeInCollectionInitializer() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/identityGovernance/lifecycleWorkflows/workflows/{{workflowId}}/createNewVersion"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new List", result);//Assert the type is escaped in the collection initializzer. Assert.Contains("using Microsoft.Graph.Models.IdentityGovernance", result);//Assert the type is escaped in the collection initializzer. } [Fact] - public async Task CorrectlyHandlesTypeFromInUrl() + public async Task CorrectlyHandlesTypeFromInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/mailFolders/?includehiddenfolders=true"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.QueryParameters.IncludeHiddenFolders = \"true\";", result); } [Fact] - public async Task MatchesPathWithPathParameter() + public async Task MatchesPathWithPathParameterAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/worksheets/{{id|name}}/range(address='A1:B2')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("var result = await graphClient.Drives[\"{drive-id}\"].Items[\"{driveItem-id}\"].Workbook.Worksheets[\"{workbookWorksheet-id}\"].RangeWithAddress(\"{address}\").GetAsync()", result); } [Fact] - public async Task UntypedNodeInWorkbooksGeneratesArray() + public async Task UntypedNodeInWorkbooksGeneratesArrayAsync() { var sampleJson = "{\n \"index\": 5,\n \"values\": [\n [1, 2, 3],\n [4, 5, 6]\n ]\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/tables/{{id|name}}/rows/add") { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("using Microsoft.Kiota.Abstractions.Serialization;", result);//verify import @@ -1001,14 +1060,15 @@ public async Task UntypedNodeInWorkbooksGeneratesArray() } [Fact] - public async Task UntypedNodeInWorkbooksGeneratesObject() + public async Task UntypedNodeInWorkbooksGeneratesObjectAsync() { var sampleJson = "{\r\n \"lookupValue\":\"pear\",\r\n \"tableArray\":{\"Address\":\"Sheet1!B2:C7\"},\r\n \"colIndexNum\":2,\r\n \"rangeLookup\":false\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/functions/vlookup") { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("using Microsoft.Kiota.Abstractions.Serialization;", result);//verify import @@ -1019,10 +1079,11 @@ public async Task UntypedNodeInWorkbooksGeneratesObject() } [Fact] - public async Task MatchesPathAlternateKeys() + public async Task MatchesPathAlternateKeysAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/applications(appId='46e6adf4-a9cf-4b60-9390-0ba6fb00bf6b')?$select=id,appId,displayName,requiredResourceAccess"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graphClient.ApplicationsWithAppId(\"{appId}\").GetAsync(", result); @@ -1039,10 +1100,11 @@ public async Task MatchesPathAlternateKeys() [InlineData("/me/drive/special/documents","graphClient.Drives[\"{drive-id}\"].Special[\"{driveItem-id}\"].GetAsync()")] [InlineData("/me/drive/root/search(q='Contoso%20Project')","graphClient.Drives[\"{drive-id}\"].Items[\"{driveItem-id}\"].SearchWithQ(\"{q}\").GetAsSearchWithQGetResponseAsync()")] [InlineData("/me/drive/items/{id}/workbook/application/calculate","graphClient.Drives[\"{drive-id}\"].Items[\"{driveItem-id}\"].Workbook.Application.Calculate", "POST")] - public async Task GeneratesSnippetWithRemappedDriveCall(string inputPath, string expected, string method = "") + public async Task GeneratesSnippetWithRemappedDriveCallAsync(string inputPath, string expected, string method = "") { using var requestPayload = new HttpRequestMessage(string.IsNullOrEmpty(method) ? HttpMethod.Get : new HttpMethod(method), $"{ServiceRootUrl}{inputPath}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(expected, result); } diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index d45175a6a..cd3208b50 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -11,6 +11,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs index 0e5c3f061..837a1322b 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs @@ -14,17 +14,19 @@ public class GoGeneratorTests : OpenApiSnippetGeneratorTestBase private readonly GoGenerator _generator = new(); [Fact] - public async Task GeneratesTheCorrectFluentAPIPath() { + public async Task GeneratesTheCorrectFluentAPIPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".Me().Messages()", result); } [Fact] - public async Task GeneratesMeImportFromUserPackage() + public async Task GeneratesMeImportFromUserPackageAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages?$select=sender,subject"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("import", result); Assert.Contains("graphusers \"github.com/microsoftgraph/msgraph-sdk-go/users\"", result); @@ -32,14 +34,15 @@ public async Task GeneratesMeImportFromUserPackage() Assert.Contains(".Me().Messages()", result); } [Fact] - public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollections() { + public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".Me().Messages().ByMessageId(\"message-id\")", result); } [Fact] - public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollectionsWithMultipleParams() { + public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollectionsWithMultipleParamsAsync() { var sampleJson = @" { ""comment"": ""Updating the latest guidelines"" @@ -48,12 +51,13 @@ public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollectionsWithMulti using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/drives/{{drive-id}}/items/{{item-id}}/checkin"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Drives().ByDriveId(\"drive-id\").Items().ByDriveItemId(\"driveItem-id\").Checkin().Post(context.Background(), requestBody, nil)", result); } [Fact] - public async Task IgnoreOdataTypeWhenGenerating() { + public async Task IgnoreOdataTypeWhenGeneratingAsync() { var sampleJson = @" { ""@odata.type"": ""microsoft.graph.socialIdentityProvider"", @@ -66,12 +70,13 @@ public async Task IgnoreOdataTypeWhenGenerating() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/identity/identityProviders"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.DoesNotContain("@odata.type", result); } [Fact] - public async Task GeneratesObjectsInArray() { + public async Task GeneratesObjectsInArrayAsync() { var sampleJson = @" { ""addLicenses"": [ @@ -86,7 +91,8 @@ public async Task GeneratesObjectsInArray() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/assignLicense"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestBody := graphusers.NewItemAssignLicensePostRequestBody()", result); Assert.Contains("disabledPlans := []uuid.UUID {", result); @@ -94,14 +100,15 @@ public async Task GeneratesObjectsInArray() { Assert.Contains("uuid.MustParse(\"bea13e0c-3828-4daa-a392-28af7ff61a0f\"),", result); } [Fact] - public async Task GeneratesTheSnippetHeader() { + public async Task GeneratesTheSnippetHeaderAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go", result); } [Fact] - public async Task GeneratesMultipleImportStatements() + public async Task GeneratesMultipleImportStatementsAsync() { var bodyContent = @" { @@ -120,12 +127,13 @@ public async Task GeneratesMultipleImportStatements() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphapplications \"github.com/microsoftgraph/msgraph-sdk-go/applications\"", result); } [Fact] - public async Task AllowsNestedModelsNameSpace() + public async Task AllowsNestedModelsNameSpaceAsync() { var bodyContent = @" { @@ -144,46 +152,50 @@ public async Task AllowsNestedModelsNameSpace() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphmodelstermstore \"github.com/microsoftgraph/msgraph-sdk-go/models/termstore\"", result); Assert.Contains("requestBody := graphmodelstermstore.NewTerm()", result); } [Fact] - public async Task GeneratesTheGetMethodCall() { + public async Task GeneratesTheGetMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get", result); Assert.DoesNotContain("WithRequestConfigurationAndResponseHandler", result); Assert.Contains("messages, err := graphClient.Me().Messages().Get(context.Background(), nil)", result); } [Fact] - public async Task GeneratesThePostMethodCall() { + public async Task GeneratesThePostMethodCallAsync() { const string messageObjectJson = "{\"subject\": \"Test Subject\"}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages") { Content = new StringContent(messageObjectJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Post", result); Assert.DoesNotContain("WithRequestConfigurationAndResponseHandler", result); Assert.Contains("messages, err := graphClient.Me().Messages().Post(context.Background(), requestBody, nil)", result); } [Fact] - public async Task GeneratesThePatchMethodCall() { + public async Task GeneratesThePatchMethodCallAsync() { const string messageObjectJson = "{\"subject\": \"Test Subject\"}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/me/messages/{{message-id}}") { Content = new StringContent(messageObjectJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Patch", result); Assert.DoesNotContain("WithRequestConfigurationAndResponseHandler", result); Assert.Contains("graphClient.Me().Messages().ByMessageId(\"message-id\").Patch(context.Background(), requestBody, nil)", result); } [Fact] - public async Task GeneratesThePutMethodCall() { + public async Task GeneratesThePutMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo") { Content = new StreamContent(new MemoryStream(new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 })) { Headers = { @@ -191,7 +203,8 @@ public async Task GeneratesThePutMethodCall() { } } }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Put", result); Assert.DoesNotContain("WithRequestConfigurationAndResponseHandler", result); @@ -203,17 +216,19 @@ public async Task GeneratesThePutMethodCall() { [InlineData("/me/photos/48x48/$value","Value().Get(")] [InlineData("/users/some-id/mailFolders/delta","GetAsDeltaGetResponse")] [InlineData("/identityGovernance/accessReviews/definitions/filterByCurrentUser(on='reviewer')", "GetAsFilterByCurrentUserWithOnGetResponse")] - public async Task GeneratesTheInlineSchemaFunctionPrefixCorrectly(string inputPath, string expectedSuffix, string method = "") + public async Task GeneratesTheInlineSchemaFunctionPrefixCorrectlyAsync(string inputPath, string expectedSuffix, string method = "") { using var requestPayload = new HttpRequestMessage(string.IsNullOrEmpty(method) ? HttpMethod.Get : new HttpMethod(method), $"{ServiceRootUrl}{inputPath}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(expectedSuffix, result); } [Fact] - public async Task GeneratesTheDeleteMethodCall() { + public async Task GeneratesTheDeleteMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Delete", result); Assert.DoesNotContain("result, err :=", result); @@ -221,7 +236,7 @@ public async Task GeneratesTheDeleteMethodCall() { Assert.Contains("graphClient.Me().Messages().ByMessageId(\"message-id\").Delete(context.Background(), nil)", result); } [Fact] - public async Task WritesTheRequestPayload() { + public async Task WritesTheRequestPayloadAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + "\"mailNickname\": \"mailNickname-value\",\r\n " + @@ -232,7 +247,8 @@ public async Task WritesTheRequestPayload() { { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphmodels.NewUser", result); Assert.Contains("SetAccountEnabled(&accountEnabled)", result); @@ -240,67 +256,73 @@ public async Task WritesTheRequestPayload() { Assert.Contains("displayName := \"displayName-value\"", result); } [Fact] - public async Task WritesALongAndFindsAnAction() { + public async Task WritesALongAndFindsAnActionAsync() { const string userJsonObject = "{\r\n \"chainId\": 10\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/teams/{{team-id}}/sendActivityNotification") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("int64(10)", result); Assert.DoesNotContain("microsoft.graph", result); } [Fact] - public async Task WritesADouble() { + public async Task WritesADoubleAsync() { const string userJsonObject = "{\r\n \"minimumAttendeePercentage\": 10\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("float64(10)", result); } [Fact] - public async Task GeneratesABinaryPayload() { + public async Task GeneratesABinaryPayloadAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo") { Content = new ByteArrayContent(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }) }; requestPayload.Content.Headers.ContentType = new ("application/octet-stream"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("make([]byte, 0)", result); } [Fact] - public async Task GeneratesABase64UrlPayload() { + public async Task GeneratesABase64UrlPayloadAsync() { const string userJsonObject = "{\r\n \"contentBytes\": \"wiubviuwbegviwubiu\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/chats/{{chat-id}}/messages/{{chatMessage-id}}/hostedContents") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("[]byte(", result); } [Fact] - public async Task GeneratesADateTimeOffsetPayload() { + public async Task GeneratesADateTimeOffsetPayloadAsync() { const string userJsonObject = "{\r\n \"receivedDateTime\": \"2021-08-30T20:00:00:00Z\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(", err := time.Parse(time.RFC3339,", result); } [Fact] - public async Task GeneratesAnArrayPayloadInAdditionalData() { + public async Task GeneratesAnArrayPayloadInAdditionalDataAsync() { const string userJsonObject = "{\r\n \"members@odata.bind\": [\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\"\r\n ]\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/groups/{{group-id}}") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("map[string]interface{}{", result); Assert.Contains("[]string {", result); @@ -308,10 +330,11 @@ public async Task GeneratesAnArrayPayloadInAdditionalData() { Assert.DoesNotContain("WithRequestConfigurationAndResponseHandler", result); } [Fact] - public async Task GeneratesSelectQueryParameters() + public async Task GeneratesSelectQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me?$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Select: [] string {\"displayName\"", result); Assert.Contains("QueryParameters: ", result); @@ -323,10 +346,11 @@ public async Task GeneratesSelectQueryParameters() Assert.Contains("me, err := graphClient.Me().Get(context.Background(), configuration)", result); } [Fact] - public async Task GeneratesNestedParameterNames() + public async Task GeneratesNestedParameterNamesAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/{{id}}?$select=displayName,givenName,postalCode,identities"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Select: [] string {\"displayName\",\"givenName\",\"postalCode\",\"identities\"}", result); Assert.Contains("QueryParameters: ", result); @@ -337,7 +361,7 @@ public async Task GeneratesNestedParameterNames() Assert.Contains("users, err := graphClient.Users().ByUserId(\"user-id\").Get(context.Background(), configuration)", result); } [Fact] - public async Task GeneratesODataTypesAreEscaped() + public async Task GeneratesODataTypesAreEscapedAsync() { const string jsonObject = @" { @@ -348,7 +372,8 @@ public async Task GeneratesODataTypesAreEscaped() { Content = new StringContent(jsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestBody := graphmodels.NewReferenceCreate()", result); Assert.Contains("requestBody.SetOdataId(&odataId)", result); @@ -356,9 +381,10 @@ public async Task GeneratesODataTypesAreEscaped() Assert.Contains("graphClient.Groups().ByGroupId(\"group-id\").Members().Ref().Post(context.Background(), requestBody, nil)", result); } [Fact] - public async Task GeneratesCountBooleanQueryParameters() { + public async Task GeneratesCountBooleanQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("displayName", result); Assert.DoesNotContain("\"true\"", result); @@ -367,9 +393,10 @@ public async Task GeneratesCountBooleanQueryParameters() { Assert.Contains("users, err := graphClient.Users().Get(context.Background(), configuration)", result); } [Fact] - public async Task GeneratesSkipQueryParameters() { + public async Task GeneratesSkipQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$skip=10"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.DoesNotContain("\"10\"", result); Assert.Contains("10", result); @@ -377,9 +404,10 @@ public async Task GeneratesSkipQueryParameters() { Assert.Contains("users, err := graphClient.Users().Get(context.Background(), configuration)", result); } [Fact] - public async Task GeneratesSelectExpandQueryParameters() { + public async Task GeneratesSelectExpandQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members($select=id,displayName),teams($select=id,displayName)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Expand", result); Assert.Contains("members($select=id,displayName)", result); @@ -388,10 +416,11 @@ public async Task GeneratesSelectExpandQueryParameters() { Assert.Contains("groups, err := graphClient.Groups().Get(context.Background(), configuration)", result); } [Fact] - public async Task GeneratesRequestHeaders() { + public async Task GeneratesRequestHeadersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("import", result); Assert.Contains("abstractions \"github.com/microsoft/kiota-abstractions-go\"", result); @@ -403,37 +432,40 @@ public async Task GeneratesRequestHeaders() { Assert.Contains("groups, err := graphClient.Groups().Get(context.Background(), configuration)", result); } [Fact] - public async Task SupportsODataOldIndexFormat() { + public async Task SupportsODataOldIndexFormatAsync() { const string userJsonObject = "{\r\n\"@odata.type\": \"#microsoft.graph.fileAttachment\",\r\n\"name\": \"menu.txt\",\r\n\"contentBytes\": \"bWFjIGFuZCBjaGVlc2UgdG9kYXk=\"\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootBetaUrl}/me/events('AAMkAGI1AAAt9AHjAAA=')/attachments") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.Me().Events().ByEventId(\"event-id\").Attachments().Post(context.Background(), requestBody, nil)", result); } [Fact] - public async Task ParsesThePayloadEvenIfContentTypeIsMissing() { + public async Task ParsesThePayloadEvenIfContentTypeIsMissingAsync() { const string messageObject = "{\r\n\"createdDateTime\":\"2019-02-04T19:58:15.511Z\",\r\n\"from\":{\r\n\"user\":{\r\n\"id\":\"id-value\",\r\n\"displayName\":\"Joh Doe\",\r\n\"userIdentityType\":\"aadUser\"\r\n}\r\n},\r\n\"body\":{\r\n\"contentType\":\"html\",\r\n\"content\":\"Hello World\"\r\n}\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/teams/57fb72d0-d811-46f4-8947-305e6072eaa5/channels/19:4b6bed8d24574f6a9e436813cb2617d8@thread.tacv2/messages") { Content = new StringContent(messageObject, Encoding.UTF8) }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.Teams().ByTeamId(\"team-id\").Channels().ByChannelId(\"channel-id\").Messages().PostAsMessagesPostResponse(context.Background(), requestBody, nil)", result); } [Fact] - public async Task WritesEmptyPrimitiveArrays() { + public async Task WritesEmptyPrimitiveArraysAsync() { const string messageObject = "{\r\n\"displayName\": \"Demo app for documentation\",\r\n\"state\": \"disabled\",\r\n\"conditions\": {\r\n\"signInRiskLevels\": [\r\n\"high\",\r\n\"medium\"\r\n],\r\n\"clientAppTypes\": [\r\n\"mobileAppsAndDesktopClients\",\r\n\"exchangeActiveSync\",\r\n\"other\"\r\n],\r\n\"applications\": {\r\n\"includeApplications\": [\r\n\"All\"\r\n],\r\n\"excludeApplications\": [\r\n\"499b84ac-1321-427f-aa17-267ca6975798\",\r\n\"00000007-0000-0000-c000-000000000000\",\r\n\"de8bc8b5-d9f9-48b1-a8ad-b748da725064\",\r\n\"00000012-0000-0000-c000-000000000000\",\r\n\"797f4846-ba00-4fd7-ba43-dac1f8f63013\",\r\n\"05a65629-4c1b-48c1-a78b-804c4abdd4af\",\r\n\"7df0a125-d3be-4c96-aa54-591f83ff541c\"\r\n],\r\n\"includeUserActions\": []\r\n},\r\n\"users\": {\r\n\"includeUsers\": [\r\n\"a702a13d-a437-4a07-8a7e-8c052de62dfd\"\r\n],\r\n\"excludeUsers\": [\r\n\"124c5b6a-ffa5-483a-9b88-04c3fce5574a\",\r\n\"GuestsOrExternalUsers\"\r\n],\r\n\"includeGroups\": [],\r\n\"excludeGroups\": [],\r\n\"includeRoles\": [\r\n\"9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3\",\r\n\"cf1c38e5-3621-4004-a7cb-879624dced7c\",\r\n\"c4e39bd9-1100-46d3-8c65-fb160da0071f\"\r\n],\r\n\"excludeRoles\": [\r\n\"b0f54661-2d74-4c50-afa3-1ec803f12efe\"\r\n]\r\n},\r\n\"platforms\": {\r\n\"includePlatforms\": [\r\n\"all\"\r\n],\r\n\"excludePlatforms\": [\r\n\"iOS\",\r\n\"windowsPhone\"\r\n]\r\n},\r\n\"locations\": {\r\n\"includeLocations\": [\r\n\"AllTrusted\"\r\n],\r\n\"excludeLocations\": [\r\n\"00000000-0000-0000-0000-000000000000\",\r\n\"d2136c9c-b049-47ae-b9cf-316e04ef7198\"\r\n]\r\n},\r\n\"deviceStates\": {\r\n\"includeStates\": [\r\n\"All\"\r\n],\r\n\"excludeStates\": [\r\n\"Compliant\"\r\n]\r\n}\r\n},\r\n\"grantControls\": {\r\n\"operator\": \"OR\",\r\n\"builtInControls\": [\r\n\"mfa\",\r\n\"compliantDevice\",\r\n\"domainJoinedDevice\",\r\n\"approvedApplication\",\r\n\"compliantApplication\"\r\n],\r\n\"customAuthenticationFactors\": [],\r\n\"termsOfUse\": [\r\n\"ce580154-086a-40fd-91df-8a60abac81a0\",\r\n\"7f29d675-caff-43e1-8a53-1b8516ed2075\"\r\n]\r\n},\r\n\"sessionControls\": {\r\n\"applicationEnforcedRestrictions\": null,\r\n\"persistentBrowser\": null,\r\n\"cloudAppSecurity\": {\r\n\"cloudAppSecurityType\": \"blockDownloads\",\r\n\"isEnabled\": true\r\n},\r\n\"signInFrequency\": {\r\n\"value\": 4,\r\n\"type\": \"hours\",\r\n\"isEnabled\": true\r\n}\r\n}\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootBetaUrl}/identity/conditionalAccess/policies") { Content = new StringContent(messageObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("SetIncludeUserActions", result); } [Fact] - public async Task WriteCorrectFunctionNameWithParametersAsModelName() + public async Task WriteCorrectFunctionNameWithParametersAsModelNameAsync() { const string messageObject = "{\r\n\"displayName\": \"Display name\"\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/applications(uniqueName='app-65278')") @@ -441,23 +473,25 @@ public async Task WriteCorrectFunctionNameWithParametersAsModelName() Content = new StringContent(messageObject, Encoding.UTF8, "application/json") }; requestPayload.Headers.Add("Prefer", "create-if-missing"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphapplicationswithuniquename \"github.com/microsoftgraph/msgraph-sdk-go/applicationswithuniquename\"", result); Assert.Contains("graphapplicationswithuniquename.ApplicationsWithUniqueNameRequestBuilderPatchRequestConfiguration", result); } [Fact] - public async Task WriteCorrectTypesForFilterParameters() + public async Task WriteCorrectTypesForFilterParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/identityGovernance/accessReviews/definitions?$top=100&$skip=0"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestTop := int32(100)", result); Assert.Contains("requestSkip := int32(0)", result); } [Fact] - public async Task DoesNotNormalizeKeysForMaps() + public async Task DoesNotNormalizeKeysForMapsAsync() { var sampleJson = @" { @@ -479,7 +513,8 @@ public async Task DoesNotNormalizeKeysForMaps() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("\"user@odata.bind\" : \"https://graph.microsoft.com/v1.0/users('0040b377-61d8-43db-94f5-81374122dc7e')\"", result); Assert.Contains("\"template@odata.bind\" : \"https://graph.microsoft.com/v1.0/teamsTemplates('standard')\"", result); @@ -492,6 +527,7 @@ public async Task DoesNotNormalizeKeysForMaps() public async Task DoesntReplaceODataFunctionCalls() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/devices/{{objectId}}/usageRights?$filter=state in ('active', 'suspended') and serviceIdentifier in ('ABCD')"); var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("state%20in%20('active',%20'suspended')%20and%20serviceIdentifier%20in%20('ABCD')", result); Assert.Contains("WithRequestConfigurationAndResponseHandler", result); @@ -499,45 +535,50 @@ public async Task DoesntReplaceODataFunctionCalls() { **/ [Fact] - public async Task FindsPathItemsWithDifferentCasing() { + public async Task FindsPathItemsWithDifferentCasingAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/directory/deleteditems/microsoft.graph.group"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.Directory().DeletedItems().GraphGroup().Get(context.Background(), nil)", result); } [Fact] - public async Task DoesntFailOnTerminalSlash() { + public async Task DoesntFailOnTerminalSlashAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/me/messages/AAMkADYAAAImV_jAAA=/?$expand=microsoft.graph.eventMessage/event"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.Me().Messages().ByMessageId(\"message-id\").Get(context.Background(), configuration)", result); } [Fact] - public async Task IncludesRequestBodyClassName() { + public async Task IncludesRequestBodyClassNameAsync() { const string payloadBody = "{\r\n \"passwordCredential\": {\r\n \"displayName\": \"Password friendly name\"\r\n }\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/applications/{{id}}/addPassword") { Content = new StringContent(payloadBody, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("NewAddPasswordPostRequestBody", result); } [Fact] - public async Task GeneratePathParametersInFluentPath() + public async Task GeneratePathParametersInFluentPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/reports/getYammerActivityCounts(period='D7')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("period := \"{period}\"", result); Assert.Contains("graphClient.Reports().GetYammerActivityCountsWithPeriod(&period).Get(context.Background(), nil)", result); } [Fact] - public async Task GeneratePathParametersInFluentPathWithPeriodsInName() + public async Task GeneratePathParametersInFluentPathWithPeriodsInNameAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/communications/callRecords/getPstnCalls(fromDateTime=2019-11-01,toDateTime=2019-12-01)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("fromDateTime , err := time.Parse(time.RFC3339, \"{fromDateTime}\")", result); Assert.Contains("toDateTime , err := time.Parse(time.RFC3339, \"{toDateTime}\")", result); @@ -545,7 +586,7 @@ public async Task GeneratePathParametersInFluentPathWithPeriodsInName() } [Fact] - public async Task GenerateFindMeetingTime() + public async Task GenerateFindMeetingTimeAsync() { var bodyContent = @" { @@ -593,17 +634,19 @@ public async Task GenerateFindMeetingTime() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("maxCandidates := int32(100)", result); Assert.Contains("minimumAttendeePercentage := float64(200)", result); Assert.Contains("isOrganizerOptional := false", result); } [Fact] - public async Task GeneratesPathSegmentsUsingVariableName() + public async Task GeneratesPathSegmentsUsingVariableNameAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/worksheets/{{id|name}}/charts"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".Drives().ByDriveId(\"drive-id\").Items().ByDriveItemId(\"driveItem-id\").Workbook().Worksheets().ByWorkbookWorksheetId(\"workbookWorksheet-id\").Charts().Get(context.Background(), nil)", result); } diff --git a/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs index d32a458fe..ae52dac46 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs @@ -29,11 +29,12 @@ public static IEnumerable GetSnippetData() [Theory] [MemberData(nameof(GetSnippetData))] - public async Task GeneratesSnippetsForCommands(HttpMethod method, string url, string expectedCommand) + public async Task GeneratesSnippetsForCommandsAsync(HttpMethod method, string url, string expectedCommand) { // Given a url and method using var requestPayload = new HttpRequestMessage(method, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -43,13 +44,14 @@ public async Task GeneratesSnippetsForCommands(HttpMethod method, string url, st } [Fact] - public async Task GeneratesSnippetsForDeepSubCommand() + public async Task GeneratesSnippetsForDeepSubCommandAsync() { // GET /users/{user-id}/todo/lists/{todoTaskList-id}/tasks/{todoTask-id}/attachments/{attachmentBase-id} // Given string url = $"{ServiceRootUrl}/users/100/todo/lists/123/tasks/1234/attachments/12345"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -61,7 +63,7 @@ public async Task GeneratesSnippetsForDeepSubCommand() [Theory] [InlineData("/users/100/directReports/graph.orgContact", "mgc users direct-reports graph-org-contact get --user-id {user-id}")] [InlineData("/users/100/directReports/123/graph.orgContact", "mgc users direct-reports graph-org-contact-by-id get --user-id {user-id} --directory-object-id {directoryObject-id}")] - public void GeneratesSnippetsForConflictingIndexerNavSubCommand(string url, string expectedCommand) + public async Task GeneratesSnippetsForConflictingIndexerNavSubCommandAsync(string url, string expectedCommand) { // Tests: // GET /users/{user-id}/directReports/graph.orgContact @@ -73,6 +75,7 @@ public void GeneratesSnippetsForConflictingIndexerNavSubCommand(string url, stri var openApiMetadata = new OpenApiSnippetMetadata(rootNode, new Dictionary()); using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}{url}"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -83,7 +86,7 @@ public void GeneratesSnippetsForConflictingIndexerNavSubCommand(string url, stri // Powershell metadata doesn't have /$count endpoints [Fact] - public void GeneratesSnippetsForCountCommand() + public async Task GeneratesSnippetsForCountCommandAsync() { // Given string schema = """{"openapi":"3.0.0","info":{"title":"Tests API","version":"1.0.11"},"servers":[{"url":"https://example.com/api/v1.0"}],"paths":{"/tests/$count":{"get":{"operationId":"getTestResults","responses":{"200":{"description":"Successful operation"}}}}}}"""; @@ -93,6 +96,7 @@ public void GeneratesSnippetsForCountCommand() var openApiMetadata = new OpenApiSnippetMetadata(rootNode, new Dictionary()); using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -102,12 +106,13 @@ public void GeneratesSnippetsForCountCommand() } [Fact] - public async Task GeneratesSnippetsForBetaCommand() + public async Task GeneratesSnippetsForBetaCommandAsync() { // Given string url = $"{ServiceRootBetaUrl}/users"; using var requestMessage = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestMessage, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestMessage, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestMessage); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -118,13 +123,14 @@ public async Task GeneratesSnippetsForBetaCommand() } [Fact] - public async Task GeneratesSnippetsForRefCommand() + public async Task GeneratesSnippetsForRefCommandAsync() { // GET /users/{user-id}/manager/$ref // Given string url = $"{ServiceRootUrl}/users/100/manager/$ref"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -134,13 +140,14 @@ public async Task GeneratesSnippetsForRefCommand() } [Fact] - public async Task GeneratesSnippetsForContentCommand() + public async Task GeneratesSnippetsForContentCommandAsync() { // GET /users/{user-id}/photo/$value // Given string url = $"{ServiceRootUrl}/users/100/photo/$value"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -150,12 +157,13 @@ public async Task GeneratesSnippetsForContentCommand() } [Fact] - public async Task GeneratesSnippetsForGetListCommand() + public async Task GeneratesSnippetsForGetListCommandAsync() { // Given string url = $"{ServiceRootUrl}/users"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -170,7 +178,7 @@ public async Task GeneratesSnippetsForGetListCommand() [InlineData("?id", "--id {id}")] // When the query parameter value is not provided, the snippet generator ignores it [InlineData(null, "--id {id}")] [InlineData("? ", "--id {id}")] - public void GeneratesSnippetsForCommandWithConflictingParameterName(string queryString, string commandSuffix) + public async Task GeneratesSnippetsForCommandWithConflictingParameterNameAsync(string queryString, string commandSuffix) { // Given string schema = """{"openapi":"3.0.0","info":{"title":"Tests API","version":"1.0.11"},"servers":[{"url":"https://example.com/api/v1.0"}],"paths":{"/tests/{id}/results":{"get":{"operationId":"getTestResults","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful operation"}}}}}}"""; @@ -180,6 +188,7 @@ public void GeneratesSnippetsForCommandWithConflictingParameterName(string query string url = $"{ServiceRootUrl}/tests/1/results{queryString}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -190,7 +199,7 @@ public void GeneratesSnippetsForCommandWithConflictingParameterName(string query } [Fact] - public void GeneratesSnippetsForCommandWithConflictingParameterNameAndNoLocation() + public async Task GeneratesSnippetsForCommandWithConflictingParameterNameAndNoLocationAsync() { // Given // This open api doc is not valid since there's a parameter that has no location @@ -202,6 +211,7 @@ public void GeneratesSnippetsForCommandWithConflictingParameterNameAndNoLocation string url = $"{ServiceRootUrl}/tests/1/results"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -212,7 +222,7 @@ public void GeneratesSnippetsForCommandWithConflictingParameterNameAndNoLocation } [Fact] - public void GeneratesSnippetsForCommandWithConflictingPathAndCookieParameterName() + public async Task GeneratesSnippetsForCommandWithConflictingPathAndCookieParameterNameAsync() { // Given // The cookie parameter will be skipped. not supported in the CLI @@ -223,6 +233,7 @@ public void GeneratesSnippetsForCommandWithConflictingPathAndCookieParameterName string url = $"{ServiceRootUrl}/tests/1/results"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -232,7 +243,7 @@ public void GeneratesSnippetsForCommandWithConflictingPathAndCookieParameterName } [Fact] - public void GeneratesSnippetsForCommandWithConflictingPathAndHeaderParameterName() + public async Task GeneratesSnippetsForCommandWithConflictingPathAndHeaderParameterNameAsync() { // Given // The cookie parameter will be skipped. not supported in the CLI @@ -244,6 +255,7 @@ public void GeneratesSnippetsForCommandWithConflictingPathAndHeaderParameterName using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); requestPayload.Headers.Add("id", "test-header"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -255,12 +267,13 @@ public void GeneratesSnippetsForCommandWithConflictingPathAndHeaderParameterName [Theory] [InlineData("?$select=name", " --select \"name\"")] [InlineData("?$filter=test&$select=name", " --filter \"test\" --select \"name\"")] - public async Task GeneratesSnippetsForCommandWithODataParameters(string queryString, string commandOptions) + public async Task GeneratesSnippetsForCommandWithODataParametersAsync(string queryString, string commandOptions) { // Given string url = $"{ServiceRootUrl}/users{queryString}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -270,7 +283,7 @@ public async Task GeneratesSnippetsForCommandWithODataParameters(string queryStr } [Fact] - public void GeneratesSnippetsForCommandWithEmptyParameterNames() + public async Task GeneratesSnippetsForCommandWithEmptyParameterNamesAsync() { // Given string schema = """{"openapi":"3.0.0","info":{"title":"Tests API","version":"1.0.11"},"servers":[{"url":"https://example.com/api/v1.0"}],"paths":{"/tests":{"get":{"operationId":"getTestResults","parameters":[{"name":"","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful operation"}}}}}}"""; @@ -280,6 +293,7 @@ public void GeneratesSnippetsForCommandWithEmptyParameterNames() string url = $"{ServiceRootUrl}/tests?"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -290,7 +304,7 @@ public void GeneratesSnippetsForCommandWithEmptyParameterNames() } [Fact] - public void GeneratesSnippetsForCommandWithQueryParameters() + public async Task GeneratesSnippetsForCommandWithQueryParametersAsync() { // Given string schema = """{"openapi":"3.0.0","info":{"title":"Tests API","version":"1.0.11"},"servers":[{"url":"https://example.com/api/v1.0"}],"paths":{"/tests":{"get":{"operationId":"getTestResults","parameters":[{"name":"id","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Successful operation"}}}}}}"""; @@ -300,6 +314,7 @@ public void GeneratesSnippetsForCommandWithQueryParameters() string url = $"{ServiceRootUrl}/tests?id=10"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, openApiMetadata); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -315,14 +330,15 @@ public void GeneratesSnippetsForCommandWithQueryParameters() [InlineData("Test content", "application/json;a=b;c=d")] [InlineData("Test content", "application/octet-stream;a=b;c=d", "mgc users create --file ")] [InlineData("""{"key": 10}""", "application/json;a=b;c=d", """mgc users create --body '{"key": 10}'""")] - public async Task GeneratesSnippetsForCreateInListCommandWithBody(string content, string contentType = "text/plain", string expectedCommand = "mgc users create --body 'Test content'") + public async Task GeneratesSnippetsForCreateInListCommandWithBodyAsync(string content, string contentType = "text/plain", string expectedCommand = "mgc users create --body 'Test content'") { // Given string url = $"{ServiceRootUrl}/users"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, url); requestPayload.Content = new StringContent(content); requestPayload.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -338,7 +354,7 @@ public async Task GeneratesSnippetsForCreateInListCommandWithBody(string content [InlineData(null, "application/json;a=b;c=d")] [InlineData(" ", "application/octet-stream;a=b;c=d")] [InlineData("Test content", null, true)] - public async Task GeneratesSnippetsForCreateInListCommandWithInvalidContent(string content, string contentType = null, bool removeContentType = false) + public async Task GeneratesSnippetsForCreateInListCommandWithInvalidContentAsync(string content, string contentType = null, bool removeContentType = false) { // Given string url = $"{ServiceRootUrl}/users"; @@ -358,7 +374,8 @@ public async Task GeneratesSnippetsForCreateInListCommandWithInvalidContent(stri } } - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -379,13 +396,14 @@ public void ReturnsEmptyStringForNullSnippetModel() } [Fact] - public async Task ThrowsExceptionOnUnsupportedApiVersion() + public async Task ThrowsExceptionOnUnsupportedApiVersionAsync() { // Given string rootUrl = "https://example.com/v303"; string url = $"{rootUrl}/users"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, rootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, rootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When // Then @@ -393,13 +411,14 @@ public async Task ThrowsExceptionOnUnsupportedApiVersion() } [Fact] - public async Task GeneratesEscapedSnippetsForMultilineCommand() + public async Task GeneratesEscapedSnippetsForMultilineCommandAsync() { // Given string url = $"{ServiceRootUrl}/users"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, url); requestPayload.Content = new StringContent("{\n \"name\": \"test\"\n}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -409,13 +428,14 @@ public async Task GeneratesEscapedSnippetsForMultilineCommand() } [Fact] - public async Task GeneratesEscapedBetaSnippetsForMultilineCommand() + public async Task GeneratesEscapedBetaSnippetsForMultilineCommandAsync() { // Given string url = $"{ServiceRootBetaUrl}/users"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, url); requestPayload.Content = new StringContent("{\n \"name\": \"test\"\n}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -424,12 +444,13 @@ public async Task GeneratesEscapedBetaSnippetsForMultilineCommand() Assert.Equal(Environment.NewLine + "mgc-beta users create --body '{\\\n \"name\": \"test\"\\\n}'", result); } [Fact] - public async Task GeneratesSnippetsContainingOverLoadedBoundFunctionsWithSingleParameter() + public async Task GeneratesSnippetsContainingOverLoadedBoundFunctionsWithSingleParameterAsync() { // Given string url = $"{ServiceRootUrl}/drives/driveid/items/driveitemid/delta(token='token')"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -439,12 +460,13 @@ public async Task GeneratesSnippetsContainingOverLoadedBoundFunctionsWithSingleP } [Fact] - public async Task GeneratesSnippetsContainingOverLoadedBoundFunctionsWithMultipleParameters() + public async Task GeneratesSnippetsContainingOverLoadedBoundFunctionsWithMultipleParametersAsync() { // Given string url = $"{ServiceRootUrl}/drives/driveid/items/driveitemid/getActivitiesByInterval(startDateTime='startdatetime',endDateTime='enddatetime',interval='interval')"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -454,12 +476,13 @@ public async Task GeneratesSnippetsContainingOverLoadedBoundFunctionsWithMultipl } [Fact] - public async Task GeneratesSnippetsContainingUnBoundedFunctions() + public async Task GeneratesSnippetsContainingUnBoundedFunctionsAsync() { // Given string url = $"{ServiceRootUrl}/identity/identityProviders/availableProviderTypes()"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -469,12 +492,13 @@ public async Task GeneratesSnippetsContainingUnBoundedFunctions() } [Fact] - public async Task GeneratesSnippetsWithSlashMeEndpoints() + public async Task GeneratesSnippetsWithSlashMeEndpointsAsync() { // Given string url = $"{ServiceRootUrl}/me/calendar/events?$filter=startsWith%28subject%2C%27All%27%29"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -483,12 +507,13 @@ public async Task GeneratesSnippetsWithSlashMeEndpoints() Assert.Equal(Environment.NewLine + "mgc users calendar events list --user-id {user-id} --filter \"startsWith(subject,'All')\"", result); } [Fact] - public async Task GeneratesSnippetsWithExpandQueryOptions() + public async Task GeneratesSnippetsWithExpandQueryOptionsAsync() { // Given string url = $"{ServiceRootUrl}/me/messages/XXXX?$expand=singleValueExtendedProperties%28$filter%3Did%20eq%20%27XXXX%27%29"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -497,12 +522,13 @@ public async Task GeneratesSnippetsWithExpandQueryOptions() Assert.Equal(Environment.NewLine + "mgc users messages get --user-id {user-id} --message-id {message-id} --expand \"singleValueExtendedProperties(\\$filter=id eq 'XXXX')\"", result); } [Fact] - public async Task GeneratesSnippetsWithFilterQueryOptions() + public async Task GeneratesSnippetsWithFilterQueryOptionsAsync() { // Given string url = $"{ServiceRootUrl}/identityGovernance/accessReviews/definitions?$filter=contains%28scope%2Fmicrosoft.graph.accessReviewQueryScope%2Fquery%2C%20%27.%2Fmembers%27%29"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); @@ -512,12 +538,13 @@ public async Task GeneratesSnippetsWithFilterQueryOptions() } [Fact] - public async Task GeneratesSnippetsForHttpSnippetsWithUrlEncodedValuesForSystemQueryOptionParameters() + public async Task GeneratesSnippetsForHttpSnippetsWithUrlEncodedValuesForSystemQueryOptionParametersAsync() { // Given string url = $"{ServiceRootUrl}/teams/XXXXXXX/members?$filter=%28microsoft.graph.aadUserConversationMember%2FdisplayName%2520eq%2520%27Harry%2520Johnson%27%2520or%2520microsoft.graph.aadUserConversationMember%2Femail%2520eq%2520%27admin%40M365x987948.OnMicrosoft.com%27%29"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, url); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); // When var result = _generator.GenerateCodeSnippet(snippetModel); diff --git a/CodeSnippetsReflection.OpenAPI.Test/JavaGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/JavaGeneratorTests.cs index c6856de30..f218b954c 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/JavaGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/JavaGeneratorTests.cs @@ -11,107 +11,118 @@ public class JavaGeneratorTests : OpenApiSnippetGeneratorTestBase private readonly JavaGenerator _generator = new(); [Fact] - public async Task GeneratesTheCorrectFluentApiPath() + public async Task GeneratesTheCorrectFluentApiPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/policies/crossTenantAccessPolicy/default/resetToSystemDefault"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".policies().crossTenantAccessPolicy().defaultEscaped().resetToSystemDefault()", result); } [Fact] - public async Task GeneratesTheCorrectFluentApiPath_2() + public async Task GeneratesTheCorrectFluentApiPath_2Async() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/security/alerts_v2"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("alertsV2", result); } [Fact] - public async Task GeneratesTheCorrectFluentApiPath_3() + public async Task GeneratesTheCorrectFluentApiPath_3Async() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/print/printers/{{printerId}}/jobs/{{printJobId}}/documents/{{printDocumentId}}/$value"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".content()", result); } [Fact] - public async Task GeneratesTheCorrectFluentApiPath_4() + public async Task GeneratesTheCorrectFluentApiPath_4Async() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/identityGovernance/lifecycleWorkflows/workflows/{{workflowId}}/versions/{{workflowVersion-versionNumber}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("byWorkflowVersionVersionNumber(2)", result); } [Fact] - public async Task GeneratesTheCorrectFluentApiPathForIndexedCollections() + public async Task GeneratesTheCorrectFluentApiPathForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/security/cases/ediscoveryCases/{{case-id}}/close"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".security().cases().ediscoveryCases().byEdiscoveryCaseId(\"{ediscoveryCase-id}\").microsoftGraphSecurityClose()", result); } [Fact] - public async Task GeneratesTheSnippetHeader() + public async Task GeneratesTheSnippetHeaderAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("GraphServiceClient graphClient = new GraphServiceClient(requestAdapter)", result); } [Fact] - public async Task GeneratesTheGetMethodCall() + public async Task GeneratesTheGetMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("get()", result); } [Fact] - public async Task GeneratesThePostMethodCall() + public async Task GeneratesThePostMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("post(", result); } [Fact] - public async Task GeneratesThePatchMethodCall() + public async Task GeneratesThePatchMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("patch(", result); } [Fact] - public async Task GeneratesThePutMethodCall() + public async Task GeneratesThePutMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("put(", result); } [Fact] - public async Task GeneratesTheDeleteMethodCall() + public async Task GeneratesTheDeleteMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("delete(", result); Assert.DoesNotContain("result =", result); } [Fact] - public async Task WritesTheRequestPayload() + public async Task WritesTheRequestPayloadAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + @@ -123,7 +134,8 @@ public async Task WritesTheRequestPayload() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new User()", result); Assert.Contains("setAccountEnabled(true);", result); @@ -132,7 +144,7 @@ public async Task WritesTheRequestPayload() } [Fact] - public async Task WritesALongAndFindsAnAction() + public async Task WritesALongAndFindsAnActionAsync() { const string userJsonObject = "{\r\n \"chainId\": 10\r\n\r\n}"; @@ -140,7 +152,8 @@ public async Task WritesALongAndFindsAnAction() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("10L", result); Assert.Contains("setChainId", result); @@ -148,7 +161,7 @@ public async Task WritesALongAndFindsAnAction() } [Fact] - public async Task WritesADouble() + public async Task WritesADoubleAsync() { const string userJsonObject = "{\r\n \"minimumAttendeePercentage\": 10\r\n\r\n}"; @@ -156,62 +169,67 @@ public async Task WritesADouble() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("10d", result); Assert.Contains("setMinimumAttendeePercentage", result); } [Fact] - public async Task GeneratesABinaryPayload() + public async Task GeneratesABinaryPayloadAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo") { Content = new ByteArrayContent(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }) }; requestPayload.Content.Headers.ContentType = new("application/octet-stream"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new ByteArrayInputStream", result); } [Fact] - public async Task GeneratesABase64UrlPayload() + public async Task GeneratesABase64UrlPayloadAsync() { const string userJsonObject = "{\r\n \"contentBytes\": \"wiubviuwbegviwubiu\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/chats/{{chat-id}}/messages/{{chatMessage-id}}/hostedContents") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Base64.getDecoder().decode", result); Assert.Contains("setContentBytes", result); } [Fact] - public async Task GeneratesADateTimeOffsetPayload() + public async Task GeneratesADateTimeOffsetPayloadAsync() { const string userJsonObject = "{\r\n \"receivedDateTime\": \"2021-08-30T20:00:00:00Z\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("OffsetDateTime.parse(", result); Assert.Contains("message.setReceivedDateTime(receivedDateTime);", result); } [Fact] - public async Task GeneratesAnArrayPayloadInAdditionalData() + public async Task GeneratesAnArrayPayloadInAdditionalDataAsync() { const string userJsonObject = "{\r\n \"members@odata.bind\": [\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\"\r\n ]\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/groups/{{group-id}}") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new LinkedList", result); Assert.Contains("AdditionalData", result); @@ -219,7 +237,7 @@ public async Task GeneratesAnArrayPayloadInAdditionalData() } [Fact] - public async Task GeneratesCorrectTypeForObjectsInAdditionalDataWithSpecifiedOdataType() + public async Task GeneratesCorrectTypeForObjectsInAdditionalDataWithSpecifiedOdataTypeAsync() { var bodyContent = """ { @@ -241,7 +259,8 @@ public async Task GeneratesCorrectTypeForObjectsInAdditionalDataWithSpecifiedOda { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new Identity()", result); Assert.Contains("phone.setOdataType(\"#microsoft.graph.identity\")", result); @@ -250,10 +269,11 @@ public async Task GeneratesCorrectTypeForObjectsInAdditionalDataWithSpecifiedOda } [Fact] - public async Task GeneratesSelectQueryParameters() + public async Task GeneratesSelectQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me?$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("displayName", result); Assert.Contains("requestConfiguration ->", result); @@ -261,10 +281,11 @@ public async Task GeneratesSelectQueryParameters() } [Fact] - public async Task GeneratesCountBooleanQueryParameters() + public async Task GeneratesCountBooleanQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("\"displayName\"", result); Assert.Contains("\"id\"", result); @@ -273,20 +294,22 @@ public async Task GeneratesCountBooleanQueryParameters() } [Fact] - public async Task GeneratesSkipQueryParameters() + public async Task GeneratesSkipQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$skip=10"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.DoesNotContain("\"10\"", result); Assert.Contains("10", result); } [Fact] - public async Task GeneratesSelectExpandQueryParameters()/// + public async Task GeneratesSelectExpandQueryParametersAsync()/// { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members($select=id,displayName)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("expand", result); Assert.Contains("members($select=id,displayName)", result); @@ -294,21 +317,23 @@ public async Task GeneratesSelectExpandQueryParameters()/// } [Fact] - public async Task GeneratesRequestHeaders() + public async Task GeneratesRequestHeadersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.headers.add(\"ConsistencyLevel\", \"eventual\");", result); Assert.Contains("requestConfiguration ->", result); } [Fact] - public async Task GeneratesFilterParameters() + public async Task GeneratesFilterParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$filter=Department eq 'Finance'&$orderBy=displayName&$select=id,displayName,department"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.queryParameters.count", result); Assert.Contains("requestConfiguration.queryParameters.filter", result); @@ -317,39 +342,42 @@ public async Task GeneratesFilterParameters() } [Fact] - public async Task GeneratesFilterParametersWithSpecialCharacters() + public async Task GeneratesFilterParametersWithSpecialCharactersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$filter=imAddresses/any(i:i eq 'admin@contoso.com')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.queryParameters.filter", result); Assert.Contains("imAddresses/any(i:i eq 'admin@contoso.com')", result); } [Fact] - public async Task GeneratesSnippetForRequestWithDeltaAndSkipToken() + public async Task GeneratesSnippetForRequestWithDeltaAndSkipTokenAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/calendarView/delta?$skiptoken=R0usmcCM996atia_s"); requestPayload.Headers.Add("Prefer", "odata.maxpagesize=2"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("DeltaGetResponse result = deltaRequestBuilder.get(", result); Assert.Contains("DeltaRequestBuilder deltaRequestBuilder = new com.microsoft.graph.users.item.calendarview.delta.DeltaRequestBuilder(", result); } [Fact] - public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjunction() + public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjunctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$search=\"displayName:di\" AND \"displayName:al\""); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.queryParameters.search", result); Assert.Contains("requestConfiguration.queryParameters.search = \"\\\"displayName:di\\\" AND \\\"displayName:al\\\"\";", result); } [Fact] - public async Task HandlesOdataTypeWhenGenerating() + public async Task HandlesOdataTypeWhenGeneratingAsync() { var sampleJson = @" { @@ -364,14 +392,15 @@ public async Task HandlesOdataTypeWhenGenerating() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("setOdataType(\"#microsoft.graph.socialIdentityProvider\")", result); Assert.Contains("new SocialIdentityProvider", result);// ensure the derived type is used } [Fact] - public async Task HandlesOdataReferenceSegmentsInUrl() + public async Task HandlesOdataReferenceSegmentsInUrlAsync() { var sampleJson = @" { @@ -382,13 +411,14 @@ public async Task HandlesOdataReferenceSegmentsInUrl() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".acceptedSenders().ref().post(", result); } [Fact] - public async Task GenerateSnippetsWithArrayNesting() + public async Task GenerateSnippetsWithArrayNestingAsync() { var eventData = @" { @@ -429,7 +459,8 @@ public async Task GenerateSnippetsWithArrayNesting() { Content = new StringContent(eventData, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("setContentType(BodyType.Html)", result); Assert.Contains("new LinkedList()", result); @@ -439,7 +470,7 @@ public async Task GenerateSnippetsWithArrayNesting() } [Fact] - public async Task GenerateFindMeetingTime() + public async Task GenerateFindMeetingTimeAsync() { var bodyContent = @" { @@ -483,7 +514,8 @@ public async Task GenerateFindMeetingTime() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("meetingDuration = PeriodAndDuration.ofDuration(Duration.parse(\"PT1H\"));", result); Assert.Contains("setMeetingDuration(meetingDuration)", result); @@ -494,7 +526,7 @@ public async Task GenerateFindMeetingTime() [Theory] [InlineData("sendMail")] [InlineData("microsoft.graph.sendMail")] - public async Task FullyQualifiesActionRequestBodyType(string sendMailString) + public async Task FullyQualifiesActionRequestBodyTypeAsync(string sendMailString) { var bodyContent = @"{ ""message"": { @@ -525,7 +557,8 @@ public async Task FullyQualifiesActionRequestBodyType(string sendMailString) { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.users().byUserId(\"{user-id}\").sendMail().post(sendMailPostRequestBody);", result); Assert.Contains("SendMailPostRequestBody sendMailPostRequestBody = new com.microsoft.graph.users.item.sendmail.SendMailPostRequestBody()", result); @@ -533,7 +566,7 @@ public async Task FullyQualifiesActionRequestBodyType(string sendMailString) } [Fact] - public async Task TypeArgumentsForListArePlacedCorrectly() + public async Task TypeArgumentsForListArePlacedCorrectlyAsync() { var bodyContent = @"{ ""businessPhones"": [ @@ -546,13 +579,14 @@ public async Task TypeArgumentsForListArePlacedCorrectly() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new LinkedList", result); } [Fact] - public async Task ModelsInNestedNamespacesAreDisambiguated() + public async Task ModelsInNestedNamespacesAreDisambiguatedAsync() { var bodyContent = @"{ ""id"": ""1431b9c38ee647f6a"", @@ -563,14 +597,15 @@ public async Task ModelsInNestedNamespacesAreDisambiguated() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new com.microsoft.graph.models.externalconnectors.Identity", result); Assert.Contains("setType(com.microsoft.graph.models.externalconnectors.IdentityType.ExternalGroup)", result); } [Fact] - public async Task ModelSubNamspacesAreExplicitlyTyped() + public async Task ModelSubNamspacesAreExplicitlyTypedAsync() { var bodyContent = """ { @@ -586,13 +621,14 @@ public async Task ModelSubNamspacesAreExplicitlyTyped() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("com.microsoft.graph.models.security.Incident result = ", result); } [Fact] - public async Task CorrectlyGeneratesEnumMember() + public async Task CorrectlyGeneratesEnumMemberAsync() { var bodyContent = @"{ ""id"": ""SHPR_eeab4fb1-20e5-48ca-ad9b-98119d94bee7"", @@ -618,14 +654,15 @@ public async Task CorrectlyGeneratesEnumMember() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("setType(RecurrencePatternType.Weekly)", result); Assert.Contains("setType(RecurrenceRangeType.NoEnd)", result); } [Fact] - public async Task CorrectlyGeneratesMultipleFlagsEnumMembers() + public async Task CorrectlyGeneratesMultipleFlagsEnumMembersAsync() { var bodyContent = """ { @@ -865,13 +902,14 @@ public async Task CorrectlyGeneratesMultipleFlagsEnumMembers() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains($"setStartMenuAppListVisibility(EnumSet.of(WindowsStartMenuAppListVisibilityType.Collapse, WindowsStartMenuAppListVisibilityType.Remove, WindowsStartMenuAppListVisibilityType.UserDefined))", result); } [Fact] - public async Task CorrectlyAddsEnumsToEnumList() + public async Task CorrectlyAddsEnumsToEnumListAsync() { var bodyContent = """ { @@ -884,14 +922,15 @@ public async Task CorrectlyAddsEnumsToEnumList() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("allowedCombinations.add(AuthenticationMethodModes.Password);", result); Assert.Contains("allowedCombinations.add(AuthenticationMethodModes.Voice);", result); } [Fact] - public async Task CorrectlyPicksSingleEnumWhenPayloadDescribesMultipleButRequestOnlyAcceptsOne() + public async Task CorrectlyPicksSingleEnumWhenPayloadDescribesMultipleButRequestOnlyAcceptsOneAsync() { var bodyContent = """ { @@ -903,22 +942,24 @@ public async Task CorrectlyPicksSingleEnumWhenPayloadDescribesMultipleButRequest { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("setStatus(RecordingStatus.NotRecording)", result); } [Fact] - public async Task CorrectlyOptionalRequestBodyParameter() + public async Task CorrectlyOptionalRequestBodyParameterAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/teams/{{id}}/archive"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.teams().byTeamId(\"{team-id}\").archive().post(null);", result); } [Fact] - public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() + public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameterAsync() { var bodyContent = @"{ ""subject"": ""Let's go for lunch"", @@ -934,7 +975,8 @@ public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("startDate = LocalDate.parse(\"2017-09-04\");", result); Assert.Contains("endDate = LocalDate.parse(\"2017-12-31\");", result); @@ -943,7 +985,7 @@ public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() } [Fact] - public async Task CorrectlyEvaluatesOdataActionRequestBodyParameter() + public async Task CorrectlyEvaluatesOdataActionRequestBodyParameterAsync() { var bodyContent = @"{ ""keyCredential"": { @@ -958,13 +1000,14 @@ public async Task CorrectlyEvaluatesOdataActionRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("AddKeyPostRequestBody addKeyPostRequestBody = new com.microsoft.graph.applications.item.addkey.AddKeyPostRequestBody()", result); } [Fact] - public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() + public async Task CorrectlyEvaluatesGuidInRequestBodyParameterAsync() { var bodyContent = @"{ ""principalId"": ""cde330e5-2150-4c11-9c5b-14bfdc948c79"", @@ -975,7 +1018,8 @@ public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("UUID.fromString(\"cde330e5-2150-4c11-9c5b-14bfdc948c79\")", result); Assert.Contains("UUID.fromString(\"8e881353-1735-45af-af21-ee1344582a4d\")", result); @@ -983,7 +1027,7 @@ public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() } [Fact] - public async Task DefaultsEnumIfNoneProvided() + public async Task DefaultsEnumIfNoneProvidedAsync() { var bodyContent = @"{ ""subject"": ""subject-value"", @@ -997,13 +1041,14 @@ public async Task DefaultsEnumIfNoneProvided() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("setContentType(BodyType.Text)", result); } [Fact] - public async Task HandlesEmptyCollection() + public async Task HandlesEmptyCollectionAsync() { var bodyContent = @"{ ""defaultUserRolePermissions"": { @@ -1014,68 +1059,75 @@ public async Task HandlesEmptyCollection() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("permissionGrantPoliciesAssigned = new LinkedList", result); } [Fact] - public async Task CorrectlyHandlesOdataFunction() + public async Task CorrectlyHandlesOdataFunctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/delta?$select=displayName,jobTitle,mobilePhone"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.users().delta().get(", result); Assert.Contains("requestConfiguration.queryParameters.select = new String []{\"displayName\", \"jobTitle\", \"mobilePhone\"};", result); } [Fact] - public async Task CorrectlyHandlesDateTimeOffsetInUrl() + public async Task CorrectlyHandlesDateTimeOffsetInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/reports/getUserArchivedPrintJobs(userId='{{id}}',startDateTime=,endDateTime=)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.reports().getUserArchivedPrintJobsWithUserIdWithStartDateTimeWithEndDateTime(OffsetDateTime.parse(\"{endDateTime}\"), OffsetDateTime.parse(\"{startDateTime}\"), \"{userId}\").get();", result); } [Fact] - public async Task CorrectlyHandlesNumberInUrl() + public async Task CorrectlyHandlesNumberInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/worksheets/{{id|name}}/cell(row=,column=)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.drives().byDriveId(\"{drive-id}\").items().byDriveItemId(\"{driveItem-id}\").workbook().worksheets().byWorkbookWorksheetId(\"{workbookWorksheet-id}\").cellWithRowWithColumn(1, 1).get()", result); } [Fact] - public async Task CorrectlyHandlesDateInUrl() + public async Task CorrectlyHandlesDateInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/reports/getYammerGroupsActivityDetail(date='2018-03-05')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.reports().getYammerGroupsActivityDetailWithDate(LocalDate.parse(\"{date}\")).get()", result); } [Fact] - public async Task CorrectlyHandlesDateInUrl2() + public async Task CorrectlyHandlesDateInUrl2Async() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/communications/callRecords/getPstnCalls(fromDateTime=2019-11-01,toDateTime=2019-12-01)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.communications().callRecords().microsoftGraphCallRecordsGetPstnCallsWithFromDateTimeWithToDateTime(OffsetDateTime.parse(\"{fromDateTime}\"), OffsetDateTime.parse(\"{toDateTime}\")).get()", result); } [Fact] - public async Task CorrectlyHandlesEnumInUrl() + public async Task CorrectlyHandlesEnumInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/identityGovernance/appConsent/appConsentRequests/filterByCurrentUser(on='reviewer')?$filter=userConsentRequests/any(u:u/status eq 'InProgress')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.identityGovernance().appConsent().appConsentRequests().filterByCurrentUserWithOn(\"reviewer\").get", result); } [Fact] - public async Task GeneratesObjectsInArray() + public async Task GeneratesObjectsInArrayAsync() { var sampleJson = @" { @@ -1092,7 +1144,8 @@ public async Task GeneratesObjectsInArray() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("com.microsoft.graph.users.item.assignlicense.AssignLicensePostRequestBody assignLicensePostRequestBody = new com.microsoft.graph.users.item.assignlicense.AssignLicensePostRequestBody();", result); Assert.Contains("LinkedList disabledPlans = new LinkedList", result); @@ -1101,7 +1154,7 @@ public async Task GeneratesObjectsInArray() } [Fact] - public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() + public async Task GeneratesCorrectCollectionTypeAndDerivedInstancesAsync() { var sampleJson = @"{ ""message"": { @@ -1131,7 +1184,8 @@ public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("SendMailPostRequestBody sendMailPostRequestBody = new com.microsoft.graph.users.item.sendmail.SendMailPostRequestBody()", result); Assert.Contains("LinkedList attachments = new LinkedList", result);// Collection defines Base type @@ -1140,7 +1194,7 @@ public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() } [Fact] - public async Task GeneratesPropertiesWithSpecialCharacters() + public async Task GeneratesPropertiesWithSpecialCharactersAsync() { var sampleJson = @"{ ""@odata.type"": ""#microsoft.graph.managedIOSLobApp"", @@ -1199,35 +1253,39 @@ public async Task GeneratesPropertiesWithSpecialCharacters() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("IosMinimumOperatingSystem minimumSupportedOperatingSystem = new IosMinimumOperatingSystem", result); Assert.Contains("setV80(true)", result); //assert property name is pascal case after the 'set' portion } [Fact] - public async Task CorrectlyHandlesTypeFromInUrl() + public async Task CorrectlyHandlesTypeFromInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/mailFolders/?includehiddenfolders=true"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("requestConfiguration.queryParameters.includeHiddenFolders = \"true\";", result); } [Fact] - public async Task MatchesPathWithPathParameter() + public async Task MatchesPathWithPathParameterAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/worksheets/{{id|name}}/range(address='A1:B2')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("var result = graphClient.drives().byDriveId(\"{drive-id}\").items().byDriveItemId(\"{driveItem-id}\").workbook().worksheets().byWorkbookWorksheetId(\"{workbookWorksheet-id}\").rangeWithAddress(\"{address}\").get()", result); } [Fact] - public async Task MatchesPathAlternateKeys() + public async Task MatchesPathAlternateKeysAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/applications(appId='46e6adf4-a9cf-4b60-9390-0ba6fb00bf6b')?$select=id,appId,displayName,requiredResourceAccess"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graphClient.applicationsWithAppId(\"{appId}\").get(", result); } @@ -1244,10 +1302,11 @@ public async Task MatchesPathAlternateKeys() [InlineData("/me/drive/special/documents", "graphClient.drives().byDriveId(\"{drive-id}\").special().byDriveItemId(\"{driveItem-id}\").get()")] [InlineData("/me/drive/root/search(q='Contoso%20Project')", "graphClient.drives().byDriveId(\"{drive-id}\").items().byDriveItemId(\"{driveItem-id}\").searchWithQ(\"{q}\").get()")] [InlineData("/me/drive/items/{id}/workbook/application/calculate", "graphClient.drives().byDriveId(\"{drive-id}\").items().byDriveItemId(\"{driveItem-id}\").workbook().application().calculate()", "POST")] - public async Task GeneratesSnippetWithRemappedDriveCall(string inputPath, string expected, string method = "") + public async Task GeneratesSnippetWithRemappedDriveCallAsync(string inputPath, string expected, string method = "") { using var requestPayload = new HttpRequestMessage(string.IsNullOrEmpty(method) ? HttpMethod.Get : new HttpMethod(method), $"{ServiceRootUrl}{inputPath}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(expected, result); } diff --git a/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetGeneratorTestBase.cs b/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetGeneratorTestBase.cs index 315451c8f..182430e48 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetGeneratorTestBase.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetGeneratorTestBase.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.IO; using System.Net.Http; +using System.Net.Http.Json; using System.Threading.Tasks; using Microsoft.OpenApi.Readers; using Microsoft.OpenApi.Services; @@ -11,27 +13,27 @@ public class OpenApiSnippetGeneratorTestBase { private static OpenApiSnippetMetadata _v1SnippetMetadata; private static OpenApiSnippetMetadata _betaSnippetMetadata; - + private static IList _commandMetadata; + private static readonly HttpClient HttpClient = new (); protected const string ServiceRootUrl = "https://graph.microsoft.com/v1.0"; protected const string ServiceRootBetaUrl = "https://graph.microsoft.com/beta"; - protected async static Task GetV1SnippetMetadata() + protected async static Task GetV1SnippetMetadataAsync() { - return _v1SnippetMetadata ??= await GetTreeNode("https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/v1.0/openapi.yaml"); + return _v1SnippetMetadata ??= await GetTreeNodeAsync("https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/v1.0/openapi.yaml"); } - protected async static Task GetBetaSnippetMetadata() + protected async static Task GetBetaSnippetMetadataAsync() { - return _betaSnippetMetadata ??= await GetTreeNode("https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/beta/openapi.yaml"); + return _betaSnippetMetadata ??= await GetTreeNodeAsync("https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/beta/openapi.yaml"); } - private static async Task GetTreeNode(string url) + private static async Task GetTreeNodeAsync(string url) { Stream stream; if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { - using var httpClient = new HttpClient(); - stream = await httpClient.GetStreamAsync(url); + stream = await HttpClient.GetStreamAsync(url); } else { @@ -44,4 +46,10 @@ private static async Task GetTreeNode(string url) await stream.DisposeAsync(); return new OpenApiSnippetMetadata(OpenApiUrlTreeNode.Create(doc, "default"), doc.Components.Schemas); } + + protected static async Task> GetMgCommandMetadataAsync() + { + return _commandMetadata ??= await HttpClient.GetFromJsonAsync>( + "https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-powershell/dev/src/Authentication/Authentication/custom/common/MgCommandMetadata.json"); + } } diff --git a/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetsGeneratortTests.cs b/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetsGeneratortTests.cs index b58ff2a7b..fd9529bcd 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetsGeneratortTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/OpenApiSnippetsGeneratortTests.cs @@ -1,6 +1,7 @@ using System; using Xunit; using System.Net.Http; +using System.Threading.Tasks; namespace CodeSnippetsReflection.OpenAPI.Test { @@ -14,29 +15,29 @@ public void DefensiveProgramming() Assert.NotNull(new OpenApiSnippetsGenerator("something", "something")); } [Fact] - public void ThrowsOnInvalidServiceVersion() { + public async Task ThrowsOnInvalidServiceVersionAsync() { var generator = new OpenApiSnippetsGenerator(); using var requestMock = new HttpRequestMessage { RequestUri = new Uri("https://graph.microsoft.com/alpha/something") }; - Assert.Throws(() => generator.ProcessPayloadRequest(requestMock, "C#")); + await Assert.ThrowsAsync(() => generator.ProcessPayloadRequestAsync(requestMock, "javascript")); } [Fact] - public void DoesntThrowOnInvalidVersionWithCustomDocument() { + public async Task DoesntThrowOnInvalidVersionWithCustomDocumentAsync() { var generator = new OpenApiSnippetsGenerator(customOpenApiPathOrUrl: "https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/v1.0/openapi.yaml"); using var requestMock = new HttpRequestMessage { RequestUri = new Uri("https://graph.microsoft.com/alpha/me"), Method = HttpMethod.Get, }; - Assert.NotEmpty(generator.ProcessPayloadRequest(requestMock, "C#")); + Assert.NotEmpty(await generator.ProcessPayloadRequestAsync(requestMock, "C#")); } [Fact] - public void ThrowsOnInvalidLanguage() { + public async Task ThrowsOnInvalidLanguageAsync() { var generator = new OpenApiSnippetsGenerator(); using var requestMock = new HttpRequestMessage { RequestUri = new Uri("https://graph.microsoft.com/v1.0/me") }; - Assert.Throws(() => generator.ProcessPayloadRequest(requestMock, "inexistingLanguage")); + await Assert.ThrowsAsync(() => generator.ProcessPayloadRequestAsync(requestMock, "inexistingLanguage")); } } } diff --git a/CodeSnippetsReflection.OpenAPI.Test/PhpGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/PhpGeneratorTests.cs index b5e0b2813..100a42abd 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/PhpGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/PhpGeneratorTests.cs @@ -12,37 +12,40 @@ public class PhpGeneratorTests : OpenApiSnippetGeneratorTestBase private readonly PhpGenerator _generator = new(); [Fact] - public async Task GeneratesTheCorrectFluentApiPathForIndexedCollections() + public async Task GeneratesTheCorrectFluentApiPathForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("->me()->messages()->byMessageId('message-id')", result); } [Fact] - public async Task GeneratesTheCorrectSnippetForUsers() + public async Task GeneratesTheCorrectSnippetForUsersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("->me()->get()", result); } [Fact] - public async Task GeneratesCorrectLongPaths() + public async Task GeneratesCorrectLongPathsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/{{user-id}}/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("->users()->byUserId('user-id')->messages()->get()->wait();", result); } [Fact] - public async Task GeneratesObjectInitializationWithCallToSetters() + public async Task GeneratesObjectInitializationWithCallToSettersAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + @@ -56,14 +59,15 @@ public async Task GeneratesObjectInitializationWithCallToSetters() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestConfiguration = new UsersRequestBuilderPostRequestConfiguration();", result); Assert.Contains("$queryParameters = UsersRequestBuilderPostRequestConfiguration::createQueryParameters();", result); } [Fact] - public async Task IncludesRequestBodyClassName() + public async Task IncludesRequestBodyClassNameAsync() { const string payloadBody = "{\r\n \"passwordCredential\": {\r\n \"displayName\": \"Password friendly name\"\r\n }\r\n}"; @@ -72,7 +76,8 @@ public async Task IncludesRequestBodyClassName() { Content = new StringContent(payloadBody, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("AddPasswordPostRequestBody", result); Assert.Contains(@"use Microsoft\Graph\Beta\GraphServiceClient;", result); @@ -80,21 +85,23 @@ public async Task IncludesRequestBodyClassName() } [Fact] - public async Task FindsPathItemsWithDifferentCasing() + public async Task FindsPathItemsWithDifferentCasingAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/directory/deleteditems/microsoft.graph.group"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$result = $graphServiceClient->directory()->deletedItems()->graphGroup()->get()->wait();", result); } [Fact] - public async Task DoesntFailOnTerminalSlash() + public async Task DoesntFailOnTerminalSlashAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/me/messages/AAMkADYAAAImV_jAAA=/?$expand=microsoft.graph.eventMessage/event"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains( "$graphServiceClient->me()->messages()->byMessageId('message-id')->get($requestConfiguration)", @@ -102,11 +109,12 @@ public async Task DoesntFailOnTerminalSlash() } [Fact] - public async Task GeneratesFilterParameters() + public async Task GeneratesFilterParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$filter=Department eq 'Finance'&$orderBy=displayName&$select=id,displayName,department"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestConfiguration->queryParameters = $queryParameters;", result); Assert.Contains("$queryParameters = UsersRequestBuilderGetRequestConfiguration::createQueryParameters();", result); @@ -116,11 +124,12 @@ public async Task GeneratesFilterParameters() } [Fact] - public async Task GeneratesRequestHeaders() { + public async Task GeneratesRequestHeadersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); requestPayload.Headers.Add("Accept", "application/json"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$headers = [", result); Assert.Contains("'ConsistencyLevel' => 'eventual',", result); @@ -128,7 +137,7 @@ public async Task GeneratesRequestHeaders() { } [Fact] - public async Task GenerateForGroupPostTestSpacing() + public async Task GenerateForGroupPostTestSpacingAsync() { const string body = @" { @@ -146,14 +155,15 @@ public async Task GenerateForGroupPostTestSpacing() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains($"$requestBody = new Group();{Environment.NewLine}" + $"$requestBody->setDescription('Self help community for library');{Environment.NewLine}" + "$requestBody->setDisplayName('Library Assist');", result); } [Fact] - public async Task GeneratesComplicatedObjectsWithNesting() + public async Task GeneratesComplicatedObjectsWithNestingAsync() { const string userJsonObject = "{\r\n \"message\": {\r\n " + @@ -173,7 +183,8 @@ public async Task GeneratesComplicatedObjectsWithNesting() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$message->setCcRecipients($ccRecipientsArray);", result); Assert.Contains("$ccRecipientsArray []= $ccRecipientsRecipient1;", result); @@ -181,35 +192,38 @@ public async Task GeneratesComplicatedObjectsWithNesting() } [Fact] - public async Task GeneratesDeleteRequest() + public async Task GeneratesDeleteRequestAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$graphServiceClient->me()->messages()->byMessageId('message-id')->delete()", result); } [Fact] - public async Task GenerateForRequestBodyCornerCase() + public async Task GenerateForRequestBodyCornerCaseAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages/{{id}}/createReply") { Content = new StringContent("{\"field\":\"Nothinkg to be done\"}", Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestBody = new CreateReplyPostRequestBody();", result); } [Fact] - public async Task GenerateForRefRequests() + public async Task GenerateForRefRequestsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/applications/{{application-id}}/tokenIssuancePolicies/$ref"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); @@ -217,7 +231,7 @@ public async Task GenerateForRefRequests() } [Fact] - public async Task GenerateForPostBodyWithEnums() + public async Task GenerateForPostBodyWithEnumsAsync() { var body = "{\"state\": \"active\", \"serviceIdentifier\":\"id\", \"catalogId\":\"id\"}"; using var requestPayload = @@ -225,24 +239,26 @@ public async Task GenerateForPostBodyWithEnums() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestBody->setState(new UsageRightState('active'));", result); } [Fact] - public async Task GenerateForComplexCornerCase() + public async Task GenerateForComplexCornerCaseAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/identityGovernance/appConsent/appConsentRequests/{{id}}/userConsentRequests/filterByCurrentUser(on='reviewer')"); - var betaTreeNode = await GetBetaSnippetMetadata(); + var betaTreeNode = await GetBetaSnippetMetadataAsync(); var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, betaTreeNode); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("appConsent", result); } [Fact] - public async Task GenerateComplexBodyName() + public async Task GenerateComplexBodyNameAsync() { var url = "/devices/{id}/registeredUsers/$ref"; @@ -251,22 +267,24 @@ public async Task GenerateComplexBodyName() { Content = new StringContent("{\"field\":\"Nothing to be done\"}", Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestBody->setAdditionalData($additionalData);", result); } [Fact] - public async Task GenerateFluentApiPathCornerCase() + public async Task GenerateFluentApiPathCornerCaseAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/activities/recent"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$result = $graphServiceClient->me()->activities()->recent()->get()->wait();", result); } [Fact /*(Skip = "Should fail by default.")*/] - public async Task GenerateWithODataTypeAndODataId() + public async Task GenerateWithODataTypeAndODataIdAsync() { var url = "/communications/calls/{id}/answer"; var bodyContent = @" @@ -291,13 +309,14 @@ public async Task GenerateWithODataTypeAndODataId() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestBody->setCallOptions($callOptions);", result); } [Fact] - public async Task GenerateFindMeetingTime() + public async Task GenerateFindMeetingTimeAsync() { var bodyContent = @" { @@ -345,14 +364,15 @@ public async Task GenerateFindMeetingTime() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new AttendeeBase();", result); Assert.Contains("new LocationConstraintItem();", result); } [Fact] - public async Task GenerateSnippetsWithArrayNesting() + public async Task GenerateSnippetsWithArrayNestingAsync() { var eventData = @" { @@ -393,14 +413,15 @@ public async Task GenerateSnippetsWithArrayNesting() { Content = new StringContent(eventData, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$location = new Location();", result); Assert.Contains("$requestBody->setAttendees($attendeesArray);", result); } [Fact] - public async Task GenerateWithValidRequestBody() + public async Task GenerateWithValidRequestBodyAsync() { var url = "/groups/{id}/acceptedSenders/$ref"; @@ -409,13 +430,14 @@ public async Task GenerateWithValidRequestBody() { Content = new StringContent("{\"@odata.id\":\"https://graph.microsoft.com/v1.0/users/alexd@contoso.com\"}", Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("= new ReferenceCreate();", result); } [Fact] - public async Task GenerateWithOdataId() + public async Task GenerateWithOdataIdAsync() { var url = "/devices/{id}/registeredUsers/$ref"; using var requestPayload = @@ -423,24 +445,26 @@ public async Task GenerateWithOdataId() { Content = new StringContent("{\"@odata.id\":\"https://graph.microsoft.com/v1.0/directoryObjects/{id}\"}", Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("= new ReferenceCreate();", result); } [Fact] - public async Task GenerateWithFilters() + public async Task GenerateWithFiltersAsync() { const string url = "/identityGovernance/lifecycleWorkflows/workflows/{workflowId}/userProcessingResults/summary(startDateTime={TimeStamp},endDateTime={TimeStamp})"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/{url}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new \\DateTime('{endDateTime}'),new \\DateTime('{startDateTime}')", result); } [Fact] - public async Task GenerateForArraysOfEnums() + public async Task GenerateForArraysOfEnumsAsync() { const string url = "/users/{userId}/settings/shiftPreferences"; @@ -470,22 +494,24 @@ public async Task GenerateForArraysOfEnums() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("->setDaysOfWeek([new DayOfWeek('monday'),new DayOfWeek('wednesday'),new DayOfWeek('friday'), ]);", result); } [Fact] - public async Task GenerateForOnPathParameters() + public async Task GenerateForOnPathParametersAsync() { const string url = "/identityGovernance/appConsent/appConsentRequests/filterByCurrentUser(on='parameterValue')"; using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}{url}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("->identityGovernance()->appConsent()->appConsentRequests()->filterByCurrentUserWithOn('reviewer', )->get()", result); } [Fact] - public async Task GenerateForEscapedTypes() + public async Task GenerateForEscapedTypesAsync() { const string url = "/sites/{site-id}/lists"; const string body = @"{ @@ -509,13 +535,14 @@ public async Task GenerateForEscapedTypes() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestBody = new EscapedList();", result); } [Fact] - public async Task GenerateForComplexMapValues() + public async Task GenerateForComplexMapValuesAsync() { const string url = "/communications/calls/{id}/transfer"; const string body = @" @@ -539,7 +566,8 @@ public async Task GenerateForComplexMapValues() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(@"'phone' => [", result); Assert.Contains("'@odata.type' => '#microsoft.graph.identity',", result); @@ -547,7 +575,7 @@ public async Task GenerateForComplexMapValues() } [Fact] - public async Task GenerateForMoreComplexMapping() + public async Task GenerateForMoreComplexMappingAsync() { const string url = "/planner/tasks/{task-id}/details"; const string body = @" @@ -585,14 +613,15 @@ public async Task GenerateForMoreComplexMapping() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("'http%3A//developer%2Emicrosoft%2Ecom' => [", result); Assert.Contains("'https%3A//developer%2Emicrosoft%2Ecom/en-us/graph/graph-explorer' => [", result); } [Fact] - public async Task GenerateForNestedObjectInsideMap() + public async Task GenerateForNestedObjectInsideMapAsync() { const string url = "/security/triggers/retentionEvents"; const string body = @" @@ -613,14 +642,15 @@ public async Task GenerateForNestedObjectInsideMap() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("'eventQuery' => [", result); Assert.Contains("'@odata.type' => 'microsoft.graph.security.eventQuery',", result); } [Fact] - public async Task GenerateWithMoreMapsWithArrayOfObjects() + public async Task GenerateWithMoreMapsWithArrayOfObjectsAsync() { const string url = "/identityGovernance/lifecycleWorkflows/workflows/{workflowId}/createNewVersion"; const string body = @" @@ -683,7 +713,8 @@ public async Task GenerateWithMoreMapsWithArrayOfObjects() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("'value' => 'Welcome to the organization {{userDisplayName}}!',", result); Assert.Contains("'executionConditions' => [", result); @@ -693,7 +724,7 @@ public async Task GenerateWithMoreMapsWithArrayOfObjects() } [Fact] - public async Task GenerateForGuid() + public async Task GenerateForGuidAsync() { const string url = "/communications/calls/logTeleconferenceDeviceQuality"; const string body = @" @@ -786,14 +817,15 @@ public async Task GenerateForGuid() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("new \\DateInterval(", result); Assert.Contains("->setCallChainId('0622673d-9f69-49b3-9d4f-5ec64f42ecce')", result); } [Fact] - public async Task GenerateWithCustomDateAndTimeTypes() + public async Task GenerateWithCustomDateAndTimeTypesAsync() { const string url = "/deviceManagement/deviceConfigurations/{deviceConfigurationId}"; const string body = @" @@ -848,7 +880,8 @@ public async Task GenerateWithCustomDateAndTimeTypes() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(@"use Microsoft\Kiota\Abstractions\Types\Date;", result); Assert.Contains(@"use Microsoft\Kiota\Abstractions\Types\Time;", result); @@ -858,7 +891,7 @@ public async Task GenerateWithCustomDateAndTimeTypes() } [Fact] - public async Task GenerateWithComplexArray() + public async Task GenerateWithComplexArrayAsync() { const string body = @" { @@ -881,14 +914,15 @@ public async Task GenerateWithComplexArray() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains($"'owners@odata.bind' => [{Environment.NewLine}"+ "'https://graph.microsoft.com/v1.0/users/26be1845-4119-4801-a799-aea79d09f1a2', ],", result); } [Fact] - public async Task GeneratesStreamInterfaceInModelSetter() + public async Task GeneratesStreamInterfaceInModelSetterAsync() { var body = @" { @@ -904,43 +938,48 @@ public async Task GeneratesStreamInterfaceInModelSetter() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$dataRecoveryCertificate->setCertificate(\\GuzzleHttp\\Psr7\\Utils::streamFor(base64_decode('Y2VydGlmaWNhdGU=')));", result); } [Fact] - public async Task ReplacesReservedWordsInFluentApiPath() + public async Task ReplacesReservedWordsInFluentApiPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/print/printers/{{printerId}}/shares"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$graphServiceClient->escapedPrint()->printers()->byPrinterId('printer-id')->shares()->get()->wait();", result); } [Fact] - public async Task ReplacesValueIdentifierInPathSegement() + public async Task ReplacesValueIdentifierInPathSegementAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/photo/$value"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$graphServiceClient->me()->photo()->content()->get()->wait();", result); } [Fact] - public async Task GeneratesCorrectRequestconfigurationObjectForIndexedCollections() + public async Task GeneratesCorrectRequestconfigurationObjectForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/{{user-id}}?$select=ext55gb1l09_msLearnCourses"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestConfiguration = new UserItemRequestBuilderGetRequestConfiguration();", result); } [Fact] - public async Task GeneratesRequestConfigurationClassNameWithMeEndpoints() + public async Task GeneratesRequestConfigurationClassNameWithMeEndpointsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me?$expand=manager($levels=max;$select=id,displayName)&$filter=distributionMethod eq 'organization'"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestConfiguration = new UserItemRequestBuilderGetRequestConfiguration();", result); Assert.Contains("$queryParameters->expand = [\"manager(\\$levels=max;\\$select=id,displayName)\"]", result); @@ -948,7 +987,7 @@ public async Task GeneratesRequestConfigurationClassNameWithMeEndpoints() } [Fact] - public async Task EscapesRequestBodySetterNames() + public async Task EscapesRequestBodySetterNamesAsync() { var body = @" { @@ -961,13 +1000,14 @@ public async Task EscapesRequestBodySetterNames() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestBody->setEscapedList($list);", result); } [Fact] - public async Task CleansUnderscoresFromSetters() + public async Task CleansUnderscoresFromSettersAsync() { var body = @" { @@ -983,7 +1023,8 @@ public async Task CleansUnderscoresFromSetters() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$minimumSupportedOperatingSystem->setV80(true);", result); Assert.Contains("$minimumSupportedOperatingSystem->setV81(true);", result); @@ -991,19 +1032,21 @@ public async Task CleansUnderscoresFromSetters() } [Fact] - public async Task GeneratesFromHyphenSeparatedRequestBuilderPath() + public async Task GeneratesFromHyphenSeparatedRequestBuilderPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/policies/crossTenantAccessPolicy/partners/{{crossTenantAccessPolicyConfigurationPartner-tenantId}}/identitySynchronization"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$graphServiceClient->policies()->crossTenantAccessPolicy()->partners()->byCrossTenantAccessPolicyConfigurationPartnerTenantId('crossTenantAccessPolicyConfigurationPartner-tenantId')->identitySynchronization()->delete()->wait();", result); } [Fact] - public async Task GeneratesCorrectRequestConfigNameWithOdataCast() + public async Task GeneratesCorrectRequestConfigNameWithOdataCastAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups/{{id}}/members/microsoft.graph.user?$count=true&$orderby=displayName"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("$requestConfiguration = new GraphUserRequestBuilderGetRequestConfiguration();", result); } diff --git a/CodeSnippetsReflection.OpenAPI.Test/PhpImportGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/PhpImportGeneratorTests.cs index bf7e59c1d..0cf35d6fa 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/PhpImportGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/PhpImportGeneratorTests.cs @@ -12,17 +12,18 @@ public class PhpImportTests : OpenApiSnippetGeneratorTestBase private readonly PhpGenerator _generator = new(); [Fact] - public async Task GeneratesRequestBuilderImports() + public async Task GeneratesRequestBuilderImportsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/calendar/events?$filter=startsWith(subject,'All')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("use Microsoft\\Graph\\GraphServiceClient;", result); Assert.Contains("use Microsoft\\Graph\\Generated\\Users\\Item\\Calendar\\Events\\EventsRequestBuilderGetRequestConfiguration;", result); } [Fact] - public async Task GenerateModelImports(){ + public async Task GenerateModelImportsAsync(){ var bodyContent = @"{ ""displayName"": ""New display name"" }"; @@ -30,14 +31,15 @@ public async Task GenerateModelImports(){ { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("use Microsoft\\Graph\\GraphServiceClient;", result); Assert.Contains("use Microsoft\\Graph\\Generated\\Models\\Application;", result); } [Fact] - public async Task GenerateComplexModelImports(){ + public async Task GenerateComplexModelImportsAsync(){ var bodyContent = @"{ ""subject"": ""Annual review"", ""body"": { @@ -65,7 +67,8 @@ public async Task GenerateComplexModelImports(){ { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("use Microsoft\\Graph\\GraphServiceClient;", result); Assert.Contains("use Microsoft\\Graph\\Generated\\Models\\Message;", result); diff --git a/CodeSnippetsReflection.OpenAPI.Test/PowerShellGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/PowerShellGeneratorTests.cs index 359a7394f..f3b6c04b0 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/PowerShellGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/PowerShellGeneratorTests.cs @@ -9,169 +9,187 @@ namespace CodeSnippetsReflection.OpenAPI.Test { public class PowerShellGeneratorTests : OpenApiSnippetGeneratorTestBase { - private readonly PowerShellGenerator _generator = new(); + private readonly PowerShellGenerator _generator = new(GetMgCommandMetadataAsync().GetAwaiter().GetResult()); [Fact] - public async Task GeneratesSnippetForTheGetMethodCall() + public async Task GeneratesSnippetForTheGetMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-", result); } [Fact] - public async Task GeneratesSnippetForThePostMethodCall() + public async Task GeneratesSnippetForThePostMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/users"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("New-", result); } [Fact] - public async Task GeneratesSnippetForThePatchMethodCall() + public async Task GeneratesSnippetForThePatchMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Update-", result); } [Fact] - public async Task GeneratesSnippetForThePutMethodCall() + public async Task GeneratesSnippetForThePutMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Set-", result); } [Fact] - public async Task GeneratesSnippetForTheDeleteMethodCall() + public async Task GeneratesSnippetForTheDeleteMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Remove-", result); } [Fact] - public async Task GeneratesSnippetForRequestWithSelectQueryOption() + public async Task GeneratesSnippetForRequestWithSelectQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Property \"displayName,id\"", result); } [Fact] - public async Task GeneratesNoneEncodedSnippetForRequestWithFilterQueryOptionAndEncodedPayloads() + public async Task GeneratesNoneEncodedSnippetForRequestWithFilterQueryOptionAndEncodedPayloadsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$filter=displayName+eq+'Megan+Bowen'"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Filter \"displayName eq 'Megan Bowen'\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithFilterQueryOption() + public async Task GeneratesSnippetForRequestWithFilterQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$filter=displayName eq 'Megan Bowen'"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Filter \"displayName eq 'Megan Bowen'\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithExpandQueryOption() + public async Task GeneratesSnippetForRequestWithExpandQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-ExpandProperty \"members\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithExpandQueryOptionWithSelect() + public async Task GeneratesSnippetForRequestWithExpandQueryOptionWithSelectAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members($select=displayName)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-ExpandProperty \"members(`$select=displayName)\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithOrderByQueryOption() + public async Task GeneratesSnippetForRequestWithOrderByQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$orderby=displayName"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Sort \"displayName\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithOrderByQueryOptionWithSortDirection() + public async Task GeneratesSnippetForRequestWithOrderByQueryOptionWithSortDirectionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$orderby=displayName desc"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Sort \"displayName desc\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithOrderByQueryOptionWithMultipleSortingFields() + public async Task GeneratesSnippetForRequestWithOrderByQueryOptionWithMultipleSortingFieldsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$orderby=displayName,mail"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Sort \"displayName,mail\"", result); } [Fact] - public async Task GeneratesSnippetForRequestWithTopQueryOption() + public async Task GeneratesSnippetForRequestWithTopQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$top=3"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Top 3", result); } [Fact] - public async Task GeneratesSnippetForRequestWithSkipQueryOption() + public async Task GeneratesSnippetForRequestWithSkipQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$skip=10"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Skip 10", result); } [Fact] - public async Task GeneratesSnippetForRequestWithCountQueryOption() + public async Task GeneratesSnippetForRequestWithCountQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-CountVariable CountVar", result); Assert.Contains("-ConsistencyLevel eventual", result); } [Fact] - public async Task GeneratesSnippetForRequestWithPathParameters() + public async Task GeneratesSnippetForRequestWithPathParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/48d31887-5fad-4d73-a9f5-3c356e68a038/appRoleAssignments/hxjTSK1fc02p9Tw1bmigOD83KvI8C1hIl2enozuqhEM"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-UserId $userId -AppRoleAssignmentId $appRoleAssignmentId", result); } [Fact] - public async Task GeneratesSnippetForRequestWithQueryParameters() + public async Task GeneratesSnippetForRequestWithQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?customParameter=value"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Customparameter \"value\"", result); } @@ -179,10 +197,11 @@ public async Task GeneratesSnippetForRequestWithQueryParameters() [Theory] [InlineData("/me")] [InlineData("/me/messages")] - public async Task GeneratesSnippetsForMeSegment(string path) + public async Task GeneratesSnippetsForMeSegmentAsync(string path) { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}{path}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-UserId $userId", result); Assert.Contains("# A UPN can also be used as -UserId.", result); @@ -191,10 +210,11 @@ public async Task GeneratesSnippetsForMeSegment(string path) [Theory] [InlineData("/users")] [InlineData("/users/48d31887-5fad-4d73-a9f5-3c356e68a038")] - public async Task GeneratesSnippetsForUserSegment(string path) + public async Task GeneratesSnippetsForUserSegmentAsync(string path) { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}{path}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-MgUser", result); @@ -204,10 +224,11 @@ public async Task GeneratesSnippetsForUserSegment(string path) [Theory] [InlineData("/me/changePassword")] [InlineData("/users/{user-id}/microsoft.graph.changePassword")] - public async Task GeneratesSnippetsForODataAction(string path) + public async Task GeneratesSnippetsForODataActionAsync(string path) { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}{path}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-UserId $userId", result); Assert.Contains("Update-MgUserPassword", result); @@ -216,57 +237,62 @@ public async Task GeneratesSnippetsForODataAction(string path) [Theory] [InlineData("/me")] [InlineData("/users/48d31887-5fad-4d73-a9f5-3c356e68a038")] - public async Task GeneratesSnippetForImportModule(string path) + public async Task GeneratesSnippetForImportModuleAsync(string path) { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}{path}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var firstLine = result.Substring(0, result.IndexOf(Environment.NewLine)); Assert.StartsWith("Import-Module Microsoft.Graph.Users", firstLine); } [Fact] - public async Task GeneratesSnippetForRequestWithSearchQueryOption() + public async Task GeneratesSnippetForRequestWithSearchQueryOptionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$search=\"displayName:Megan\""); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Search '\"displayName:Megan\"'", result); Assert.Contains("-ConsistencyLevel eventual", result); } [Fact] - public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithORLogicalConjuction() + public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithORLogicalConjuctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$search=\"displayName:di\" OR \"displayName:al\""); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Search '\"displayName:di\" OR \"displayName:al\"'", result); Assert.Contains("-ConsistencyLevel eventual", result); } [Fact] - public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjuction() + public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjuctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$search=\"displayName:di\" AND \"displayName:al\""); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-Search '\"displayName:di\" AND \"displayName:al\"'", result); Assert.Contains("-ConsistencyLevel eventual", result); } [Fact] - public async Task GeneratesSnippetForRequestWithNoBody() + public async Task GeneratesSnippetForRequestWithNoBodyAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.DoesNotContain("-BodyParameter", result); } [Fact] - public async Task GeneratesSnippetForRequestWithBody() + public async Task GeneratesSnippetForRequestWithBodyAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/users") { @@ -275,7 +301,8 @@ public async Task GeneratesSnippetForRequestWithBody() Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expectedParams = $"$params = @{{{Environment.NewLine}\t" + $"displayName = \"Melissa Darrow\"{Environment.NewLine}\t" + @@ -285,7 +312,7 @@ public async Task GeneratesSnippetForRequestWithBody() } [Fact] - public async Task GeneratesSnippetForRequestWithNestedBody() + public async Task GeneratesSnippetForRequestWithNestedBodyAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/users") { @@ -298,7 +325,8 @@ public async Task GeneratesSnippetForRequestWithNestedBody() Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expectedParams = $"$params = @{{{Environment.NewLine}\t" + $"displayName = \"Melissa Darrow\"{Environment.NewLine}\t" + @@ -313,7 +341,7 @@ public async Task GeneratesSnippetForRequestWithNestedBody() } [Fact] - public async Task GeneratesSnippetForRequestWithArrayInBody() + public async Task GeneratesSnippetForRequestWithArrayInBodyAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/groups") { @@ -322,7 +350,8 @@ public async Task GeneratesSnippetForRequestWithArrayInBody() Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expectedParams = $"$params = @{{{Environment.NewLine}\t" + $"displayName = \"Library Assist\"{Environment.NewLine}\t" + @@ -335,7 +364,7 @@ public async Task GeneratesSnippetForRequestWithArrayInBody() Assert.Contains("-BodyParameter $params", result); } [Fact] - public async Task GeneratesSnippetForRequestWithWrongQuotesForStringLiteralsInBody() + public async Task GeneratesSnippetForRequestWithWrongQuotesForStringLiteralsInBodyAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/policies/claimsMappingPolicies") { @@ -344,7 +373,8 @@ public async Task GeneratesSnippetForRequestWithWrongQuotesForStringLiteralsInBo Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expectedParams = $"$params = @{{{Environment.NewLine}\t" + $"definition = @(" + @@ -360,43 +390,47 @@ public async Task GeneratesSnippetForRequestWithWrongQuotesForStringLiteralsInBo } [Fact] - public async Task GeneratesSnippetForDeltaFunctionsWithoutParams() + public async Task GeneratesSnippetForDeltaFunctionsWithoutParamsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/contacts/delta()?$select=displayName%2CjobTitle%2Cmail"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgContactDelta", result); } [Fact] - public async Task GeneratesSnippetForHttpSnippetsWithGraphPrefixOnLastPathSegment() + public async Task GeneratesSnippetForHttpSnippetsWithGraphPrefixOnLastPathSegmentAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/places/graph.room"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgPlaceAsRoom", result); } [Fact] - public async Task GeneratesSnippetForHttpSnippetsWithoutGraphPrefixOnLastPathSegment() + public async Task GeneratesSnippetForHttpSnippetsWithoutGraphPrefixOnLastPathSegmentAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/places/microsoft.graph.room"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgPlaceAsRoom", result); } [Fact] - public async Task GeneratesSnippetForPathsWithIdentityProviderAsRootNode() + public async Task GeneratesSnippetForPathsWithIdentityProviderAsRootNodeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/identityProviders"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgIdentityProvider", result); } [Fact] - public async Task GeneratesSnippetForRequestWithTextContentType() + public async Task GeneratesSnippetForRequestWithTextContentTypeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/me/drive/items/XXXX/content") { @@ -405,13 +439,14 @@ public async Task GeneratesSnippetForRequestWithTextContentType() Encoding.UTF8, "text/plain") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Set-MgDriveItemContent", result); } [Fact] - public async Task GeneratesSnippetForRequestWithApplicationZipContentType() + public async Task GeneratesSnippetForRequestWithApplicationZipContentTypeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/me/drive/items/XXXX/content") { @@ -420,13 +455,14 @@ public async Task GeneratesSnippetForRequestWithApplicationZipContentType() Encoding.UTF8, "application/zip") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Set-MgDriveItemContent", result); } [Fact] - public async Task GeneratesSnippetForRequestWithImageContentType() + public async Task GeneratesSnippetForRequestWithImageContentTypeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/me/photo/$value") { @@ -435,61 +471,67 @@ public async Task GeneratesSnippetForRequestWithImageContentType() Encoding.UTF8, "image/jpeg") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Set-MgUserPhotoContent", result); Assert.Contains("-BodyParameter", result); } [Fact] - public async Task GeneratesBetaSnippetForFunctionsWithoutParams() + public async Task GeneratesBetaSnippetForFunctionsWithoutParamsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/contacts/delta()?$select=displayName%2CjobTitle%2Cmail"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgBetaContactDelta", result); } [Fact] - public async Task GeneratesBetaSnippetForFunctionsWithSingleParam() + public async Task GeneratesBetaSnippetForFunctionsWithSingleParamAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/roleManagement/directory/roleEligibilitySchedules/filterByCurrentUser(on='principal')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Invoke-MgBetaFilterRoleManagementDirectoryRoleEligibilityScheduleByCurrentUser", result); Assert.Contains("-On", result); } [Fact] - public async Task GeneratesBetaSnippetForFunctionsWithMultipleParam() + public async Task GeneratesBetaSnippetForFunctionsWithMultipleParamAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/communications/callRecords/getPstnBlockedUsersLog(fromDateTime=XXXXXX,toDateTime=XXXXX)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgBetaCommunicationCallRecordPstnBlockedUserLog", result); Assert.Contains("-ToDateTime", result); } [Fact] - public async Task GeneratesBetaSnippetForHttpSnippetsWithGraphPrefixOnLastPathSegment() + public async Task GeneratesBetaSnippetForHttpSnippetsWithGraphPrefixOnLastPathSegmentAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/places/graph.room"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgBetaPlaceAsRoom", result); } [Fact] - public async Task GeneratesBetaSnippetForPathsWithIdentityProviderAsRootNode() + public async Task GeneratesBetaSnippetForPathsWithIdentityProviderAsRootNodeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/identityProviders"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Get-MgBetaIdentityProvider", result); } [Fact] - public async Task GeneratesBetaSnippetForRequestWithTextContentType() + public async Task GeneratesBetaSnippetForRequestWithTextContentTypeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootBetaUrl}/me/drive/items/XXXX/content") { @@ -498,13 +540,14 @@ public async Task GeneratesBetaSnippetForRequestWithTextContentType() Encoding.UTF8, "text/plain") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Set-MgBetaDriveItemContent", result); } [Fact] - public async Task GeneratesBetaSnippetForRequestWithApplicationZipContentType() + public async Task GeneratesBetaSnippetForRequestWithApplicationZipContentTypeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootBetaUrl}/me/drive/items/XXXX/content") { @@ -513,13 +556,14 @@ public async Task GeneratesBetaSnippetForRequestWithApplicationZipContentType() Encoding.UTF8, "application/zip") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Set-MgBetaDriveItemContent", result); } [Fact] - public async Task GeneratesBetaSnippetForRequestWithImageContentType() + public async Task GeneratesBetaSnippetForRequestWithImageContentTypeAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootBetaUrl}/me/photo/$value") { @@ -528,24 +572,26 @@ public async Task GeneratesBetaSnippetForRequestWithImageContentType() Encoding.UTF8, "image/jpeg") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("Set-MgBetaUserPhotoContent", result); Assert.Contains("-BodyParameter", result); } [Fact] - public async Task GeneratesSnippetForRequestWithHyphenatedRequestHeaderNames() + public async Task GeneratesSnippetForRequestWithHyphenatedRequestHeaderNamesAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootBetaUrl}/planner/tasks/xxxxxxxx"); requestPayload.Headers.Add("If-Match", "W/\"lastEtagId\""); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("-IfMatch W/'\"lastEtagId\"'", result); Assert.Contains("Update-MgBetaPlannerTask", result); } [Fact] - public async Task GeneratesSnippetForRequestWithNestedArrayAndObjectsInBody() + public async Task GeneratesSnippetForRequestWithNestedArrayAndObjectsInBodyAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/education/classes/XXXXX/assignmentSettings") { @@ -554,7 +600,8 @@ public async Task GeneratesSnippetForRequestWithNestedArrayAndObjectsInBody() Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expectedParams = $"$params = @{{{Environment.NewLine}\t" + $"gradingSchemes = @({Environment.NewLine}\t\t" + diff --git a/CodeSnippetsReflection.OpenAPI.Test/PythonGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/PythonGeneratorTests.cs index ab53752fd..e7b643d7b 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/PythonGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/PythonGeneratorTests.cs @@ -11,73 +11,81 @@ public class PythonGeneratorTests : OpenApiSnippetGeneratorTestBase private readonly PythonGenerator _generator = new(); [Fact] - public async Task GeneratesTheCorrectFluentApiPath() + public async Task GeneratesTheCorrectFluentApiPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".me.messages.get()", result); } [Fact] - public async Task GeneratesTheCorrectFluentApiPathForIndexedCollections() + public async Task GeneratesTheCorrectFluentApiPathForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".me.messages.by_message_id('message-id').get()", result); } [Fact] - public async Task GeneratesTheCorrectSnippetForUsers() + public async Task GeneratesTheCorrectSnippetForUsersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".me.get()", result); } [Fact] - public async Task GeneratesTheClientCommnet() + public async Task GeneratesTheSnippetHeaderAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python", result); } [Fact] - public async Task GeneratesThePostMethodCall() + public async Task GeneratesThePostMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("post(None)", result); } [Fact] - public async Task GeneratesThePatchMethodCall() + public async Task GeneratesThePatchMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("patch(None)", result); } [Fact] - public async Task GeneratesThePutMethodCall() + public async Task GeneratesThePutMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("put()", result); } [Fact] - public async Task GeneratesTheDeleteMethodCall() + public async Task GeneratesTheDeleteMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("delete()", result); Assert.DoesNotContain("result =", result); } [Fact] - public async Task WritesTheRequestPayload() + public async Task WritesTheRequestPayloadAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + @@ -89,7 +97,8 @@ public async Task WritesTheRequestPayload() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = User(", result); Assert.Contains("account_enabled = True", result); @@ -99,7 +108,7 @@ public async Task WritesTheRequestPayload() Assert.Contains("password = \"password-value\"", result); } [Fact] - public async Task WritesAnIntAndFindsAnAction() + public async Task WritesAnIntAndFindsAnActionAsync() { const string userJsonObject = "{\r\n \"chainId\": 10\r\n\r\n}"; @@ -107,54 +116,59 @@ public async Task WritesAnIntAndFindsAnAction() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = SendActivityNotificationPostRequestBody(", result); Assert.Contains("chain_id = 10", result); Assert.DoesNotContain("microsoft.graph", result); } [Fact] - public async Task GeneratesABinaryPayload() + public async Task GeneratesABinaryPayloadAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo") { Content = new ByteArrayContent(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }) }; requestPayload.Content.Headers.ContentType = new ("application/octet-stream"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = BytesIO()", result); } [Fact] - public async Task GeneratesABase64UrlPayload() { + public async Task GeneratesABase64UrlPayloadAsync() { const string userJsonObject = "{\r\n \"contentBytes\": \"wiubviuwbegviwubiu\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/chats/{{chat-id}}/messages/{{chatMessage-id}}/hostedContents") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = ChatMessageHostedContent(", result); Assert.Contains("content_bytes = base64.urlsafe_b64decode(\"wiubviuwbegviwubiu\")", result); } [Fact] - public async Task GeneratesADateTimePayload() + public async Task GeneratesADateTimePayloadAsync() { const string userJsonObject = "{\r\n \"receivedDateTime\": \"2021-08-30T20:00:00:00Z\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = Message(", result); Assert.Contains("received_date_time = \"2021-08-30T20:00:00:00Z\"", result); } [Fact] - public async Task GeneratesAnArrayPayloadInAdditionalData() + public async Task GeneratesAnArrayPayloadInAdditionalDataAsync() { const string userJsonObject = "{\r\n \"members@odata.bind\": [\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",\r\n \"https://graph.microsoft.com/v1.0/directoryObjects/{id}\"\r\n ]\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/groups/{{group-id}}") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = Group(", result); Assert.Contains("additional_data = {", result); @@ -162,10 +176,11 @@ public async Task GeneratesAnArrayPayloadInAdditionalData() Assert.Contains("\"https://graph.microsoft.com/v1.0/directoryObjects/{id}\",", result); } [Fact] - public async Task GeneratesSelectQueryParameters() + public async Task GeneratesSelectQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me?$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("RequestBuilderGetQueryParameters(", result); Assert.Contains("select = [\"displayName\",\"id\"]", result); @@ -173,10 +188,11 @@ public async Task GeneratesSelectQueryParameters() Assert.Contains("query_parameters = query_params,", result); } [Fact] - public async Task GeneratesCountBooleanQueryParameters() + public async Task GeneratesCountBooleanQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("query_params = UsersRequestBuilder.UsersRequestBuilderGetQueryParameters(", result); Assert.Contains("count = True", result); @@ -186,40 +202,44 @@ public async Task GeneratesCountBooleanQueryParameters() Assert.Contains("query_parameters = query_params,", result); } [Fact] - public async Task GeneratesSkipQueryParameters() + public async Task GeneratesSkipQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$skip=10"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.DoesNotContain("\"10\"", result); Assert.Contains("skip = 10", result); } [Fact] - public async Task GeneratesSelectExpandQueryParameters() + public async Task GeneratesSelectExpandQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members($select=id,displayName)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("expand =", result); Assert.Contains("members($select=id,displayName)", result); Assert.DoesNotContain("Select", result); } [Fact] - public async Task GeneratesRequestHeaders() + public async Task GeneratesRequestHeadersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_configuration = RequestConfiguration()", result); Assert.Contains("from kiota_abstractions.base_request_configuration import RequestConfiguration", result); Assert.Contains("request_configuration.headers.add(\"ConsistencyLevel\", \"eventual\")", result); } [Fact] - public async Task GeneratesFilterParameters() + public async Task GeneratesFilterParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$filter=Department eq 'Finance'&$orderBy=displayName&$select=id,displayName,department"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("RequestBuilderGetQueryParameters(", result); Assert.Contains("count = True,", result); @@ -228,20 +248,22 @@ public async Task GeneratesFilterParameters() Assert.Contains("select = [\"id\",\"displayName\",\"department\"],", result); } [Fact] - public async Task GeneratesFilterParametersWithSpecialCharacters() + public async Task GeneratesFilterParametersWithSpecialCharactersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$filter=imAddresses/any(i:i eq 'admin@contoso.com')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("RequestBuilderGetQueryParameters(", result); Assert.Contains("filter = \"imAddresses/any(i:i eq 'admin@contoso.com')\",", result); } [Fact] - public async Task GeneratesSnippetForRequestWithDeltaAndSkipToken() + public async Task GeneratesSnippetForRequestWithDeltaAndSkipTokenAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/calendarView/delta?$skiptoken=R0usmcCM996atia_s"); requestPayload.Headers.Add("Prefer", "odata.maxpagesize=2"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("DeltaRequestBuilderGetQueryParameters(", result); Assert.Contains("skiptoken = \"R0usmcCM996atia_s\",", result); @@ -252,18 +274,19 @@ public async Task GeneratesSnippetForRequestWithDeltaAndSkipToken() Assert.Contains("result = await graph_client.me.calendar_view.delta.get", result); } [Fact] - public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjunction() + public async Task GeneratesSnippetForRequestWithSearchQueryOptionWithANDLogicalConjunctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$search=\"displayName:di\" AND \"displayName:al\""); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("RequestBuilderGetQueryParameters(", result); Assert.Contains("search = \"\\\"displayName:di\\\" AND \\\"displayName:al\\\"\"", result); Assert.Contains("request_configuration.headers.add(\"ConsistencyLevel\", \"eventual\")", result); } [Fact] - public async Task HandlesOdataTypeWhenGenerating() + public async Task HandlesOdataTypeWhenGeneratingAsync() { var sampleJson = @" { @@ -277,13 +300,14 @@ public async Task HandlesOdataTypeWhenGenerating() using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/identity/identityProviders"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = SocialIdentityProvider(", result);// ensure the derived type is used Assert.Contains("odata_type = \"#microsoft.graph.socialIdentityProvider\",", result); } [Fact] - public async Task HandlesOdataReferenceSegmentsInUrl() + public async Task HandlesOdataReferenceSegmentsInUrlAsync() { var sampleJson = @" { @@ -293,14 +317,15 @@ public async Task HandlesOdataReferenceSegmentsInUrl() using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/groups/id/acceptedSenders/$ref"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = ReferenceCreate(", result); Assert.Contains("odata_id = \"https://graph.microsoft.com/beta/users/alexd@contoso.com\"", result); Assert.Contains(".accepted_senders.ref.post(request_body)", result); } [Fact] - public async Task GenerateSnippetsWithArrayNesting() + public async Task GenerateSnippetsWithArrayNestingAsync() { var eventData = @" { @@ -341,7 +366,8 @@ public async Task GenerateSnippetsWithArrayNesting() { Content = new StringContent(eventData, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("subject = \"Let's go for lunch\",", result); @@ -354,7 +380,7 @@ public async Task GenerateSnippetsWithArrayNesting() Assert.Contains("type = AttendeeType.Optional", result); } [Fact] - public async Task GenerateFindMeetingTime() + public async Task GenerateFindMeetingTimeAsync() { var bodyContent = @" { @@ -398,7 +424,8 @@ public async Task GenerateFindMeetingTime() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("meeting_duration = \"PT1H\"", result); Assert.Contains("is_required = False,", result); @@ -407,7 +434,7 @@ public async Task GenerateFindMeetingTime() [Theory] [InlineData("sendMail")] [InlineData("microsoft.graph.sendMail")] - public async Task FullyQualifiesActionRequestBodyType(string sendMailString) + public async Task FullyQualifiesActionRequestBodyTypeAsync(string sendMailString) { var bodyContent = @"{ ""message"": { @@ -438,7 +465,8 @@ public async Task FullyQualifiesActionRequestBodyType(string sendMailString) { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("graph_client.users.by_user_id('user-id').send_mail.post(request_body)", result); @@ -447,7 +475,7 @@ public async Task FullyQualifiesActionRequestBodyType(string sendMailString) Assert.Contains("],", result); } [Fact] - public async Task TypeArgumentsForListArePlacedCorrectly() + public async Task TypeArgumentsForListArePlacedCorrectlyAsync() { var bodyContent = @"{ ""businessPhones"": [ @@ -460,14 +488,15 @@ public async Task TypeArgumentsForListArePlacedCorrectly() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("business_phones = [", result); Assert.Contains("+1 425 555 0109", result); } [Fact] - public async Task ModelsInNestedNamespacesAreDisambiguated() + public async Task ModelsInNestedNamespacesAreDisambiguatedAsync() { var bodyContent = @"{ ""id"": ""1431b9c38ee647f6a"", @@ -478,14 +507,15 @@ public async Task ModelsInNestedNamespacesAreDisambiguated() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = Identity(", result); Assert.Contains("type = IdentityType.ExternalGroup,", result); } [Fact] - public async Task CorrectlyGeneratesEnumMember() + public async Task CorrectlyGeneratesEnumMemberAsync() { var bodyContent = @"{ ""id"": ""SHPR_eeab4fb1-20e5-48ca-ad9b-98119d94bee7"", @@ -511,14 +541,15 @@ public async Task CorrectlyGeneratesEnumMember() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("type = RecurrencePatternType.Weekly,", result); Assert.Contains("type = RecurrenceRangeType.NoEnd,", result); } [Fact] - public async Task CorrectlyGeneratesMultipleFlagsEnumMembers() + public async Task CorrectlyGeneratesMultipleFlagsEnumMembersAsync() { var bodyContent = @"{ ""clientContext"": ""clientContext-value"", @@ -529,23 +560,25 @@ public async Task CorrectlyGeneratesMultipleFlagsEnumMembers() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("client_context = \"clientContext-value\",", result); Assert.Contains("status = RecordingStatus.NotRecording | RecordingStatus.Recording | RecordingStatus.Failed", result); } [Fact] - public async Task CorrectlyOptionalRequestBodyParameter() + public async Task CorrectlyOptionalRequestBodyParameterAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/teams/{{id}}/archive"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graph_client.teams.by_team_id('team-id').archive.post(None)", result); } [Fact] - public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() + public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameterAsync() { var bodyContent = @"{ ""subject"": ""Let's go for lunch"", @@ -561,14 +594,15 @@ public async Task CorrectlyEvaluatesDatePropertyTypeRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("start_date = \"2017-09-04\",", result); Assert.Contains("end_date = \"2017-12-31\",", result); } [Fact] - public async Task CorrectlyEvaluatesOdataActionRequestBodyParameter() + public async Task CorrectlyEvaluatesOdataActionRequestBodyParameterAsync() { var bodyContent = @"{ ""keyCredential"": { @@ -583,14 +617,15 @@ public async Task CorrectlyEvaluatesOdataActionRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = AddKeyPostRequestBody(", result); Assert.Contains("key_credential = KeyCredential(", result); } [Fact] - public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() + public async Task CorrectlyEvaluatesGuidInRequestBodyParameterAsync() { var bodyContent = @"{ ""principalId"": ""cde330e5-2150-4c11-9c5b-14bfdc948c79"", @@ -601,7 +636,8 @@ public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("UUID(\"cde330e5-2150-4c11-9c5b-14bfdc948c79\")", result); @@ -609,7 +645,7 @@ public async Task CorrectlyEvaluatesGuidInRequestBodyParameter() Assert.Contains("UUID(\"00000000-0000-0000-0000-000000000000\")", result); } [Fact] - public async Task DefaultsEnumIfNoneProvided() + public async Task DefaultsEnumIfNoneProvidedAsync() { var bodyContent = @"{ ""subject"": ""subject-value"", @@ -623,12 +659,13 @@ public async Task DefaultsEnumIfNoneProvided() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("content_type = BodyType.Text,", result); } [Fact] - public async Task HandlesEmptyCollection() + public async Task HandlesEmptyCollectionAsync() { var bodyContent = @"{ ""defaultUserRolePermissions"": { @@ -639,15 +676,17 @@ public async Task HandlesEmptyCollection() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("permission_grant_policies_assigned = [", result); } [Fact] - public async Task CorrectlyHandlesOdataFunction() + public async Task CorrectlyHandlesOdataFunctionAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/delta?$select=displayName,jobTitle,mobilePhone"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graph_client.users.delta.get(request_configuration = request_configuration)", result); @@ -656,46 +695,51 @@ public async Task CorrectlyHandlesOdataFunction() Assert.Contains("request_configuration = RequestConfiguration(", result); } [Fact] - public async Task CorrectlyHandlesDateTimeOffsetInUrl() + public async Task CorrectlyHandlesDateTimeOffsetInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/reports/getUserArchivedPrintJobs(userId='{{id}}',startDateTime=,endDateTime=)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graph_client.reports.get_user_archived_print_jobs_with_user_id_with_start_date_time_with_end_date_time(\"{endDateTime}\",\"{startDateTime}\",\"{userId}\").get()", result); } [Fact] - public async Task CorrectlyHandlesNumberInUrl() + public async Task CorrectlyHandlesNumberInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/worksheets/{{id|name}}/cell(row=,column=)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(" await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').workbook.worksheets.by_workbook_worksheet_id('workbookWorksheet-id').cell_with_row_with_column(1,1).get()",result); } [Fact] - public async Task CorrectlyHandlesDateInUrl() + public async Task CorrectlyHandlesDateInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/reports/getYammerGroupsActivityDetail(date='2018-03-05')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graph_client.reports.get_yammer_groups_activity_detail_with_date(\"{date}\").get()", result); } [Fact] - public async Task CorrectlyHandlesDateInUrl2() + public async Task CorrectlyHandlesDateInUrl2Async() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/communications/callRecords/getPstnCalls(fromDateTime=2019-11-01,toDateTime=2019-12-01)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("await graph_client.communications.call_records.microsoft_graph_call_records_get_pstn_calls_with_from_date_time_with_to_date_time(\"{fromDateTime}\",\"{toDateTime}\").get()", result); } [Fact] - public async Task CorrectlyHandlesEnumInUrl() + public async Task CorrectlyHandlesEnumInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/identityGovernance/appConsent/appConsentRequests/filterByCurrentUser(on='reviewer')?$filter=userConsentRequests/any(u:u/status eq 'InProgress')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("query_params = FilterByCurrentUserWithOnRequestBuilder.FilterByCurrentUserWithOnRequestBuilderGetQueryParameters(", result); @@ -703,7 +747,7 @@ public async Task CorrectlyHandlesEnumInUrl() Assert.Contains("result = await graph_client.identity_governance.app_consent.app_consent_requests.filter_by_current_user_with_on(\"reviewer\").get(request_configuration = request_configuration)", result); } [Fact] - public async Task GeneratesObjectsInArray() { + public async Task GeneratesObjectsInArrayAsync() { var sampleJson = @" { ""addLicenses"": [ @@ -718,7 +762,8 @@ public async Task GeneratesObjectsInArray() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/assignLicense"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = AssignLicensePostRequestBody(", result); Assert.Contains("disabled_plans = [", result); @@ -726,7 +771,7 @@ public async Task GeneratesObjectsInArray() { Assert.Contains("UUID(\"bea13e0c-3828-4daa-a392-28af7ff61a0f\"),", result); } [Fact] - public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() { + public async Task GeneratesCorrectCollectionTypeAndDerivedInstancesAsync() { var sampleJson = @"{ ""message"": { ""subject"": ""Meet for lunch?"", @@ -754,7 +799,8 @@ public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/sendMail"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = SendMailPostRequestBody(", result); Assert.Contains("attachments = [", result);// Collection defines Base type @@ -762,7 +808,7 @@ public async Task GeneratesCorrectCollectionTypeAndDerivedInstances() { Assert.Contains("content_bytes = base64.urlsafe_b64decode(\"SGVsbG8gV29ybGQh\"),", result); } [Fact] - public async Task GeneratesPropertiesWithSpecialCharacters() { + public async Task GeneratesPropertiesWithSpecialCharactersAsync() { var sampleJson = @"{ ""@odata.type"": ""#microsoft.graph.managedIOSLobApp"", ""displayName"": ""Display Name value"", @@ -819,7 +865,8 @@ public async Task GeneratesPropertiesWithSpecialCharacters() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootBetaUrl}/deviceAppManagement/mobileApps/{{mobileAppId}}"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = ManagedIOSLobApp(", result); Assert.Contains("odata_type = \"#microsoft.graph.managedIOSLobApp\",", result); @@ -828,7 +875,7 @@ public async Task GeneratesPropertiesWithSpecialCharacters() { Assert.Contains("\"v16_0\" : True,", result); } [Fact] - public async Task GeneratesCorrectTypeInCollectionInitializer() { + public async Task GeneratesCorrectTypeInCollectionInitializerAsync() { var sampleJson = @"{ ""workflow"":{ ""category"": ""joiner"", @@ -871,7 +918,8 @@ public async Task GeneratesCorrectTypeInCollectionInitializer() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/identityGovernance/lifecycleWorkflows/workflows/{{workflowId}}/createNewVersion"){ Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = CreateNewVersionPostRequestBody(", result); Assert.Contains("category = LifecycleWorkflowCategory.Joiner,", result); @@ -881,10 +929,11 @@ public async Task GeneratesCorrectTypeInCollectionInitializer() { Assert.Contains("from msgraph.generated.models.lifecycle_workflow_category import LifecycleWorkflowCategory", result); } [Fact] - public async Task CorrectlyHandlesTypeFromInUrl() + public async Task CorrectlyHandlesTypeFromInUrlAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/mailFolders/?includehiddenfolders=true"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("query_params = MailFoldersRequestBuilder.MailFoldersRequestBuilderGetQueryParameters(", result); @@ -892,34 +941,37 @@ public async Task CorrectlyHandlesTypeFromInUrl() Assert.Contains("request_configuration = RequestConfiguration(", result); } [Fact] - public async Task MatchesPathWithPathParameter() + public async Task MatchesPathWithPathParameterAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/drive/items/{{id}}/workbook/worksheets/{{id|name}}/range(address='A1:B2')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').workbook.worksheets.by_workbook_worksheet_id('workbookWorksheet-id').range_with_address(\"{address}\").get()", result); } [Fact] - public async Task MatchesPathAlternateKeys() + public async Task MatchesPathAlternateKeysAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/applications(appId='46e6adf4-a9cf-4b60-9390-0ba6fb00bf6b')?$select=id,appId,displayName,requiredResourceAccess"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("result = await graph_client.applications_with_app_id(\"{appId}\").get(request_configuration = request_configuration)", result); } [Fact] - public async Task GeneratesCorrectLongPaths() + public async Task GeneratesCorrectLongPathsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/{{user-id}}/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("users.by_user_id('user-id').messages.get()", result); } [Fact] - public async Task GeneratesObjectInitializationWithCallToSetters() + public async Task GeneratesObjectInitializationWithCallToSettersAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + @@ -933,14 +985,15 @@ public async Task GeneratesObjectInitializationWithCallToSetters() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("select = [\"displayName\",\"mailNickName\"],", result); Assert.Contains("account_enabled = True", result); Assert.Contains("from msgraph import GraphServiceClient", result); } [Fact] - public async Task IncludesRequestBodyClassName() + public async Task IncludesRequestBodyClassNameAsync() { const string payloadBody = "{\r\n \"passwordCredential\": {\r\n \"displayName\": \"Password friendly name\"\r\n }\r\n}"; @@ -949,34 +1002,37 @@ public async Task IncludesRequestBodyClassName() { Content = new StringContent(payloadBody, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = AddPasswordPostRequestBody(", result); Assert.Contains("from msgraph_beta.generated.models.password_credential import PasswordCredential", result); Assert.Contains("from msgraph_beta import GraphServiceClient", result); } [Fact] - public async Task FindsPathItemsWithDifferentCasing() + public async Task FindsPathItemsWithDifferentCasingAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/directory/deleteditems/microsoft.graph.group"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".directory.deleted_items.graph_group.get()", result); } [Fact] - public async Task DoesntFailOnTerminalSlash() + public async Task DoesntFailOnTerminalSlashAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/me/messages/AAMkADYAAAImV_jAAA=/?$expand=microsoft.graph.eventMessage/event"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains( ".me.messages.by_message_id('message-id').get(request_configuration = request_configuration)", result); } [Fact] - public async Task GeneratesComplicatedObjectsWithNesting() + public async Task GeneratesComplicatedObjectsWithNestingAsync() { const string userJsonObject = "{\r\n \"message\": {\r\n " + @@ -996,48 +1052,52 @@ public async Task GeneratesComplicatedObjectsWithNesting() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("cc_recipients = [", result); Assert.Contains("Recipient(", result); Assert.Contains("body = ItemBody(", result); } [Fact] - public async Task GeneratesDeleteRequest() + public async Task GeneratesDeleteRequestAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".me.messages.by_message_id('message-id').delete()", result); } [Fact] - public async Task GenerateForRequestBodyCornerCase() + public async Task GenerateForRequestBodyCornerCaseAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages/{{id}}/createReply") { Content = new StringContent("{\"field\":\"Nothinkg to be done\"}", Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = CreateReplyPostRequestBody(", result); } [Fact] - public async Task GenerateForRefRequests() + public async Task GenerateForRefRequestsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootBetaUrl}/applications/{{application-id}}/tokenIssuancePolicies/$ref"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".token_issuance_policies.ref.get()", result); } [Fact] - public async Task GenerateForPostBodyWithEnums() + public async Task GenerateForPostBodyWithEnumsAsync() { var body = "{\"state\": \"active\", \"serviceIdentifier\":\"id\", \"catalogId\":\"id\"}"; using var requestPayload = @@ -1045,13 +1105,14 @@ public async Task GenerateForPostBodyWithEnums() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = UsageRight(", result); Assert.Contains("state = UsageRightState.Active,", result); } [Fact] - public async Task GenerateComplexBodyName() + public async Task GenerateComplexBodyNameAsync() { var url = "/devices/{id}/registeredUsers/$ref"; @@ -1060,7 +1121,8 @@ public async Task GenerateComplexBodyName() { Content = new StringContent("{\"field\":\"Nothing to be done\"}", Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = ReferenceCreate(", result); Assert.Contains("additional_data = {", result); @@ -1068,15 +1130,16 @@ public async Task GenerateComplexBodyName() } [Fact] - public async Task GenerateFluentApiPathCornerCase() + public async Task GenerateFluentApiPathCornerCaseAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/activities/recent"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains(".me.activities.recent.get()", result); } [Fact] - public async Task GenerateWithODataTypeAndODataId() + public async Task GenerateWithODataTypeAndODataIdAsync() { var url = "/communications/calls/{id}/answer"; var bodyContent = @" @@ -1101,14 +1164,15 @@ public async Task GenerateWithODataTypeAndODataId() { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootBetaUrl, await GetBetaSnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("media_config = AppHostedMediaConfig(", result); Assert.Contains("odata_type = \"#microsoft.graph.appHostedMediaConfig\",", result); Assert.Contains("odata_type = \"#microsoft.graph.incomingCallOptions\",", result); } [Fact] - public async Task GenerateWithValidRequestBody() + public async Task GenerateWithValidRequestBodyAsync() { var url = "/groups/{id}/acceptedSenders/$ref"; @@ -1117,7 +1181,8 @@ public async Task GenerateWithValidRequestBody() { Content = new StringContent("{\"@odata.id\":\"https://graph.microsoft.com/v1.0/users/alexd@contoso.com\"}", Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("request_body = ReferenceCreate(", result); Assert.Contains("odata_id = \"https://graph.microsoft.com/v1.0/users/alexd@contoso.com\",", result); @@ -1125,7 +1190,7 @@ public async Task GenerateWithValidRequestBody() } [Fact] - public async Task GenerateWithMoreMapsWithArrayOfObjects() + public async Task GenerateWithMoreMapsWithArrayOfObjectsAsync() { const string url = "/identityGovernance/lifecycleWorkflows/workflows/{workflowId}/createNewVersion"; const string body = @" @@ -1188,7 +1253,8 @@ public async Task GenerateWithMoreMapsWithArrayOfObjects() { Content = new StringContent(body, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("\"execution_conditions\" : {", result); Assert.Contains("\"trigger\" : {", result); @@ -1197,10 +1263,11 @@ public async Task GenerateWithMoreMapsWithArrayOfObjects() } [Fact] - public async Task GeneratesCorrectRequestBuilderNameForIndexedCollections() + public async Task GeneratesCorrectRequestBuilderNameForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/{{user-id}}?$select=ext55gb1l09_msLearnCourses"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("query_params = UserItemRequestBuilder.UserItemRequestBuilderGetQueryParameters(", result); Assert.Contains("request_configuration = RequestConfiguration(", result); diff --git a/CodeSnippetsReflection.OpenAPI.Test/PythonImportGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/PythonImportGeneratorTests.cs index fa049c6b1..a8112b2fb 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/PythonImportGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/PythonImportGeneratorTests.cs @@ -12,10 +12,11 @@ public class PythonImportTests : OpenApiSnippetGeneratorTestBase private readonly PythonGenerator _generator = new(); [Fact] - public async Task GeneratesRequestBuilderImports() + public async Task GeneratesRequestBuilderImportsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/calendar/events?$filter=startsWith(subject,'All')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("from msgraph import GraphServiceClient", result); Assert.Contains("from kiota_abstractions.base_request_configuration import RequestConfiguration", result); @@ -23,7 +24,7 @@ public async Task GeneratesRequestBuilderImports() } [Fact] - public async Task GenerateModelImports(){ + public async Task GenerateModelImportsAsync(){ var bodyContent = @"{ ""displayName"": ""New display name"" }"; @@ -31,14 +32,15 @@ public async Task GenerateModelImports(){ { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("from msgraph import GraphServiceClient", result); Assert.Contains("from msgraph.generated.models.application import Application", result); } [Fact] - public async Task GenerateComplexModelImports(){ + public async Task GenerateComplexModelImportsAsync(){ var bodyContent = @"{ ""subject"": ""Annual review"", ""body"": { @@ -66,7 +68,8 @@ public async Task GenerateComplexModelImports(){ { Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("from msgraph import GraphServiceClient", result); Assert.Contains("from msgraph.generated.models.message import Message", result); @@ -78,16 +81,17 @@ public async Task GenerateComplexModelImports(){ } [Fact] - public async Task GenerateNestedRequestBuilderImports() + public async Task GenerateNestedRequestBuilderImportsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/applications(appId={{application-id}})?$select=id,appId,displayName,requiredResourceAccess"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("from msgraph import GraphServiceClient", result); Assert.Contains("from msgraph.generated.applications_with_app_id.applications_with_app_id_request_builder import ApplicationsWithAppIdRequestBuilder", result); } [Fact] - public async Task GenerateRequestBodyImports() + public async Task GenerateRequestBodyImportsAsync() { string bodyContent = @" { @@ -99,18 +103,20 @@ public async Task GenerateRequestBodyImports() using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/applications/{{application-id}}/addPassword"){ Content = new StringContent(bodyContent, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("from msgraph import GraphServiceClient", result); Assert.Contains("from msgraph.generated.models.password_credential import PasswordCredential", result); Assert.Contains("from msgraph.generated.applications.item.add_password.add_password_post_request_body import AddPasswordPostRequestBody", result); } [Fact] - public async Task GeneratesImportsWithoutFilterAttrbutesInPath() + public async Task GeneratesImportsWithoutFilterAttrbutesInPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/servicePrincipals/$count"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("from msgraph import GraphServiceClient", result); Assert.Contains("from msgraph.generated.service_principals.count.count_request_builder import CountRequestBuilder", result); diff --git a/CodeSnippetsReflection.OpenAPI.Test/SimpleLazyTest.cs b/CodeSnippetsReflection.OpenAPI.Test/SimpleLazyTest.cs deleted file mode 100644 index 2e655335d..000000000 --- a/CodeSnippetsReflection.OpenAPI.Test/SimpleLazyTest.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Xunit; -using Xunit.Abstractions; - -namespace CodeSnippetsReflection.OpenAPI.Test -{ - public class SimpleLazyTest - { - private readonly ITestOutputHelper _testOutputHelper; - private static Random random = new Random(); - - public SimpleLazyTest(ITestOutputHelper testOutputHelper) - { - _testOutputHelper = testOutputHelper; - } - - // return a random string or throw an exception - private String chaoticService() - { - if (random.Next() % 2 == 0 ) throw new Exception("Chaos just because"); - - Thread.Sleep(300); - const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - return new string(Enumerable.Repeat(chars, 10) - .Select(s => s[random.Next(s.Length)]).ToArray()); - } - - [Fact] - public void NoExceptionCaching() - { - var responseProvider = new SimpleLazy(() => chaoticService()); - - String result = default; - - Parallel.For(0, 15, t => - { - for (int i = 0; i < 10; i++) - { - - if(result != default) // once value is set value should not be changed - { - if (result != responseProvider.Value) - { - Assert.Equal(result , responseProvider.Value); - } - } - else - { - try - { - result = responseProvider.Value; - } - catch (Exception ex) - { - _testOutputHelper.WriteLine(ex.ToString()); - } - } - } - }); - } - } -} diff --git a/CodeSnippetsReflection.OpenAPI.Test/SnippetCodeGraphTests.cs b/CodeSnippetsReflection.OpenAPI.Test/SnippetCodeGraphTests.cs index 9cc36f21c..6183a8679 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/SnippetCodeGraphTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/SnippetCodeGraphTests.cs @@ -53,10 +53,13 @@ public class SnippetCodeGraphTests : OpenApiSnippetGeneratorTestBase } "; [Fact] - public async Task SkipParametersAreIntegers() + public async Task SkipParametersAreIntegersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$skip=10"); - var result = new SnippetCodeGraph(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); + var result = new SnippetCodeGraph(snippetModel); Assert.True(result.HasParameters()); var param = result.Parameters.First(); @@ -65,10 +68,13 @@ public async Task SkipParametersAreIntegers() } [Fact] - public async Task CountParameterIsBoolean() + public async Task CountParameterIsBooleanAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$select=displayName,id"); - var result = new SnippetCodeGraph(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); + var result = new SnippetCodeGraph(snippetModel); Assert.True(result.HasParameters()); var paramCount = result.Parameters.Count(); @@ -82,10 +88,13 @@ public async Task CountParameterIsBoolean() } [Fact] - public async Task ArrayParametersSplitOnExternalCommas() + public async Task ArrayParametersSplitOnExternalCommasAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members($select=id,displayName),teams($select=id,displayName)"); - var result = new SnippetCodeGraph(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); + var result = new SnippetCodeGraph(snippetModel); Assert.True(result.HasParameters()); Assert.Single(result.Parameters); @@ -104,7 +113,7 @@ public async Task ArrayParametersSplitOnExternalCommas() } [Fact] - public async Task ParsesGuidProperty() + public async Task ParsesGuidPropertyAsync() { const string userJsonObject = "{\r\n \"keyId\": \"f0b0b335-1d71-4883-8f98-567911bfdca6\"\r\n\r\n}"; @@ -112,7 +121,9 @@ public async Task ParsesGuidProperty() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetCodeGraph = new SnippetCodeGraph(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); + var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "keyId").Value; @@ -121,7 +132,7 @@ public async Task ParsesGuidProperty() } [Fact] - public async Task ParsesInt32Property() + public async Task ParsesInt32PropertyAsync() { const string userJsonObject = "{\r\n \"maxCandidates\": 23\r\n\r\n}"; @@ -129,7 +140,9 @@ public async Task ParsesInt32Property() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetCodeGraph = new SnippetCodeGraph(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); + var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "maxCandidates").Value; @@ -138,7 +151,7 @@ public async Task ParsesInt32Property() } [Fact] - public async Task ParsesInt64Property() + public async Task ParsesInt64PropertyAsync() { const string userJsonObject = "{\r\n \"chainId\": 10\r\n\r\n}"; @@ -146,7 +159,9 @@ public async Task ParsesInt64Property() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetCodeGraph = new SnippetCodeGraph(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); + var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "chainId").Value; @@ -155,7 +170,7 @@ public async Task ParsesInt64Property() } [Fact] - public async Task ParsesDoubleProperty() + public async Task ParsesDoublePropertyAsync() { const string userJsonObject = "{\r\n \"minimumAttendeePercentage\": 10\r\n\r\n}"; @@ -163,7 +178,9 @@ public async Task ParsesDoubleProperty() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetCodeGraph = new SnippetCodeGraph(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); + var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "minimumAttendeePercentage").Value; @@ -172,14 +189,15 @@ public async Task ParsesDoubleProperty() } [Fact] - public async Task ParsesHeaders() + public async Task ParsesHeadersAsync() { using var request = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users"); request.Headers.Add("Host", "graph.microsoft.com"); request.Headers.Add("Prefer", "outlook.timezone=\"Pacific Standard Time\""); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); var header = result.Headers.First(); @@ -191,12 +209,13 @@ public async Task ParsesHeaders() } [Fact] - public async Task ParsesParametersWithExpressionsCorrectly() + public async Task ParsesParametersWithExpressionsCorrectlyAsync() { using var request = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$filter=groupTypes/any(c:c eq 'Unified')"); request.Headers.Add("Host", "graph.microsoft.com"); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); Assert.True(result.HasParameters()); @@ -206,12 +225,13 @@ public async Task ParsesParametersWithExpressionsCorrectly() } [Fact] - public async Task ParsesParametersWithExpressionsCorrectlyComplex() + public async Task ParsesParametersWithExpressionsCorrectlyComplexAsync() { using var request = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$filter=mailEnabled eq false and securityEnabled eq true and NOT(groupTypes/any(s:s eq 'Unified')) and membershipRuleProcessingState eq 'On'&$count=true&$select=id,membershipRule,membershipRuleProcessingState"); request.Headers.Add("Host", "graph.microsoft.com"); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); Assert.True(result.HasParameters()); @@ -228,23 +248,25 @@ public async Task ParsesParametersWithExpressionsCorrectlyComplex() } [Fact] - public async Task HasHeadersIsFalseWhenNoneIsInRequest() + public async Task HasHeadersIsFalseWhenNoneIsInRequestAsync() { using var request = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users"); request.Headers.Add("Host", "graph.microsoft.com"); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); Assert.False(result.HasHeaders()); } [Fact] - public async Task ParsesParameters() + public async Task ParsesParametersAsync() { using var request = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/19:4b6bed8d24574f6a9e436813cb2617d8?$select=displayName,givenName,postalCode,identities"); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); var parameter = result.Parameters.First(); @@ -269,11 +291,12 @@ public async Task ParsesParameters() } [Fact] - public async Task ParsesQueryParametersWithSpaces() + public async Task ParsesQueryParametersWithSpacesAsync() { using var request = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/roleManagement/directory/roleAssignments?$filter=roleDefinitionId eq '62e90394-69f5-4237-9190-012177145e10'&$expand=principal"); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); Assert.True(result.HasParameters()); @@ -295,18 +318,19 @@ public async Task ParsesQueryParametersWithSpaces() } [Fact] - public async Task HasParametersIsFalseWhenNoParameterExists() + public async Task HasParametersIsFalseWhenNoParameterExistsAsync() { using var request = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/19:4b6bed8d24574f6a9e436813cb2617d8"); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); Assert.False(result.HasParameters()); } [Fact] - public async Task ParsesBodyTypeBinary() + public async Task ParsesBodyTypeBinaryAsync() { using var request = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo") { @@ -314,14 +338,15 @@ public async Task ParsesBodyTypeBinary() }; request.Content.Headers.ContentType = new("application/octet-stream"); - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); Assert.Equal(PropertyType.Binary, result.Body.PropertyType); } [Fact] - public async Task ParsesBodyWithoutProperContentType() + public async Task ParsesBodyWithoutProperContentTypeAsync() { var sampleBody = @" @@ -334,7 +359,8 @@ public async Task ParsesBodyWithoutProperContentType() { Content = new StringContent(sampleBody, Encoding.UTF8) // snippet missing content type }; - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var result = new SnippetCodeGraph(snippetModel); var expectedObject = new CodeProperty { Name = "MessagesPostRequestBody", Value = null, PropertyType = PropertyType.Object, Children = new List() }; @@ -348,25 +374,24 @@ public async Task ParsesBodyWithoutProperContentType() { if (codeProperty.Name == name) return codeProperty; - if (codeProperty.Children.Count != 0) + if (codeProperty.Children is null || codeProperty.Children.Count == 0) return null; + foreach (var param in codeProperty.Children) { - foreach (var param in codeProperty.Children) - { - if(FindPropertyInSnippet(param, name) is CodeProperty result) return result; - } + if(FindPropertyInSnippet(param, name) is CodeProperty result) return result; } return null; } [Fact] - public async Task ParsesBodyPropertyTypeString() + public async Task ParsesBodyPropertyTypeStringAsync() { using var request = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(TypesSample, Encoding.UTF8) }; - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var snippetCodeGraph = new SnippetCodeGraph(snippetModel); // meetingDuration should be a string @@ -377,13 +402,14 @@ public async Task ParsesBodyPropertyTypeString() } [Fact] - public async Task ParsesBodyPropertyTypeNumber() + public async Task ParsesBodyPropertyTypeNumberAsync() { using var request = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(TypesSample, Encoding.UTF8) }; - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "minimumAttendeePercentage").Value; @@ -393,13 +419,14 @@ public async Task ParsesBodyPropertyTypeNumber() } [Fact] - public async Task ParsesBodyPropertyTypeBoolean() + public async Task ParsesBodyPropertyTypeBooleanAsync() { using var request = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(TypesSample, Encoding.UTF8) }; - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "suggestLocation").Value; @@ -409,13 +436,14 @@ public async Task ParsesBodyPropertyTypeBoolean() } [Fact] - public async Task ParsesBodyPropertyTypeObject() + public async Task ParsesBodyPropertyTypeObjectAsync() { using var request = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(TypesSample, Encoding.UTF8) }; - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "locationConstraint").Value; @@ -424,13 +452,14 @@ public async Task ParsesBodyPropertyTypeObject() } [Fact] - public async Task ParsesBodyPropertyTypeArray() + public async Task ParsesBodyPropertyTypeArrayAsync() { using var request = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(TypesSample, Encoding.UTF8) }; - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "attendees").Value; @@ -439,13 +468,14 @@ public async Task ParsesBodyPropertyTypeArray() } [Fact] - public async Task ParsesBodyPropertyTypeMap() + public async Task ParsesBodyPropertyTypeMapAsync() { using var request = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/findMeetingTimes") { Content = new StringContent(TypesSample, Encoding.UTF8) }; - var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(request, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(request); var snippetCodeGraph = new SnippetCodeGraph(snippetModel); var property = FindPropertyInSnippet(snippetCodeGraph.Body, "additionalData").Value; diff --git a/CodeSnippetsReflection.OpenAPI.Test/SnippetImportTests.cs b/CodeSnippetsReflection.OpenAPI.Test/SnippetImportTests.cs index 053a94f81..f01951446 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/SnippetImportTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/SnippetImportTests.cs @@ -12,7 +12,7 @@ namespace CodeSnippetsReflection.OpenAPI.Test; public class ImportsGeneratorTests : OpenApiSnippetGeneratorTestBase { [Fact] - public async Task TestGenerateImportTemplatesForModelImports() + public async Task TestGenerateImportTemplatesForModelImportsAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + @@ -24,17 +24,19 @@ public async Task TestGenerateImportTemplatesForModelImports() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = ImportsGenerator.GenerateImportTemplates(snippetModel); Assert.NotNull(result); Assert.IsType>(result); Assert.Equal(2, result.Count); } [Fact] - public async Task TestGenerateImportTemplatesForRequestBuilderImports() + public async Task TestGenerateImportTemplatesForRequestBuilderImportsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/calendar/events?$filter=startsWith(subject,'All')"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = ImportsGenerator.GenerateImportTemplates(snippetModel); Assert.NotNull(result); Assert.IsType>(result); @@ -42,10 +44,11 @@ public async Task TestGenerateImportTemplatesForRequestBuilderImports() Assert.NotNull(result[0].RequestBuilderName); } [Fact] - public async Task TestGenerateImportTemplatesForNestedRequestBuilderImports() + public async Task TestGenerateImportTemplatesForNestedRequestBuilderImportsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/applications(appId={{application-id}})?$select=id,appId,displayName,requiredResourceAccess"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = ImportsGenerator.GenerateImportTemplates(snippetModel); Assert.NotNull(result); Assert.IsType>(result); diff --git a/CodeSnippetsReflection.OpenAPI.Test/SnippetModelTests.cs b/CodeSnippetsReflection.OpenAPI.Test/SnippetModelTests.cs index f0375a0f0..da9d6b0f5 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/SnippetModelTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/SnippetModelTests.cs @@ -24,7 +24,7 @@ public void DefensiveProgramming() Assert.Throws(() => new SnippetModel(requestMock, "something", null)); } [Fact] - public async Task FindsThePathItem() + public async Task FindsThePathItemAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + @@ -36,7 +36,8 @@ public async Task FindsThePathItem() { Content = new StringContent(userJsonObject) }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); Assert.NotNull(snippetModel.EndPathNode); Assert.NotNull(snippetModel.RootPathNode); Assert.Equal(snippetModel.EndPathNode, snippetModel.RootPathNode); @@ -44,10 +45,11 @@ public async Task FindsThePathItem() Assert.InRange(snippetModel.PathNodes.Count, 1, 1); } [Fact] - public async Task FindsTheSubPathItem() + public async Task FindsTheSubPathItemAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); Assert.NotNull(snippetModel.EndPathNode); Assert.NotNull(snippetModel.RootPathNode); Assert.NotEqual(snippetModel.EndPathNode, snippetModel.RootPathNode); @@ -55,7 +57,7 @@ public async Task FindsTheSubPathItem() Assert.InRange(snippetModel.PathNodes.Count, 2, 2); } [Fact] - public async Task GetsTheRequestSchema() + public async Task GetsTheRequestSchemaAsync() { const string userJsonObject = "{\r\n \"accountEnabled\": true,\r\n " + "\"displayName\": \"displayName-value\",\r\n " + @@ -67,15 +69,17 @@ public async Task GetsTheRequestSchema() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); Assert.NotNull(snippetModel.RequestSchema); Assert.NotEmpty(snippetModel.RequestSchema.AllOf); } [Fact] - public async Task GetsTheResponseSchema() + public async Task GetsTheResponseSchemaAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); Assert.NotNull(snippetModel.ResponseSchema); Assert.True(snippetModel.ResponseSchema.Properties.Any() || snippetModel.ResponseSchema.AnyOf.Any() || @@ -84,7 +88,7 @@ public async Task GetsTheResponseSchema() } [Fact] - public async Task ThrowsExceptionForUnsupportedHttpOperation() + public async Task ThrowsExceptionForUnsupportedHttpOperationAsync() { // DELETE /users/{user-id}/delta // Given @@ -93,13 +97,13 @@ public async Task ThrowsExceptionForUnsupportedHttpOperation() // When // Then - var snippetMetadata = await GetV1SnippetMetadata(); + var snippetMetadata = await GetV1SnippetMetadataAsync(); var entryPointNotFoundException = Assert.Throws(() => new SnippetModel(requestPayload, ServiceRootUrl, snippetMetadata)); Assert.Equal("HTTP Method 'DELETE' not found for path.",entryPointNotFoundException.Message); } [Fact] - public async Task ThrowsExceptionForUnsupportedPathOperation() + public async Task ThrowsExceptionForUnsupportedPathOperationAsync() { // GET /users/{user-id}/deltaTest // Given @@ -108,7 +112,7 @@ public async Task ThrowsExceptionForUnsupportedPathOperation() // When // Then - var snippetMetadata = await GetV1SnippetMetadata(); + var snippetMetadata = await GetV1SnippetMetadataAsync(); var entryPointNotFoundException = Assert.Throws(() => new SnippetModel(requestPayload, ServiceRootUrl, snippetMetadata)); Assert.Equal("Path segment 'deltaTest' not found in path",entryPointNotFoundException.Message); } diff --git a/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs b/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs index f0c9e04b3..333be8b66 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs @@ -12,10 +12,11 @@ public class TypeScriptGeneratorTest : OpenApiSnippetGeneratorTestBase // check path correctness [Fact] - public async Task GeneratesTheCorrectFluentAPIPath() + public async Task GeneratesTheCorrectFluentAPIPathAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -31,14 +32,15 @@ public async Task GeneratesTheCorrectFluentAPIPath() } [Fact] - public async Task GeneratesClassWithDefaultBodyWhenSchemaNotPresent() + public async Task GeneratesClassWithDefaultBodyWhenSchemaNotPresentAsync() { const string userJsonObject = "{ \"decision\": \"Approve\", \"justification\": \"All principals with access need continued access to the resource (Marketing Group) as all the principals are on the marketing team\", \"resourceId\": \"a5c51e59-3fcd-4a37-87a1-835c0c21488a\"}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/identityGovernance/accessReviews/definitions/e6cafba0-cbf0-4748-8868-0810c7f4cc06/instances/1234fba0-cbf0-6778-8868-9999c7f4cc06/batchRecordDecisions") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -60,10 +62,11 @@ public async Task GeneratesClassWithDefaultBodyWhenSchemaNotPresent() } [Fact] - public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollections() + public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollectionsAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -80,19 +83,21 @@ public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollections() } [Fact] - public async Task GeneratesTheSnippetInitializationStatement() + public async Task GeneratesTheSnippetInitializationStatementAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("const graphServiceClient = GraphServiceClient.init({authProvider});", result); } [Fact] - public async Task GeneratesTheGetMethodCall() + public async Task GeneratesTheGetMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" const graphServiceClient = GraphServiceClient.init({authProvider}); @@ -108,10 +113,11 @@ public async Task GeneratesTheGetMethodCall() } [Fact] - public async Task GeneratesThePostMethodCall() + public async Task GeneratesThePostMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" const result = async () => { @@ -124,10 +130,11 @@ public async Task GeneratesThePostMethodCall() } [Fact] - public async Task GeneratesThePatchMethodCall() + public async Task GeneratesThePatchMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" const result = async () => { @@ -140,19 +147,21 @@ public async Task GeneratesThePatchMethodCall() } [Fact] - public async Task GeneratesThePutMethodCall() + public async Task GeneratesThePutMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("put", result); } [Fact] - public async Task GeneratesTheDeleteMethodCall() + public async Task GeneratesTheDeleteMethodCallAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Delete, $"{ServiceRootUrl}/me/messages/{{message-id}}"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" const graphServiceClient = GraphServiceClient.init({authProvider}); @@ -168,7 +177,7 @@ public async Task GeneratesTheDeleteMethodCall() } [Fact] - public async Task WritesTheRequestPayload() + public async Task WritesTheRequestPayloadAsync() { var sampleJson = @" { @@ -187,7 +196,8 @@ public async Task WritesTheRequestPayload() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -216,7 +226,7 @@ public async Task WritesTheRequestPayload() } [Fact] - public async Task WritesALongAndFindsAnAction() + public async Task WritesALongAndFindsAnActionAsync() { const string userJsonObject = "{\r\n \"chainId\": 10\r\n\r\n}"; @@ -224,14 +234,15 @@ public async Task WritesALongAndFindsAnAction() { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("10", result); Assert.DoesNotContain("microsoft.graph1", result); } [Fact] - public async Task WritesADouble() + public async Task WritesADoubleAsync() { var sampleJson = @" { @@ -243,7 +254,8 @@ public async Task WritesADouble() { Content = new StringContent(sampleJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -262,14 +274,15 @@ public async Task WritesADouble() } [Fact] - public async Task GeneratesABinaryPayload() + public async Task GeneratesABinaryPayloadAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Put, $"{ServiceRootUrl}/applications/{{application-id}}/logo") { Content = new ByteArrayContent(new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }) }; requestPayload.Content.Headers.ContentType = new("application/octet-stream"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -286,14 +299,15 @@ public async Task GeneratesABinaryPayload() } [Fact] - public async Task GeneratesABase64UrlPayload() + public async Task GeneratesABase64UrlPayloadAsync() { const string userJsonObject = "{\r\n \"contentBytes\": \"wiubviuwbegviwubiu\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/chats/{{chat-id}}/messages/{{chatMessage-id}}/hostedContents") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -313,14 +327,15 @@ public async Task GeneratesABase64UrlPayload() } [Fact] - public async Task GeneratesADatePayload() + public async Task GeneratesADatePayloadAsync() { const string userJsonObject = "{\r\n \"receivedDateTime\": \"2021-08-30T20:00:00:00Z\"\r\n\r\n}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Post, $"{ServiceRootUrl}/me/messages") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -340,7 +355,7 @@ public async Task GeneratesADatePayload() } [Fact] - public async Task GeneratesAnArrayPayloadInAdditionalData() + public async Task GeneratesAnArrayPayloadInAdditionalDataAsync() { var samplePayload = @" { @@ -356,7 +371,8 @@ public async Task GeneratesAnArrayPayloadInAdditionalData() { Content = new StringContent(samplePayload, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -377,14 +393,15 @@ public async Task GeneratesAnArrayPayloadInAdditionalData() } [Fact] - public async Task GeneratesAnArrayOfObjectsPayloadData() + public async Task GeneratesAnArrayOfObjectsPayloadDataAsync() { const string userJsonObject = "{ \"body\": { \"contentType\": \"HTML\"}, \"extensions\": [{ \"dealValue\": 10000}]}"; using var requestPayload = new HttpRequestMessage(HttpMethod.Patch, $"{ServiceRootUrl}/groups/{{group-id}}") { Content = new StringContent(userJsonObject, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -414,10 +431,11 @@ public async Task GeneratesAnArrayOfObjectsPayloadData() } [Fact] - public async Task GeneratesSelectQueryParameters() + public async Task GeneratesSelectQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me?$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -438,10 +456,11 @@ public async Task GeneratesSelectQueryParameters() } [Fact] - public async Task GeneratesCountBooleanQueryParameters() + public async Task GeneratesCountBooleanQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$count=true&$select=displayName,id"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -464,10 +483,11 @@ public async Task GeneratesCountBooleanQueryParameters() } [Fact] - public async Task GeneratesSkipQueryParameters() + public async Task GeneratesSkipQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users?$skip=10"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -488,10 +508,11 @@ public async Task GeneratesSkipQueryParameters() } [Fact] - public async Task GeneratesSelectExpandQueryParameters() + public async Task GeneratesSelectExpandQueryParametersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups?$expand=members($select=id,displayName)"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); Assert.Contains("expand", result); Assert.Contains("members($select=id,displayName)", result); @@ -499,11 +520,12 @@ public async Task GeneratesSelectExpandQueryParameters() } [Fact] - public async Task GeneratesRequestHeaders() + public async Task GeneratesRequestHeadersAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/groups"); requestPayload.Headers.Add("ConsistencyLevel", "eventual"); - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -524,7 +546,7 @@ public async Task GeneratesRequestHeaders() } [Fact] - public async Task GenerateAdditionalData() + public async Task GenerateAdditionalDataAsync() { var samplePayload = @" { @@ -547,7 +569,8 @@ public async Task GenerateAdditionalData() { Content = new StringContent(samplePayload, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" @@ -579,7 +602,7 @@ public async Task GenerateAdditionalData() } [Fact] - public async Task GeneratesEnumsWhenVariableIsEnum() + public async Task GeneratesEnumsWhenVariableIsEnumAsync() { const string payloadJson = @"{ ""displayName"": ""Test create"", @@ -600,7 +623,8 @@ public async Task GeneratesEnumsWhenVariableIsEnum() { Content = new StringContent(payloadJson, Encoding.UTF8, "application/json") }; - var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadata()); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" diff --git a/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj b/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj index 5e6b2c4d6..df12d9d3f 100644 --- a/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj +++ b/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj @@ -8,7 +8,12 @@ - + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PhpGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PhpGenerator.cs index 43c1603eb..43b63def3 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PhpGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PhpGenerator.cs @@ -121,10 +121,11 @@ public string GenerateCodeSnippet(SnippetModel snippetModel) } private static HashSet GetImportStatements(SnippetModel snippetModel) { - var packagePrefix = snippetModel.ApiVersion switch + var packagePrefix = snippetModel.ApiVersion.ToLowerInvariant() switch { "v1.0" => @"Microsoft\Graph", "beta" => @"Microsoft\Graph\Beta", + _ => throw new ArgumentOutOfRangeException($"Unsupported API version {snippetModel.ApiVersion}") }; var modelImportPrefix = $@"use {packagePrefix}\Generated\Models"; var requestBuilderImportPrefix = $@"use {packagePrefix}\Generated"; diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PowerShellGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PowerShellGenerator.cs index 31ba84387..4a14808af 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PowerShellGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PowerShellGenerator.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Net.Http.Json; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; @@ -15,23 +16,16 @@ namespace CodeSnippetsReflection.OpenAPI.LanguageGenerators { - public class PowerShellGenerator : ILanguageGenerator + public class PowerShellGenerator(IList psCommands) + : ILanguageGenerator { private const string requestBodyVarName = "params"; private const string modulePrefix = "Microsoft.Graph"; - private const string mgCommandMetadataUrl = "https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-powershell/dev/src/Authentication/Authentication/custom/common/MgCommandMetadata.json"; - private static readonly SimpleLazy> psCommands = new( - () => - { - using var httpClient = new HttpClient(); - using var stream = httpClient.GetStreamAsync(mgCommandMetadataUrl).GetAwaiter().GetResult(); - return JsonSerializer.Deserialize>(stream); - } - ); private static readonly Regex meSegmentRegex = new("^/me($|(?=/))", RegexOptions.Compiled, TimeSpan.FromSeconds(5)); private static readonly Regex encodedQueryParamsPayLoad = new(@"\w*\+", RegexOptions.Compiled, TimeSpan.FromSeconds(5)); private static readonly Regex wrongQoutesInStringLiterals = new(@"""\{", RegexOptions.Compiled, TimeSpan.FromSeconds(5)); private static readonly Regex functionWithParams = new(@"^[0-9a-zA-Z\- \/_?:.,\s]+\([\w*='{\w*}\',]*\)|^[0-9a-zA-Z\- \/_?:.,\s]+\([\w*='\w*\',]*\)|^[0-9a-zA-Z\- \/_?:.,\s]+\([\w*={w*},]*\)|^[0-9a-zA-Z\- \/_?:.,\s]+\([\w*=,]*\)", RegexOptions.Compiled, TimeSpan.FromSeconds(5)); + public string GenerateCodeSnippet(SnippetModel snippetModel) { var indentManager = new IndentManager(); @@ -277,14 +271,14 @@ private static (string, Dictionary) ReplaceNestedOdataQueryParam } private static readonly Regex keyIndexRegex = new(@"(?<={)(.*?)(?=})", RegexOptions.Compiled, TimeSpan.FromSeconds(5)); - private static IList GetCommandForRequest(string path, string method, string apiVersion) + private List GetCommandForRequest(string path, string method, string apiVersion) { - if (psCommands.Value.Count == 0) - return default; + if (psCommands.Count == 0) + return []; path = Regex.Escape(SnippetModel.TrimNamespace(path)); // Tokenize uri by substituting parameter values with "{.*}" e.g, "/users/{user-id}" to "/users/{.*}". path = $"^{keyIndexRegex.Replace(path, "(\\w*-\\w*|\\w*)")}$"; - return psCommands.Value.Where(c => c.Method == method && c.ApiVersion == apiVersion && Regex.Match(c.Uri, + return psCommands.Where(c => c.Method == method && c.ApiVersion == apiVersion && Regex.Match(c.Uri, path, RegexOptions.None, TimeSpan.FromSeconds(5)).Success).ToList(); } private static (string, string) GetRequestPayloadAndVariableName(SnippetModel snippetModel, IndentManager indentManager) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PythonGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PythonGenerator.cs index 3a406ecd2..a88ed548c 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PythonGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/PythonGenerator.cs @@ -80,10 +80,11 @@ public string GenerateCodeSnippet(SnippetModel snippetModel) } private static HashSet GetImportStatements(SnippetModel snippetModel) { - var packageName = snippetModel.ApiVersion switch + var packageName = snippetModel.ApiVersion.ToLowerInvariant() switch { "v1.0" => "msgraph", "beta" => "msgraph_beta", + _ => throw new ArgumentOutOfRangeException($"Unsupported Graph version in url: {snippetModel.ApiVersion}") }; var modelImportPrefix = $"from {packageName}.generated.models"; var requestBuilderImportPrefix = $"from {packageName}.generated"; diff --git a/CodeSnippetsReflection.OpenAPI/ModelGraph/SnippetCodeGraph.cs b/CodeSnippetsReflection.OpenAPI/ModelGraph/SnippetCodeGraph.cs index 780594ba8..9c8be789d 100644 --- a/CodeSnippetsReflection.OpenAPI/ModelGraph/SnippetCodeGraph.cs +++ b/CodeSnippetsReflection.OpenAPI/ModelGraph/SnippetCodeGraph.cs @@ -41,8 +41,6 @@ public record SnippetCodeGraph private static readonly char NamespaceNameSeparator = '.'; - public SnippetCodeGraph(HttpRequestMessage requestPayload, string serviceRootUrl, OpenApiSnippetMetadata openApiSnippetMetadata) : this(new SnippetModel(requestPayload, serviceRootUrl, openApiSnippetMetadata)) {} - public SnippetCodeGraph(SnippetModel snippetModel) { ResponseSchema = snippetModel.ResponseSchema; diff --git a/CodeSnippetsReflection.OpenAPI/OpenAPISnippetsGenerator.cs b/CodeSnippetsReflection.OpenAPI/OpenAPISnippetsGenerator.cs index 11841efbb..2cc315425 100644 --- a/CodeSnippetsReflection.OpenAPI/OpenAPISnippetsGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/OpenAPISnippetsGenerator.cs @@ -3,12 +3,14 @@ using System.IO; using System.Linq; using System.Net.Http; +using System.Net.Http.Json; using System.Threading.Tasks; using CodeSnippetsReflection.OpenAPI.LanguageGenerators; using Microsoft.ApplicationInsights; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.OpenApi.Readers; using Microsoft.OpenApi.Services; +using Microsoft.VisualStudio.Threading; using UtilityService; namespace CodeSnippetsReflection.OpenAPI @@ -16,12 +18,21 @@ namespace CodeSnippetsReflection.OpenAPI public class OpenApiSnippetsGenerator : IOpenApiSnippetsGenerator { public const string treeNodeLabel = "default"; + private const string MgCommandMetadataUrl = "https://raw.githubusercontent.com/microsoftgraph/msgraph-sdk-powershell/dev/src/Authentication/Authentication/custom/common/MgCommandMetadata.json"; private readonly TelemetryClient _telemetryClient; private readonly Dictionary _snippetsTraceProperties = new() { { UtilityConstants.TelemetryPropertyKey_Snippets, nameof(OpenApiSnippetsGenerator) } }; - private readonly SimpleLazy _v1OpenApiSnippetMetadata; - private readonly SimpleLazy _betaOpenApiSnippetMetadata; - private readonly SimpleLazy _customOpenApiSnippetMetadata; + private readonly AsyncLazy _v1OpenApiSnippetMetadata; + private readonly AsyncLazy _betaOpenApiSnippetMetadata; + private readonly AsyncLazy> _psCommands; + #nullable enable + private readonly AsyncLazy? _customOpenApiSnippetMetadata; + private static readonly JoinableTaskFactory JoinableTaskFactory = new(new JoinableTaskContext()); + private static readonly HttpClient HttpClient = new () + { + Timeout = TimeSpan.FromMinutes(5), + }; + #nullable restore public OpenApiSnippetsGenerator( string v1OpenApiDocumentUrl = "https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/v1.0/openapi.yaml", string betaOpenApiDocumentUrl = "https://raw.githubusercontent.com/microsoftgraph/msgraph-metadata/master/openapi/beta/openapi.yaml", @@ -32,17 +43,16 @@ public OpenApiSnippetsGenerator( if(string.IsNullOrEmpty(betaOpenApiDocumentUrl)) throw new ArgumentNullException(nameof(betaOpenApiDocumentUrl)); _telemetryClient = telemetryClient; - _v1OpenApiSnippetMetadata = new SimpleLazy(() => GetOpenApiReferences(v1OpenApiDocumentUrl).GetAwaiter().GetResult()); - _betaOpenApiSnippetMetadata = new SimpleLazy(() => GetOpenApiReferences(betaOpenApiDocumentUrl).GetAwaiter().GetResult()); + _v1OpenApiSnippetMetadata = new AsyncLazy(() => GetOpenApiReferencesAsync(v1OpenApiDocumentUrl), JoinableTaskFactory); + _betaOpenApiSnippetMetadata = new AsyncLazy(() => GetOpenApiReferencesAsync(betaOpenApiDocumentUrl), JoinableTaskFactory); + _psCommands = new AsyncLazy>(() => HttpClient.GetFromJsonAsync>(MgCommandMetadataUrl), JoinableTaskFactory); if(!string.IsNullOrEmpty(customOpenApiPathOrUrl)) - _customOpenApiSnippetMetadata = new SimpleLazy(() => GetOpenApiReferences(customOpenApiPathOrUrl).GetAwaiter().GetResult()); + _customOpenApiSnippetMetadata = new AsyncLazy(() => GetOpenApiReferencesAsync(customOpenApiPathOrUrl), JoinableTaskFactory); } - private async Task GetOpenApiReferences(string url) { + private async Task GetOpenApiReferencesAsync(string url) { Stream stream; if(url.StartsWith("http", StringComparison.OrdinalIgnoreCase)) { - using var httpClient = new HttpClient(); - httpClient.Timeout = TimeSpan.FromMinutes(5); - stream = await httpClient.GetStreamAsync(url); + stream = await HttpClient.GetStreamAsync(url); } else { stream = File.OpenRead(url); } @@ -66,15 +76,16 @@ private async Task GetOpenApiReferences(string url) { } return new OpenApiSnippetMetadata(OpenApiUrlTreeNode.Create(doc, treeNodeLabel), doc.Components.Schemas) ; } - public string ProcessPayloadRequest(HttpRequestMessage requestPayload, string language) + public async Task ProcessPayloadRequestAsync(HttpRequestMessage requestPayload, string language) { _telemetryClient?.TrackTrace($"Generating code snippet for '{language}' from the request payload", SeverityLevel.Information, _snippetsTraceProperties); - var (openApiSnippetMetadata, serviceRootUri) = GetModelAndServiceUriTuple(requestPayload.RequestUri); + var (openApiSnippetMetadata, serviceRootUri) = await GetModelAndServiceUriTupleAsync(requestPayload.RequestUri); var snippetModel = new SnippetModel(requestPayload, serviceRootUri.AbsoluteUri, openApiSnippetMetadata); + await snippetModel.InitializeModelAsync(requestPayload); - var generator = GetLanguageGenerator(language); + var generator = await GetLanguageGeneratorAsync(language); return generator.GenerateCodeSnippet(snippetModel); } public static HashSet SupportedLanguages { get; set; } = new(StringComparer.OrdinalIgnoreCase) @@ -88,12 +99,12 @@ public string ProcessPayloadRequest(HttpRequestMessage requestPayload, string la "cli", "java" }; - private static ILanguageGenerator GetLanguageGenerator(string language) { + private async Task> GetLanguageGeneratorAsync(string language) { return language.ToLowerInvariant() switch { "c#" => new CSharpGenerator(), "typescript" => new TypeScriptGenerator(), "go" => new GoGenerator(), - "powershell" => new PowerShellGenerator(), + "powershell" => new PowerShellGenerator(await _psCommands.GetValueAsync()), "php" => new PhpGenerator(), "python" => new PythonGenerator(), "cli" => new GraphCliGenerator(), @@ -106,15 +117,17 @@ private static ILanguageGenerator GetLanguageG /// /// The URI of the service requested /// Tuple of the OpenApiUrlTreeNode and the URI of the service root - private (OpenApiSnippetMetadata, Uri) GetModelAndServiceUriTuple(Uri requestUri) + private async Task<(OpenApiSnippetMetadata, Uri)> GetModelAndServiceUriTupleAsync(Uri requestUri) { var apiVersion = requestUri.Segments[1].Trim('/'); var serviceRootUri = new Uri(new Uri(requestUri.GetLeftPart(UriPartial.Authority)), $"/{apiVersion}"); return apiVersion.ToLowerInvariant() switch { - "v1.0" => ((_customOpenApiSnippetMetadata ?? _v1OpenApiSnippetMetadata).Value, serviceRootUri), - "beta" => ((_customOpenApiSnippetMetadata ?? _betaOpenApiSnippetMetadata).Value, serviceRootUri), - _ when _customOpenApiSnippetMetadata != null => (_customOpenApiSnippetMetadata.Value, serviceRootUri), + "v1.0" when _customOpenApiSnippetMetadata is not null => (await _customOpenApiSnippetMetadata.GetValueAsync(), serviceRootUri), + "v1.0" when _customOpenApiSnippetMetadata is null => (await _v1OpenApiSnippetMetadata.GetValueAsync(), serviceRootUri), + "beta" when _customOpenApiSnippetMetadata is not null => (await _customOpenApiSnippetMetadata.GetValueAsync(), serviceRootUri), + "beta" when _customOpenApiSnippetMetadata is null => (await _betaOpenApiSnippetMetadata.GetValueAsync(), serviceRootUri), + _ when _customOpenApiSnippetMetadata != null => (await _customOpenApiSnippetMetadata.GetValueAsync(), serviceRootUri), _ => throw new ArgumentOutOfRangeException(nameof(requestUri), "Unsupported Graph version in url"), }; } diff --git a/CodeSnippetsReflection.OpenAPI/PowerShellCommandInfo.cs b/CodeSnippetsReflection.OpenAPI/PowerShellCommandInfo.cs index 7acbe14db..83ea0e7dc 100644 --- a/CodeSnippetsReflection.OpenAPI/PowerShellCommandInfo.cs +++ b/CodeSnippetsReflection.OpenAPI/PowerShellCommandInfo.cs @@ -6,7 +6,7 @@ namespace CodeSnippetsReflection.OpenAPI { - internal record PowerShellCommandInfo + public record PowerShellCommandInfo { public string Method { get; set; } public string OutputType { get; set; } diff --git a/CodeSnippetsReflection.OpenAPI/SimpleLazy.cs b/CodeSnippetsReflection.OpenAPI/SimpleLazy.cs deleted file mode 100644 index 1ab1c2e2a..000000000 --- a/CodeSnippetsReflection.OpenAPI/SimpleLazy.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CodeSnippetsReflection.OpenAPI -{ - - /* - * A Simple lazy factory that substitues https://referencesource.microsoft.com/#mscorlib/system/Lazy.cs - * by disregarding any exceptions thrown by the value factory. - * This is a bypass for the dotnet issue https://github.com/dotnet/runtime/issues/27421 for lazy initialization without exception caching - * - */ - public class SimpleLazy where T : class - { - private readonly Func valueFactory; - private T instance; - private readonly object locker = new object(); - - public SimpleLazy(Func valueFactory) - { - this.valueFactory = valueFactory ?? throw new ArgumentNullException(nameof(valueFactory)); - this.instance = null; - } - - public T Value - { - get - { - if (instance != null) - return instance;// no need to acquire the lock if the instance is already initialized. - - lock (locker) - return instance ??= valueFactory(); - } - } - } -} diff --git a/CodeSnippetsReflection.OpenAPI/SnippetModel.cs b/CodeSnippetsReflection.OpenAPI/SnippetModel.cs index 5ccdf41e9..e508436f5 100644 --- a/CodeSnippetsReflection.OpenAPI/SnippetModel.cs +++ b/CodeSnippetsReflection.OpenAPI/SnippetModel.cs @@ -46,7 +46,6 @@ public SnippetModel(HttpRequestMessage requestPayload, string serviceRootUrl, Op .Skip(1); //skipping the version LoadPathNodes(openApiSnippetMetadata.OpenApiUrlTreeNode, splatPath, requestPayload.Method); Schemas = openApiSnippetMetadata.Schemas ?? new Dictionary(); - InitializeModel(requestPayload); } private static readonly Dictionary KnownReMappings = new() diff --git a/CodeSnippetsReflection/CodeSnippetsReflection.csproj b/CodeSnippetsReflection/CodeSnippetsReflection.csproj index 58990cd56..54669eeb9 100644 --- a/CodeSnippetsReflection/CodeSnippetsReflection.csproj +++ b/CodeSnippetsReflection/CodeSnippetsReflection.csproj @@ -4,4 +4,11 @@ net8.0 + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + diff --git a/CodeSnippetsReflection/ISnippetsGenerator.cs b/CodeSnippetsReflection/ISnippetsGenerator.cs index 14b8dcbb3..a69887102 100644 --- a/CodeSnippetsReflection/ISnippetsGenerator.cs +++ b/CodeSnippetsReflection/ISnippetsGenerator.cs @@ -1,9 +1,10 @@ using System.Net.Http; +using System.Threading.Tasks; namespace CodeSnippetsReflection { public interface ISnippetsGenerator { - string ProcessPayloadRequest(HttpRequestMessage requestPayload, string language); + Task ProcessPayloadRequestAsync(HttpRequestMessage requestPayload, string language); } -} \ No newline at end of file +} diff --git a/CodeSnippetsReflection/SnippetBaseModel.cs b/CodeSnippetsReflection/SnippetBaseModel.cs index ef4bea609..6aeff3d19 100644 --- a/CodeSnippetsReflection/SnippetBaseModel.cs +++ b/CodeSnippetsReflection/SnippetBaseModel.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net.Http; @@ -44,7 +44,8 @@ protected SnippetBaseModel(HttpRequestMessage requestPayload, string serviceRoot /// Initializes the model from the request message. This method MUST be called in the derived type constructor /// /// The request message to initialize the snippet from - protected void InitializeModel(HttpRequestMessage requestPayload) { + public async System.Threading.Tasks.Task InitializeModelAsync(HttpRequestMessage requestPayload) + { // replace the response variable name with generic response when URL has placeholder // e.g. {size} in GET graph.microsoft.com/v1.0/me/drive/items/{item-id}/thumbnails/{thumb-id}/{size} var lastPathSegment = GetLastPathSegment(); @@ -52,7 +53,7 @@ protected void InitializeModel(HttpRequestMessage requestPayload) { this.ResponseVariableName = responseVariableName.StartsWith("{") ? "response" : responseVariableName; PopulateQueryFieldLists(QueryString); - GetRequestBody(requestPayload); + await GetRequestBodyAsync(requestPayload); } protected abstract PathSegment GetLastPathSegment(); /// @@ -101,12 +102,12 @@ private void PopulateQueryFieldLists(string queryString) /// Reads the request body from the request payload to save it as a string for later processing /// /// to read the body from - private void GetRequestBody(HttpRequestMessage requestPayload) + private async System.Threading.Tasks.Task GetRequestBodyAsync(HttpRequestMessage requestPayload) { //do not try to read in the content if there isn't any if (null != requestPayload.Content) { - this.RequestBody = requestPayload.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + this.RequestBody = await requestPayload.Content.ReadAsStringAsync(); if(null != requestPayload.Content.Headers.ContentType) this.ContentType = requestPayload.Content.Headers.ContentType.MediaType; } diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 605afa84d..8f749984d 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -14,6 +14,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ExceptionMiddleware/ExceptionMiddlewareShould.cs b/ExceptionMiddleware/ExceptionMiddlewareShould.cs index f58958971..33137c7da 100644 --- a/ExceptionMiddleware/ExceptionMiddlewareShould.cs +++ b/ExceptionMiddleware/ExceptionMiddlewareShould.cs @@ -14,12 +14,12 @@ namespace ExceptionMiddlewareShould public class ExceptionMiddlewareShould { [Fact] - public async Task ExceptionMiddlewareShouldThrowArgumentNullException() + public async Task ExceptionMiddlewareShouldThrowArgumentNullExceptionAsync() { // Arrange var expected = "{\"StatusCode\":400,\"Message\":\"Value cannot be null.\"}"; - static Task mockNextMiddleware(HttpContext HttpContext) + static Task mockNextMiddlewareAsync(HttpContext HttpContext) { return Task.FromException(new ArgumentNullException()); } @@ -29,7 +29,7 @@ static Task mockNextMiddleware(HttpContext HttpContext) httpContext.Response.Body = new MemoryStream(); // Call the middleware - var exceptionHandlingMiddleware = new ExceptionMiddleware(mockNextMiddleware, null); + var exceptionHandlingMiddleware = new ExceptionMiddleware(mockNextMiddlewareAsync, null); // Act await exceptionHandlingMiddleware.InvokeAsync(httpContext); @@ -38,7 +38,7 @@ static Task mockNextMiddleware(HttpContext HttpContext) var bodyContent = ""; using (var sr = new StreamReader(httpContext.Response.Body)) { - bodyContent = sr.ReadToEnd(); + bodyContent = await sr.ReadToEndAsync(); } // Assert @@ -46,12 +46,12 @@ static Task mockNextMiddleware(HttpContext HttpContext) } [Fact] - public async Task ExceptionMiddlewareShouldThrowInvalidOperationException() + public async Task ExceptionMiddlewareShouldThrowInvalidOperationExceptionAsync() { // Arrange var expected = "{\"StatusCode\":400,\"Message\":\"Operation is not valid due to the current state of the object.\"}"; - static Task mockNextMiddleware(HttpContext HttpContext) + static Task mockNextMiddlewareAsync(HttpContext HttpContext) { return Task.FromException(new InvalidOperationException()); } @@ -61,7 +61,7 @@ static Task mockNextMiddleware(HttpContext HttpContext) httpContext.Response.Body = new MemoryStream(); // Call the middleware - var exceptionHandlingMiddleware = new ExceptionMiddleware(mockNextMiddleware, null); + var exceptionHandlingMiddleware = new ExceptionMiddleware(mockNextMiddlewareAsync, null); // Act await exceptionHandlingMiddleware.InvokeAsync(httpContext); @@ -70,7 +70,7 @@ static Task mockNextMiddleware(HttpContext HttpContext) var bodyContent = ""; using (var sr = new StreamReader(httpContext.Response.Body)) { - bodyContent = sr.ReadToEnd(); + bodyContent = await sr.ReadToEndAsync(); } // Assert @@ -78,12 +78,12 @@ static Task mockNextMiddleware(HttpContext HttpContext) } [Fact] - public async Task ExceptionMiddlewareShouldThrowArgumentException() + public async Task ExceptionMiddlewareShouldThrowArgumentExceptionAsync() { // Arrange var expected = "{\"StatusCode\":404,\"Message\":\"Value does not fall within the expected range.\"}"; - static Task mockNextMiddleware(HttpContext HttpContext) + static Task mockNextMiddlewareAsync(HttpContext HttpContext) { return Task.FromException(new ArgumentException()); } @@ -93,7 +93,7 @@ static Task mockNextMiddleware(HttpContext HttpContext) httpContext.Response.Body = new MemoryStream(); // Call the middleware - var exceptionHandlingMiddleware = new ExceptionMiddleware(mockNextMiddleware, null); + var exceptionHandlingMiddleware = new ExceptionMiddleware(mockNextMiddlewareAsync, null); // Act await exceptionHandlingMiddleware.InvokeAsync(httpContext); @@ -102,7 +102,7 @@ static Task mockNextMiddleware(HttpContext HttpContext) var bodyContent = ""; using (var sr = new StreamReader(httpContext.Response.Body)) { - bodyContent = sr.ReadToEnd(); + bodyContent = await sr.ReadToEndAsync(); } // Assert diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index a710cb676..7ddcd778d 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -11,6 +11,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/FileService.Test/HttpClientUtilityShould.cs b/FileService.Test/HttpClientUtilityShould.cs index 5c40f23e0..777b6b8e0 100644 --- a/FileService.Test/HttpClientUtilityShould.cs +++ b/FileService.Test/HttpClientUtilityShould.cs @@ -23,7 +23,7 @@ public HttpClientUtilityShould() } [Fact] - public async Task ReturnContentAsString() + public async Task ReturnContentAsStringAsync() { var uri = "http://api/test"; var testContent = MockHttpConstants.UriContentDictionary[uri]; @@ -41,7 +41,7 @@ public async Task ReturnContentAsString() } [Fact] - public async Task ThrowArgumentNullExceptionIfRequestMessageIsNull() + public async Task ThrowArgumentNullExceptionIfRequestMessageIsNullAsync() { // Act and Assert await Assert.ThrowsAsync(() => _httpClientUtility.ReadFromDocumentAsync(null)); diff --git a/FileService/FileService.csproj b/FileService/FileService.csproj index 4798d8950..784ce29f7 100644 --- a/FileService/FileService.csproj +++ b/FileService/FileService.csproj @@ -8,6 +8,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/FileService/Interfaces/IFileUtility.cs b/FileService/Interfaces/IFileUtility.cs index 842184c8d..a45759630 100644 --- a/FileService/Interfaces/IFileUtility.cs +++ b/FileService/Interfaces/IFileUtility.cs @@ -11,8 +11,8 @@ namespace FileService.Interfaces /// public interface IFileUtility { - Task ReadFromFile(string filePathSource); + Task ReadFromFileAsync(string filePathSource); - Task WriteToFile(string fileContents, string filePathSource); + Task WriteToFileAsync(string fileContents, string filePathSource); } } diff --git a/FileService/Services/AzureBlobStorageUtility.cs b/FileService/Services/AzureBlobStorageUtility.cs index ac7e7c07f..10920adfb 100644 --- a/FileService/Services/AzureBlobStorageUtility.cs +++ b/FileService/Services/AzureBlobStorageUtility.cs @@ -37,7 +37,7 @@ public AzureBlobStorageUtility(IConfiguration configuration) /// /// The path of the file. /// A json string of file contents. - public async Task ReadFromFile(string filePathSource) + public async Task ReadFromFileAsync(string filePathSource) { FileServiceHelper.CheckArgumentNullOrEmpty(filePathSource, nameof(filePathSource)); CheckFileFormat(filePathSource); @@ -76,7 +76,7 @@ public async Task ReadFromFile(string filePathSource) /// Contents of the file. /// The path of the file. /// - public Task WriteToFile(string fileContents, string filePathSource) + public Task WriteToFileAsync(string fileContents, string filePathSource) { throw new NotImplementedException(); } diff --git a/FileService/Services/DiskFileUtility.cs b/FileService/Services/DiskFileUtility.cs index 25e4bee61..3b00a612c 100644 --- a/FileService/Services/DiskFileUtility.cs +++ b/FileService/Services/DiskFileUtility.cs @@ -18,7 +18,7 @@ public class DiskFileUtility : IFileUtility /// /// The directory path name of the file on disk. /// The contents of the file. - public async Task ReadFromFile(string filePathSource) + public async Task ReadFromFileAsync(string filePathSource) { using (StreamReader streamReader = new StreamReader(filePathSource)) { @@ -32,7 +32,7 @@ public async Task ReadFromFile(string filePathSource) /// The string content to be written. /// The directory path name of the file on disk. /// - public async Task WriteToFile(string fileContents, string filePathSource) + public async Task WriteToFileAsync(string fileContents, string filePathSource) { using (StreamWriter streamWriter = new StreamWriter(filePathSource)) { diff --git a/GraphWebApi/Controllers/KnownIssuesController.cs b/GraphWebApi/Controllers/KnownIssuesController.cs index 6e90cdd98..c15bd527f 100644 --- a/GraphWebApi/Controllers/KnownIssuesController.cs +++ b/GraphWebApi/Controllers/KnownIssuesController.cs @@ -35,7 +35,7 @@ public KnownIssuesController(IKnownIssuesService knownIssuesService, TelemetryCl [Route("api/[controller]")] [Route("knownissues")] [HttpGet] - public async Task GetKnownIssues([FromQuery] string environment = EnvironmentType.Staging) + public async Task GetKnownIssuesAsync([FromQuery] string environment = EnvironmentType.Staging) { _telemetryClient?.TrackTrace("Request to query the list of known issues", SeverityLevel.Information, diff --git a/GraphWebApi/Controllers/OpenApiController.cs b/GraphWebApi/Controllers/OpenApiController.cs index c2ad2eda1..743ec748b 100644 --- a/GraphWebApi/Controllers/OpenApiController.cs +++ b/GraphWebApi/Controllers/OpenApiController.cs @@ -43,7 +43,7 @@ public OpenApiController(IConfiguration configuration, IOpenApiService openApiSe [Route("openapi")] [Route("$openapi")] [HttpGet] - public async Task Get( + public async Task GetAsync( [FromQuery] string operationIds = null, [FromQuery] string tags = null, [FromQuery] string url = null, @@ -72,7 +72,7 @@ public async Task Get( [Route("openapi/operations")] [HttpGet] - public async Task Get([FromQuery] string graphVersion = null, + public async Task GetAsync([FromQuery] string graphVersion = null, [FromQuery] string openApiVersion = null, [FromQuery] OpenApiStyle style = OpenApiStyle.Plain, [FromQuery] string format = null, @@ -90,7 +90,7 @@ public async Task Get([FromQuery] string graphVersion = null, } var graphOpenApi = await _openApiService.GetGraphOpenApiDocumentAsync(graphUri, style, forceRefresh, fileName); - await WriteIndex(Request.Scheme + "://" + Request.Host.Value, styleOptions.GraphVersion, styleOptions.OpenApiVersion, styleOptions.OpenApiFormat, + await WriteIndexAsync(Request.Scheme + "://" + Request.Host.Value, styleOptions.GraphVersion, styleOptions.OpenApiVersion, styleOptions.OpenApiFormat, graphOpenApi, Response.Body, styleOptions.Style, singularizeOperationIds, fileName); return new EmptyResult(); @@ -98,7 +98,7 @@ await WriteIndex(Request.Scheme + "://" + Request.Host.Value, styleOptions.Graph [Route("openapi/tree")] [HttpGet] - public async Task Get([FromQuery] string graphVersions = "*", + public async Task GetAsync([FromQuery] string graphVersions = "*", [FromQuery] bool forceRefresh = false) { if (string.IsNullOrEmpty(graphVersions)) @@ -166,7 +166,7 @@ private FileStreamResult CreateSubsetOpenApiDocument(string operationIds, string } } - private static async Task WriteIndex( + private static async Task WriteIndexAsync( string baseUrl, string graphVersion, string openApiVersion, diff --git a/GraphWebApi/Controllers/PermissionsController.cs b/GraphWebApi/Controllers/PermissionsController.cs index b7e47bf88..f2365d43e 100644 --- a/GraphWebApi/Controllers/PermissionsController.cs +++ b/GraphWebApi/Controllers/PermissionsController.cs @@ -42,7 +42,7 @@ public PermissionsController(IPermissionsStore permissionsStore, TelemetryClient // Gets the permissions scopes [HttpGet] [Produces("application/json")] - public async Task GetPermissionScopes([FromQuery]ScopeType? scopeType = null, + public async Task GetPermissionScopesAsync([FromQuery]ScopeType? scopeType = null, [FromQuery]string requestUrl = null, [FromQuery]string method = null, [FromQuery]string org = null, @@ -78,7 +78,7 @@ public async Task GetPermissionScopes([FromQuery]ScopeType? scope [HttpPost] [Produces("application/json")] - public async Task GetPermissionScopes([FromBody] List requests, + public async Task GetPermissionScopesAsync([FromBody] List requests, [FromQuery] ScopeType? scopeType = null, [FromQuery] string org = null, [FromQuery] string branchName = null, diff --git a/GraphWebApi/Controllers/SnippetsController.cs b/GraphWebApi/Controllers/SnippetsController.cs index 7e95567c3..2ebb9f2c9 100644 --- a/GraphWebApi/Controllers/SnippetsController.cs +++ b/GraphWebApi/Controllers/SnippetsController.cs @@ -86,7 +86,7 @@ public async Task PostAsync(string lang = "c#", string generation SeverityLevel.Information, _snippetsTraceProperties); - var response = GetSnippetGenerator(generation).ProcessPayloadRequest(requestPayload, lang); + var response = await GetSnippetGenerator(generation).ProcessPayloadRequestAsync(requestPayload, lang); _telemetryClient?.TrackTrace("Finished generating a code snippet", SeverityLevel.Information, @@ -95,7 +95,7 @@ public async Task PostAsync(string lang = "c#", string generation return string.IsNullOrEmpty(response) ? NoContent() : new StringResult(response); } private ISnippetsGenerator GetSnippetGenerator(string generation) { - return (generation.ToLowerInvariant()) switch { + return generation.ToLowerInvariant() switch { "odata" => _oDataSnippetGenerator, "openapi" => _openApiSnippetGenerator, _ => throw new ArgumentException($"{generation} is not a valid generation type") diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index 0dab1d54d..5c01748fe 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -47,10 +47,14 @@ - + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/GraphWebApi/Program.cs b/GraphWebApi/Program.cs index 37f4da7ae..f1d04bb56 100644 --- a/GraphWebApi/Program.cs +++ b/GraphWebApi/Program.cs @@ -41,7 +41,7 @@ public static async Task Main(string[] args) } finally { - Log.CloseAndFlush(); + await Log.CloseAndFlushAsync(); } } diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 9e0ae089f..5d5bedef1 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -20,11 +20,15 @@ all - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/KnownIssuesService.Test/KnownIssuesServiceShould.cs b/KnownIssuesService.Test/KnownIssuesServiceShould.cs index 73e34fb80..5fbe0b2ad 100644 --- a/KnownIssuesService.Test/KnownIssuesServiceShould.cs +++ b/KnownIssuesService.Test/KnownIssuesServiceShould.cs @@ -36,7 +36,7 @@ public KnownIssuesServiceShould() } [Fact] - public async Task GetQueryByWiql() + public async Task GetQueryByWiqlAsync() { //Arrange int expectedNoOfWorkItems = 5; @@ -50,7 +50,7 @@ public async Task GetQueryByWiql() } [Fact] - public async Task GetWorkItemsQuery() + public async Task GetWorkItemsQueryAsync() { //Arrange int expectedNoOfWorkItems = 5; @@ -65,7 +65,7 @@ public async Task GetWorkItemsQuery() } [Fact] - public async Task QueryBugs() + public async Task QueryBugsAsync() { //Arrange int expectedNoOfWorkItems = 3; diff --git a/KnownIssuesService/KnownIssuesService.csproj b/KnownIssuesService/KnownIssuesService.csproj index 68b69facf..9531d8f3f 100644 --- a/KnownIssuesService/KnownIssuesService.csproj +++ b/KnownIssuesService/KnownIssuesService.csproj @@ -8,6 +8,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/MockTestUtility/FileUtilityMock.cs b/MockTestUtility/FileUtilityMock.cs index 9331659b0..cfa59a23b 100644 --- a/MockTestUtility/FileUtilityMock.cs +++ b/MockTestUtility/FileUtilityMock.cs @@ -17,7 +17,7 @@ namespace MockTestUtility /// public class FileUtilityMock : IFileUtility, IHttpClientUtility { - public async Task ReadFromFile(string filePathSource) + public async Task ReadFromFileAsync(string filePathSource) { UtilityFunctions.CheckArgumentNull(filePathSource, nameof(filePathSource)); @@ -35,10 +35,10 @@ public async Task ReadFromDocumentAsync(HttpRequestMessage requestMessag UtilityFunctions.CheckArgumentNull(requestMessage, nameof(requestMessage)); // Mock reading from an HTTP source. - return await ReadFromFile(requestMessage.RequestUri.OriginalString); + return await ReadFromFileAsync(requestMessage.RequestUri.OriginalString); } - public Task WriteToFile(string fileContents, string filePathSource) + public Task WriteToFileAsync(string fileContents, string filePathSource) { // Not implemented return Task.CompletedTask; diff --git a/MockTestUtility/MockTestUtility.csproj b/MockTestUtility/MockTestUtility.csproj index 6f04d904f..f0e9a44f0 100644 --- a/MockTestUtility/MockTestUtility.csproj +++ b/MockTestUtility/MockTestUtility.csproj @@ -7,11 +7,15 @@ - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + - + diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index 1325fb70e..f7c39e66c 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -25,9 +25,13 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + - all diff --git a/OpenAPIService.Test/OpenAPIServiceShould.cs b/OpenAPIService.Test/OpenAPIServiceShould.cs index 0f98f1ff3..58d8f419a 100644 --- a/OpenAPIService.Test/OpenAPIServiceShould.cs +++ b/OpenAPIService.Test/OpenAPIServiceShould.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Text.Json; +using System.Threading.Tasks; using Microsoft.OpenApi; using Microsoft.OpenApi.Extensions; using Microsoft.OpenApi.Models; @@ -584,7 +585,7 @@ public void SetByRefPostfixForRefOperationIds() } [Fact] - public void GetOpenApiTreeNode() + public async Task GetOpenApiTreeNodeAsync() { // Arrange var sources = new ConcurrentDictionary(); @@ -593,7 +594,7 @@ public void GetOpenApiTreeNode() // Act var rootNode = _openApiService.CreateOpenApiUrlTreeNode(sources); using MemoryStream stream = new(); - ConvertOpenApiUrlTreeNodeToJson(rootNode, stream); + await ConvertOpenApiUrlTreeNodeToJsonAsync(rootNode, stream); // Assert var jsonPayload = Encoding.ASCII.GetString(stream.ToArray()); @@ -720,10 +721,10 @@ public void ConvertOpenApiUrlTreeNodeToJsonRendersExternalDocs() Assert.Contains("\"children\":[{\"segment\":\"{user-id}\",\"labels\":[{\"name\":\"mock\",\"methods\":[{\"name\":\"Get\",\"documentationUrl\":\"https://docs.microsoft.com/foobar\"}", output); } - private void ConvertOpenApiUrlTreeNodeToJson(OpenApiUrlTreeNode node, Stream stream) + private async Task ConvertOpenApiUrlTreeNodeToJsonAsync(OpenApiUrlTreeNode node, Stream stream) { Assert.NotNull(node); - _openApiService.ConvertOpenApiUrlTreeNodeToJson(node, stream); + await _openApiService.ConvertOpenApiUrlTreeNodeToJsonAsync(node, stream); Assert.True(stream.Length > 0); } } diff --git a/OpenAPIService/Interfaces/IOpenApiService.cs b/OpenAPIService/Interfaces/IOpenApiService.cs index d6df9a39a..c9baea41d 100644 --- a/OpenAPIService/Interfaces/IOpenApiService.cs +++ b/OpenAPIService/Interfaces/IOpenApiService.cs @@ -25,7 +25,7 @@ Func CreatePredicate(string operationIds, string tags, s OpenApiUrlTreeNode CreateOpenApiUrlTreeNode(ConcurrentDictionary sources); - void ConvertOpenApiUrlTreeNodeToJson(OpenApiUrlTreeNode rootNode, Stream stream); + Task ConvertOpenApiUrlTreeNodeToJsonAsync(OpenApiUrlTreeNode rootNode, Stream stream); OpenApiDocument ApplyStyle(OpenApiStyle style, OpenApiDocument subsetOpenApiDocument, bool includeRequestBody = false, bool singularizeOperationIds = false); diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index ab92eb16c..2ce71e458 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -7,12 +7,16 @@ - + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/OpenAPIService/OpenApiService.cs b/OpenAPIService/OpenApiService.cs index 0cc59bb4a..fe84c0401 100644 --- a/OpenAPIService/OpenApiService.cs +++ b/OpenAPIService/OpenApiService.cs @@ -394,11 +394,11 @@ private OpenApiOperation[] GetOpenApiOperations(OpenApiUrlTreeNode rootNode, str /// /// The target root node. /// The destination for writing the JSON text to. - public void ConvertOpenApiUrlTreeNodeToJson(OpenApiUrlTreeNode rootNode, Stream stream) + public async Task ConvertOpenApiUrlTreeNodeToJsonAsync(OpenApiUrlTreeNode rootNode, Stream stream) { using Utf8JsonWriter writer = new Utf8JsonWriter(stream); ConvertOpenApiUrlTreeNodeToJson(writer, rootNode); - writer.FlushAsync(); + await writer.FlushAsync(); } /// diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index 04acb68cb..521709880 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -34,6 +34,10 @@ all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/PermissionsService.Test/PermissionsStoreShould.cs b/PermissionsService.Test/PermissionsStoreShould.cs index 493e4c9b9..7f0edcdab 100644 --- a/PermissionsService.Test/PermissionsStoreShould.cs +++ b/PermissionsService.Test/PermissionsStoreShould.cs @@ -25,7 +25,7 @@ public PermissionsStoreShould() } [Fact] - public async Task GetAllRequiredPermissionScopesGivenAnExistingRequestUrl() + public async Task GetAllRequiredPermissionScopesGivenAnExistingRequestUrlAsync() { // Act var result = await _permissionsStore.GetScopesAsync( @@ -79,7 +79,7 @@ public async Task GetAllRequiredPermissionScopesGivenAnExistingRequestUrl() [InlineData(ScopeType.DelegatedWork)] [InlineData(ScopeType.DelegatedPersonal)] [InlineData(ScopeType.Application)] - public async Task GetRequiredPermissionScopesGivenAnExistingRequestUrlByScopeType(ScopeType scopeType) + public async Task GetRequiredPermissionScopesGivenAnExistingRequestUrlByScopeTypeAsync(ScopeType scopeType) { // Act var result = await _permissionsStore.GetScopesAsync( @@ -144,7 +144,7 @@ public async Task GetRequiredPermissionScopesGivenAnExistingRequestUrlByScopeTyp } [Fact] - public async Task GetLeastPrivilegePermissionScopesGivenAnExistingRequestUrl() + public async Task GetLeastPrivilegePermissionScopesGivenAnExistingRequestUrlAsync() { // Act var result = await _permissionsStore.GetScopesAsync( @@ -171,7 +171,7 @@ public async Task GetLeastPrivilegePermissionScopesGivenAnExistingRequestUrl() [InlineData(ScopeType.DelegatedWork, 497)] [InlineData(ScopeType.DelegatedPersonal, 468)] [InlineData(ScopeType.Application, 475)] - public async Task GetAllPermissionScopesGivenNoRequestUrlFilteredByScopeType(ScopeType scopeType, int expectedCount) + public async Task GetAllPermissionScopesGivenNoRequestUrlFilteredByScopeTypeAsync(ScopeType scopeType, int expectedCount) { // Act var result = await _permissionsStore.GetScopesAsync(scopeType: scopeType); @@ -182,7 +182,7 @@ public async Task GetAllPermissionScopesGivenNoRequestUrlFilteredByScopeType(Sco } [Fact] - public async Task GetAllPermissionScopesGivenNoRequestUrl() + public async Task GetAllPermissionScopesGivenNoRequestUrlAsync() { // Act var result = await _permissionsStore.GetScopesAsync(); @@ -193,7 +193,7 @@ public async Task GetAllPermissionScopesGivenNoRequestUrl() } [Fact] - public async Task ReturnNullGivenANonExistentRequestUrl() + public async Task ReturnNullGivenANonExistentRequestUrlAsync() { // Act var result = await _permissionsStore.GetScopesAsync( @@ -204,7 +204,7 @@ public async Task ReturnNullGivenANonExistentRequestUrl() } [Fact] - public async Task ReturnNullGivenANonExistentHttpVerb() + public async Task ReturnNullGivenANonExistentHttpVerbAsync() { // Act var result = await _permissionsStore.GetScopesAsync( @@ -220,7 +220,7 @@ public async Task ReturnNullGivenANonExistentHttpVerb() [Theory] [InlineData(true, 6)] [InlineData(false, 12)] - public async Task ReturnLeastPrivilegePermissionsForSetOfResources(bool leastPrivilegeOnly, int expectedCount) + public async Task ReturnLeastPrivilegePermissionsForSetOfResourcesAsync(bool leastPrivilegeOnly, int expectedCount) { // Arrange var requests = new List() @@ -242,7 +242,7 @@ public async Task ReturnLeastPrivilegePermissionsForSetOfResources(bool leastPri } [Fact] - public async Task ReturnCorrectLeastPrivilegePermissionsForResourcesThatHaveMatchMoreThanOneTemplate() + public async Task ReturnCorrectLeastPrivilegePermissionsForResourcesThatHaveMatchMoreThanOneTemplateAsync() { // Arrange var request1 = new List() @@ -266,7 +266,7 @@ public async Task ReturnCorrectLeastPrivilegePermissionsForResourcesThatHaveMatc } [Fact] - public async Task ReturnErrorWhenLeastPrivilegePermissionsForSetOfResourcesIsNotAvailable() + public async Task ReturnErrorWhenLeastPrivilegePermissionsForSetOfResourcesIsNotAvailableAsync() { // Act var result = await _permissionsStore.GetScopesAsync( @@ -286,7 +286,7 @@ public async Task ReturnErrorWhenLeastPrivilegePermissionsForSetOfResourcesIsNot [InlineData("/users/{id}/drive/items/{id}/workbook/worksheets/{id}/range")] [InlineData("/users/{id}/drive/items/{id}/workbook/worksheets/{id}/range()")] [InlineData("/users/{id}/drive/items/{id}/workbook/worksheets/{id}/range(address={value})")] - public async Task RemoveFunctionParametersFromRequestUrlsDuringLoadingAndQueryingOfPermissionsFiles(string url) + public async Task RemoveFunctionParametersFromRequestUrlsDuringLoadingAndQueryingOfPermissionsFilesAsync(string url) { // Act var result = @@ -307,7 +307,7 @@ await _permissionsStore.GetScopesAsync( } [Fact] - public async Task ReturnLocalizedPermissionsDescriptionsForSupportedLanguage() + public async Task ReturnLocalizedPermissionsDescriptionsForSupportedLanguageAsync() { // Act var result = await _permissionsStore.GetScopesAsync( @@ -334,7 +334,7 @@ public async Task ReturnLocalizedPermissionsDescriptionsForSupportedLanguage() } [Fact] - public async Task ReturnsErrorsForEmptyRequestUrl() + public async Task ReturnsErrorsForEmptyRequestUrlAsync() { // Act PermissionResult result = @@ -354,7 +354,7 @@ await _permissionsStore.GetScopesAsync( } [Fact] - public async Task ReturnsErrorsForNullRequestUrl() + public async Task ReturnsErrorsForNullRequestUrlAsync() { // Act PermissionResult result = @@ -374,7 +374,7 @@ await _permissionsStore.GetScopesAsync( } [Fact] - public async Task ReturnsErrorsForNonExistentRequestUrls() + public async Task ReturnsErrorsForNonExistentRequestUrlsAsync() { // Act PermissionResult result = @@ -394,7 +394,7 @@ await _permissionsStore.GetScopesAsync( } [Fact] - public async Task ReturnsUniqueListOfPermissionsForPathsWithSharedPermissions() + public async Task ReturnsUniqueListOfPermissionsForPathsWithSharedPermissionsAsync() { // Act PermissionResult result = @@ -420,7 +420,7 @@ public async Task ReturnsUniqueListOfPermissionsForPathsWithSharedPermissions() } [Fact] - public async Task FetchPermissionsDescriptionsFromGithub() + public async Task FetchPermissionsDescriptionsFromGithubAsync() { //Arrange string org = "\\Org"; @@ -434,7 +434,7 @@ public async Task FetchPermissionsDescriptionsFromGithub() } [Fact] - public async Task FetchPermissionsDescriptionsFromGithubGivenARequestUrl() + public async Task FetchPermissionsDescriptionsFromGithubGivenARequestUrlAsync() { // Arrange string org = "\\Org"; diff --git a/PermissionsService/PermissionsService.csproj b/PermissionsService/PermissionsService.csproj index 14cdf2727..54f20a22c 100644 --- a/PermissionsService/PermissionsService.csproj +++ b/PermissionsService/PermissionsService.csproj @@ -5,11 +5,16 @@ + - + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/PermissionsService/Services/PermissionsStore.cs b/PermissionsService/Services/PermissionsStore.cs index d9f19e7bc..2d5a003c9 100644 --- a/PermissionsService/Services/PermissionsStore.cs +++ b/PermissionsService/Services/PermissionsStore.cs @@ -10,6 +10,7 @@ using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; +using AsyncKeyedLock; using FileService.Common; using FileService.Interfaces; using Kibali; @@ -45,7 +46,7 @@ public class PermissionsStore : IPermissionsStore private readonly string _scopesInformation; private readonly int _defaultRefreshTimeInHours; // life span of the in-memory cache private const string DefaultLocale = "en-US"; // default locale language - private readonly object _scopesLock = new(); + private static readonly AsyncKeyedLocker _asyncKeyedLocker = new(); private const string Delegated = "Delegated"; private const string Application = "Application"; private const string CacheRefreshTimeConfig = "FileCacheRefreshTimeInHours:Permissions"; @@ -87,37 +88,47 @@ public PermissionsStore(IConfiguration configuration, IHttpClientUtility httpCli _defaultRefreshTimeInHours = FileServiceHelper.GetFileCacheRefreshTime(configuration[CacheRefreshTimeConfig]); } - private Task PermissionsData => - _cache.GetOrCreateAsync("PermissionsData", async entry => + private async Task GetPermissionsDataAsync() + { + using(await _asyncKeyedLocker.LockAsync("PermissionData")) { - var permissionsData = await LoadPermissionsDataAsync(); - entry.AbsoluteExpirationRelativeToNow = permissionsData is not null ? TimeSpan.FromHours(_defaultRefreshTimeInHours) : TimeSpan.FromMilliseconds(1); - return permissionsData; - }); + return await _cache.GetOrCreateAsync("PermissionsData", async entry => + { + var permissionsData = await LoadPermissionsDataAsync(); + entry.AbsoluteExpirationRelativeToNow = permissionsData is not null ? TimeSpan.FromHours(_defaultRefreshTimeInHours) : TimeSpan.FromMilliseconds(1); + return permissionsData; + }); + } + } - private Task LoadDocument => - _cache.GetOrCreateAsync("PermissionsDocument", async entry => + private async Task LoadDocumentAsync() + { + using(await _asyncKeyedLocker.LockAsync("PermissionsDocument")) { - _telemetryClient?.TrackTrace($"Fetching permissions from file source '{_permissionsBlobName}'", - SeverityLevel.Information, - _permissionsTracePropertiesWithSanitizeIgnore); - PermissionsDocument permissionsDocument; - - try - { - string relativePermissionPath = FileServiceHelper.GetLocalizedFilePathSource(_permissionsContainerName, _permissionsBlobName); - string permissions = await _fileUtility.ReadFromFile(relativePermissionPath); - permissionsDocument = PermissionsDocument.Load(permissions); - entry.AbsoluteExpirationRelativeToNow = permissionsDocument is not null ? TimeSpan.FromHours(_defaultRefreshTimeInHours) : TimeSpan.FromMilliseconds(1); - } - catch (Exception exception) + return await _cache.GetOrCreateAsync("PermissionsDocument", async entry => { + _telemetryClient?.TrackTrace($"Fetching permissions from file source '{_permissionsBlobName}'", + SeverityLevel.Information, + _permissionsTracePropertiesWithSanitizeIgnore); + PermissionsDocument permissionsDocument; - _telemetryClient?.TrackException(exception); - permissionsDocument = null; - } - return permissionsDocument; - }); + try + { + string relativePermissionPath = FileServiceHelper.GetLocalizedFilePathSource(_permissionsContainerName, _permissionsBlobName); + string permissions = await _fileUtility.ReadFromFileAsync(relativePermissionPath); + permissionsDocument = PermissionsDocument.Load(permissions); + entry.AbsoluteExpirationRelativeToNow = permissionsDocument is not null ? TimeSpan.FromHours(_defaultRefreshTimeInHours) : TimeSpan.FromMilliseconds(1); + } + catch (Exception exception) + { + + _telemetryClient?.TrackException(exception); + permissionsDocument = null; + } + return permissionsDocument; + }); + } + } /// /// Populates the template table with the request urls and the scopes table with the permission scopes. @@ -135,7 +146,7 @@ private async Task LoadPermissionsDataAsync() // Get file contents from source string relativePermissionPath = FileServiceHelper.GetLocalizedFilePathSource(_permissionsContainerName, _permissionsBlobName); - string permissionsJson = await _fileUtility.ReadFromFile(relativePermissionPath); + string permissionsJson = await _fileUtility.ReadFromFileAsync(relativePermissionPath); var fetchedPermissions = JsonSerializer.Deserialize>>>(permissionsJson); _telemetryClient?.TrackTrace("Finished fetching permissions from file", @@ -195,56 +206,38 @@ private async Task>> G SeverityLevel.Information, _permissionsTraceProperties); - var scopesInformationDictionary = await _cache.GetOrCreateAsync($"ScopesInfoList_{locale}", cacheEntry => + // making sure only a single thread at a time access the cache + // when already seeded, lock will resolve fast and access the cache + // when not seeded, lock will resolve slow for all other threads and seed the cache on the first thread + using (await _asyncKeyedLocker.LockAsync("scopes")) { - _telemetryClient?.TrackTrace($"In-memory cache 'ScopesInfoList_{locale}' empty. " + - $"Seeding permissions for locale '{locale}' from Azure blob resource", - SeverityLevel.Information, - _permissionsTraceProperties); - - /* Localized copy of permissions descriptions - is to be seeded by only one executing thread. - */ - lock (_scopesLock) + var scopesInformationDictionary = await _cache.GetOrCreateAsync($"ScopesInfoList_{locale}", async cacheEntry => { - /* Check whether a previous thread already seeded an - * instance of the localized permissions descriptions - * during the lock. - */ - var seededScopesInfoDictionary = _cache.Get>>($"ScopesInfoList_{locale}"); - var sourceMsg = $"Return locale '{locale}' permissions from in-memory cache 'ScopesInfoList_{locale}'"; - - if (seededScopesInfoDictionary == null) - { - string relativeScopesInfoPath = FileServiceHelper.GetLocalizedFilePathSource(_permissionsContainerName, _scopesInformation, locale); + _telemetryClient?.TrackTrace($"In-memory cache 'ScopesInfoList_{locale}' empty. " + + $"Seeding permissions for locale '{locale}' from Azure blob resource", + SeverityLevel.Information, + _permissionsTraceProperties); - // Get file contents from source - string scopesInfoJson = _fileUtility.ReadFromFile(relativeScopesInfoPath).GetAwaiter().GetResult(); - _telemetryClient?.TrackTrace($"Successfully seeded permissions for locale '{locale}' from Azure blob resource", - SeverityLevel.Information, - _permissionsTraceProperties); + string relativeScopesInfoPath = FileServiceHelper.GetLocalizedFilePathSource(_permissionsContainerName, _scopesInformation, locale); - seededScopesInfoDictionary = CreateScopesInformationTables(scopesInfoJson); - cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(_defaultRefreshTimeInHours); - sourceMsg = $"Return locale '{locale}' permissions from Azure blob resource"; - } - else - { - _telemetryClient?.TrackTrace($"In-memory cache 'ScopesInfoList_{locale}' of permissions " + - $"already seeded by a concurrently running thread", - SeverityLevel.Information, - _permissionsTraceProperties); - } + // Get file contents from source + string scopesInfoJson = await _fileUtility.ReadFromFileAsync(relativeScopesInfoPath); + _telemetryClient?.TrackTrace($"Successfully seeded permissions for locale '{locale}' from Azure blob resource", + SeverityLevel.Information, + _permissionsTraceProperties); - _telemetryClient?.TrackTrace(sourceMsg, - SeverityLevel.Information, - _permissionsTraceProperties); + var seededScopesInfoDictionary = CreateScopesInformationTables(scopesInfoJson); + cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(_defaultRefreshTimeInHours); - return Task.FromResult(seededScopesInfoDictionary); - } - }); + _telemetryClient?.TrackTrace($"Return locale '{locale}' permissions from Azure blob resource", + SeverityLevel.Information, + _permissionsTraceProperties); - return scopesInformationDictionary; + return seededScopesInfoDictionary; + }); + + return scopesInformationDictionary; + } } /// @@ -254,7 +247,7 @@ is to be seeded by only one executing thread. /// The org or owner of the repo. /// The name of the branch with the file version. /// The localized instance of permissions descriptions. - private async Task>> GetPermissionsDescriptionsFromGithub(string org, + private async Task>> GetPermissionsDescriptionsFromGithubAsync(string org, string branchName, string locale = DefaultLocale) { @@ -271,7 +264,7 @@ private async Task>> G var queriesFilePathSource = string.Concat(host, org, repo, branchName, FileServiceConstants.DirectorySeparator, localizedFilePathSource); // Get file contents from source - string scopesInfoJson = await FetchHttpSourceDocument(queriesFilePathSource); + string scopesInfoJson = await FetchHttpSourceDocumentAsync(queriesFilePathSource); var scopesInformationDictionary = CreateScopesInformationTables(scopesInfoJson); @@ -287,7 +280,7 @@ private async Task>> G /// /// The relative file path. /// A document retrieved from the Http source. - private async Task FetchHttpSourceDocument(string sourceUri) + private async Task FetchHttpSourceDocumentAsync(string sourceUri) { // Construct the http request message using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, sourceUri); @@ -341,10 +334,7 @@ public async Task GetScopesAsync(List requests = string org = null, string branchName = null) { - var permissionsDocument = await LoadDocument; - if (permissionsDocument == null) - throw new InvalidOperationException("Failed to fetch permissions"); - + var permissionsDocument = await LoadDocumentAsync() ?? throw new InvalidOperationException("Failed to fetch permissions"); var scopes = new List(); var errors = new List(); @@ -430,7 +420,7 @@ public async Task GetScopesAsync(List requests = // Create a dict of scopes information from GitHub files or cached files var scopesInformationDictionary = !(string.IsNullOrEmpty(org) || string.IsNullOrEmpty(branchName)) - ? await GetPermissionsDescriptionsFromGithub(org, branchName, locale) + ? await GetPermissionsDescriptionsFromGithubAsync(org, branchName, locale) : await GetOrCreatePermissionsDescriptionsAsync(locale); // Get consent display name and description @@ -630,7 +620,7 @@ private List GetAdditionalScopesInformation(IDictionary public async Task GetUriTemplateMatcherAsync() { - var permissionsData = await PermissionsData; + var permissionsData = await GetPermissionsDataAsync(); return permissionsData.UriTemplateMatcher; } } diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index 26e293e86..aa978ef44 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -57,6 +57,10 @@ all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/SamplesService.Test/SamplesStoreShould.cs b/SamplesService.Test/SamplesStoreShould.cs index 9e2de3d29..115dec215 100644 --- a/SamplesService.Test/SamplesStoreShould.cs +++ b/SamplesService.Test/SamplesStoreShould.cs @@ -37,7 +37,7 @@ public SamplesStoreShould() } [Fact] - public async Task CorrectlySeedLocaleCachesOfSampleQueriesWhenMultipleRequestsReceived() + public async Task CorrectlySeedLocaleCachesOfSampleQueriesWhenMultipleRequestsReceivedAsync() { // Arrange _samplesStore = new SamplesStore(_configuration, _httpClientUtility, _fileUtility, _samplesCache); @@ -72,7 +72,7 @@ public async Task CorrectlySeedLocaleCachesOfSampleQueriesWhenMultipleRequestsRe } [Fact] - public async Task ReturnNullIfSampleQueryFileIsEmpty() + public async Task ReturnNullIfSampleQueryFileIsEmptyAsync() { // Arrange _samplesStore = new SamplesStore(_configuration, _httpClientUtility, _fileUtility, _samplesCache); @@ -85,7 +85,7 @@ public async Task ReturnNullIfSampleQueryFileIsEmpty() } [Fact] - public async Task FetchSamplesFromGithub() + public async Task FetchSamplesFromGithubAsync() { //Arrange var configuration = new ConfigurationBuilder() @@ -117,7 +117,7 @@ public async Task FetchSamplesFromGithub() } [Fact] - public async Task ReturnNotNullIfSampleQueriesFileHasEmptyJsonObject() + public async Task ReturnNotNullIfSampleQueriesFileHasEmptyJsonObjectAsync() { //Arrange var configuration = new ConfigurationBuilder() diff --git a/SamplesService/SamplesService.csproj b/SamplesService/SamplesService.csproj index 0fb9ae25d..0e85b9e28 100644 --- a/SamplesService/SamplesService.csproj +++ b/SamplesService/SamplesService.csproj @@ -5,12 +5,17 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/SamplesService/Services/SamplesStore.cs b/SamplesService/Services/SamplesStore.cs index 584dfb77b..863770669 100644 --- a/SamplesService/Services/SamplesStore.cs +++ b/SamplesService/Services/SamplesStore.cs @@ -2,6 +2,7 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information. // ------------------------------------------------------------------------------------------------------------------------------------------------------ +using AsyncKeyedLock; using FileService.Common; using FileService.Interfaces; using Microsoft.ApplicationInsights; @@ -23,7 +24,7 @@ namespace SamplesService.Services /// public class SamplesStore : ISamplesStore { - private readonly object _samplesLock = new(); + private static readonly AsyncKeyedLocker _asyncKeyedLocker = new(); private readonly IFileUtility _fileUtility; private readonly IHttpClientUtility _httpClientUtility; private readonly IMemoryCache _samplesCache; @@ -67,63 +68,47 @@ public async Task FetchSampleQueriesListAsync(string locale) string sourceMsg = $"Return sample queries list for locale '{locale}' from in-memory cache '{locale}'"; - // Fetch cached sample queries - SampleQueriesList sampleQueriesList = await _samplesCache.GetOrCreateAsync(locale, cacheEntry => + // making sure only a single thread at a time access the cache + // when already seeded, lock will resolve fast and access the cache + // when not seeded, lock will resolve slow for all other threads and seed the cache on the first thread + using (await _asyncKeyedLocker.LockAsync("samples")) { - _telemetryClient?.TrackTrace($"In-memory cache '{locale}' empty. " + - $"Seeding sample queries list from Azure Blob resource", - SeverityLevel.Information, - SamplesTraceProperties); - - // Localized copy of samples is to be seeded by only one executing thread. - lock (_samplesLock) + // Fetch cached sample queries + var sampleQueriesList = await _samplesCache.GetOrCreateAsync(locale, async cacheEntry => { - /* Check whether a previous thread already seeded an - * instance of the localized samples during the lock. - */ - var lockedLocale = locale; - var seededSampleQueriesList = _samplesCache?.Get(lockedLocale); - - if (seededSampleQueriesList != null) - { - _telemetryClient?.TrackTrace($"In-memory cache '{lockedLocale}' of sample queries list " + - $"already seeded by a concurrently running thread", - SeverityLevel.Information, - SamplesTraceProperties); - sourceMsg = $"Return sample queries list for locale '{lockedLocale}' from in-memory cache '{lockedLocale}'"; - - return Task.FromResult(seededSampleQueriesList); - } + _telemetryClient?.TrackTrace($"In-memory cache '{locale}' empty. " + + $"Seeding sample queries list from Azure Blob resource", + SeverityLevel.Information, + SamplesTraceProperties); cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(_defaultRefreshTimeInHours); // Fetch the requisite sample path source based on the locale string queriesFilePathSource = - FileServiceHelper.GetLocalizedFilePathSource(_sampleQueriesContainerName, _sampleQueriesBlobName, lockedLocale); + FileServiceHelper.GetLocalizedFilePathSource(_sampleQueriesContainerName, _sampleQueriesBlobName, locale); // Get the file contents from source - string jsonFileContents = _fileUtility.ReadFromFile(queriesFilePathSource).GetAwaiter().GetResult(); + string jsonFileContents = await _fileUtility.ReadFromFileAsync(queriesFilePathSource); - _telemetryClient?.TrackTrace($"Successfully seeded sample queries list for locale '{lockedLocale}' from Azure Blob resource", - SeverityLevel.Information, - SamplesTraceProperties); + _telemetryClient?.TrackTrace($"Successfully seeded sample queries list for locale '{locale}' from Azure Blob resource", + SeverityLevel.Information, + SamplesTraceProperties); /* Current business process only supports ordering of the English - translation of the sample queries. - */ - bool orderSamples = lockedLocale.Equals("en-us", StringComparison.OrdinalIgnoreCase); + translation of the sample queries. + */ - sourceMsg = $"Return sample queries list for locale '{lockedLocale}' from Azure Blob resource"; + sourceMsg = $"Return sample queries list for locale '{locale}' from Azure Blob resource"; - return Task.FromResult(DeserializeSamplesList(jsonFileContents, locale)); - } - }); + return DeserializeSamplesList(jsonFileContents, locale); + }); - _telemetryClient?.TrackTrace(sourceMsg, - SeverityLevel.Information, - SamplesTraceProperties); + _telemetryClient?.TrackTrace(sourceMsg, + SeverityLevel.Information, + SamplesTraceProperties); - return sampleQueriesList; + return sampleQueriesList; + } } /// diff --git a/TelemetryService.Test/CustomPIIFilterShould.cs b/TelemetryService.Test/CustomPIIFilterShould.cs index 8a9bdeb8c..7611031ae 100644 --- a/TelemetryService.Test/CustomPIIFilterShould.cs +++ b/TelemetryService.Test/CustomPIIFilterShould.cs @@ -44,7 +44,7 @@ public void ThrowsArgumentNullExceptionIfPermissionsStoreArgumentNull() // Non-existent path in UriTemplateMatcher table [InlineData("/permissions?requestUrl=/me/people/12345/drives&method=GET", "/permissions?requestUrl=/me/people/****/drives&method=GET")] - public void RedactNumberFromEventTelemetry(string requestPath, string expectedPath) + public async System.Threading.Tasks.Task RedactNumberFromEventTelemetryAsync(string requestPath, string expectedPath) { // Arrange var httpMethod = "GET"; @@ -59,7 +59,7 @@ public void RedactNumberFromEventTelemetry(string requestPath, string expectedPa eventTelemetry.Properties.Add("RenderedMessage", renderedMessage); // Act - _telemetryClientProcessor.Process(eventTelemetry); + await _telemetryClientProcessor.ProcessAsync(eventTelemetry); var expectedMessage = $"HTTP {httpMethod + expectedPath} responded {statusCode} in {elapsed} ms"; // Assert @@ -76,7 +76,7 @@ public void RedactNumberFromEventTelemetry(string requestPath, string expectedPa // Non-existent path in UriTemplateMatcher table [InlineData("/permissions?requestUrl=/me/people/9f376303-1936-44a9-b4fd-7271483525bb/drives&method=GET", "/permissions?requestUrl=/me/people/****/drives&method=GET")] - public void RedactGUIDFromEventTelemetry(string requestPath, string expectedPath) + public async System.Threading.Tasks.Task RedactGUIDFromEventTelemetryAsync(string requestPath, string expectedPath) { // Arrange var httpMethod = "GET"; @@ -91,7 +91,7 @@ public void RedactGUIDFromEventTelemetry(string requestPath, string expectedPath eventTelemetry.Properties.Add("RenderedMessage", renderedMessage); // Act - _telemetryClientProcessor.Process(eventTelemetry); + await _telemetryClientProcessor.ProcessAsync(eventTelemetry); var expectedMessage = $"HTTP {httpMethod + expectedPath} responded {statusCode} in {elapsed} ms"; // Assert @@ -106,7 +106,7 @@ public void RedactGUIDFromEventTelemetry(string requestPath, string expectedPath // Valid query param & existing path in UriTemplateMatcher table [InlineData("/openapi?url=/users?$filter(emailAddress eq 'MiriamG@M365x214355.onmicrosoft.com')", "/openapi?url=/users")] - public void RedactEmailFromEventTelemetry(string requestPath, string expectedPath) + public async System.Threading.Tasks.Task RedactEmailFromEventTelemetryAsync(string requestPath, string expectedPath) { // Arrange var httpMethod = "GET"; @@ -121,7 +121,7 @@ public void RedactEmailFromEventTelemetry(string requestPath, string expectedPat eventTelemetry.Properties.Add("RenderedMessage", renderedMessage); // Act - _telemetryClientProcessor.Process(eventTelemetry); + await _telemetryClientProcessor.ProcessAsync(eventTelemetry); var expectedMessage = $"HTTP {httpMethod} {expectedPath} responded {statusCode} in {elapsed} ms"; // Assert @@ -136,7 +136,7 @@ public void RedactEmailFromEventTelemetry(string requestPath, string expectedPat // Valid query param & existing path in UriTemplateMatcher table [InlineData("/permissions?requestUrl=/users?$filter(displayName eq 'Megan Bowen')", "/permissions?requestUrl=/users")] - public void RedactUsernameFromEventTelemetry(string requestPath, string expectedPath) + public async System.Threading.Tasks.Task RedactUsernameFromEventTelemetryAsync(string requestPath, string expectedPath) { // Arrange var httpMethod = "GET"; @@ -151,7 +151,7 @@ public void RedactUsernameFromEventTelemetry(string requestPath, string expected eventTelemetry.Properties.Add("RenderedMessage", renderedMessage); // Act - _telemetryClientProcessor.Process(eventTelemetry); + await _telemetryClientProcessor.ProcessAsync(eventTelemetry); var expectedMessage = $"HTTP {httpMethod} {expectedPath} responded {statusCode} in {elapsed} ms"; // Assert @@ -166,7 +166,7 @@ public void RedactUsernameFromEventTelemetry(string requestPath, string expected // Valid query param & existing path in UriTemplateMatcher table [InlineData("/openapi?url=/users?$filter(firstName eq 'Megan')", "/openapi?url=/users")] - public void RedactFirstNameFromEventTelemetry(string requestPath, string expectedPath) + public async System.Threading.Tasks.Task RedactFirstNameFromEventTelemetryAsync(string requestPath, string expectedPath) { // Arrange var httpMethod = "GET"; @@ -181,7 +181,7 @@ public void RedactFirstNameFromEventTelemetry(string requestPath, string expecte eventTelemetry.Properties.Add("RenderedMessage", renderedMessage); // Act - _telemetryClientProcessor.Process(eventTelemetry); + await _telemetryClientProcessor.ProcessAsync(eventTelemetry); var expectedMessage = $"HTTP {httpMethod} {expectedPath} responded {statusCode} in {elapsed} ms"; // Assert @@ -243,7 +243,7 @@ public void RedactFirstNameFromEventTelemetry(string requestPath, string expecte #endregion - public void SanitizeRequestTelemetry(string incomingUrl, string expectedUrl) + public async System.Threading.Tasks.Task SanitizeRequestTelemetryAsync(string incomingUrl, string expectedUrl) { // Arrange var request = new RequestTelemetry @@ -252,7 +252,7 @@ public void SanitizeRequestTelemetry(string incomingUrl, string expectedUrl) }; // Act - _telemetryClientProcessor.Process(request); + await _telemetryClientProcessor.ProcessAsync(request); // Assert Assert.Equal(expectedUrl, request.Url.ToString()); @@ -263,7 +263,7 @@ public void SanitizeRequestTelemetry(string incomingUrl, string expectedUrl) "Fetching 'DelegatedWork' permissions for url '/users/****/drives' and method 'GET'")] [InlineData("Fetching 'DelegatedWork' permissions for url '/users?$expand=directreports($filter=firstName eq 'mary')' and method 'GET'", "Fetching 'DelegatedWork' permissions for url '/users?$expand=directreports($filter=firstName eq ****)' and method 'GET'")] - public void RedactPIIFromTraceTelemetry(string incomingMsg, string expectedMsg) + public async System.Threading.Tasks.Task RedactPIIFromTraceTelemetryAsync(string incomingMsg, string expectedMsg) { // Arrange var trace = new TraceTelemetry @@ -272,7 +272,7 @@ public void RedactPIIFromTraceTelemetry(string incomingMsg, string expectedMsg) }; // Act - _telemetryClientProcessor.Process(trace); + await _telemetryClientProcessor.ProcessAsync(trace); // Assert Assert.Equal(expectedMsg, trace.Message); diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index a50bf91af..3fc4bffad 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -28,6 +28,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelemetryService/CustomPIIFilter.cs b/TelemetryService/CustomPIIFilter.cs index 44ab24bd1..934dad4b4 100644 --- a/TelemetryService/CustomPIIFilter.cs +++ b/TelemetryService/CustomPIIFilter.cs @@ -84,23 +84,23 @@ public CustomPIIFilter(ITelemetryProcessor next, IServiceProvider serviceProvide /// Filters telemetry data and calls the next ITelemetryProcessor in the chain. /// /// A telemetry Item. - public void Process(ITelemetry item) + public async Task ProcessAsync(ITelemetry item) { if (item is EventTelemetry customEvent && customEvent.Properties.ContainsKey(RequestPath) && customEvent.Properties.ContainsKey(RenderedMessage)) { - SanitizeTelemetryAsync(customEvent: customEvent).GetAwaiter().GetResult(); + await SanitizeTelemetryAsync(customEvent: customEvent); } if (item is RequestTelemetry request) { - SanitizeTelemetryAsync(request: request).GetAwaiter().GetResult(); + await SanitizeTelemetryAsync(request: request); } if (item is TraceTelemetry trace && !trace.Properties.ContainsKey(UtilityConstants.TelemetryPropertyKey_SanitizeIgnore)) { - SanitizeTelemetryAsync(trace: trace).GetAwaiter().GetResult(); + await SanitizeTelemetryAsync(trace: trace); } _next.Process(item); @@ -316,5 +316,12 @@ private static string RedactSearchableValues(string content) return contents[0] + ODataSearchOperator + searchableContent; } + + public void Process(ITelemetry item) + { +#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits + ProcessAsync(item).GetAwaiter().GetResult(); +#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits + } } } diff --git a/TelemetryService/TelemetrySanitizerService.csproj b/TelemetryService/TelemetrySanitizerService.csproj index b4f44f1bf..1feaa564a 100644 --- a/TelemetryService/TelemetrySanitizerService.csproj +++ b/TelemetryService/TelemetrySanitizerService.csproj @@ -8,6 +8,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 85ae4eefd..77a5f7026 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -16,6 +16,10 @@ all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/UriMatchService/UriMatchService.csproj b/UriMatchService/UriMatchService.csproj deleted file mode 100644 index 9f5c4f4ab..000000000 --- a/UriMatchService/UriMatchService.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - netstandard2.0 - - - diff --git a/UriMatchService/UriMatchingService.csproj b/UriMatchService/UriMatchingService.csproj index 9f5c4f4ab..54669eeb9 100644 --- a/UriMatchService/UriMatchingService.csproj +++ b/UriMatchService/UriMatchingService.csproj @@ -1,7 +1,14 @@ - netstandard2.0 + net8.0 + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index dc61dba94..6b4041274 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -12,6 +12,10 @@ all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UtilityService/UtilityService.csproj b/UtilityService/UtilityService.csproj index 7debfb17b..652c76724 100644 --- a/UtilityService/UtilityService.csproj +++ b/UtilityService/UtilityService.csproj @@ -6,6 +6,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/apidoctor b/apidoctor index a34a80d1a..e1742c28a 160000 --- a/apidoctor +++ b/apidoctor @@ -1 +1 @@ -Subproject commit a34a80d1a6fc4a88820464325a1f6b4f59b2ca2b +Subproject commit e1742c28a446cdc801e83f638e4650ce685e47ca From c50cc518fc5d75868fffc203b487b30caf851101 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 06:15:15 +0000 Subject: [PATCH 02/45] Bump AsyncKeyedLock from 7.1.3 to 7.1.4 (#2257) Bumps [AsyncKeyedLock](https://github.com/MarkCiliaVincenti/AsyncKeyedLock) from 7.1.3 to 7.1.4. - [Release notes](https://github.com/MarkCiliaVincenti/AsyncKeyedLock/releases) - [Commits](https://github.com/MarkCiliaVincenti/AsyncKeyedLock/compare/7.1.3...7.1.4) --- updated-dependencies: - dependency-name: AsyncKeyedLock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- PermissionsService/PermissionsService.csproj | 2 +- SamplesService/SamplesService.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PermissionsService/PermissionsService.csproj b/PermissionsService/PermissionsService.csproj index 54f20a22c..8dcfd85cb 100644 --- a/PermissionsService/PermissionsService.csproj +++ b/PermissionsService/PermissionsService.csproj @@ -5,7 +5,7 @@ - + diff --git a/SamplesService/SamplesService.csproj b/SamplesService/SamplesService.csproj index 0e85b9e28..2f4254a31 100644 --- a/SamplesService/SamplesService.csproj +++ b/SamplesService/SamplesService.csproj @@ -5,7 +5,7 @@ - + From ac89736afa7931477e7656d3092875afe7f0a578 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:15:41 +0300 Subject: [PATCH 03/45] Bump apidoctor from `e1742c2` to `7d8ebd4` (#2259) Bumps [apidoctor](https://github.com/OneDrive/apidoctor) from `e1742c2` to `7d8ebd4`. - [Commits](https://github.com/OneDrive/apidoctor/compare/e1742c28a446cdc801e83f638e4650ce685e47ca...7d8ebd44df525326e28e74bc9c6e1a6115c223c8) --- updated-dependencies: - dependency-name: apidoctor dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- apidoctor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apidoctor b/apidoctor index e1742c28a..7d8ebd44d 160000 --- a/apidoctor +++ b/apidoctor @@ -1 +1 @@ -Subproject commit e1742c28a446cdc801e83f638e4650ce685e47ca +Subproject commit 7d8ebd44df525326e28e74bc9c6e1a6115c223c8 From 6ce4aaea9a74108ac08ef8d5ec49ce3319212224 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:16:21 +0300 Subject: [PATCH 04/45] Bump MSTest.TestFramework from 3.6.3 to 3.6.4 (#2258) Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.6.3 to 3.6.4. - [Release notes](https://github.com/microsoft/testfx/releases) - [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md) - [Commits](https://github.com/microsoft/testfx/compare/v3.6.3...v3.6.4) --- updated-dependencies: - dependency-name: MSTest.TestFramework dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 8f749984d..167ea2ffc 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -13,7 +13,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From d43fba9f372c87c8e9d7f40c93f49b10b6790436 Mon Sep 17 00:00:00 2001 From: Ronald K <43806892+rkodev@users.noreply.github.com> Date: Fri, 6 Dec 2024 09:41:36 +0300 Subject: [PATCH 05/45] Fix go generation (#2260) * Fix go generation --- .../GoGeneratorTests.cs | 13 ++++++- .../LanguageGenerators/GoGenerator.cs | 35 ++++++++++--------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs index 837a1322b..50a596746 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs @@ -584,7 +584,18 @@ public async Task GeneratePathParametersInFluentPathWithPeriodsInNameAsync() Assert.Contains("toDateTime , err := time.Parse(time.RFC3339, \"{toDateTime}\")", result); Assert.Contains("microsoftGraphCallRecordsGetPstnCalls, err := graphClient.Communications().CallRecords().MicrosoftGraphCallRecordsGetPstnCallsWithFromDateTimeWithToDateTime(&fromDateTime, &toDateTime).GetAsGetPstnCallsWithFromDateTimeWithToDateTimeGetResponse(context.Background(), nil)", result); } - + + [Fact] + public async Task GeneratesConfigurationObject() + { + using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/users/{{id}}/mailFolders('inbox')/messages/delta?changeType=created&$select=subject,from,isRead,body,receivedDateTime"); + var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); + var result = _generator.GenerateCodeSnippet(snippetModel); + Assert.Contains("requestParameters := &graphusers.ItemMailFoldersItemMessagesDeltaRequestBuilderGetQueryParameters{", result); + Assert.Contains("configuration := &graphusers.ItemMailFoldersItemMessagesDeltaRequestBuilderGetRequestConfiguration{", result); + Assert.Contains("delta, err := graphClient.Users().ByUserId(\"user-id\").MailFolders().ByMailFolderId(\"mailFolder-id\").Messages().Delta().GetAsDeltaGetResponse(context.Background(), configuration)", result); + } + [Fact] public async Task GenerateFindMeetingTimeAsync() { diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GoGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GoGenerator.cs index 9beaf3f30..7b164639b 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GoGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GoGenerator.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -311,23 +310,25 @@ private static void WriteParameters(SnippetCodeGraph codeGraph, StringBuilder bu private static string GetNestedObjectName(IEnumerable nodes) { - if (!(nodes?.Any() ?? false)) return string.Empty; - // if the first element is a collection index skip it - var isCollection = nodes.First().Segment.IsCollectionIndex(); - var isSingleElement = nodes.Count() == 1; + var enumeratedNodes = nodes?.ToList() ?? new List(); + if (enumeratedNodes.Count == 0) return string.Empty; - var filteredNodes = (isCollection && !isSingleElement) ? nodes.Skip(2) : isCollection ? nodes.Skip(1) : nodes; // skip first element if its not only element - if (!(filteredNodes?.Any() ?? false)) return string.Empty; - return filteredNodes.Select(static x => - { - if (x.Segment.IsCollectionIndex()) - return "Item"; - else - return EscapeFunctionNames(x.Segment.ToFirstCharacterUpperCase()); - }) - .Aggregate(static (x, y) => + // if the first element is a collection index skip it + var isCollection = enumeratedNodes[0].Segment.IsCollectionIndex(); + var isSingleElement = enumeratedNodes.Count == 1; + var elementCount = enumeratedNodes.Count; // check if its a nested element + + var filteredNodes = enumeratedNodes; + if (isCollection && !isSingleElement) + filteredNodes = enumeratedNodes.Skip(2).ToList(); + else if (isCollection || elementCount > 2) + filteredNodes = enumeratedNodes.Skip(1).ToList(); + + if (filteredNodes.Count == 0) return string.Empty; + return filteredNodes.Select(static x => x.Segment.IsCollectionIndex() ? "Item" : EscapeFunctionNames(x.Segment.ToFirstCharacterUpperCase())) + .Aggregate((x, y) => { - var w = x.EndsWith('s') && y.Equals("Item") ? x.Remove(x.Length - 1, 1) : x; + var w = elementCount < 3 && x.EndsWith('s') && y.Equals("Item") ? x.Remove(x.Length - 1, 1) : x; w = "Me".Equals(w, StringComparison.Ordinal) ? "Item" : w; return $"{w}{y}"; }); @@ -344,7 +345,7 @@ private static string EscapeFunctionNames(String objectName) var paramMatches = ParamRegex.Matches(match.Groups[2].Value); var paramNames = paramMatches.Cast().Select(static m => m.Groups[1].Value.ToFirstCharacterUpperCase()).ToList(); - return match.Groups[1].Value + "With" + string.Join("With", paramNames); + return paramNames.Count > 0 ? match.Groups[1].Value + "With" + string.Join("With", paramNames) : match.Groups[1].Value; } return objectName; } From e7c05f5456fc8321538b2dba38982a0966faaab4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 08:55:24 +0300 Subject: [PATCH 06/45] Bump Serilog from 4.1.0 to 4.2.0 (#2261) Bumps [Serilog](https://github.com/serilog/serilog) from 4.1.0 to 4.2.0. - [Release notes](https://github.com/serilog/serilog/releases) - [Commits](https://github.com/serilog/serilog/compare/v4.1.0...v4.2.0) --- updated-dependencies: - dependency-name: Serilog dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- GraphWebApi/GraphWebApi.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index 5c01748fe..3d306400a 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -55,7 +55,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + From 567edfa83695d7af0bff309506cfb79a1b8eba3a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:24:02 +0300 Subject: [PATCH 07/45] Bump Microsoft.Extensions.Configuration.Binder, Serilog, Serilog.AspNetCore and Serilog.Sinks.Console (#2262) Bumps [Microsoft.Extensions.Configuration.Binder](https://github.com/dotnet/runtime), [Serilog](https://github.com/serilog/serilog), [Serilog.AspNetCore](https://github.com/serilog/serilog-aspnetcore) and [Serilog.Sinks.Console](https://github.com/serilog/serilog-sinks-console). These dependencies needed to be updated together. Updates `Microsoft.Extensions.Configuration.Binder` from 9.0.0 to 9.0.0 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.0) Updates `Serilog` from 4.2.0 to 4.2.0 - [Release notes](https://github.com/serilog/serilog/releases) - [Commits](https://github.com/serilog/serilog/compare/v4.2.0...v4.2.0) Updates `Serilog.AspNetCore` from 8.0.3 to 9.0.0 - [Release notes](https://github.com/serilog/serilog-aspnetcore/releases) - [Commits](https://github.com/serilog/serilog-aspnetcore/compare/v8.0.3...v9.0.0) Updates `Serilog.Sinks.Console` from 6.0.0 to 6.0.0 - [Release notes](https://github.com/serilog/serilog-sinks-console/releases) - [Commits](https://github.com/serilog/serilog-sinks-console/compare/v6.0.0...v6.0.0) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Configuration.Binder dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Serilog dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Serilog.AspNetCore dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Serilog.Sinks.Console dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- GraphWebApi/GraphWebApi.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index 3d306400a..a0fd57c47 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -56,7 +56,7 @@ all - + From fce135b4e9157bfafbc1b31ea1e0e695ba856f8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:32:28 +0300 Subject: [PATCH 08/45] Bump Microsoft.OData.Edm from 8.2.2 to 8.2.3 (#2263) Bumps Microsoft.OData.Edm from 8.2.2 to 8.2.3. --- updated-dependencies: - dependency-name: Microsoft.OData.Edm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OData.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- GraphWebApi/GraphWebApi.csproj | 2 +- OpenAPIService/OpenAPIService.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj b/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj index 739b2db13..98d8a235d 100644 --- a/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj +++ b/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 167ea2ffc..c85e1e31c 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index a0fd57c47..995795420 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -47,7 +47,7 @@ - + diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index 2ce71e458..f802ddea7 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -9,7 +9,7 @@ - + From 172b2f609340e50def5bc227c90c828ac33be10d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:00:40 +0300 Subject: [PATCH 09/45] Bump NUnit from 4.2.2 to 4.3.0 (#2266) Bumps [NUnit](https://github.com/nunit/nunit) from 4.2.2 to 4.3.0. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/4.2.2...4.3.0) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index 4b609e19f..0178888a8 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -14,7 +14,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive From 657d00ec3b4942de14f94738b9518abce8e05f86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 09:06:01 +0300 Subject: [PATCH 10/45] Bump xunit.runner.visualstudio from 2.8.2 to 3.0.0 (#2267) Bumps [xunit.runner.visualstudio](https://github.com/xunit/visualstudio.xunit) from 2.8.2 to 3.0.0. - [Release notes](https://github.com/xunit/visualstudio.xunit/releases) - [Commits](https://github.com/xunit/visualstudio.xunit/compare/2.8.2...3.0.0) --- updated-dependencies: - dependency-name: xunit.runner.visualstudio dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OpenAPI.Test.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- FileService.Test/FileService.Test.csproj | 2 +- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- OpenAPIService.Test/OpenAPIService.Test.csproj | 2 +- PermissionsService.Test/PermissionsService.Test.csproj | 2 +- SamplesService.Test/SamplesService.Test.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 2 +- UriMatchService.Test/UriMatchingService.Test.csproj | 2 +- UtilityService.Test/UtilityService.Test.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index 44308bafa..512431cf7 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -19,7 +19,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index cd3208b50..9fb3695e8 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -18,7 +18,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index c85e1e31c..87ff4e8f4 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -19,7 +19,7 @@ all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index 7ddcd778d..8b775e430 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -18,7 +18,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 5d5bedef1..4714843dd 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -30,7 +30,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index f7c39e66c..cf2dab492 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -33,7 +33,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index 521709880..a5515069d 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -39,7 +39,7 @@ all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index aa978ef44..584f77368 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -62,7 +62,7 @@ all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index 3fc4bffad..d0df39407 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -33,7 +33,7 @@ all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 77a5f7026..814c2601b 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -21,7 +21,7 @@ all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index 6b4041274..3cc38354a 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -17,7 +17,7 @@ all - + runtime; build; native; contentfiles; analyzers; buildtransitive all From a51c951afc21c86b84222990c203363e15ae2446 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 23:58:46 +0300 Subject: [PATCH 11/45] Bump NUnit from 4.3.0 to 4.3.1 (#2271) Bumps [NUnit](https://github.com/nunit/nunit) from 4.3.0 to 4.3.1. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/4.3.0...4.3.1) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index 0178888a8..74761aa95 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -14,7 +14,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive From dfb3483eebc8359083a6776861307b630f8ab079 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:35:44 +0300 Subject: [PATCH 12/45] Bump NUnit.Analyzers from 4.4.0 to 4.5.0 (#2270) Bumps [NUnit.Analyzers](https://github.com/nunit/nunit.analyzers) from 4.4.0 to 4.5.0. - [Release notes](https://github.com/nunit/nunit.analyzers/releases) - [Changelog](https://github.com/nunit/nunit.analyzers/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit.analyzers/compare/4.4.0...4.5.0) --- updated-dependencies: - dependency-name: NUnit.Analyzers dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index 74761aa95..af5642146 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -16,7 +16,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From d7ff2cff61096e35ca8dafa6facb9b21ee3272ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:36:12 +0300 Subject: [PATCH 13/45] Bump MSTest.TestFramework from 3.6.4 to 3.7.0 (#2269) Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.6.4 to 3.7.0. - [Release notes](https://github.com/microsoft/testfx/releases) - [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md) - [Commits](https://github.com/microsoft/testfx/compare/v3.6.4...v3.7.0) --- updated-dependencies: - dependency-name: MSTest.TestFramework dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 87ff4e8f4..92ef58d26 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -13,7 +13,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 00487d0788e733399cfef05538ba79e204d5b1ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:36:44 +0300 Subject: [PATCH 14/45] Bump Microsoft.OpenApi and Microsoft.OpenApi.Readers (#2268) Bumps [Microsoft.OpenApi](https://github.com/Microsoft/OpenAPI.NET) and [Microsoft.OpenApi.Readers](https://github.com/Microsoft/OpenAPI.NET). These dependencies needed to be updated together. Updates `Microsoft.OpenApi` from 1.6.22 to 1.6.23 - [Release notes](https://github.com/Microsoft/OpenAPI.NET/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET/compare/1.6.22...1.6.23) Updates `Microsoft.OpenApi.Readers` from 1.6.22 to 1.6.23 - [Release notes](https://github.com/Microsoft/OpenAPI.NET/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET/compare/1.6.22...1.6.23) --- updated-dependencies: - dependency-name: Microsoft.OpenApi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.OpenApi.Readers dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OpenAPI.csproj | 2 +- OpenAPIService/OpenAPIService.csproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj b/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj index df12d9d3f..51d79dda2 100644 --- a/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj +++ b/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index f802ddea7..5c95c20ba 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -10,9 +10,9 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all From bf3ffb58e323f3d66c185fcfac09bf41be5de86b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 09:16:10 +0300 Subject: [PATCH 15/45] Bump coverlet.collector from 6.0.2 to 6.0.3 (#2275) Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 6.0.2 to 6.0.3. - [Release notes](https://github.com/coverlet-coverage/coverlet/releases) - [Commits](https://github.com/coverlet-coverage/coverlet/compare/v6.0.2...v6.0.3) --- updated-dependencies: - dependency-name: coverlet.collector dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj | 2 +- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OpenAPI.Test.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- FileService.Test/FileService.Test.csproj | 2 +- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- OpenAPIService.Test/OpenAPIService.Test.csproj | 2 +- PermissionsService.Test/PermissionsService.Test.csproj | 2 +- SamplesService.Test/SamplesService.Test.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 2 +- UriMatchService.Test/UriMatchingService.Test.csproj | 2 +- UtilityService.Test/UtilityService.Test.csproj | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index af5642146..dd3760383 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -20,7 +20,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index 512431cf7..714928eec 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index 9fb3695e8..b284a56ec 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -22,7 +22,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 92ef58d26..6302b60f1 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -23,7 +23,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index 8b775e430..7e21713bb 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -22,7 +22,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 4714843dd..41ec7c1d3 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -34,7 +34,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index cf2dab492..d1645452d 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -17,7 +17,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index a5515069d..e228f408b 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -25,7 +25,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index 584f77368..b627754f9 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -48,7 +48,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index d0df39407..9edc9d20b 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -37,7 +37,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 814c2601b..32c3b42fa 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index 3cc38354a..d04460068 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -21,7 +21,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 772a6bcb640a951620e21afc58bc142af95be171 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 09:16:50 +0300 Subject: [PATCH 16/45] Bump coverlet.msbuild from 6.0.2 to 6.0.3 (#2274) Bumps [coverlet.msbuild](https://github.com/coverlet-coverage/coverlet) from 6.0.2 to 6.0.3. - [Release notes](https://github.com/coverlet-coverage/coverlet/releases) - [Commits](https://github.com/coverlet-coverage/coverlet/compare/v6.0.2...v6.0.3) --- updated-dependencies: - dependency-name: coverlet.msbuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OpenAPI.Test.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- FileService.Test/FileService.Test.csproj | 2 +- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- OpenAPIService.Test/OpenAPIService.Test.csproj | 2 +- PermissionsService.Test/PermissionsService.Test.csproj | 2 +- SamplesService.Test/SamplesService.Test.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 2 +- UriMatchService.Test/UriMatchingService.Test.csproj | 2 +- UtilityService.Test/UtilityService.Test.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index 714928eec..f21dabc3e 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index b284a56ec..f6b3ced29 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 6302b60f1..f5dbd36d1 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index 7e21713bb..8776018ed 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 41ec7c1d3..c1ed36e6e 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -15,7 +15,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index d1645452d..b59fb3323 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -21,7 +21,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index e228f408b..8d2b8e625 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -29,7 +29,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index b627754f9..bf11629ce 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -52,7 +52,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index 9edc9d20b..e6a52f054 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -20,7 +20,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 32c3b42fa..46413ec0e 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -11,7 +11,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index d04460068..ad88494fc 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 149e478bc3adb19375c6a4d38f4c6e3fe2061114 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 09:17:16 +0300 Subject: [PATCH 17/45] Bump NUnit from 4.3.1 to 4.3.2 (#2273) Bumps [NUnit](https://github.com/nunit/nunit) from 4.3.1 to 4.3.2. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/4.3.1...4.3.2) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index dd3760383..a86269982 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -14,7 +14,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive From d3bf1b3be3ac47c439121dafbba428166d9c9ead Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 06:17:52 +0000 Subject: [PATCH 18/45] Bump Microsoft.OData.Edm, Microsoft.OpenApi and Microsoft.OpenApi.OData (#2277) Bumps Microsoft.OData.Edm, [Microsoft.OpenApi](https://github.com/Microsoft/OpenAPI.NET) and [Microsoft.OpenApi.OData](https://github.com/Microsoft/OpenAPI.NET.OData). These dependencies needed to be updated together. Updates `Microsoft.OData.Edm` from 8.2.3 to 7.21.6 Updates `Microsoft.OpenApi` from 1.6.22 to 1.6.23 - [Release notes](https://github.com/Microsoft/OpenAPI.NET/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET/compare/1.6.22...1.6.23) Updates `Microsoft.OpenApi.OData` from 1.6.8 to 1.7.0 - [Release notes](https://github.com/Microsoft/OpenAPI.NET.OData/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET.OData/compare/v1.6.8...v.1.7.0) --- updated-dependencies: - dependency-name: Microsoft.OData.Edm dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Microsoft.OpenApi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.OpenApi.OData dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- OpenAPIService/OpenAPIService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index 5c95c20ba..c1864dcf8 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -11,7 +11,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From 2645549eb072f1d50f397157d1afe5d66db7a90f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 06:24:22 +0000 Subject: [PATCH 19/45] Bump apidoctor from `7d8ebd4` to `92c3089` (#2276) Bumps [apidoctor](https://github.com/OneDrive/apidoctor) from `7d8ebd4` to `92c3089`. - [Commits](https://github.com/OneDrive/apidoctor/compare/7d8ebd44df525326e28e74bc9c6e1a6115c223c8...92c30894b7391e97a34510e15cd573c6a9e61fbd) --- updated-dependencies: - dependency-name: apidoctor dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- apidoctor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apidoctor b/apidoctor index 7d8ebd44d..92c30894b 160000 --- a/apidoctor +++ b/apidoctor @@ -1 +1 @@ -Subproject commit 7d8ebd44df525326e28e74bc9c6e1a6115c223c8 +Subproject commit 92c30894b7391e97a34510e15cd573c6a9e61fbd From be89982a21f9c06e988544081d64798d64fbbb17 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:00:03 +0300 Subject: [PATCH 20/45] Bump xunit from 2.9.2 to 2.9.3 (#2279) Bumps [xunit](https://github.com/xunit/xunit) from 2.9.2 to 2.9.3. - [Commits](https://github.com/xunit/xunit/compare/v2-2.9.2...v2-2.9.3) --- updated-dependencies: - dependency-name: xunit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OpenAPI.Test.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- FileService.Test/FileService.Test.csproj | 2 +- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- OpenAPIService.Test/OpenAPIService.Test.csproj | 2 +- PermissionsService.Test/PermissionsService.Test.csproj | 2 +- SamplesService.Test/SamplesService.Test.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 2 +- UriMatchService.Test/UriMatchingService.Test.csproj | 2 +- UtilityService.Test/UtilityService.Test.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index f21dabc3e..aeaae9666 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -18,7 +18,7 @@ all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index f6b3ced29..b6e2fb9e2 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -17,7 +17,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index f5dbd36d1..538f32469 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -18,7 +18,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index 8776018ed..e0ec09d98 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -17,7 +17,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index c1ed36e6e..63bbcf39b 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -29,7 +29,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index b59fb3323..6a9b5c69d 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index 8d2b8e625..8d659b6f0 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -38,7 +38,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index bf11629ce..79221ec8a 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -61,7 +61,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index e6a52f054..35a49f098 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -32,7 +32,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 46413ec0e..9cde1b318 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -20,7 +20,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index ad88494fc..2621d7f48 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -16,7 +16,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 083ad0f0a6a06310e9c32f736f9bc0e6627bf158 Mon Sep 17 00:00:00 2001 From: Ronald K <43806892+rkodev@users.noreply.github.com> Date: Thu, 9 Jan 2025 15:30:44 +0300 Subject: [PATCH 21/45] fix sonnar cloud scanner (#2280) --- .github/workflows/sonarcloud.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 9ee07e96c..d597c4403 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -36,18 +36,14 @@ jobs: with: distribution: 'adopt' java-version: 17 - - name: Setup .NET 5 # At the moment the scanner requires dotnet 5 https://www.nuget.org/packages/dotnet-sonarscanner + - name: Setup .NET uses: actions/setup-dotnet@v4 - with: - dotnet-version: 5.0.x - - name: Setup .NET 6 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 6.0.x - - name: Setup .NET 7 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 7.0.x + with: # At the moment the scanner requires dotnet 5 https://www.nuget.org/packages/dotnet-sonarscanner + dotnet-version: | + 5.x + 6.x + 7.x + 8.x - uses: actions/checkout@v4 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis From e443a920095ccf0f1ff4588e2b44be9b6b979c9d Mon Sep 17 00:00:00 2001 From: Ronald K <43806892+rkodev@users.noreply.github.com> Date: Thu, 9 Jan 2025 16:15:57 +0300 Subject: [PATCH 22/45] Fix typescript snippets (#2278) * Fix typescript snippets * code cleanup --- .../TypeScriptGeneratorTest.cs | 124 ++++++--- .../LanguageGenerators/TypeScriptGenerator.cs | 261 +++++++++++++++--- 2 files changed, 302 insertions(+), 83 deletions(-) diff --git a/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs b/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs index 333be8b66..e6b93696d 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/TypeScriptGeneratorTest.cs @@ -20,8 +20,7 @@ public async Task GeneratesTheCorrectFluentAPIPathAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); - + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript const result = async () => { await graphServiceClient.me.messages.get(); @@ -44,7 +43,10 @@ public async Task GeneratesClassWithDefaultBodyWhenSchemaNotPresentAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + // Dependencies + import ""@microsoft/msgraph-sdk-identitygovernance""; + import { BatchRecordDecisionsPostRequestBody } from ""@microsoft/msgraph-sdk-identitygovernance/identityGovernance/accessReviews/definitions/item/instances/item/batchRecordDecisions""; + //other-imports const requestBody : BatchRecordDecisionsPostRequestBody = { decision : ""Approve"", @@ -52,12 +54,13 @@ public async Task GeneratesClassWithDefaultBodyWhenSchemaNotPresentAsync() resourceId : ""a5c51e59-3fcd-4a37-87a1-835c0c21488a"", }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { - await graphServiceClient.identityGovernance.accessReviews.definitionsById(""accessReviewScheduleDefinition-id"").instancesById(""accessReviewInstance-id"").batchRecordDecisions.post(requestBody); + await graphServiceClient.identityGovernance.accessReviews.definitions.byAccessReviewScheduleDefinitionId(""accessReviewScheduleDefinition-id"").instances.byAccessReviewInstanceId(""accessReviewInstance-id"").batchRecordDecisions.post(requestBody); } "; - AssertExtensions.ContainsIgnoreWhiteSpace(expected, result); } @@ -70,26 +73,28 @@ public async Task GeneratesTheCorrectFluentAPIPathForIndexedCollectionsAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + // Dependencies + import ""@microsoft/msgraph-sdk-users""; + //other-imports + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript const result = async () => { - await graphServiceClient.me.messagesById(""message-id"").get(); + await graphServiceClient.me.messages.byMessageId(""message-id"").get(); } "; - AssertExtensions.ContainsIgnoreWhiteSpace(expected, result); } [Fact] - public async Task GeneratesTheSnippetInitializationStatementAsync() + public async Task GeneratesTheSnippetInitializationDeclarationAsync() { using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages"); var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1SnippetMetadataAsync()); await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); - Assert.Contains("const graphServiceClient = GraphServiceClient.init({authProvider});", result); + Assert.Contains("// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript", result); } [Fact] @@ -100,15 +105,17 @@ public async Task GeneratesTheGetMethodCallAsync() await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + // Dependencies + import ""@microsoft/msgraph-sdk-users""; + //other-imports + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript const result = async () => { await graphServiceClient.me.messages.get(); } "; - AssertExtensions.ContainsIgnoreWhiteSpace(expected, result); } @@ -137,8 +144,14 @@ public async Task GeneratesThePatchMethodCallAsync() await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const result = async () => { - await graphServiceClient.me.messagesById(""message-id"").patch(); + // Dependencies + import ""@microsoft/msgraph-sdk-users""; + //other-imports + + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + + const result = async () => { + await graphServiceClient.me.messages.byMessageId(""message-id"").patch(); } "; @@ -164,15 +177,17 @@ public async Task GeneratesTheDeleteMethodCallAsync() await snippetModel.InitializeModelAsync(requestPayload); var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + // Dependencies + import ""@microsoft/msgraph-sdk-users""; + //other-imports + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript const result = async () => { - await graphServiceClient.me.messagesById(""message-id"").delete(); + await graphServiceClient.me.messages.byMessageId(""message-id"").delete(); } "; - AssertExtensions.ContainsIgnoreWhiteSpace(expected, result); } @@ -201,7 +216,11 @@ public async Task WritesTheRequestPayloadAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + //THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY + // Dependencies + import ""@microsoft/msgraph-sdk-users""; + import { User } from ""@microsoft/msgraph-sdk/models""; + //other-imports const requestBody : User = { accountEnabled : true, @@ -216,6 +235,8 @@ public async Task WritesTheRequestPayloadAsync() }, }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.users.post(requestBody); } @@ -259,12 +280,18 @@ public async Task WritesADoubleAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + //THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY + // Dependencies + import ""@microsoft/msgraph-sdk-users""; + import { FindMeetingTimesPostRequestBody } from ""@microsoft/msgraph-sdk-users/users/item/findMeetingTimes""; + //other-imports const requestBody : FindMeetingTimesPostRequestBody = { minimumAttendeePercentage : 10, }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.me.findMeetingTimes.post(requestBody); } @@ -286,12 +313,13 @@ public async Task GeneratesABinaryPayloadAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const requestBody = new ArrayBuffer(16); + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + async () => { - await graphServiceClient.applicationsById(""application-id"").logo.put(requestBody); + await graphServiceClient.applications.byApplicationId(""application-id"").logo.put(requestBody); } "; @@ -311,14 +339,19 @@ public async Task GeneratesABase64UrlPayloadAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + // Dependencies + import ""@microsoft/msgraph-sdk-chats""; + import { ChatMessageHostedContent} from ""@microsoft/msgraph-sdk/models""; + //other-imports const requestBody : ChatMessageHostedContent = { contentBytes : ""wiubviuwbegviwubiu"", }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { - await graphServiceClient.chatsById(""chat-id"").messagesById(""chatMessage-id"").hostedContents.post(requestBody); + await graphServiceClient.chats.byChatId(""chat-id"").messages.byChatMessageId(""chatMessage-id"").hostedContents.post(requestBody); } "; @@ -339,12 +372,13 @@ public async Task GeneratesADatePayloadAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const requestBody : Message = { receivedDateTime : new Date(""2021-08-30T20:00:00:00Z""), }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.me.messages.post(requestBody); } @@ -376,7 +410,6 @@ public async Task GeneratesAnArrayPayloadInAdditionalDataAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const requestBody : Group = { additionalData : { @@ -405,7 +438,6 @@ public async Task GeneratesAnArrayOfObjectsPayloadDataAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const requestBody : Group = { extensions : [ @@ -422,8 +454,10 @@ public async Task GeneratesAnArrayOfObjectsPayloadDataAsync() }, }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { - await graphServiceClient.groupsById(""group-id"").patch(requestBody); + await graphServiceClient.groups.byGroupId(""group-id"").patch(requestBody); } "; @@ -439,7 +473,6 @@ public async Task GeneratesSelectQueryParametersAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const configuration = { queryParameters : { @@ -447,6 +480,8 @@ public async Task GeneratesSelectQueryParametersAsync() } }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.me.get(configuration); } @@ -464,7 +499,6 @@ public async Task GeneratesCountBooleanQueryParametersAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const configuration = { queryParameters : { @@ -473,6 +507,8 @@ public async Task GeneratesCountBooleanQueryParametersAsync() } }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.users.get(configuration); } @@ -491,7 +527,6 @@ public async Task GeneratesSkipQueryParametersAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const configuration = { queryParameters : { @@ -499,6 +534,8 @@ public async Task GeneratesSkipQueryParametersAsync() } }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.users.get(configuration); } @@ -529,7 +566,6 @@ public async Task GeneratesRequestHeadersAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); const configuration = { headers : { @@ -537,6 +573,8 @@ public async Task GeneratesRequestHeadersAsync() } }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.groups.get(configuration); } @@ -574,7 +612,10 @@ public async Task GenerateAdditionalDataAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + // Dependencies + import ""@microsoft/msgraph-sdk-teams""; + import { ChatMessage, BodyTypeObject } from ""@microsoft/msgraph-sdk/models""; + //other-imports const requestBody : ChatMessage = { createdDateTime : new Date(""2019-02-04T19:58:15.511Z""), @@ -588,13 +629,15 @@ public async Task GenerateAdditionalDataAsync() }, }, body : { - contentType : BodyType.Html, + contentType : BodyTypeObject.Html, content : ""Hello World"", }, }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { - await graphServiceClient.teamsById(""team-id"").channelsById(""channel-id"").messages.post(requestBody); + await graphServiceClient.teams.byTeamId(""team-id"").channels.byChannelId(""channel-id"").messages.post(requestBody); } "; @@ -628,24 +671,29 @@ public async Task GeneratesEnumsWhenVariableIsEnumAsync() var result = _generator.GenerateCodeSnippet(snippetModel); var expected = @" - const graphServiceClient = GraphServiceClient.init({authProvider}); + import ""@microsoft/msgraph-sdk-identitygovernance""; + import { AccessReviewScheduleDefinition, RecurrencePatternTypeObject, RecurrenceRangeTypeObject } from ""@microsoft/msgraph-sdk/models""; + import { DateOnly } from ""@microsoft/kiota-abstractions""; + //other-imports const requestBody : AccessReviewScheduleDefinition = { displayName : ""Test create"", settings : { recurrence : { pattern : { - type : RecurrencePatternType.Weekly, + type : RecurrencePatternTypeObject.Weekly, interval : 1, }, range : { - type : RecurrenceRangeType.NoEnd, - startDate : ""2020-09-08T12:02:30.667Z"", + type : RecurrenceRangeTypeObject.NoEnd, + startDate : DateOnly.parse(""2020-09-08T12:02:30.667Z""), }, }, }, }; + // To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript + const result = async () => { await graphServiceClient.identityGovernance.accessReviews.definitions.post(requestBody); } diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/TypeScriptGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/TypeScriptGenerator.cs index 2c19646dd..bd662293c 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/TypeScriptGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/TypeScriptGenerator.cs @@ -1,13 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Net.Http; using System.Text; -using System.Text.Json; using System.Text.RegularExpressions; using CodeSnippetsReflection.OpenAPI.ModelGraph; using CodeSnippetsReflection.StringExtensions; -using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Services; namespace CodeSnippetsReflection.OpenAPI.LanguageGenerators @@ -20,40 +17,183 @@ public class TypeScriptGenerator : ILanguageGeneratorModel of the Snippets info /// String of the snippet in TypeScript code /// - private const string ClientVarName = "graphServiceClient"; - private const string ClientVarType = "GraphServiceClient"; + private const string RequestHeadersVarName = "headers"; private const string RequestOptionsVarName = "options"; private const string RequestConfigurationVarName = "configuration"; private const string RequestParametersVarName = "queryParameters"; private const string RequestBodyVarName = "requestBody"; + private static readonly Regex FunctionRegex = + new Regex(@"(\w+)\(([^)]*)\)", RegexOptions.Compiled, TimeSpan.FromMilliseconds(200)); + + private static readonly Regex ParamRegex = + new Regex(@"(\w+)\s*=\s*'[^']*'", RegexOptions.Compiled, TimeSpan.FromMilliseconds(200)); + public string GenerateCodeSnippet(SnippetModel snippetModel) { if (snippetModel == null) throw new ArgumentNullException("Argument snippetModel cannot be null"); var codeGraph = new SnippetCodeGraph(snippetModel); var snippetBuilder = new StringBuilder( - "//THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY" + Environment.NewLine + - $"const {ClientVarName} = {ClientVarType}.init({{authProvider}});{Environment.NewLine}{Environment.NewLine}"); + "//THIS SNIPPET IS A PREVIEW FOR THE KIOTA BASED SDK. NON-PRODUCTION USE ONLY" + Environment.NewLine); - writeSnippet(codeGraph, snippetBuilder); + WriteImportStatements(codeGraph, snippetBuilder); + WriteSnippet(codeGraph, snippetBuilder); return snippetBuilder.ToString(); } - private static void writeSnippet(SnippetCodeGraph codeGraph, StringBuilder builder) + private static void WriteImportStatements(SnippetCodeGraph codeGraph, StringBuilder builder) + { + builder.AppendLine("// Dependencies"); + var apiVersion = "v1.0".Equals(codeGraph.ApiVersion, StringComparison.Ordinal) ? "msgraph-sdk" : "msgraph-beta-sdk"; + + var initialPackage = codeGraph.Nodes.First().Segment.ToLowerInvariant(); + if (initialPackage.Equals("me", StringComparison.OrdinalIgnoreCase)) + { + initialPackage = "users"; + } + + builder.AppendLine($"import \"@microsoft/{apiVersion}-{initialPackage}\";"); // api version + + // add models + var models = GetImportNamespaces(apiVersion, codeGraph); + foreach (var path in models) + { + var pathModels = path.Value.Select(static x => x.ToFirstCharacterUpperCase()) + .Where(static s => !string.IsNullOrEmpty(s)).Aggregate(static (a, b) => $"{a}, {b}"); + builder.AppendLine($"import {{ {pathModels} }} from \"{path.Key}\";"); + } + + builder.AppendLine("//other-imports"); // models version + builder.AppendLine(""); + } + + private static string GetCleanNamespaceName(string namespaceName) + { + var nameSpaceName = ProcessNameSpaceName(namespaceName); + var pathSegments = nameSpaceName.Split("."); + return pathSegments.FirstOrDefault()?.Equals("models") == true + ? nameSpaceName + : pathSegments.FirstOrDefault(); + } + + private static void AddNamespace(Dictionary> result, string nameSpace, + string valueToAdd) + { + if (result.TryGetValue(nameSpace, out var value)) + { + value.Add(valueToAdd); + } + else + { + result.Add(nameSpace, [valueToAdd]); + } + } + + private static Dictionary> GetImportNamespaces(String apiVersion, + SnippetCodeGraph codeGraph) + { + Dictionary> result = + new Dictionary>(StringComparer.OrdinalIgnoreCase); + if (codeGraph.HasBody()) + { + var modelsNameSpace = $"@microsoft/{apiVersion}/models"; + TraverseProperty(codeGraph.Body, x => + { + switch (x.PropertyType) + { + case PropertyType.DateOnly when !string.IsNullOrEmpty(x.Value): + AddNamespace(result, "@microsoft/kiota-abstractions", "DateOnly"); + break; + case PropertyType.TimeOnly when !string.IsNullOrEmpty(x.Value): + AddNamespace(result, "@microsoft/kiota-abstractions", "TimeOnly"); + break; + case PropertyType.Enum when !string.IsNullOrEmpty(x.Value) && + !string.IsNullOrWhiteSpace(x.NamespaceName): + var enumNameSpace = GetCleanNamespaceName(x.NamespaceName); + var enumType = x.Value.Split(".").First().ToFirstCharacterUpperCase() + "Object"; + AddNamespace(result, $"@microsoft/{apiVersion}/{enumNameSpace.ToLowerInvariant()}", + enumType); + break; + case PropertyType.Object when !string.IsNullOrWhiteSpace(x.NamespaceName) && + !result.ContainsKey(modelsNameSpace): + var formatNameSpace = x.NamespaceName.Split(".").Select(static x => + { + var result = x.ToFirstCharacterLowerCase(); + return result.Equals("me", StringComparison.OrdinalIgnoreCase) ? "users/item" : result; + }).Aggregate(static (x, y) => $"{x}/{y}"); + var objectCleanNameSpace = GetCleanNamespaceName(x.NamespaceName); + + var objectNameSpace = objectCleanNameSpace.ToFirstCharacterLowerCase().Equals("models", StringComparison.OrdinalIgnoreCase) + ? $"@microsoft/{apiVersion}/{objectCleanNameSpace.ToLowerInvariant()}" + : $"@microsoft/{apiVersion}-{objectCleanNameSpace.ToLowerInvariant()}"; + + var lastNameSpace = objectCleanNameSpace.ToFirstCharacterLowerCase().Equals("models", StringComparison.OrdinalIgnoreCase) + ? objectNameSpace + : $"{objectNameSpace}/{formatNameSpace.ToFirstCharacterLowerCase()}"; + AddNamespace(result, lastNameSpace, x.Name); + break; + } + }); + } + + return result; + } + + private static void TraverseProperty(CodeProperty property, Action act) + { + act(property); + if (property.Children != null) + { + foreach (var prop in property.Children) + { + TraverseProperty(prop, act); + } + } + } + + private static String ProcessNameSpaceName(String nameSpace) + { + if (String.IsNullOrEmpty(nameSpace)) + return ""; + + // process function names and parameters + var functionNameMatch = FunctionRegex.Match(nameSpace); + if (functionNameMatch.Success) + { + var paramMatches = ParamRegex.Matches(functionNameMatch.Groups[2].Value); + var paramNames = paramMatches.Cast().Select(static m => m.Groups[1].Value).ToList(); + + return functionNameMatch.Groups[1].Value + "With" + string.Join("With", paramNames); + } + + var processedName = (nameSpace.Split(".", StringSplitOptions.RemoveEmptyEntries) + .Select(x => x.Equals("Me", StringComparison.OrdinalIgnoreCase) ? "Users" : x) + .Aggregate(static (current, next) => current + "." + next)).Replace(".microsoft.graph", ""); + + return processedName; + } + + private static void WriteSnippet(SnippetCodeGraph codeGraph, StringBuilder builder) { writeHeadersAndOptions(codeGraph, builder); WriteBody(codeGraph, builder); builder.AppendLine(""); + builder.AppendLine( + "// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=typescript"); + builder.AppendLine(""); + WriteExecutionStatement( codeGraph, builder, codeGraph.HasBody() ? RequestBodyVarName : default, - codeGraph.HasHeaders() || codeGraph.HasOptions() || codeGraph.HasParameters() ? RequestConfigurationVarName : default + codeGraph.HasHeaders() || codeGraph.HasOptions() || codeGraph.HasParameters() + ? RequestConfigurationVarName + : default ); } @@ -82,6 +222,7 @@ private static void WriteHeader(SnippetCodeGraph codeGraph, StringBuilder builde indentManager.Unindent(); builder.AppendLine($"{indentManager.GetIndent()}}}"); } + private static void WriteOptions(SnippetCodeGraph codeGraph, StringBuilder builder, IndentManager indentManager) { if (!codeGraph.HasOptions()) return; @@ -97,7 +238,8 @@ private static void WriteOptions(SnippetCodeGraph codeGraph, StringBuilder build builder.AppendLine($"{indentManager.GetIndent()}}}"); } - private static void WriteParameters(SnippetCodeGraph codeGraph, StringBuilder builder, IndentManager indentManager) + private static void WriteParameters(SnippetCodeGraph codeGraph, StringBuilder builder, + IndentManager indentManager) { if (!codeGraph.HasParameters()) return; @@ -107,21 +249,24 @@ private static void WriteParameters(SnippetCodeGraph codeGraph, StringBuilder bu builder.AppendLine($"{indentManager.GetIndent()}{RequestParametersVarName} : {{"); indentManager.Indent(); foreach (var param in codeGraph.Parameters) - builder.AppendLine($"{indentManager.GetIndent()}{NormalizeJsonName(param.Name)}: {evaluateParameter(param)},"); + builder.AppendLine( + $"{indentManager.GetIndent()}{NormalizeJsonName(param.Name)}: {evaluateParameter(param)},"); indentManager.Unindent(); builder.AppendLine($"{indentManager.GetIndent()}}}"); } - private static string evaluateParameter(CodeProperty param){ - if(param.PropertyType == PropertyType.Array) - return $"[{string.Join(",", param.Children.Select(static x => $"\"{x.Value}\"" ).ToList())}]"; + private static string evaluateParameter(CodeProperty param) + { + if (param.PropertyType == PropertyType.Array) + return $"[{string.Join(",", param.Children.Select(static x => $"\"{x.Value}\"").ToList())}]"; else if (param.PropertyType == PropertyType.Boolean || param.PropertyType == PropertyType.Int32) return param.Value; else return $"\"{param.Value.EscapeQuotes()}\""; } - private static void WriteExecutionStatement(SnippetCodeGraph codeGraph, StringBuilder builder, params string[] parameters) + private static void WriteExecutionStatement(SnippetCodeGraph codeGraph, StringBuilder builder, + params string[] parameters) { var methodName = codeGraph.HttpMethod.ToString().ToLower(); var responseAssignment = codeGraph.ResponseSchema == null ? string.Empty : "const result = "; @@ -131,7 +276,8 @@ private static void WriteExecutionStatement(SnippetCodeGraph codeGraph, StringBu var indentManager = new IndentManager(); builder.AppendLine($"{responseAssignment}async () => {{"); indentManager.Indent(); - builder.AppendLine($"{indentManager.GetIndent()}await {ClientVarName}.{GetFluentApiPath(codeGraph.Nodes)}.{methodName}({parametersList});"); + builder.AppendLine( + $"{indentManager.GetIndent()}await {ClientVarName}.{GetFluentApiPath(codeGraph.Nodes)}.{methodName}({parametersList});"); indentManager.Unindent(); builder.AppendLine($"}}"); } @@ -144,11 +290,13 @@ private static void WriteBody(SnippetCodeGraph codeGraph, StringBuilder builder) if (codeGraph.Body.PropertyType == PropertyType.Binary) { - builder.AppendLine($"{indentManager.GetIndent()}const {RequestBodyVarName} = new ArrayBuffer({codeGraph.Body.Value.Length});"); + builder.AppendLine( + $"{indentManager.GetIndent()}const {RequestBodyVarName} = new ArrayBuffer({codeGraph.Body.Value.Length});"); } else { - builder.AppendLine($"{indentManager.GetIndent()}const {RequestBodyVarName} : {codeGraph.Body.Name} = {{"); + builder.AppendLine( + $"{indentManager.GetIndent()}const {RequestBodyVarName} : {codeGraph.Body.Name} = {{"); indentManager.Indent(); WriteCodePropertyObject(builder, codeGraph.Body, indentManager); indentManager.Unindent(); @@ -158,10 +306,14 @@ private static void WriteBody(SnippetCodeGraph codeGraph, StringBuilder builder) private static string NormalizeJsonName(string Name) { - return (!String.IsNullOrWhiteSpace(Name) && Name.Substring(1) != "\"") && (Name.Contains('.') || Name.Contains('-')) ? $"\"{Name}\"" : Name; + return (!String.IsNullOrWhiteSpace(Name) && Name.Substring(1) != "\"") && + (Name.Contains('.') || Name.Contains('-')) + ? $"\"{Name}\"" + : Name; } - - private static void WriteCodePropertyObject(StringBuilder builder, CodeProperty codeProperty, IndentManager indentManager) + + private static void WriteCodePropertyObject(StringBuilder builder, CodeProperty codeProperty, + IndentManager indentManager) { var isArray = codeProperty.PropertyType == PropertyType.Array; foreach (var child in codeProperty.Children) @@ -173,7 +325,8 @@ private static void WriteCodePropertyObject(StringBuilder builder, CodeProperty if (isArray) builder.AppendLine($"{indentManager.GetIndent()}{{"); else - builder.AppendLine($"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : {{"); + builder.AppendLine( + $"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : {{"); indentManager.Indent(); WriteCodePropertyObject(builder, child, indentManager); @@ -190,28 +343,41 @@ private static void WriteCodePropertyObject(StringBuilder builder, CodeProperty builder.AppendLine($"{indentManager.GetIndent()}],"); break; - case PropertyType.DateOnly: case PropertyType.Guid: case PropertyType.String: - var propName = codeProperty.PropertyType == PropertyType.Map ? $"\"{child.Name.ToFirstCharacterLowerCase()}\"" : NormalizeJsonName(child.Name.ToFirstCharacterLowerCase()); + var propName = codeProperty.PropertyType == PropertyType.Map + ? $"\"{child.Name.ToFirstCharacterLowerCase()}\"" + : NormalizeJsonName(child.Name.ToFirstCharacterLowerCase()); if (isArray || String.IsNullOrWhiteSpace(propName)) builder.AppendLine($"{indentManager.GetIndent()}\"{child.Value}\","); else builder.AppendLine($"{indentManager.GetIndent()}{propName} : \"{child.Value}\","); break; case PropertyType.Enum: - if (!String.IsNullOrWhiteSpace(child.Value)) { - builder.AppendLine($"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : {child.Value},"); + if (!String.IsNullOrWhiteSpace(child.Value)) + { + var enumParts = child.Value.Split('.'); + var enumValue = $"{enumParts[0].ToFirstCharacterUpperCase()}Object.{enumParts.Last()}"; + builder.AppendLine( + $"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : {enumValue},"); } + break; case PropertyType.DateTime: - builder.AppendLine($"{indentManager.GetIndent()}{NormalizeJsonName(child.Name)} : new Date(\"{child.Value}\"),"); + builder.AppendLine( + $"{indentManager.GetIndent()}{NormalizeJsonName(child.Name)} : new Date(\"{child.Value}\"),"); + break; + case PropertyType.DateOnly: + builder.AppendLine( + $"{indentManager.GetIndent()}{NormalizeJsonName(child.Name)} : DateOnly.parse(\"{child.Value}\"),"); break; case PropertyType.Base64Url: - builder.AppendLine($"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : \"{child.Value.ToFirstCharacterLowerCase()}\","); + builder.AppendLine( + $"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : \"{child.Value.ToFirstCharacterLowerCase()}\","); break; default: - builder.AppendLine($"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : {child.Value.ToFirstCharacterLowerCase()},"); + builder.AppendLine( + $"{indentManager.GetIndent()}{NormalizeJsonName(child.Name.ToFirstCharacterLowerCase())} : {child.Value.ToFirstCharacterLowerCase()},"); break; } } @@ -222,27 +388,32 @@ private static string GetActionParametersList(params string[] parameters) var nonEmptyParameters = parameters.Where(static p => !string.IsNullOrEmpty(p)); if (nonEmptyParameters.Any()) return string.Join(", ", nonEmptyParameters.Aggregate(static (a, b) => $"{a}, {b}")); - else return string.Empty; + return string.Empty; } private static string GetFluentApiPath(IEnumerable nodes) { - if (!(nodes?.Any() ?? false)) return string.Empty; - return nodes.Select(static x => { - if (x.Segment.IsCollectionIndex()) - return $"ById{x.Segment.Replace("{", "(\"").Replace("}", "\")")}"; - else if (x.Segment.IsFunction()) - return x.Segment.Split('.') + List enumeratedNodes = nodes.ToList(); + if (!(enumeratedNodes?.Any() ?? false)) return string.Empty; + + return enumeratedNodes.Select((part, index) => + { + if (part.Segment.IsCollectionIndex()) + { + var node = part.Segment.Replace("{", "").Replace("}", ""); + var nodeName = + $"by{node.Split("-").Select(static x => x.ToFirstCharacterUpperCase()).Aggregate(static (x, y) => $"{x}{y}")}"; + return $"{nodeName}(\"{node}\")"; + } + + if (part.Segment.IsFunction()) + return part.Segment.Split('.') .Select(static s => s.ToFirstCharacterUpperCase()) .Aggregate(static (a, b) => $"{a}{b}").ToFirstCharacterLowerCase(); - return x.Segment.ToFirstCharacterLowerCase(); - }) - .Aggregate(static (x, y) => { - var dot = y.StartsWith("ById") ? - string.Empty : - "."; - return $"{x}{dot}{y}"; - }); + return part.Segment.ToFirstCharacterLowerCase(); + }) + .Where(static s => !string.IsNullOrEmpty(s)) // Remove any empty entries + .Aggregate(static (x, y) => $"{x}.{y}"); } } } From 12c04f496eae33395e521f276ca8d43da9f0c18a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jan 2025 09:11:30 +0300 Subject: [PATCH 23/45] Bump NUnit.Analyzers from 4.5.0 to 4.6.0 (#2281) Bumps [NUnit.Analyzers](https://github.com/nunit/nunit.analyzers) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/nunit/nunit.analyzers/releases) - [Changelog](https://github.com/nunit/nunit.analyzers/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit.analyzers/compare/4.5.0...4.6.0) --- updated-dependencies: - dependency-name: NUnit.Analyzers dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index a86269982..8e05f7c45 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -16,7 +16,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 715e74332884aeeefb2329ab4293189402133b33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 09:13:41 +0300 Subject: [PATCH 24/45] Bump xunit.runner.visualstudio from 3.0.0 to 3.0.1 (#2282) Bumps [xunit.runner.visualstudio](https://github.com/xunit/visualstudio.xunit) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/xunit/visualstudio.xunit/releases) - [Commits](https://github.com/xunit/visualstudio.xunit/compare/3.0.0...3.0.1) --- updated-dependencies: - dependency-name: xunit.runner.visualstudio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OpenAPI.Test.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- FileService.Test/FileService.Test.csproj | 2 +- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- OpenAPIService.Test/OpenAPIService.Test.csproj | 2 +- PermissionsService.Test/PermissionsService.Test.csproj | 2 +- SamplesService.Test/SamplesService.Test.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 2 +- UriMatchService.Test/UriMatchingService.Test.csproj | 2 +- UtilityService.Test/UtilityService.Test.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index aeaae9666..47eeeede9 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -19,7 +19,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index b6e2fb9e2..bec0fad19 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -18,7 +18,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 538f32469..c0109f83d 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -19,7 +19,7 @@ all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index e0ec09d98..090a680de 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -18,7 +18,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 63bbcf39b..99153d81f 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -30,7 +30,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index 6a9b5c69d..9da02ca6b 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -33,7 +33,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index 8d659b6f0..f3279948d 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -39,7 +39,7 @@ all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index 79221ec8a..710dc0751 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -62,7 +62,7 @@ all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index 35a49f098..c951d29d1 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -33,7 +33,7 @@ all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 9cde1b318..71461690b 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -21,7 +21,7 @@ all - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index 2621d7f48..2da7fa303 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -17,7 +17,7 @@ all - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 4db0998d97a7fdb46ff55f7dd7e9349449c1e188 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 08:48:39 +0300 Subject: [PATCH 25/45] Bump MSTest.TestFramework from 3.7.0 to 3.7.1 (#2283) Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.7.0 to 3.7.1. - [Release notes](https://github.com/microsoft/testfx/releases) - [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md) - [Commits](https://github.com/microsoft/testfx/compare/v3.7.0...v3.7.1) --- updated-dependencies: - dependency-name: MSTest.TestFramework dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index c0109f83d..5ff38203b 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -13,7 +13,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From d10f8cb6d9ea9d5d61bb85dc398b3e0ca4c25e35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 09:22:22 +0300 Subject: [PATCH 26/45] Bump Microsoft.AspNetCore.Authentication.JwtBearer from 8.0.11 to 8.0.12 (#2291) Bumps [Microsoft.AspNetCore.Authentication.JwtBearer](https://github.com/dotnet/aspnetcore) from 8.0.11 to 8.0.12. - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](https://github.com/dotnet/aspnetcore/compare/v8.0.11...v8.0.12) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Authentication.JwtBearer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- GraphWebApi/GraphWebApi.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index 995795420..734f8c5d7 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -44,7 +44,7 @@ - + From 6a897d7e6158207c5697af483bcdd0f5f34c1f41 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 09:22:53 +0300 Subject: [PATCH 27/45] Bump Microsoft.Extensions.Caching.Abstractions from 9.0.0 to 9.0.1 (#2290) Bumps [Microsoft.Extensions.Caching.Abstractions](https://github.com/dotnet/runtime) from 9.0.0 to 9.0.1. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Caching.Abstractions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- MockTestUtility/MockTestUtility.csproj | 2 +- PermissionsService/PermissionsService.csproj | 2 +- SamplesService/SamplesService.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MockTestUtility/MockTestUtility.csproj b/MockTestUtility/MockTestUtility.csproj index f0e9a44f0..5c1e7e4c9 100644 --- a/MockTestUtility/MockTestUtility.csproj +++ b/MockTestUtility/MockTestUtility.csproj @@ -6,7 +6,7 @@ - + diff --git a/PermissionsService/PermissionsService.csproj b/PermissionsService/PermissionsService.csproj index 8dcfd85cb..fa9532197 100644 --- a/PermissionsService/PermissionsService.csproj +++ b/PermissionsService/PermissionsService.csproj @@ -6,7 +6,7 @@ - + diff --git a/SamplesService/SamplesService.csproj b/SamplesService/SamplesService.csproj index 2f4254a31..914e5041b 100644 --- a/SamplesService/SamplesService.csproj +++ b/SamplesService/SamplesService.csproj @@ -9,7 +9,7 @@ - + From feba819bb974370754653cb33fab1ea2dd0a008c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 09:24:44 +0300 Subject: [PATCH 28/45] Bump Microsoft.Extensions.Configuration.CommandLine from 9.0.0 to 9.0.1 (#2287) Bumps [Microsoft.Extensions.Configuration.CommandLine](https://github.com/dotnet/runtime) from 9.0.0 to 9.0.1. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Configuration.CommandLine dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj b/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj index 70bb3e625..aa5e1ce6d 100644 --- a/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj +++ b/CodeSnippetsReflection.App/CodeSnippetsReflection.App.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 0e27ccd2097c0666454667e0332100c2d819703b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 09:25:15 +0300 Subject: [PATCH 29/45] Bump Microsoft.Extensions.Configuration, Microsoft.Extensions.Configuration.Json and System.Text.Json (#2288) Bumps [Microsoft.Extensions.Configuration](https://github.com/dotnet/runtime), [Microsoft.Extensions.Configuration.Json](https://github.com/dotnet/runtime) and [System.Text.Json](https://github.com/dotnet/runtime). These dependencies needed to be updated together. Updates `Microsoft.Extensions.Configuration` from 9.0.0 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) Updates `Microsoft.Extensions.Configuration.Json` from 9.0.0 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) Updates `System.Text.Json` from 9.0.0 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Configuration dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.Extensions.Configuration.Json dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: System.Text.Json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 6 +++--- MockTestUtility/MockTestUtility.csproj | 4 ++-- OpenAPIService.Test/OpenAPIService.Test.csproj | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 99153d81f..4702e36cc 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -19,8 +19,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -28,7 +28,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MockTestUtility/MockTestUtility.csproj b/MockTestUtility/MockTestUtility.csproj index 5c1e7e4c9..8d4583c33 100644 --- a/MockTestUtility/MockTestUtility.csproj +++ b/MockTestUtility/MockTestUtility.csproj @@ -8,14 +8,14 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index 9da02ca6b..aa32d18ce 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -25,12 +25,12 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + From 81ac117fe7a33ff65f15d1778bf943ed62fc89a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 09:41:12 +0300 Subject: [PATCH 30/45] Bump Microsoft.Extensions.Configuration.Abstractions from 9.0.0 to 9.0.1 (#2293) Bumps [Microsoft.Extensions.Configuration.Abstractions](https://github.com/dotnet/runtime) from 9.0.0 to 9.0.1. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Configuration.Abstractions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- KnownIssuesService/KnownIssuesService.csproj | 2 +- OpenAPIService/OpenAPIService.csproj | 2 +- SamplesService/SamplesService.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/KnownIssuesService/KnownIssuesService.csproj b/KnownIssuesService/KnownIssuesService.csproj index 9531d8f3f..aee5f64cf 100644 --- a/KnownIssuesService/KnownIssuesService.csproj +++ b/KnownIssuesService/KnownIssuesService.csproj @@ -5,7 +5,7 @@ - + diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index c1864dcf8..079f21024 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -6,7 +6,7 @@ - + diff --git a/SamplesService/SamplesService.csproj b/SamplesService/SamplesService.csproj index 914e5041b..15e8d2699 100644 --- a/SamplesService/SamplesService.csproj +++ b/SamplesService/SamplesService.csproj @@ -10,7 +10,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From b0b90ef322ca4a35bfb5f751b50bcea34a009d7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:09:45 +0300 Subject: [PATCH 31/45] Bump Microsoft.AspNetCore.Authorization from 9.0.0 to 9.0.1 (#2286) Bumps [Microsoft.AspNetCore.Authorization](https://github.com/dotnet/aspnetcore) from 9.0.0 to 9.0.1. - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](https://github.com/dotnet/aspnetcore/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Authorization dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- GraphWebApi/GraphWebApi.csproj | 2 +- SamplesService/SamplesService.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index 734f8c5d7..76eda7408 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -45,7 +45,7 @@ - + diff --git a/SamplesService/SamplesService.csproj b/SamplesService/SamplesService.csproj index 15e8d2699..41bab8c88 100644 --- a/SamplesService/SamplesService.csproj +++ b/SamplesService/SamplesService.csproj @@ -7,7 +7,7 @@ - + From b91c0cfe915ddd100e130e1a2ed6276f560597c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:10:12 +0300 Subject: [PATCH 32/45] Bump Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.DependencyInjection.Abstractions (#2285) Bumps [Microsoft.Extensions.DependencyInjection](https://github.com/dotnet/runtime) and [Microsoft.Extensions.DependencyInjection.Abstractions](https://github.com/dotnet/runtime). These dependencies needed to be updated together. Updates `Microsoft.Extensions.DependencyInjection` from 9.0.0 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) Updates `Microsoft.Extensions.DependencyInjection.Abstractions` from 9.0.0 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.DependencyInjection dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.Extensions.DependencyInjection.Abstractions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- SamplesService/SamplesService.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 4 ++-- TelemetryService/TelemetrySanitizerService.csproj | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SamplesService/SamplesService.csproj b/SamplesService/SamplesService.csproj index 41bab8c88..edf9a5498 100644 --- a/SamplesService/SamplesService.csproj +++ b/SamplesService/SamplesService.csproj @@ -11,7 +11,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index c951d29d1..57876eae3 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -25,8 +25,8 @@ all - - + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelemetryService/TelemetrySanitizerService.csproj b/TelemetryService/TelemetrySanitizerService.csproj index 1feaa564a..0187de4ba 100644 --- a/TelemetryService/TelemetrySanitizerService.csproj +++ b/TelemetryService/TelemetrySanitizerService.csproj @@ -6,8 +6,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all From e23680784b89ed01eb80e58ea866ff8a0c71c597 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 10:59:01 +0300 Subject: [PATCH 33/45] Bump Microsoft.Extensions.Configuration from 9.0.0 to 9.0.1 (#2292) Bumps [Microsoft.Extensions.Configuration](https://github.com/dotnet/runtime) from 9.0.0 to 9.0.1. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Configuration dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- FileService/FileService.csproj | 2 +- GraphWebApi/GraphWebApi.csproj | 2 +- PermissionsService/PermissionsService.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FileService/FileService.csproj b/FileService/FileService.csproj index 784ce29f7..f6f528d9a 100644 --- a/FileService/FileService.csproj +++ b/FileService/FileService.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/GraphWebApi/GraphWebApi.csproj b/GraphWebApi/GraphWebApi.csproj index 76eda7408..6485ed429 100644 --- a/GraphWebApi/GraphWebApi.csproj +++ b/GraphWebApi/GraphWebApi.csproj @@ -46,7 +46,7 @@ - + diff --git a/PermissionsService/PermissionsService.csproj b/PermissionsService/PermissionsService.csproj index fa9532197..8f866bd3e 100644 --- a/PermissionsService/PermissionsService.csproj +++ b/PermissionsService/PermissionsService.csproj @@ -7,7 +7,7 @@ - + From 893dcef850961851f96021131dea55b97af08631 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:53:22 +0300 Subject: [PATCH 34/45] Bump Microsoft.AspNetCore.Authorization, Microsoft.AspNetCore.Mvc.DataAnnotations, Microsoft.Extensions.Configuration.Abstractions and Microsoft.Extensions.DependencyInjection (#2298) Bumps [Microsoft.AspNetCore.Authorization](https://github.com/dotnet/aspnetcore), [Microsoft.AspNetCore.Mvc.DataAnnotations](https://github.com/dotnet/aspnetcore), [Microsoft.Extensions.Configuration.Abstractions](https://github.com/dotnet/runtime) and [Microsoft.Extensions.DependencyInjection](https://github.com/dotnet/runtime). These dependencies needed to be updated together. Updates `Microsoft.AspNetCore.Authorization` from 9.0.1 to 2.3.0 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](https://github.com/dotnet/aspnetcore/commits) Updates `Microsoft.AspNetCore.Mvc.DataAnnotations` from 2.2.0 to 2.3.0 - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](https://github.com/dotnet/aspnetcore/commits) Updates `Microsoft.Extensions.Configuration.Abstractions` from 9.0.1 to 8.0.0 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.1...v8.0.0) Updates `Microsoft.Extensions.DependencyInjection` from 9.0.1 to 8.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.1...v8.0.1) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Authorization dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Microsoft.AspNetCore.Mvc.DataAnnotations dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: Microsoft.Extensions.Configuration.Abstractions dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Microsoft.Extensions.DependencyInjection dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- SamplesService/SamplesService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SamplesService/SamplesService.csproj b/SamplesService/SamplesService.csproj index edf9a5498..5f66d487d 100644 --- a/SamplesService/SamplesService.csproj +++ b/SamplesService/SamplesService.csproj @@ -8,7 +8,7 @@ - + From 7cce44c43bc345d971c08a37f9f7e490f69d8c5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:54:02 +0300 Subject: [PATCH 35/45] Bump Microsoft.OData.Edm, Microsoft.OpenApi and Microsoft.OpenApi.OData (#2297) Bumps Microsoft.OData.Edm, [Microsoft.OpenApi](https://github.com/Microsoft/OpenAPI.NET) and [Microsoft.OpenApi.OData](https://github.com/Microsoft/OpenAPI.NET.OData). These dependencies needed to be updated together. Updates `Microsoft.OData.Edm` from 8.2.3 to 7.21.6 Updates `Microsoft.OpenApi` from 1.6.22 to 1.6.23 - [Release notes](https://github.com/Microsoft/OpenAPI.NET/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET/compare/1.6.22...1.6.23) Updates `Microsoft.OpenApi.OData` from 1.7.0 to 1.7.1 - [Release notes](https://github.com/Microsoft/OpenAPI.NET.OData/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET.OData/compare/v.1.7.0...v.1.7.1) --- updated-dependencies: - dependency-name: Microsoft.OData.Edm dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Microsoft.OpenApi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.OpenApi.OData dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- OpenAPIService/OpenAPIService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index 079f21024..a17f7ab95 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -11,7 +11,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From be9ac3de1c9c257b46300d0cfed86557fc7c034d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:54:33 +0300 Subject: [PATCH 36/45] Bump System.Text.Json from 9.0.0 to 9.0.1 (#2296) Bumps [System.Text.Json](https://github.com/dotnet/runtime) from 9.0.0 to 9.0.1. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: System.Text.Json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OpenAPI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj b/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj index 51d79dda2..71249bd22 100644 --- a/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj +++ b/CodeSnippetsReflection.OpenAPI/CodeSnippetsReflection.OpenAPI.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + From 9bec950ee3113ff9a32984050d90615951413dec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:55:07 +0300 Subject: [PATCH 37/45] Bump Azure.Identity from 1.13.1 to 1.13.2 (#2295) Bumps [Azure.Identity](https://github.com/Azure/azure-sdk-for-net) from 1.13.1 to 1.13.2. - [Release notes](https://github.com/Azure/azure-sdk-for-net/releases) - [Commits](https://github.com/Azure/azure-sdk-for-net/compare/Azure.Identity_1.13.1...Azure.Identity_1.13.2) --- updated-dependencies: - dependency-name: Azure.Identity dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- FileService/FileService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FileService/FileService.csproj b/FileService/FileService.csproj index f6f528d9a..da408ffd2 100644 --- a/FileService/FileService.csproj +++ b/FileService/FileService.csproj @@ -5,7 +5,7 @@ - + From 3fe0c9693ccff17a27c407f07a723b98604ee9e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:55:39 +0300 Subject: [PATCH 38/45] Bump Microsoft.Extensions.DependencyInjection.Abstractions (#2294) Bumps [Microsoft.Extensions.DependencyInjection.Abstractions](https://github.com/dotnet/runtime) from 9.0.0 to 9.0.1. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.DependencyInjection.Abstractions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OData.csproj | 2 +- MockTestUtility/MockTestUtility.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index 47eeeede9..d2fe81daf 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -12,7 +12,7 @@ all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj b/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj index 98d8a235d..d56538b7c 100644 --- a/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj +++ b/CodeSnippetsReflection.OData/CodeSnippetsReflection.OData.csproj @@ -6,7 +6,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/MockTestUtility/MockTestUtility.csproj b/MockTestUtility/MockTestUtility.csproj index 8d4583c33..ce540d23c 100644 --- a/MockTestUtility/MockTestUtility.csproj +++ b/MockTestUtility/MockTestUtility.csproj @@ -9,7 +9,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From d1163765410ecf1e9e72fa3f98a0d66b0b874bf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 09:24:47 +0300 Subject: [PATCH 39/45] Bump Microsoft.Extensions.Configuration, Microsoft.Extensions.Configuration.Json, Microsoft.Extensions.Configuration.UserSecrets and System.Text.Json (#2299) Bumps [Microsoft.Extensions.Configuration](https://github.com/dotnet/runtime), [Microsoft.Extensions.Configuration.Json](https://github.com/dotnet/runtime), [Microsoft.Extensions.Configuration.UserSecrets](https://github.com/dotnet/runtime) and [System.Text.Json](https://github.com/dotnet/runtime). These dependencies needed to be updated together. Updates `Microsoft.Extensions.Configuration` from 9.0.1 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.1...v9.0.1) Updates `Microsoft.Extensions.Configuration.Json` from 9.0.1 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.1...v9.0.1) Updates `Microsoft.Extensions.Configuration.UserSecrets` from 9.0.0 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.0...v9.0.1) Updates `System.Text.Json` from 9.0.1 to 9.0.1 - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v9.0.1...v9.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Configuration dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.Extensions.Configuration.Json dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.Extensions.Configuration.UserSecrets dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: System.Text.Json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 4702e36cc..2e23b428c 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -21,7 +21,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 24ae87a33a24e1747f80cbeb9b249b9884153fd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:12:39 +0300 Subject: [PATCH 40/45] Bump Microsoft.OData.Edm, Microsoft.OpenApi and Microsoft.OpenApi.OData (#2302) Bumps Microsoft.OData.Edm, [Microsoft.OpenApi](https://github.com/Microsoft/OpenAPI.NET) and [Microsoft.OpenApi.OData](https://github.com/Microsoft/OpenAPI.NET.OData). These dependencies needed to be updated together. Updates `Microsoft.OData.Edm` from 8.2.3 to 7.21.6 Updates `Microsoft.OpenApi` from 1.6.22 to 1.6.23 - [Release notes](https://github.com/Microsoft/OpenAPI.NET/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET/compare/1.6.22...1.6.23) Updates `Microsoft.OpenApi.OData` from 1.7.1 to 1.7.2 - [Release notes](https://github.com/Microsoft/OpenAPI.NET.OData/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET.OData/compare/v.1.7.1...v.1.7.2) --- updated-dependencies: - dependency-name: Microsoft.OData.Edm dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Microsoft.OpenApi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.OpenApi.OData dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- OpenAPIService/OpenAPIService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index a17f7ab95..c4a5c574c 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -11,7 +11,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive From 692935d2861889d48a1e1d1e88906696bc9b82fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:13:06 +0300 Subject: [PATCH 41/45] Bump coverlet.msbuild from 6.0.3 to 6.0.4 (#2300) Bumps [coverlet.msbuild](https://github.com/coverlet-coverage/coverlet) from 6.0.3 to 6.0.4. - [Release notes](https://github.com/coverlet-coverage/coverlet/releases) - [Commits](https://github.com/coverlet-coverage/coverlet/compare/v6.0.3...v6.0.4) --- updated-dependencies: - dependency-name: coverlet.msbuild dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OpenAPI.Test.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- FileService.Test/FileService.Test.csproj | 2 +- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- OpenAPIService.Test/OpenAPIService.Test.csproj | 2 +- PermissionsService.Test/PermissionsService.Test.csproj | 2 +- SamplesService.Test/SamplesService.Test.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 2 +- UriMatchService.Test/UriMatchingService.Test.csproj | 2 +- UtilityService.Test/UtilityService.Test.csproj | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index d2fe81daf..b85772f37 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index bec0fad19..abe492bd2 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 5ff38203b..8ef265d48 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index 090a680de..adb4acec6 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 2e23b428c..70761bc4e 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -15,7 +15,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index aa32d18ce..c613fbbc7 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -21,7 +21,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index f3279948d..c36e684de 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -29,7 +29,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index 710dc0751..f92215573 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -52,7 +52,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index 57876eae3..16594caf7 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -20,7 +20,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 71461690b..66a8e9db0 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -11,7 +11,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index 2da7fa303..31fcab737 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -7,7 +7,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 820ac737556ce077aab74844488aa81c5cfa77a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:13:27 +0300 Subject: [PATCH 42/45] Bump coverlet.collector from 6.0.3 to 6.0.4 (#2301) Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 6.0.3 to 6.0.4. - [Release notes](https://github.com/coverlet-coverage/coverlet/releases) - [Commits](https://github.com/coverlet-coverage/coverlet/compare/v6.0.3...v6.0.4) --- updated-dependencies: - dependency-name: coverlet.collector dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj | 2 +- .../CodeSnippetsReflection.OData.Test.csproj | 2 +- .../CodeSnippetsReflection.OpenAPI.Test.csproj | 2 +- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- FileService.Test/FileService.Test.csproj | 2 +- KnownIssuesService.Test/KnownIssuesService.Test.csproj | 2 +- OpenAPIService.Test/OpenAPIService.Test.csproj | 2 +- PermissionsService.Test/PermissionsService.Test.csproj | 2 +- SamplesService.Test/SamplesService.Test.csproj | 2 +- TelemetryService.Test/TelemetrySanitizerService.Test.csproj | 2 +- UriMatchService.Test/UriMatchingService.Test.csproj | 2 +- UtilityService.Test/UtilityService.Test.csproj | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj index 8e05f7c45..b1c6d625e 100644 --- a/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj +++ b/CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj @@ -20,7 +20,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj index b85772f37..369a0fe46 100644 --- a/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj +++ b/CodeSnippetsReflection.OData.Test/CodeSnippetsReflection.OData.Test.csproj @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj index abe492bd2..cd6a30f8e 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj +++ b/CodeSnippetsReflection.OpenAPI.Test/CodeSnippetsReflection.OpenAPI.Test.csproj @@ -22,7 +22,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 8ef265d48..33370b391 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -23,7 +23,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/FileService.Test/FileService.Test.csproj b/FileService.Test/FileService.Test.csproj index adb4acec6..c67732f06 100644 --- a/FileService.Test/FileService.Test.csproj +++ b/FileService.Test/FileService.Test.csproj @@ -22,7 +22,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/KnownIssuesService.Test/KnownIssuesService.Test.csproj b/KnownIssuesService.Test/KnownIssuesService.Test.csproj index 70761bc4e..bb7e3010e 100644 --- a/KnownIssuesService.Test/KnownIssuesService.Test.csproj +++ b/KnownIssuesService.Test/KnownIssuesService.Test.csproj @@ -34,7 +34,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/OpenAPIService.Test/OpenAPIService.Test.csproj b/OpenAPIService.Test/OpenAPIService.Test.csproj index c613fbbc7..8562bce7d 100644 --- a/OpenAPIService.Test/OpenAPIService.Test.csproj +++ b/OpenAPIService.Test/OpenAPIService.Test.csproj @@ -17,7 +17,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/PermissionsService.Test/PermissionsService.Test.csproj b/PermissionsService.Test/PermissionsService.Test.csproj index c36e684de..e9cfd936d 100644 --- a/PermissionsService.Test/PermissionsService.Test.csproj +++ b/PermissionsService.Test/PermissionsService.Test.csproj @@ -25,7 +25,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/SamplesService.Test/SamplesService.Test.csproj b/SamplesService.Test/SamplesService.Test.csproj index f92215573..6662dd41c 100644 --- a/SamplesService.Test/SamplesService.Test.csproj +++ b/SamplesService.Test/SamplesService.Test.csproj @@ -48,7 +48,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj index 16594caf7..84b48fd15 100644 --- a/TelemetryService.Test/TelemetrySanitizerService.Test.csproj +++ b/TelemetryService.Test/TelemetrySanitizerService.Test.csproj @@ -37,7 +37,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/UriMatchService.Test/UriMatchingService.Test.csproj b/UriMatchService.Test/UriMatchingService.Test.csproj index 66a8e9db0..f3d0f1154 100644 --- a/UriMatchService.Test/UriMatchingService.Test.csproj +++ b/UriMatchService.Test/UriMatchingService.Test.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/UtilityService.Test/UtilityService.Test.csproj b/UtilityService.Test/UtilityService.Test.csproj index 31fcab737..4fdff3515 100644 --- a/UtilityService.Test/UtilityService.Test.csproj +++ b/UtilityService.Test/UtilityService.Test.csproj @@ -21,7 +21,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 75e1c3be626ea839718815b9b7dda8eb50af849b Mon Sep 17 00:00:00 2001 From: Michael Wamae <68949852+Michael-Wamae@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:07:48 +0300 Subject: [PATCH 43/45] Remediate Unsafe PAT Usage (#2052) * Remediate Unsafe PAT Usage Switch from using Personal Access Token (PATs) to using Application Service Principal and Managed Identities * Exclude constructor from Code Coverage * Add Microsoft Tenant Servers to the OpenApi.yaml * Update GraphWebApi/appsettings.json Co-authored-by: Musale Martin * Update KnownIssuesService/Services/KnownIssuesService.cs Co-authored-by: Musale Martin * Update KnownIssuesService.csproj * Update KnownIssuesService.csproj --------- Co-authored-by: Musale Martin --- GraphWebApi/appsettings.json | 4 +- GraphWebApi/wwwroot/OpenApi.yaml | 4 ++ KnownIssuesService/KnownIssuesService.csproj | 11 +-- .../FederatedApplicationCredential.cs | 69 +++++++++++++++++++ .../Services/KnownIssuesService.cs | 13 ++-- 5 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 KnownIssuesService/Services/FederatedApplicationCredential.cs diff --git a/GraphWebApi/appsettings.json b/GraphWebApi/appsettings.json index ffca94195..5e6c59a2b 100644 --- a/GraphWebApi/appsettings.json +++ b/GraphWebApi/appsettings.json @@ -5,7 +5,9 @@ } }, "KnownIssues": { - "Token": "ENTER_TOKEN", + "TenantId": "ENTER_TENANT_ID", + "MsiClientId": "ENTER_MSI_CLIENT_ID", + "AppClientId": "ENTER_APP_CLIENT_ID", "Uri": "https://microsoftgraph.visualstudio.com/" }, "ApplicationInsights": { diff --git a/GraphWebApi/wwwroot/OpenApi.yaml b/GraphWebApi/wwwroot/OpenApi.yaml index 79dda9ace..8f89d706b 100644 --- a/GraphWebApi/wwwroot/OpenApi.yaml +++ b/GraphWebApi/wwwroot/OpenApi.yaml @@ -7,6 +7,10 @@ servers: description: Main server - url: https://graphexplorerapi-staging.azurewebsites.net/ description: Staging server + - url: https://devxapi-func-prod-eastus.azurewebsites.net/ + description: Torus Main server + - url: https://devxapi-func-ppe-eastus.azurewebsites.net/ + description: Torus Staging server - url: https://localhost:44399/ description: Local test server - url: https://localhost:5001/ diff --git a/KnownIssuesService/KnownIssuesService.csproj b/KnownIssuesService/KnownIssuesService.csproj index aee5f64cf..813d48fae 100644 --- a/KnownIssuesService/KnownIssuesService.csproj +++ b/KnownIssuesService/KnownIssuesService.csproj @@ -1,13 +1,16 @@ - + net8.0 - - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/KnownIssuesService/Services/FederatedApplicationCredential.cs b/KnownIssuesService/Services/FederatedApplicationCredential.cs new file mode 100644 index 000000000..fcd03a3d1 --- /dev/null +++ b/KnownIssuesService/Services/FederatedApplicationCredential.cs @@ -0,0 +1,69 @@ +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Identity; + +namespace KnownIssuesService.Services +{ + /// + /// TokenCredential implementation to use a managed identity's access token + /// as a signed client assertion when acquiring tokens for a primary client + /// application. The primary application must have a federated credential + /// configured to allow the managed identity to exchange tokens. + /// + public sealed class FederatedApplicationCredential : TokenCredential + { + /// + /// Constructor implementation for the federated application credential. + /// + /// TenantId where you want to use the credential (not necessarily the home tenant). + /// ClientId for the managed identity. + /// ClientId for the application registration. + [ExcludeFromCodeCoverage] + public FederatedApplicationCredential(string tenantId, string msiClientId, string appClientId) + { + ManagedIdentity = new ManagedIdentityCredential(msiClientId); + ClientAssertion = new ClientAssertionCredential(tenantId, appClientId, ComputeAssertionAsync); + } + + [ExcludeFromCodeCoverage] + private ManagedIdentityCredential ManagedIdentity + { + get; + } + + [ExcludeFromCodeCoverage] + private ClientAssertionCredential ClientAssertion + { + get; + } + + /// + [ExcludeFromCodeCoverage] + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return ClientAssertion.GetToken(requestContext, cancellationToken); + } + + /// + [ExcludeFromCodeCoverage] + public override async ValueTask GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) + { + return await ClientAssertion.GetTokenAsync(requestContext, cancellationToken); + } + + /// + /// Get an exchange token from our managed identity to use as an assertion. + /// + /// Cancellation token. + /// A signed assertion to authenticate with AzureAD. + [ExcludeFromCodeCoverage] + private async Task ComputeAssertionAsync(CancellationToken cancellationToken) + { + TokenRequestContext msiContext = new(["api://AzureADTokenExchange/.default"]); + AccessToken msiToken = await ManagedIdentity.GetTokenAsync(msiContext, cancellationToken); + return msiToken.Token; + } + } + } diff --git a/KnownIssuesService/Services/KnownIssuesService.cs b/KnownIssuesService/Services/KnownIssuesService.cs index dd566bd78..3916fe2f6 100644 --- a/KnownIssuesService/Services/KnownIssuesService.cs +++ b/KnownIssuesService/Services/KnownIssuesService.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.TeamFoundation.WorkItemTracking.WebApi; using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models; +using Microsoft.VisualStudio.Services.Client; using Microsoft.VisualStudio.Services.Common; using System; using System.Collections.Generic; @@ -31,8 +32,10 @@ public class KnownIssuesService : IKnownIssuesService private readonly TelemetryClient _telemetryClient; private readonly Dictionary _knownIssuesTraceProperties = new() { { UtilityConstants.TelemetryPropertyKey_KnownIssues, nameof(KnownIssuesService) } }; - private const string AccessTokenValue = "KnownIssues:Token"; - private const string KnownIssuesPath = "KnownIssues:Uri"; + private const string tenantId = "KnownIssues:TenantId"; + private const string msiClientId = "KnownIssues:MsiClientId"; + private const string appClientId = "KnownIssues:AppClientId"; + private const string KnownIssuesPath = "KnownIssues:Uri"; public KnownIssuesService(IConfiguration configuration, TelemetryClient telemetryClient = null, @@ -49,14 +52,14 @@ public KnownIssuesService(IConfiguration configuration, /// /// An instance of the authenticated VS Service [ExcludeFromCodeCoverage] - private VssBasicCredential Authenticate() + private VssAzureIdentityCredential Authenticate() { _telemetryClient?.TrackTrace("Fetch personal access token from configuration and use it to authenticate into Visual Studio Service", SeverityLevel.Information, _knownIssuesTraceProperties); - var accessToken = _configuration[AccessTokenValue]; - return new VssBasicCredential(string.Empty, accessToken); + FederatedApplicationCredential credentialAzure = new FederatedApplicationCredential(_configuration[tenantId], _configuration[msiClientId], _configuration[appClientId]); + return new VssAzureIdentityCredential(credentialAzure); } /// From 5c572480c3a8fd951c74af6d7ef564d134559d19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Jan 2025 09:03:25 +0300 Subject: [PATCH 44/45] Bump MSTest.TestFramework from 3.7.1 to 3.7.2 (#2303) Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.7.1 to 3.7.2. - [Release notes](https://github.com/microsoft/testfx/releases) - [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md) - [Commits](https://github.com/microsoft/testfx/compare/v3.7.1...v3.7.2) --- updated-dependencies: - dependency-name: MSTest.TestFramework dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- ExceptionMiddleware/ExceptionMiddleware.Test.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj index 33370b391..3c1434c62 100644 --- a/ExceptionMiddleware/ExceptionMiddleware.Test.csproj +++ b/ExceptionMiddleware/ExceptionMiddleware.Test.csproj @@ -13,7 +13,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all From cdafba32a062fb8a9706826c0fe99b16c3a479b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 09:12:48 +0300 Subject: [PATCH 45/45] Bump Microsoft.OData.Edm, Microsoft.OpenApi and Microsoft.OpenApi.OData (#2304) Bumps Microsoft.OData.Edm, [Microsoft.OpenApi](https://github.com/Microsoft/OpenAPI.NET) and [Microsoft.OpenApi.OData](https://github.com/Microsoft/OpenAPI.NET.OData). These dependencies needed to be updated together. Updates `Microsoft.OData.Edm` from 8.2.3 to 7.21.6 Updates `Microsoft.OpenApi` from 1.6.22 to 1.6.23 - [Release notes](https://github.com/Microsoft/OpenAPI.NET/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET/compare/1.6.22...1.6.23) Updates `Microsoft.OpenApi.OData` from 1.7.2 to 1.7.3 - [Release notes](https://github.com/Microsoft/OpenAPI.NET.OData/releases) - [Commits](https://github.com/Microsoft/OpenAPI.NET.OData/compare/v.1.7.2...v.1.7.3) --- updated-dependencies: - dependency-name: Microsoft.OData.Edm dependency-type: direct:production update-type: version-update:semver-major - dependency-name: Microsoft.OpenApi dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.OpenApi.OData dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- OpenAPIService/OpenAPIService.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenAPIService/OpenAPIService.csproj b/OpenAPIService/OpenAPIService.csproj index c4a5c574c..163c2fe90 100644 --- a/OpenAPIService/OpenAPIService.csproj +++ b/OpenAPIService/OpenAPIService.csproj @@ -11,7 +11,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive