Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ public IList<ValidationError> Validate(ParsedFile file)
{
var errors = new List<ValidationError>();

foreach (var validator in fileValidators)
{
errors.AddRange(validator.Validate(file));
}

foreach (var dataRecord in file.DataRecords)
{
foreach (var recordValidator in recordValidators)
Expand All @@ -19,11 +24,6 @@ public IList<ValidationError> Validate(ParsedFile file)
}
}

foreach (var validator in fileValidators)
{
errors.AddRange(validator.Validate(file));
}

return errors;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
using Moq;
using ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents.Models;
using ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents.Validation;

namespace ServiceLayer.Mesh.Tests.FileTypes.NbssAppointmentEvents.Validation;

public class ValidationRunnerTests
{
[Fact]
public void Validate_FileAndRecordValidatorsReturnErrors_ReturnsAllErrors()
{
// Arrange
var file = new ParsedFile
{
DataRecords = [new FileDataRecord(), new FileDataRecord()]
};

var fileValidationError1 = BuildValidationError(ValidationErrorScope.File);
var fileValidationError2 = BuildValidationError(ValidationErrorScope.File);
var fileValidationError3 = BuildValidationError(ValidationErrorScope.File);
var recordValidationError1 = BuildValidationError(ValidationErrorScope.Record);
var recordValidationError2 = BuildValidationError(ValidationErrorScope.Record);
var recordValidationError3 = BuildValidationError(ValidationErrorScope.Record);

var expectedErrors = new List<ValidationError>
{
fileValidationError1, fileValidationError2, fileValidationError3,
recordValidationError1, recordValidationError2, recordValidationError3,
recordValidationError1, recordValidationError2, recordValidationError3,
};

var fileValidator1 = new Mock<IFileValidator>();
fileValidator1
.Setup(v => v.Validate(file))
.Returns([fileValidationError1, fileValidationError2]);

var fileValidator2 = new Mock<IFileValidator>();
fileValidator2
.Setup(v => v.Validate(file))
.Returns([fileValidationError3]);

var recordValidator1 = new Mock<IRecordValidator>();
recordValidator1
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([recordValidationError1]);

var recordValidator2 = new Mock<IRecordValidator>();
recordValidator2
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([recordValidationError2, recordValidationError3]);

var runner = new ValidationRunner(
[fileValidator1.Object, fileValidator2.Object],
[recordValidator1.Object, recordValidator2.Object]);

// Act
var results = runner.Validate(file);

// Assert
Assert.Equal(expectedErrors, results, new ValidationErrorComparer());
}

[Fact]
public void Validate_OnlyRecordValidatorsReturnErrors_ReturnsAllErrors()
{
// Arrange
var file = new ParsedFile
{
DataRecords = [new FileDataRecord(), new FileDataRecord()]
};

var recordValidationError1 = BuildValidationError(ValidationErrorScope.Record);
var recordValidationError2 = BuildValidationError(ValidationErrorScope.Record);
var recordValidationError3 = BuildValidationError(ValidationErrorScope.Record);

var expectedErrors = new List<ValidationError>
{
recordValidationError1, recordValidationError2, recordValidationError3,
recordValidationError1, recordValidationError2, recordValidationError3,
};

var fileValidator1 = new Mock<IFileValidator>();
fileValidator1
.Setup(v => v.Validate(file))
.Returns([]);

var fileValidator2 = new Mock<IFileValidator>();
fileValidator2
.Setup(v => v.Validate(file))
.Returns([]);

var recordValidator1 = new Mock<IRecordValidator>();
recordValidator1
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([recordValidationError1]);

var recordValidator2 = new Mock<IRecordValidator>();
recordValidator2
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([recordValidationError2, recordValidationError3]);

var runner = new ValidationRunner(
[fileValidator1.Object, fileValidator2.Object],
[recordValidator1.Object, recordValidator2.Object]);

// Act
var results = runner.Validate(file);

// Assert
Assert.Equal(expectedErrors, results, new ValidationErrorComparer());
}

[Fact]
public void Validate_OnlyFileValidatorsReturnErrors_ReturnsAllErrors()
{
// Arrange
var file = new ParsedFile
{
DataRecords = [new FileDataRecord(), new FileDataRecord()]
};

var fileValidationError1 = BuildValidationError(ValidationErrorScope.File);
var fileValidationError2 = BuildValidationError(ValidationErrorScope.File);
var fileValidationError3 = BuildValidationError(ValidationErrorScope.File);

var expectedErrors = new List<ValidationError>
{
fileValidationError1, fileValidationError2, fileValidationError3
};

var fileValidator1 = new Mock<IFileValidator>();
fileValidator1
.Setup(v => v.Validate(file))
.Returns([fileValidationError1, fileValidationError2]);

var fileValidator2 = new Mock<IFileValidator>();
fileValidator2
.Setup(v => v.Validate(file))
.Returns([fileValidationError3]);

var recordValidator1 = new Mock<IRecordValidator>();
recordValidator1
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([]);

var recordValidator2 = new Mock<IRecordValidator>();
recordValidator2
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([]);

var runner = new ValidationRunner(
[fileValidator1.Object, fileValidator2.Object],
[recordValidator1.Object, recordValidator2.Object]);

// Act
var results = runner.Validate(file);

// Assert
Assert.Equal(expectedErrors, results, new ValidationErrorComparer());
}

[Fact]
public void Validate_FileAndRecordValidatorsReturnNoErrors_ReturnsNoErrors()
{
// Arrange
var file = new ParsedFile
{
DataRecords = [new FileDataRecord(), new FileDataRecord()]
};

var fileValidator1 = new Mock<IFileValidator>();
fileValidator1
.Setup(v => v.Validate(file))
.Returns([]);

var fileValidator2 = new Mock<IFileValidator>();
fileValidator2
.Setup(v => v.Validate(file))
.Returns([]);

var recordValidator1 = new Mock<IRecordValidator>();
recordValidator1
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([]);

var recordValidator2 = new Mock<IRecordValidator>();
recordValidator2
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
.Returns([]);

var runner = new ValidationRunner(
[fileValidator1.Object, fileValidator2.Object],
[recordValidator1.Object, recordValidator2.Object]);

// Act
var results = runner.Validate(file);

// Assert
Assert.Empty(results);
}

private static ValidationError BuildValidationError(ValidationErrorScope scope)
{
var validationError = new ValidationError
{
Code = Guid.NewGuid().ToString(),
Error = Guid.NewGuid().ToString(),
Field = Guid.NewGuid().ToString(),
Scope = scope
};

if (scope == ValidationErrorScope.Record)
{
validationError.RowNumber = 1;
}

return validationError;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,23 +205,4 @@ private static List<ValidationError> DeserializeValidationErrorsFromMeshFile(Mes
ValidationErrorJsonOptions
) ?? [];
}

private class ValidationErrorComparer : IEqualityComparer<ValidationError>
{
public bool Equals(ValidationError? x, ValidationError? y)
{
if (ReferenceEquals(x, y)) return true;
if (x is null || y is null) return false;

return x.Field == y.Field &&
x.Error == y.Error &&
x.Code == y.Code &&
x.RowNumber == y.RowNumber;
}

public int GetHashCode(ValidationError obj)
{
return HashCode.Combine(obj.Field, obj.Error, obj.Code, obj.RowNumber);
}
}
}
20 changes: 20 additions & 0 deletions tests/ServiceLayer.Mesh.Tests/ValidationErrorComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace ServiceLayer.Mesh.Tests;

public class ValidationErrorComparer : IEqualityComparer<ValidationError>
{
public bool Equals(ValidationError? x, ValidationError? y)
{
if (ReferenceEquals(x, y)) return true;
if (x is null || y is null) return false;

return x.Field == y.Field &&
x.Error == y.Error &&
x.Code == y.Code &&
x.RowNumber == y.RowNumber;
}

public int GetHashCode(ValidationError obj)
{
return HashCode.Combine(obj.Field, obj.Error, obj.Code, obj.RowNumber);
}
}
Loading