Skip to content

Commit

Permalink
Use plural resource name
Browse files Browse the repository at this point in the history
  • Loading branch information
simpat-adam committed Jul 19, 2024
1 parent 82caf1e commit 867d22b
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ public class Given_A_Sample_ApiSchema() : DependencyCalculatorTests
},
"projectSchemas": {
"ed-fi": {
"resourceNameMapping": {
"AbsenceEventCategory": "absenceEventCategoryDescriptors"
},
"resourceSchemas": {
"absenceEventCategoryDescriptors": {
"documentPathsMapping": {
},
"isSchoolYearEnumeration": false,
"resourceName": "AbsenceEventCategoryDescriptor"
}
}
Expand All @@ -42,7 +46,7 @@ public class Given_A_Sample_ApiSchema() : DependencyCalculatorTests
"""
[
{
"resource": "/ed-fi/absenceEventCategoryDescriptor",
"resource": "/ed-fi/absenceEventCategoryDescriptors",
"order": 1,
"operations": [
"Create",
Expand Down Expand Up @@ -84,11 +88,17 @@ public class Given_A_Sample_ApiSchema_With_Subclass_Resources() : DependencyCalc
},
"projectSchemas": {
"ed-fi": {
"resourceNameMapping": {
"EducationOrganizationCategory": "educationOrganizationCategoryDescriptors",
"LocalEducationAgency": "localEducationAgencies",
"School": "schools"
},
"resourceSchemas": {
"educationOrganizationCategoryDescriptors": {
"documentPathsMapping": {
},
"isDescriptor": true,
"isDescriptor": true,
"isSchoolYearEnumeration": false,
"isSubclass": false,
"resourceName": "EducationOrganizationCategoryDescriptor"
},
Expand All @@ -106,7 +116,8 @@ public class Given_A_Sample_ApiSchema_With_Subclass_Resources() : DependencyCalc
"resourceName": "LocalEducationAgency"
}
},
"isSubclass": true,
"isSubclass": true,
"isSchoolYearEnumeration": false,
"resourceName": "LocalEducationAgency",
"subclassType": "domainEntity",
"superclassProjectName": "Ed-Fi",
Expand All @@ -131,6 +142,7 @@ public class Given_A_Sample_ApiSchema_With_Subclass_Resources() : DependencyCalc
}
},
"isSubclass": true,
"isSchoolYearEnumeration": false,
"resourceName": "School",
"subclassType": "domainEntity",
"superclassProjectName": "Ed-Fi",
Expand All @@ -146,23 +158,23 @@ public class Given_A_Sample_ApiSchema_With_Subclass_Resources() : DependencyCalc
"""
[
{
"resource": "/ed-fi/educationOrganizationCategoryDescriptor",
"resource": "/ed-fi/educationOrganizationCategoryDescriptors",
"order": 1,
"operations": [
"Create",
"Update"
]
},
{
"resource": "/ed-fi/localEducationAgency",
"resource": "/ed-fi/localEducationAgencies",
"order": 2,
"operations": [
"Create",
"Update"
]
},
{
"resource": "/ed-fi/school",
"resource": "/ed-fi/schools",
"order": 3,
"operations": [
"Create",
Expand Down Expand Up @@ -192,6 +204,120 @@ public void It_should_calculate_dependencies()
}
}


[TestFixture]
public class Given_A_Sample_ApiSchema_With_Superclass_Reference() : DependencyCalculatorTests
{
private readonly string _sampleSchema =
"""
{
"projectNameMapping": {
"Ed-Fi": "ed-fi"
},
"projectSchemas": {
"ed-fi": {
"resourceNameMapping": {
"EducationOrganizationCategory": "educationOrganizationCategoryDescriptors",
"LocalEducationAgency": "localEducationAgencies",
"OpenStaffPosition": "openStaffPositions",
"School": "schools"
},
"resourceSchemas": {
"educationOrganizationCategoryDescriptors": {
"documentPathsMapping": {
},
"isDescriptor": true,
"isSchoolYearEnumeration": false,
"isSubclass": false,
"resourceName": "EducationOrganizationCategoryDescriptor"
},
"openStaffPositions": {
"allowIdentityUpdates": false,
"documentPathsMapping": {
"EducationOrganization": {
"isDescriptor": false,
"isReference": true,
"projectName": "Ed-Fi",
"resourceName": "EducationOrganization"
}
},
"isSubclass": false,
"isSchoolYearEnumeration": false,
"resourceName": "OpenStaffPosition"
},
"schools": {
"documentPathsMapping": {
"EducationOrganizationCategoryDescriptor": {
"isDescriptor": true,
"isReference": true,
"projectName": "Ed-Fi",
"resourceName": "EducationOrganizationCategoryDescriptor"
},
"LocalEducationAgency": {
"isReference": true,
"projectName": "Ed-Fi",
"resourceName": "LocalEducationAgency"
}
},
"isSubclass": true,
"isSchoolYearEnumeration": false,
"resourceName": "School"
}
}
}
}
}
""";

private readonly string _expectedDescriptor =
"""
[
{
"resource": "/ed-fi/educationOrganizationCategoryDescriptors",
"order": 1,
"operations": [
"Create",
"Update"
]
},
{
"resource": "/ed-fi/schools",
"order": 2,
"operations": [
"Create",
"Update"
]
},
{
"resource": "/ed-fi/openStaffPositions",
"order": 3,
"operations": [
"Create",
"Update"
]
}
]
""";

[SetUp]
public void Setup()
{
var logger = NullLogger<ApiSchemaSchemaProvider>.Instance;
_dependencyCalculator = new DependencyCalculator(JsonNode.Parse(_sampleSchema)!, logger);
}

[Test]
public void It_should_calculate_dependencies()
{
var dependencies = _dependencyCalculator!.GetDependencies();
dependencies.Should().NotBeEmpty();

var expectedDependencies = JsonNode.Parse(_expectedDescriptor)!.AsArray();
dependencies!.Should().BeEquivalentTo(expectedDependencies!, options => options
.WithoutStrictOrdering()
.IgnoringCyclicReferences());
}
}
[TestFixture]
public class Given_A_Sample_ApiSchema_Missing_ProjectSchemas() : DependencyCalculatorTests
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,44 @@ public JsonArray GetDependencies()
var resourceSchemas = projectSchemaNode["resourceSchemas"]?.AsObject().Select(x => new ResourceSchema(x.Value!)).ToList()!;

Dictionary<string, List<string>> dependencies =
resourceSchemas.ToDictionary(rs => rs.ResourceName.Value, rs => new List<string>());
resourceSchemas
.Where(rs => !rs.IsSchoolYearEnumeration)
.ToDictionary(rs => rs.ResourceName.Value, rs => rs.DocumentPaths.Where(d => d.IsReference).Select(d => d.ResourceName.Value).ToList());

foreach (var resourceSchema in resourceSchemas)
{
foreach (var documentPath in resourceSchema.DocumentPaths.Where(d => d.IsReference))
{
dependencies[resourceSchema.ResourceName.Value].Add(documentPath.ResourceName.Value);
}
}

List<KeyValuePair<string, int>> orderedResources = [];
Dictionary<string, int> orderedResources = dependencies.ToDictionary(d => d.Key, _ => 0);
Dictionary<string, int> visitedResources = [];
foreach (var dependency in dependencies.OrderBy(d => d.Value.Count).ThenBy(d => d.Key).Select(d => d.Key))
{
RecursivelyDetermineDependencies(dependency, 0);
}

string ResourceNameMapping(string resourceName)
{
var resourceNameNode = projectSchemaNode["resourceNameMapping"];
if (resourceNameNode == null)
{
throw new InvalidOperationException("ResourceNameMapping missing");
}

if (resourceName.EndsWith("Descriptor"))
{
resourceName = resourceName.Replace("Descriptor", string.Empty);
}

var resourceNode = resourceNameNode[resourceName];
if (resourceNode == null)
{
throw new InvalidOperationException($"No resource name mapping for {resourceName}");
}

return resourceNode.GetValue<string>();
}

foreach (var orderedResource in orderedResources.OrderBy(o => o.Value).ThenBy(o => o.Key))
{
dependenciesJsonArray.Add(new { resource = $"/{projectSchemaNode!.GetPropertyName()}/{orderedResource.Key.First().ToString().ToLowerInvariant()}{orderedResource.Key.Substring(1)}", order = orderedResource.Value, operations = new[] { "Create", "Update" } });
string resourceName = ResourceNameMapping(orderedResource.Key);

dependenciesJsonArray.Add(new { resource = $"/{projectSchemaNode!.GetPropertyName()}/{resourceName}", order = orderedResource.Value, operations = new[] { "Create", "Update" } });
}

int RecursivelyDetermineDependencies(string resourceName, int depth)
Expand Down Expand Up @@ -80,7 +98,8 @@ int RecursivelyDetermineDependencies(string resourceName, int depth)
maxDepth = level;
}
}
orderedResources.Add(new KeyValuePair<string, int>(resourceName, maxDepth + 1));

orderedResources[resourceName] = maxDepth + 1;
visitedResources[resourceName] = maxDepth + 1;
}

Expand Down

0 comments on commit 867d22b

Please sign in to comment.