Skip to content

Commit

Permalink
Merge pull request #1599 from microsoftgraph/dev
Browse files Browse the repository at this point in the history
Merges dev into master
  • Loading branch information
millicentachieng committed Jun 19, 2023
2 parents 93cf470 + ff1f170 commit 838e570
Show file tree
Hide file tree
Showing 31 changed files with 246 additions and 46 deletions.
86 changes: 86 additions & 0 deletions .github/policies/microsoft-graph-devx-api-branch-protection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# File initially created using https://github.com/MIchaelMainer/policyservicetoolkit/blob/main/branch_protection_export.ps1.

name: microsoft-graph-devx-api-branch-protection
description: Branch protection policy for the microsoft-graph-devx-api repository
resource: repository
configuration:
branchProtectionRules:

# The following GitHub PolicyService properties are not yet supported: whoCanDismissReviews
- branchNamePattern: dev
# This branch pattern applies to the following branches as of 06/08/2023 16:23:32:
# dev

# Specifies whether this branch can be deleted. boolean
allowsDeletions: false
# Specifies whether forced pushes are allowed on this branch. boolean
allowsForcePushes: false
# Specifies whether new commits pushed to the matching branches dismiss pull request review approvals. boolean
dismissStaleReviews: true
# Specifies whether admins can overwrite branch protection. boolean
isAdminEnforced: false
# Indicates whether "Require a pull request before merging" is enabled. boolean
requiresPullRequestBeforeMerging: true
# Specifies the number of pull request reviews before merging. int (0-6). Should be null/empty if PRs are not required
requiredApprovingReviewsCount: 1
# Require review from Code Owners. Requires requiredApprovingReviewsCount. boolean
requireCodeOwnersReview: true
# Are commits required to be signed. boolean. TODO: all contributors must have commit signing on local machines.
requiresCommitSignatures: false
# Are conversations required to be resolved before merging? boolean
requiresConversationResolution: false
# Are merge commits prohibited from being pushed to this branch. boolean
requiresLinearHistory: true
# Required status checks to pass before merging. Values can be any string, but if the value does not correspond to any existing status check, the status check will be stuck on pending for status since nothing exists to push an actual status
requiredStatusChecks:
- license/cla
- DevX API Validate PR
# Require branches to be up to date before merging. Requires requiredStatusChecks. boolean
requiresStrictStatusChecks: false
# Indicates whether there are restrictions on who can push. boolean. Requires whoCanPush.
restrictsPushes: false
# Restrict who can dismiss pull request reviews. boolean
restrictsReviewDismissals: true
# List of Apps, Users, and Teams that can dismiss pull request reviews to this branch pattern.
whoCanDismissReviews:
- msgraph-devx-api-write

- branchNamePattern: master
# This branch pattern applies to the following branches as of 06/08/2023 16:23:32:
# master

# Specifies whether this branch can be deleted. boolean
allowsDeletions: false
# Specifies whether forced pushes are allowed on this branch. boolean
allowsForcePushes: false
# Specifies whether new commits pushed to the matching branches dismiss pull request review approvals. boolean
dismissStaleReviews: true
# Specifies whether admins can overwrite branch protection. boolean
isAdminEnforced: false
# Indicates whether "Require a pull request before merging" is enabled. boolean
requiresPullRequestBeforeMerging: true
# Specifies the number of pull request reviews before merging. int (0-6). Should be null/empty if PRs are not required
requiredApprovingReviewsCount: 1
# Require review from Code Owners. Requires requiredApprovingReviewsCount. boolean
requireCodeOwnersReview: true
# Are commits required to be signed. boolean. TODO: all contributors must have commit signing on local machines.
requiresCommitSignatures: false
# Are conversations required to be resolved before merging? boolean
requiresConversationResolution: false
# Are merge commits prohibited from being pushed to this branch. boolean
requiresLinearHistory: false
# Required status checks to pass before merging. Values can be any string, but if the value does not correspond to any existing status check, the status check will be stuck on pending for status since nothing exists to push an actual status
requiredStatusChecks:
- license/cla
- DevX API Validate PR
# Require branches to be up to date before merging. Requires requiredStatusChecks. boolean
requiresStrictStatusChecks: false
# Indicates whether there are restrictions on who can push. boolean. Requires whoCanPush.
restrictsPushes: false
# Restrict who can dismiss pull request reviews. boolean
restrictsReviewDismissals: true


2 changes: 1 addition & 1 deletion ChangesService.Test/ChangesService.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageReference Include="coverlet.collector" Version="6.0.0" />
Expand Down
2 changes: 1 addition & 1 deletion CodeSnippetsPipeline.Test/CodeSnippetsPipeline.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
Expand Down
23 changes: 23 additions & 0 deletions CodeSnippetsReflection.OpenAPI.Test/GoGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,29 @@ public async Task GeneratesMeImportFromUserPackage()
Assert.DoesNotContain("@odata.type", result);
}
[Fact]
public async Task GeneratesObjectsInArray() {
var sampleJson = @"
{
""addLicenses"": [
{
""disabledPlans"": [ ""11b0131d-43c8-4bbb-b2c8-e80f9a50834a"" ],
""skuId"": ""45715bb8-13f9-4bf6-927f-ef96c102d394""
}
],
""removeLicenses"": [ ""bea13e0c-3828-4daa-a392-28af7ff61a0f"" ]
}
";
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 GetV1TreeNode());
var result = _generator.GenerateCodeSnippet(snippetModel);
Assert.Contains("requestBody := graphusers.NewItemAssignLicensePostRequestBody()", result);
Assert.Contains("disabledPlans := []uuid.UUID {", result);
Assert.Contains("removeLicenses := []uuid.UUID {", result);
Assert.Contains("uuid.MustParse(\"bea13e0c-3828-4daa-a392-28af7ff61a0f\"),", result);
}
[Fact]
public async Task GeneratesTheSnippetHeader() {
using var requestPayload = new HttpRequestMessage(HttpMethod.Get, $"{ServiceRootUrl}/me/messages");
var snippetModel = new SnippetModel(requestPayload, ServiceRootUrl, await GetV1TreeNode());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.21.0" />
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.4" />
<PackageReference Include="System.Text.Json" Version="7.0.2" />
<PackageReference Include="System.Text.Json" Version="7.0.3" />
</ItemGroup>

<PropertyGroup>
Expand Down
41 changes: 36 additions & 5 deletions CodeSnippetsReflection.OpenAPI/LanguageGenerators/GoGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ static IImmutableSet<string> GetNativeTypes()
return ImmutableHashSet.Create("string", "int", "float");
}

private static readonly Dictionary<string, string> formatPropertyName = new(StringComparer.OrdinalIgnoreCase)
{
{"guid", "uuid.UUID"},
{"uuid", "uuid.UUID"},
{"date-time", "time.Time"},
{"date", "serialization.DateOnly"},
{"duration", "serialization.ISODuration"}
};

public string GenerateCodeSnippet(SnippetModel snippetModel)
{
if (snippetModel == null) throw new ArgumentNullException("Argument snippetModel cannot be null");
Expand Down Expand Up @@ -345,7 +354,9 @@ private static void WriteBody(SnippetCodeGraph codeGraph, StringBuilder builder)
}
else
{
builder.AppendLine($"{indentManager.GetIndent()}{requestBodyVarName} := graph{ProcessFinalNameSpaceName(codeGraph.Body.NamespaceName).Replace(".","").ToLowerInvariant()}.New{codeGraph.Body.Name.ToFirstCharacterUpperCase()}()");
// objects in namespace user have a prefix of item
string bodyName = codeGraph.Body.NamespaceName.StartsWith("Me", StringComparison.OrdinalIgnoreCase) ? $"Item{codeGraph.Body.Name}" : codeGraph.Body.Name;
builder.AppendLine($"{indentManager.GetIndent()}{requestBodyVarName} := graph{ProcessFinalNameSpaceName(codeGraph.Body.NamespaceName).Replace(".","").ToLowerInvariant()}.New{bodyName.ToFirstCharacterUpperCase()}()");
WriteCodePropertyObject(requestBodyVarName, builder, codeGraph.Body, indentManager);
}
}
Expand Down Expand Up @@ -388,9 +399,21 @@ private static void WriteArrayProperty(string propertyAssignment, string objectN
builder.AppendLine(objectBuilder.ToString());
}

var typeName = NativeTypes.Contains(codeProperty.TypeDefinition?.ToLowerInvariant()?.Trim()) ? codeProperty.TypeDefinition?.ToLowerInvariant() : $"graph{ProcessFinalNameSpaceName(parentProperty.NamespaceName).Replace(".","").ToLowerInvariant()}.{codeProperty.TypeDefinition}able";
var typeDefinition = codeProperty.TypeDefinition?.ToLowerInvariant()?.Trim();

String typeName;
if (NativeTypes.Contains(typeDefinition)) {
typeName = typeDefinition;
} else if (formatPropertyName.TryGetValue(typeDefinition, out var type))
{
typeName = type;
} else
{
typeName = $"graph{ProcessFinalNameSpaceName(codeProperty.NamespaceName).Replace(".", "").ToLowerInvariant()}.{codeProperty.TypeDefinition}able";
}

builder.AppendLine($"{indentManager.GetIndent()}{propertyName} := []{typeName} {{");
builder.AppendLine(contentBuilder.ToString());
builder.AppendLine(contentBuilder.ToString().TrimEnd());
builder.AppendLine($"{indentManager.GetIndent()}}}");
if (parentProperty.PropertyType == PropertyType.Object)
builder.AppendLine($"{indentManager.GetIndent()}{propertyAssignment}.Set{propertyName.ToFirstCharacterUpperCase()}({objectName})");
Expand Down Expand Up @@ -433,8 +456,16 @@ private static void WriteCodeProperty(string propertyAssignment, StringBuilder b
WriteArrayProperty(propertyAssignment, objectName, builder, codeProperty, child, indentManager);
break;
case PropertyType.Guid:
builder.AppendLine($"{propertyName} := uuid.MustParse(\"{child.Value}\")");
builder.AppendLine($"{propertyAssignment}.Set{propertyName.ToFirstCharacterUpperCase()}(&{propertyName}) ");

if (!isArray)
{
builder.AppendLine($"{propertyName} := uuid.MustParse(\"{child.Value}\")");
builder.AppendLine($"{propertyAssignment}.Set{propertyName.ToFirstCharacterUpperCase()}(&{propertyName}) ");
}
else
{
builder.AppendLine($"{indentManager.GetIndent()}uuid.MustParse(\"{child.Value}\"),");
}
break;
case PropertyType.String:
WriteStringProperty(propertyAssignment, codeProperty, builder, indentManager, child);
Expand Down
29 changes: 25 additions & 4 deletions CodeSnippetsReflection.OpenAPI/ModelGraph/SnippetCodeGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public record SnippetCodeGraph

private static readonly CodeProperty EMPTY_PROPERTY = new() { Name = null, Value = null, Children = null, PropertyType = PropertyType.Default };

private static Dictionary<string, PropertyType> _formatPropertyTypes = new (StringComparer.OrdinalIgnoreCase)
private static readonly Dictionary<string, PropertyType> _formatPropertyTypes = new (StringComparer.OrdinalIgnoreCase)
{
{"int32", PropertyType.Int32},
{"int64", PropertyType.Int64},
Expand Down Expand Up @@ -417,7 +417,7 @@ private static String escapeSpecialCharacters(string value)
var namespaceSuffix = lastDotIndex != -1 ? $".{referenceId[..lastDotIndex]}" : string.Empty;
return $"models{namespaceSuffix}";
}

private static CodeProperty evaluateStringProperty(string propertyName, string value, OpenApiSchema propSchema)
{
if ((propSchema?.Type?.Equals("boolean", StringComparison.OrdinalIgnoreCase) ?? false))
Expand Down Expand Up @@ -494,14 +494,35 @@ private static CodeProperty parseProperty(string propertyName, JsonElement value
private static CodeProperty parseJsonArrayValue(string propertyName, JsonElement value, OpenApiSchema schema)
{
var alternativeType = schema?.Items?.AnyOf?.FirstOrDefault()?.AllOf?.LastOrDefault()?.Title;
var children = value.EnumerateArray().Select(item => parseProperty(schema.GetSchemaTitle() ?? alternativeType?.ToFirstCharacterUpperCase(), item, schema?.Items)).ToList();
// uuid schemas
var genericType = schema.GetSchemaTitle().ToFirstCharacterUpperCase() ??
(value.EnumerateArray().Any() ?
value.EnumerateArray().First().ValueKind.ToString() :
evaluatePropertyTypeDefinition(value.EnumerateArray().First().ValueKind.ToString(), schema?.Items) :
schema?.Items?.Type);
var children = value.EnumerateArray().Select(item =>
{
var prop = parseProperty(schema.GetSchemaTitle() ?? alternativeType?.ToFirstCharacterUpperCase(), item,
schema?.Items);
prop.TypeDefinition = prop.TypeDefinition ?? genericType;
return prop;
}).ToList();
return new CodeProperty { Name = propertyName, Value = null, PropertyType = PropertyType.Array, Children = children, TypeDefinition = genericType ?? alternativeType };
}

private static string evaluatePropertyTypeDefinition(String typeInfo, OpenApiSchema propSchema)
{
if (!typeInfo.Equals("String", StringComparison.CurrentCultureIgnoreCase))
return typeInfo;

if ((propSchema?.Type?.Equals("boolean", StringComparison.OrdinalIgnoreCase) ?? false))
return "boolean";
var formatString = propSchema?.Format;
if (!string.IsNullOrEmpty(formatString) && _formatPropertyTypes.TryGetValue(formatString, out var type))
return formatString;

return typeInfo;
}

private static CodeProperty parseAnonymousObjectValues(string propertyName, JsonElement value, OpenApiSchema schema)
{
if (value.ValueKind != JsonValueKind.Object) throw new InvalidOperationException($"Expected JSON object and got {value.ValueKind}");
Expand Down
2 changes: 1 addition & 1 deletion ExceptionMiddleware/ExceptionMiddleware.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.0.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
Expand Down
2 changes: 1 addition & 1 deletion FileService.Test/FileService.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
Expand Down
2 changes: 1 addition & 1 deletion GraphWebApi/Controllers/PermissionsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public PermissionsController(IPermissionsStore permissionsStore, TelemetryClient
SeverityLevel.Information,
_permissionsTraceProperties);

return result == null || result.Results == null ? NotFound() : Ok(result.Results);
return result?.Results == null || !result.Results.Any() ? NotFound() : Ok(result.Results);
}

[HttpPost]
Expand Down
8 changes: 4 additions & 4 deletions GraphWebApi/GraphWebApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@
<PackageReference Include="Microsoft.ApplicationInsights.Web" Version="2.21.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
<PackageReference Include="Microsoft.AspNetCore.ApplicationInsights.HostingStartup" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="7.0.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.7" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.6" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.7" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" />
Expand Down
3 changes: 2 additions & 1 deletion GraphWebApi/wwwroot/OpenApi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ paths:
Description: Notifications fail when an organization has several Bookings businesses,
WorkloadArea: Notifications,
Workaround: Upgrade Notifications,
APIPathLink: https://docs.microsoft.com/en-us/graph/api/resources/calendar?view=graph-rest-1.0
APIPathLink: https://docs.microsoft.com/en-us/graph/api/resources/calendar?view=graph-rest-1.0,
SubArea: NotificationsSubArea
"404":
description: Not found
"500":
Expand Down

0 comments on commit 838e570

Please sign in to comment.