Skip to content

Commit

Permalink
Add validation for claim set name with white spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
CSR2017 committed Jan 7, 2025
1 parent 3d7a60c commit 1381edd
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: Apache-2.0
// Licensed to the Ed-Fi Alliance under one or more agreements.
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

namespace EdFi.DmsConfigurationService.DataModel.Infrastructure;

public static class ValidationConstants
{
public const string ClaimSetNameNoWhiteSpaceMessage = "Claim set name must not contain white spaces.";
public const string ClaimSetNameNoWhiteSpaceRegex = @"^[^\s]*$";
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System.Text.RegularExpressions;
using EdFi.DmsConfigurationService.DataModel.Infrastructure;
using FluentValidation;

namespace EdFi.DmsConfigurationService.DataModel.Model.Application;
Expand All @@ -20,6 +22,10 @@ public Validator()
{
RuleFor(a => a.ApplicationName).NotEmpty().MaximumLength(256);
RuleFor(a => a.ClaimSetName).NotEmpty().MaximumLength(256);
RuleFor(m => m.ClaimSetName)
.Matches(new Regex(ValidationConstants.ClaimSetNameNoWhiteSpaceRegex))
.When(m => !string.IsNullOrEmpty(m.ClaimSetName))
.WithMessage(ValidationConstants.ClaimSetNameNoWhiteSpaceMessage);
RuleForEach(a => a.EducationOrganizationIds).NotNull().GreaterThan(0);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System.Text.RegularExpressions;
using EdFi.DmsConfigurationService.DataModel.Infrastructure;
using FluentValidation;

namespace EdFi.DmsConfigurationService.DataModel.Model.Application;
Expand All @@ -22,6 +24,10 @@ public Validator()
RuleFor(a => a.Id).GreaterThan(0);
RuleFor(a => a.ApplicationName).NotEmpty().MaximumLength(256);
RuleFor(a => a.ClaimSetName).NotEmpty().MaximumLength(256);
RuleFor(m => m.ClaimSetName)
.Matches(new Regex(ValidationConstants.ClaimSetNameNoWhiteSpaceRegex))
.When(m => !string.IsNullOrEmpty(m.ClaimSetName))
.WithMessage(ValidationConstants.ClaimSetNameNoWhiteSpaceMessage);
RuleForEach(a => a.EducationOrganizationIds).NotNull().GreaterThan(0);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
// See the LICENSE and NOTICES files in the project root for more information.

using System.Text.RegularExpressions;
using EdFi.DmsConfigurationService.DataModel.Infrastructure;
using FluentValidation;

namespace EdFi.DmsConfigurationService.DataModel.Model.ClaimSets;
Expand All @@ -21,6 +23,11 @@ public ClaimSetCommandValidator(
.MaximumLength(256)
.WithMessage("The claim set name must be less than 256 characters.");

RuleFor(m => m.Name)
.Matches(new Regex(ValidationConstants.ClaimSetNameNoWhiteSpaceRegex))
.When(m => !string.IsNullOrEmpty(m.Name))
.WithMessage(ValidationConstants.ClaimSetNameNoWhiteSpaceMessage);

RuleFor(c => c.ResourceClaims)
.Cascade(CascadeMode.Stop)
.NotEmpty()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,26 @@ public async Task Should_return_bad_request()
}
""";

string invalidClaimSetName = """
{
"ApplicationName": "Application101",
"ClaimSetName": "ClaimSet name with white space",
"VendorId":1,
"EducationOrganizationIds": [255901]
}
""";

//Act
var addResponse = await client.PostAsync(
"/v2/applications",
new StringContent(invalidBody, Encoding.UTF8, "application/json")
);

var addResponseForInvalidClaimSetName = await client.PostAsync(
"/v2/applications",
new StringContent(invalidClaimSetName, Encoding.UTF8, "application/json")
);

//Assert
string addResponseContent = await addResponse.Content.ReadAsStringAsync();
var actualResponse = JsonNode.Parse(addResponseContent);
Expand Down Expand Up @@ -237,6 +251,37 @@ public async Task Should_return_bad_request()
);
addResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest);
JsonNode.DeepEquals(JsonNode.Parse(addResponseContent), expectedResponse).Should().Be(true);

string addResponseContentForInvalidClaimSetName =
await addResponseForInvalidClaimSetName.Content.ReadAsStringAsync();
var actualResponseForInvalidClaimSetName = JsonNode.Parse(
addResponseContentForInvalidClaimSetName
);
var expectedResponseForInvalidClaimSetName = JsonNode.Parse(
"""
{
"detail": "Data validation failed. See 'validationErrors' for details.",
"type": "urn:ed-fi:api:bad-request:data-validation-failed",
"title": "Data Validation Failed",
"status": 400,
"correlationId": "{correlationId}",
"validationErrors": {
"ClaimSetName": [
"Claim set name must not contain white spaces."
]
},
"errors": []
}
""".Replace(
"{correlationId}",
actualResponseForInvalidClaimSetName!["correlationId"]!.GetValue<string>()
)
);
addResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest);
JsonNode
.DeepEquals(actualResponseForInvalidClaimSetName, expectedResponseForInvalidClaimSetName)
.Should()
.Be(true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public async Task Should_return_success_responses()
new StringContent(
"""
{
"name":"Testing POST for ClaimSet"
"name":"Testing-POST-for-ClaimSet"
}
""",
Encoding.UTF8,
Expand All @@ -162,7 +162,7 @@ public async Task Should_return_success_responses()
"""
{
"id": 1,
"name": "Test 11",
"name": "Test-11",
"resourceClaims": [
{
"name": "Test ResourceClaim",
Expand All @@ -187,7 +187,7 @@ public async Task Should_return_success_responses()
"""
{
"originalId" : 1,
"name": "Test Copy"
"name": "Test-Copy"
}
""",
Encoding.UTF8,
Expand All @@ -200,7 +200,7 @@ public async Task Should_return_success_responses()
new StringContent(
"""
{
"name" : "Testing Import for ClaimSet",
"name" : "Testing-Import-for-ClaimSet",
"resourceClaims" : [
{
"name": "Test ResourceClaim",
Expand Down Expand Up @@ -248,6 +248,12 @@ public async Task Should_return_bad_request()
"name" : "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
}
""";
string claimSetNameWithWhiteSpace = """
{
"name" : "ClaimSet name with white space"
}
""";

string invalidPutBody = """
{
"id": 1,
Expand Down Expand Up @@ -285,6 +291,11 @@ public async Task Should_return_bad_request()
new StringContent(invalidInsertBody, Encoding.UTF8, "application/json")
);

var addResponseWithInvalidName = await client.PostAsync(
"/v2/claimSets",
new StringContent(claimSetNameWithWhiteSpace, Encoding.UTF8, "application/json")
);

var updateResponse = await client.PutAsync(
"/v2/claimSets/1",
new StringContent(invalidPutBody, Encoding.UTF8, "application/json")
Expand Down Expand Up @@ -319,6 +330,30 @@ public async Task Should_return_bad_request()
""".Replace("{correlationId}", actualPostResponse!["correlationId"]!.GetValue<string>())
);

var actualPostResponseForInvalidName = JsonNode.Parse(
await addResponseWithInvalidName.Content.ReadAsStringAsync()
);
var expectedPostResponseForInvalidName = JsonNode.Parse(
"""
{
"detail": "Data validation failed. See 'validationErrors' for details.",
"type": "urn:ed-fi:api:bad-request:data-validation-failed",
"title": "Data Validation Failed",
"status": 400,
"correlationId": "{correlationId}",
"validationErrors": {
"Name": [
"Claim set name must not contain white spaces."
]
},
"errors": []
}
""".Replace(
"{correlationId}",
actualPostResponseForInvalidName!["correlationId"]!.GetValue<string>()
)
);

var actualPutResponse = JsonNode.Parse(await updateResponse.Content.ReadAsStringAsync());
var expectedPutResponse = JsonNode.Parse(
"""
Expand Down Expand Up @@ -381,6 +416,12 @@ public async Task Should_return_bad_request()
addResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest);
JsonNode.DeepEquals(actualPostResponse, expectedPostResponse).Should().Be(true);

addResponseWithInvalidName.StatusCode.Should().Be(HttpStatusCode.BadRequest);
JsonNode
.DeepEquals(actualPostResponseForInvalidName, expectedPostResponseForInvalidName)
.Should()
.Be(true);

updateResponse.StatusCode.Should().Be(HttpStatusCode.BadRequest);
JsonNode.DeepEquals(actualPutResponse, expectedPutResponse).Should().Be(true);

Expand All @@ -396,6 +437,7 @@ public async Task Should_return_bad_request_mismatch_id()
{
//Arrange
using var client = SetUpClient();
A.CallTo(() => _dataProvider.GetActions()).Returns(["Create", "Read", "Update", "Delete"]);

//Act
var updateResponse = await client.PutAsync(
Expand All @@ -404,7 +446,7 @@ public async Task Should_return_bad_request_mismatch_id()
"""
{
"id": 2,
"name": "Test 11",
"name": "Test-11",
"resourceClaims": [
{
"name": "Test ResourceClaim",
Expand Down Expand Up @@ -468,7 +510,7 @@ public async Task Should_return_not_found_responses()
"""
{
"id": 1,
"name": "Test 11",
"name": "Test-11",
"resourceClaims": [
{
"name": "Test ResourceClaim",
Expand All @@ -493,7 +535,7 @@ public async Task Should_return_not_found_responses()
"""
{
"originalId" : 1,
"name": "Test Copy"
"name": "Test-Copy"
}
""",
Encoding.UTF8,
Expand Down Expand Up @@ -556,7 +598,7 @@ public async Task Should_return_internal_server_error_response()
new StringContent(
"""
{
"name":"Testing POST for ClaimSet"
"name":"Testing-POST-for-ClaimSet"
}
""",
Encoding.UTF8,
Expand All @@ -572,7 +614,7 @@ public async Task Should_return_internal_server_error_response()
"""
{
"id": 1,
"name": "Test 11",
"name": "Test-11",
"resourceClaims": [
{
"name": "Test ResourceClaim",
Expand All @@ -597,7 +639,7 @@ public async Task Should_return_internal_server_error_response()
"""
{
"originalId" : 1,
"name": "Test Copy"
"name": "Test-Copy"
}
""",
Encoding.UTF8,
Expand All @@ -610,7 +652,7 @@ public async Task Should_return_internal_server_error_response()
new StringContent(
"""
{
"name" : "Testing Import for ClaimSet",
"name" : "Testing-Import-for-ClaimSet",
"resourceClaims" : [
{
"name": "Test ResourceClaim",
Expand Down Expand Up @@ -668,7 +710,7 @@ public async Task Should_return_duplicate_claimSetName_error_message_on_insert()
new StringContent(
"""
{
"name":"Testing POST for ClaimSet"
"name":"Testing-POST-for-ClaimSet"
}
""",
Encoding.UTF8,
Expand All @@ -678,7 +720,7 @@ public async Task Should_return_duplicate_claimSetName_error_message_on_insert()

string importBody = """
{
"name" : "Test Duplicate",
"name" : "Test-Duplicate",
"resourceClaims" : [
{
"name": "Test ResourceClaim",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,35 @@ Feature: Applications endpoints
}
"""

Scenario: 15 Verify validation invalid EducationOrganizationId
Scenario: 15 Verify validation invalid claim set name with white space
When a POST request is made to "/v2/applications" with
"""
{
"vendorId": 9999,
"applicationName": "Test 1234",
"claimSetName": "Claim set name with white space",
"educationOrganizationIds": [1, 2, 3]
}
"""
Then it should respond with 400
And the response body is
"""
{
"detail": "Data validation failed. See 'validationErrors' for details.",
"type": "urn:ed-fi:api:bad-request:data-validation-failed",
"title": "Data Validation Failed",
"status": 400,
"correlationId": "0HN8RI9E3O45G:00000004",
"validationErrors": {
"ClaimSetName": [
"Claim set name must not contain white spaces."
]
},
"errors": []
}
"""

Scenario: 16 Verify validation invalid EducationOrganizationId
When a POST request is made to "/v2/applications" with
"""
{
Expand Down

0 comments on commit 1381edd

Please sign in to comment.