From 0a7a78b8b765128c5d679228f787c50aebea462f Mon Sep 17 00:00:00 2001 From: Timothy Wamalwa Date: Wed, 28 Jun 2023 19:41:59 +0300 Subject: [PATCH 1/9] Fixed incomplete snippets with expand query options --- .../GraphCliGeneratorTests.cs | 28 +++++++++++++++ .../LanguageGenerators/GraphCliGenerator.cs | 34 +++++++++++++------ 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs index e7acd01d7..1570c803e 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs @@ -483,4 +483,32 @@ public async Task GeneratesSnippetsWithSlashMeEndpoints() // Then Assert.Equal("mgc users calendar events list --user-id {user-id} --filter startsWith(subject,'All')", result); } + [Fact] + public async Task GeneratesSnippetsWithExpandQueryOptions() + { + // 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()); + + // When + var result = _generator.GenerateCodeSnippet(snippetModel); + + // Then + Assert.Equal("mgc users messages get --user-id {user-id} --message-id {message-id} --expand \"singleValueExtendedProperties(`$filter=id eq 'XXXX')\"", result); + } + [Fact] + public async Task GeneratesSnippetsWithFilterQueryOptions() + { + // 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()); + + // When + var result = _generator.GenerateCodeSnippet(snippetModel); + + // Then + Assert.Equal("mgc identity-governance access-reviews definitions list --filter \"contains(scope/microsoft.graph.accessReviewQueryScope/query, './members')\"", result); + } } diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index 464f733d5..cf12ba61d 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -17,6 +17,7 @@ public partial class GraphCliGenerator : ILanguageGenerator ProcessQueryParameters([NotNull] in S IDictionary splitQueryString = new Dictionary(); if (!string.IsNullOrWhiteSpace(snippetModel.QueryString)) { - splitQueryString = snippetModel.QueryString - .Remove(0, 1) - .Split('&') - .Select(q => - { - var x = q.Split('='); - return x.Length > 1 ? (x[0], x[1]) : (x[0], string.Empty); - }) - .Where(t => !string.IsNullOrWhiteSpace(t.Item2)) - .ToDictionary(t => t.Item1, t => t.Item2); + if (systemQueryOptionRegex.IsMatch(snippetModel.QueryString)) + { + string pattern = "\\?\\$\\w*="; + string[] splittedQueryString = Regex.Split(snippetModel.QueryString, pattern); + var match = Regex.Match(snippetModel.QueryString, pattern); + string queryOption = match.Groups[0].Value.Replace("?", "").Replace("=", ""); + string queryOptionFunction = splittedQueryString[1].Replace("$", "`$"); + queryOptionFunction = queryOptionFunction.Replace(queryOptionFunction, "\"" + queryOptionFunction + "\""); + splitQueryString.Add(queryOption, queryOptionFunction); + } + else + { + splitQueryString = snippetModel.QueryString + .Remove(0, 1) + .Split('&') + .Select(q => + { + var x = q.Split('='); + return x.Length > 1 ? (x[0], x[1]) : (x[0], string.Empty); + }) + .Where(t => !string.IsNullOrWhiteSpace(t.Item2)) + .ToDictionary(t => t.Item1, t => t.Item2); + } } return splitQueryString; From 9d6e322e70ddb13057816c42146614bbe7023c48 Mon Sep 17 00:00:00 2001 From: Timothy Wamalwa Date: Wed, 28 Jun 2023 20:21:25 +0300 Subject: [PATCH 2/9] Rectified testcase --- CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs b/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs index 1570c803e..3b03b069c 100644 --- a/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs +++ b/CodeSnippetsReflection.OpenAPI.Test/GraphCliGeneratorTests.cs @@ -481,7 +481,7 @@ public async Task GeneratesSnippetsWithSlashMeEndpoints() var result = _generator.GenerateCodeSnippet(snippetModel); // Then - Assert.Equal("mgc users calendar events list --user-id {user-id} --filter startsWith(subject,'All')", result); + Assert.Equal("mgc users calendar events list --user-id {user-id} --filter \"startsWith(subject,'All')\"", result); } [Fact] public async Task GeneratesSnippetsWithExpandQueryOptions() From 0796b6085a1ec0106b4b0cdf23e5c0af6601dad5 Mon Sep 17 00:00:00 2001 From: Timothy Wamalwa Date: Wed, 28 Jun 2023 20:40:40 +0300 Subject: [PATCH 3/9] Added regex execution timeout --- .../LanguageGenerators/GraphCliGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index cf12ba61d..1eeabb194 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -224,7 +224,7 @@ private static IDictionary ProcessQueryParameters([NotNull] in S if (systemQueryOptionRegex.IsMatch(snippetModel.QueryString)) { string pattern = "\\?\\$\\w*="; - string[] splittedQueryString = Regex.Split(snippetModel.QueryString, pattern); + string[] splittedQueryString = Regex.Split(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); var match = Regex.Match(snippetModel.QueryString, pattern); string queryOption = match.Groups[0].Value.Replace("?", "").Replace("=", ""); string queryOptionFunction = splittedQueryString[1].Replace("$", "`$"); From 429326d5592c646447d7348d39e888fe6e7a2598 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 28 Jun 2023 21:28:48 +0300 Subject: [PATCH 4/9] Update CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs Co-authored-by: Vincent Biret --- .../LanguageGenerators/GraphCliGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index 1eeabb194..aa902fcb1 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -236,7 +236,7 @@ private static IDictionary ProcessQueryParameters([NotNull] in S splitQueryString = snippetModel.QueryString .Remove(0, 1) .Split('&') - .Select(q => + .Select(static q => { var x = q.Split('='); return x.Length > 1 ? (x[0], x[1]) : (x[0], string.Empty); From dd9221048489158d9050b7ee2b2650a8ababe82f Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 28 Jun 2023 21:29:03 +0300 Subject: [PATCH 5/9] Update CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs Co-authored-by: Vincent Biret --- .../LanguageGenerators/GraphCliGenerator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index aa902fcb1..7bc83d3f0 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -241,8 +241,8 @@ private static IDictionary ProcessQueryParameters([NotNull] in S var x = q.Split('='); return x.Length > 1 ? (x[0], x[1]) : (x[0], string.Empty); }) - .Where(t => !string.IsNullOrWhiteSpace(t.Item2)) - .ToDictionary(t => t.Item1, t => t.Item2); + .Where(static t => !string.IsNullOrWhiteSpace(t.Item2)) + .ToDictionary(static t => t.Item1, static t => t.Item2); } } From d977de3288911b81b0d66ad2a6af40e8e26511e9 Mon Sep 17 00:00:00 2001 From: Timothy Wamalwa Date: Wed, 28 Jun 2023 21:31:13 +0300 Subject: [PATCH 6/9] Added time limit to the regex --- .../LanguageGenerators/GraphCliGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index 7bc83d3f0..8acb41d2e 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -225,7 +225,7 @@ private static IDictionary ProcessQueryParameters([NotNull] in S { string pattern = "\\?\\$\\w*="; string[] splittedQueryString = Regex.Split(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); - var match = Regex.Match(snippetModel.QueryString, pattern); + var match = Regex.Match(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); string queryOption = match.Groups[0].Value.Replace("?", "").Replace("=", ""); string queryOptionFunction = splittedQueryString[1].Replace("$", "`$"); queryOptionFunction = queryOptionFunction.Replace(queryOptionFunction, "\"" + queryOptionFunction + "\""); From 7ce2e2a3737d8abbeac0d830bfa739e091572812 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 28 Jun 2023 22:29:03 +0300 Subject: [PATCH 7/9] Update CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs Co-authored-by: Vincent Biret --- .../LanguageGenerators/GraphCliGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index 8acb41d2e..4592d5c2b 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -226,7 +226,7 @@ private static IDictionary ProcessQueryParameters([NotNull] in S string pattern = "\\?\\$\\w*="; string[] splittedQueryString = Regex.Split(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); var match = Regex.Match(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); - string queryOption = match.Groups[0].Value.Replace("?", "").Replace("=", ""); + string queryOption = match.Groups[0].Value.Replace("?", string.Empty, StringComparison.OrdinalIgnoreCase).Replace("=", string.Empty, StringComparison.OrdinalIgnoreCase); string queryOptionFunction = splittedQueryString[1].Replace("$", "`$"); queryOptionFunction = queryOptionFunction.Replace(queryOptionFunction, "\"" + queryOptionFunction + "\""); splitQueryString.Add(queryOption, queryOptionFunction); From e856a858c7a0d1cb27345a7cc95f328830ff6096 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 28 Jun 2023 22:29:18 +0300 Subject: [PATCH 8/9] Update CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs Co-authored-by: Vincent Biret --- .../LanguageGenerators/GraphCliGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index 4592d5c2b..5d3ca0e6d 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -227,7 +227,7 @@ private static IDictionary ProcessQueryParameters([NotNull] in S string[] splittedQueryString = Regex.Split(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); var match = Regex.Match(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); string queryOption = match.Groups[0].Value.Replace("?", string.Empty, StringComparison.OrdinalIgnoreCase).Replace("=", string.Empty, StringComparison.OrdinalIgnoreCase); - string queryOptionFunction = splittedQueryString[1].Replace("$", "`$"); + string queryOptionFunction = splittedQueryString[1].Replace("$", "`$", StringComparison.OrdinalIgnoreCase); queryOptionFunction = queryOptionFunction.Replace(queryOptionFunction, "\"" + queryOptionFunction + "\""); splitQueryString.Add(queryOption, queryOptionFunction); } From 703d7199313927243405da787654bc9be4b82adc Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 28 Jun 2023 22:29:30 +0300 Subject: [PATCH 9/9] Update CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs Co-authored-by: Vincent Biret --- .../LanguageGenerators/GraphCliGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs index 5d3ca0e6d..195640a40 100644 --- a/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs +++ b/CodeSnippetsReflection.OpenAPI/LanguageGenerators/GraphCliGenerator.cs @@ -228,7 +228,7 @@ private static IDictionary ProcessQueryParameters([NotNull] in S var match = Regex.Match(snippetModel.QueryString, pattern, RegexOptions.Compiled, TimeSpan.FromSeconds(5)); string queryOption = match.Groups[0].Value.Replace("?", string.Empty, StringComparison.OrdinalIgnoreCase).Replace("=", string.Empty, StringComparison.OrdinalIgnoreCase); string queryOptionFunction = splittedQueryString[1].Replace("$", "`$", StringComparison.OrdinalIgnoreCase); - queryOptionFunction = queryOptionFunction.Replace(queryOptionFunction, "\"" + queryOptionFunction + "\""); + queryOptionFunction = queryOptionFunction.Replace(queryOptionFunction, "\"" + queryOptionFunction + "\"", StringComparison.Ordinal); splitQueryString.Add(queryOption, queryOptionFunction); } else