Skip to content

Commit

Permalink
Enumerating over create method parameter enum values
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Schulte committed May 24, 2016
1 parent f32e824 commit 3f84226
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,121 @@ public void IsCreateResourceMethodWhenUrlDoesntEndWithResourceNamePlaceholder()
}

[Fact]
public void GetResourceTypeWithOneLevelOfResources()
public void GetResourceTypesWithOneLevelOfResources()
{
Assert.Equal("Microsoft.Cdn/profiles", ResourceSchemaParser.GetResourceType("Microsoft.Cdn", "profiles/{profileName}"));
Assert.Equal(new string[] { "Microsoft.Cdn/profiles" }, ResourceSchemaParser.GetResourceTypes("Microsoft.Cdn", "profiles/{profileName}", new List<Parameter>()));
}

[Fact]
public void GetResourceTypeWithMultipleLevelsOfResources()
public void GetResourceTypesWithMultipleLevelsOfResources()
{
Assert.Equal("Microsoft.Cdn/profiles/endpoints/customDomains", ResourceSchemaParser.GetResourceType("Microsoft.Cdn", "profiles/{profileName}/endpoints/{endpointName}/customDomains/{customDomainName}"));
Assert.Equal(new string[] { "Microsoft.Cdn/profiles/endpoints/customDomains" }, ResourceSchemaParser.GetResourceTypes("Microsoft.Cdn", "profiles/{profileName}/endpoints/{endpointName}/customDomains/{customDomainName}", new List<Parameter>()));
}

[Fact]
public void GetResourceTypesParameterReferenceWithNoMatchingParameterDefinition()
{
const string provider = "Microsoft.Network";
const string pathAfterProvider = "dnszones/{zoneName}/{recordType}/{relativeRecordSetName}";
List<Parameter> methodParameters = new List<Parameter>();
Assert.Throws<ArgumentException>(() => { ResourceSchemaParser.GetResourceTypes(provider, pathAfterProvider, methodParameters); });
}

[Fact]
public void GetResourceTypesWithParameterReferenceWithParameterDefinitionWithNoType()
{
const string provider = "Microsoft.Network";
const string pathAfterProvider = "dnszones/{zoneName}/{recordType}/{relativeRecordSetName}";
List<Parameter> methodParameters = new List<Parameter>()
{
new Parameter()
{
Name = "recordType"
}
};
Assert.Throws<ArgumentException>(() => { ResourceSchemaParser.GetResourceTypes(provider, pathAfterProvider, methodParameters); });
}

[Fact]
public void GetResourceTypesWithParameterReferenceWithParameterDefinitionWithPrimaryType()
{
const string provider = "Microsoft.Network";
const string pathAfterProvider = "dnszones/{zoneName}/{recordType}/{relativeRecordSetName}";
List<Parameter> methodParameters = new List<Parameter>()
{
new Parameter()
{
Name = "recordType",
Type = new PrimaryType(KnownPrimaryType.String)
}
};
Assert.Throws<ArgumentException>(() => { ResourceSchemaParser.GetResourceTypes(provider, pathAfterProvider, methodParameters); });
}

[Fact]
public void GetResourceTypesWithParameterReferenceWithParameterDefinitionWithEnumTypeWithNoValues()
{
const string provider = "Microsoft.Network";
const string pathAfterProvider = "dnszones/{zoneName}/{recordType}/{relativeRecordSetName}";
List<Parameter> methodParameters = new List<Parameter>()
{
new Parameter()
{
Name = "recordType",
Type = new EnumType()
}
};
Assert.Throws<ArgumentException>(() => { ResourceSchemaParser.GetResourceTypes(provider, pathAfterProvider, methodParameters); });
}

[Fact]
public void GetResourceTypesWithParameterReferenceWithParameterDefinitionWithEnumTypeWithOneValue()
{
const string provider = "Microsoft.Network";
const string pathAfterProvider = "dnszones/{zoneName}/{recordType}/{relativeRecordSetName}";
EnumType enumType = new EnumType();
enumType.Values.Add(new EnumValue()
{
Name = "A"
});
List<Parameter> methodParameters = new List<Parameter>()
{
new Parameter()
{
Name = "recordType",
Type = enumType
}
};
Assert.Equal(new string[] { "Microsoft.Network/dnszones/A" }, ResourceSchemaParser.GetResourceTypes(provider, pathAfterProvider, methodParameters));
}

[Fact]
public void GetResourceTypesWithParameterReferenceWithParameterDefinitionWithEnumTypeWithMultipleValues()
{
const string provider = "Microsoft.Network";
const string pathAfterProvider = "dnszones/{zoneName}/{recordType}/{relativeRecordSetName}";
EnumType enumType = new EnumType();
enumType.Values.Add(new EnumValue() { Name = "A" });
enumType.Values.Add(new EnumValue() { Name = "AAAA" });
enumType.Values.Add(new EnumValue() { Name = "CNAME" });
enumType.Values.Add(new EnumValue() { Name = "MX" });
List<Parameter> methodParameters = new List<Parameter>()
{
new Parameter()
{
Name = "recordType",
Type = enumType
}
};
Assert.Equal(
new string[]
{
"Microsoft.Network/dnszones/A",
"Microsoft.Network/dnszones/AAAA",
"Microsoft.Network/dnszones/CNAME",
"Microsoft.Network/dnszones/MX"
},
ResourceSchemaParser.GetResourceTypes(provider, pathAfterProvider, methodParameters));
}

private static Method CreateMethod(HttpMethod httpMethod = HttpMethod.Put, Parameter body = null, IType responseBody = null, string url = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public static class ResourceSchemaParser
}

string methodUrlPathAfterProvider = afterPrefix.Substring(forwardSlashIndexAfterProvider + 1);
string resourceType = GetResourceType(resourceProvider, methodUrlPathAfterProvider);
string resourceType = GetResourceTypes(resourceProvider, methodUrlPathAfterProvider, createResourceMethod.Parameters)[0];

resourceDefinition.AddProperty("type", new JsonSchema()
{
Expand Down Expand Up @@ -397,8 +397,9 @@ public static bool IsCreateResourceMethod(Method method)
/// </summary>
/// <param name="resourceProvider"></param>
/// <param name="methodPathAfterProvider"></param>
/// <param name="createResourceMethodParameters"></param>
/// <returns></returns>
public static string GetResourceType(string resourceProvider, string methodPathAfterProvider)
public static string[] GetResourceTypes(string resourceProvider, string methodPathAfterProvider, List<Parameter> createResourceMethodParameters)
{
if (string.IsNullOrWhiteSpace(resourceProvider))
{
Expand All @@ -409,16 +410,63 @@ public static string GetResourceType(string resourceProvider, string methodPathA
throw new ArgumentException("methodPathAfterProvider cannot be null or whitespace", "methodPathAfterProvider");
}

List<string> resourceTypeParts = new List<string>();
resourceTypeParts.Add(resourceProvider);
List<string> resourceTypes = new List<string>();
resourceTypes.Add(resourceProvider);

string[] pathSegments = methodPathAfterProvider.Split(new char[] { '/' });
for (int i = 0; i < pathSegments.Length; i += 2)
{
resourceTypeParts.Add(pathSegments[i]);
string pathSegment = pathSegments[i];
if (pathSegment.StartsWith("{") && pathSegment.EndsWith("}"))
{
string parameterName = pathSegment.Substring(1, pathSegment.Length - 2);
Parameter parameter = createResourceMethodParameters.FirstOrDefault(methodParameter => methodParameter.Name == parameterName);
if (parameter == null)
{
string errorMessage = string.Format("Found undefined parameter reference {0} in create resource method \"{1}/{2}/{3}\".", pathSegment, resourceMethodPrefix, resourceProvider, methodPathAfterProvider);
throw new ArgumentException(errorMessage, "createResourceMethodParameters");
}

if (parameter.Type == null)
{
string errorMessage = string.Format("Parameter reference {0} has no defined type.", pathSegment);
throw new ArgumentException(errorMessage, "createResourceMethodParameters");
}

EnumType parameterType = parameter.Type as EnumType;
if (parameterType == null)
{
string errorMessage = string.Format("Parameter reference {0} is defined as a type other than an EnumType: {1}", pathSegment, parameter.Type.GetType().Name);
throw new ArgumentException(errorMessage, "createResourceMethodParameters");
}

if (parameterType.Values == null || parameterType.Values.Count == 0)
{
string errorMessage = string.Format("Parameter reference {0} is defined as an EnumType, but it doesn't have any specified values.", pathSegment);
throw new ArgumentException(errorMessage, "createResourceMethodParameters");
}

List<string> newResourceTypes = new List<string>();
foreach (string resourceType in resourceTypes)
{
foreach (EnumValue parameterValue in parameterType.Values)
{
newResourceTypes.Add(string.Join("/", resourceType, parameterValue.Name));
}
}

resourceTypes = newResourceTypes;
}
else
{
for (int j = 0; j < resourceTypes.Count; ++j)
{
resourceTypes[j] = string.Join("/", resourceTypes[j], pathSegment);
}
}
}

return string.Join("/", resourceTypeParts);
return resourceTypes.ToArray();
}
}
}

0 comments on commit 3f84226

Please sign in to comment.