Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit fadfae6

Browse files
committed
fix: DTOSS-9177 - unit tests for ValidationRunner
1 parent a1dc97a commit fadfae6

File tree

4 files changed

+244
-24
lines changed

4 files changed

+244
-24
lines changed

src/ServiceLayer.Mesh/FileTypes/NbssAppointmentEvents/Validation/ValidationRunner.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ public IList<ValidationError> Validate(ParsedFile file)
1111
{
1212
var errors = new List<ValidationError>();
1313

14+
foreach (var validator in fileValidators)
15+
{
16+
errors.AddRange(validator.Validate(file));
17+
}
18+
1419
foreach (var dataRecord in file.DataRecords)
1520
{
1621
foreach (var recordValidator in recordValidators)
@@ -19,11 +24,6 @@ public IList<ValidationError> Validate(ParsedFile file)
1924
}
2025
}
2126

22-
foreach (var validator in fileValidators)
23-
{
24-
errors.AddRange(validator.Validate(file));
25-
}
26-
2727
return errors;
2828
}
2929
}
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
using Moq;
2+
using ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents.Models;
3+
using ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents.Validation;
4+
5+
namespace ServiceLayer.Mesh.Tests.FileTypes.NbssAppointmentEvents.Validation;
6+
7+
public class ValidationRunnerTests
8+
{
9+
[Fact]
10+
public void Validate_FileAndRecordValidatorsReturnErrors_ReturnsAllErrors()
11+
{
12+
// Arrange
13+
var file = new ParsedFile
14+
{
15+
DataRecords = [new FileDataRecord(), new FileDataRecord()]
16+
};
17+
18+
var fileValidationError1 = BuildValidationError(ValidationErrorScope.File);
19+
var fileValidationError2 = BuildValidationError(ValidationErrorScope.File);
20+
var fileValidationError3 = BuildValidationError(ValidationErrorScope.File);
21+
var recordValidationError1 = BuildValidationError(ValidationErrorScope.Record);
22+
var recordValidationError2 = BuildValidationError(ValidationErrorScope.Record);
23+
var recordValidationError3 = BuildValidationError(ValidationErrorScope.Record);
24+
25+
var expectedErrors = new List<ValidationError>
26+
{
27+
fileValidationError1, fileValidationError2, fileValidationError3,
28+
recordValidationError1, recordValidationError2, recordValidationError3,
29+
recordValidationError1, recordValidationError2, recordValidationError3,
30+
};
31+
32+
var fileValidator1 = new Mock<IFileValidator>();
33+
fileValidator1
34+
.Setup(v => v.Validate(file))
35+
.Returns([fileValidationError1, fileValidationError2]);
36+
37+
var fileValidator2 = new Mock<IFileValidator>();
38+
fileValidator2
39+
.Setup(v => v.Validate(file))
40+
.Returns([fileValidationError3]);
41+
42+
var recordValidator1 = new Mock<IRecordValidator>();
43+
recordValidator1
44+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
45+
.Returns([recordValidationError1]);
46+
47+
var recordValidator2 = new Mock<IRecordValidator>();
48+
recordValidator2
49+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
50+
.Returns([recordValidationError2, recordValidationError3]);
51+
52+
var runner = new ValidationRunner(
53+
[fileValidator1.Object, fileValidator2.Object],
54+
[recordValidator1.Object, recordValidator2.Object]);
55+
56+
// Act
57+
var results = runner.Validate(file);
58+
59+
// Assert
60+
Assert.Equal(expectedErrors, results, new ValidationErrorComparer());
61+
}
62+
63+
[Fact]
64+
public void Validate_OnlyRecordValidatorsReturnErrors_ReturnsAllErrors()
65+
{
66+
// Arrange
67+
var file = new ParsedFile
68+
{
69+
DataRecords = [new FileDataRecord(), new FileDataRecord()]
70+
};
71+
72+
var recordValidationError1 = BuildValidationError(ValidationErrorScope.Record);
73+
var recordValidationError2 = BuildValidationError(ValidationErrorScope.Record);
74+
var recordValidationError3 = BuildValidationError(ValidationErrorScope.Record);
75+
76+
var expectedErrors = new List<ValidationError>
77+
{
78+
recordValidationError1, recordValidationError2, recordValidationError3,
79+
recordValidationError1, recordValidationError2, recordValidationError3,
80+
};
81+
82+
var fileValidator1 = new Mock<IFileValidator>();
83+
fileValidator1
84+
.Setup(v => v.Validate(file))
85+
.Returns([]);
86+
87+
var fileValidator2 = new Mock<IFileValidator>();
88+
fileValidator2
89+
.Setup(v => v.Validate(file))
90+
.Returns([]);
91+
92+
var recordValidator1 = new Mock<IRecordValidator>();
93+
recordValidator1
94+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
95+
.Returns([recordValidationError1]);
96+
97+
var recordValidator2 = new Mock<IRecordValidator>();
98+
recordValidator2
99+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
100+
.Returns([recordValidationError2, recordValidationError3]);
101+
102+
var runner = new ValidationRunner(
103+
[fileValidator1.Object, fileValidator2.Object],
104+
[recordValidator1.Object, recordValidator2.Object]);
105+
106+
// Act
107+
var results = runner.Validate(file);
108+
109+
// Assert
110+
Assert.Equal(expectedErrors, results, new ValidationErrorComparer());
111+
}
112+
113+
[Fact]
114+
public void Validate_OnlyFileValidatorsReturnErrors_ReturnsAllErrors()
115+
{
116+
// Arrange
117+
var file = new ParsedFile
118+
{
119+
DataRecords = [new FileDataRecord(), new FileDataRecord()]
120+
};
121+
122+
var fileValidationError1 = BuildValidationError(ValidationErrorScope.File);
123+
var fileValidationError2 = BuildValidationError(ValidationErrorScope.File);
124+
var fileValidationError3 = BuildValidationError(ValidationErrorScope.File);
125+
126+
var expectedErrors = new List<ValidationError>
127+
{
128+
fileValidationError1, fileValidationError2, fileValidationError3
129+
};
130+
131+
var fileValidator1 = new Mock<IFileValidator>();
132+
fileValidator1
133+
.Setup(v => v.Validate(file))
134+
.Returns([fileValidationError1, fileValidationError2]);
135+
136+
var fileValidator2 = new Mock<IFileValidator>();
137+
fileValidator2
138+
.Setup(v => v.Validate(file))
139+
.Returns([fileValidationError3]);
140+
141+
var recordValidator1 = new Mock<IRecordValidator>();
142+
recordValidator1
143+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
144+
.Returns([]);
145+
146+
var recordValidator2 = new Mock<IRecordValidator>();
147+
recordValidator2
148+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
149+
.Returns([]);
150+
151+
var runner = new ValidationRunner(
152+
[fileValidator1.Object, fileValidator2.Object],
153+
[recordValidator1.Object, recordValidator2.Object]);
154+
155+
// Act
156+
var results = runner.Validate(file);
157+
158+
// Assert
159+
Assert.Equal(expectedErrors, results, new ValidationErrorComparer());
160+
}
161+
162+
[Fact]
163+
public void Validate_FileAndRecordValidatorsReturnNoErrors_ReturnsNoErrors()
164+
{
165+
// Arrange
166+
var file = new ParsedFile
167+
{
168+
DataRecords = [new FileDataRecord(), new FileDataRecord()]
169+
};
170+
171+
var fileValidator1 = new Mock<IFileValidator>();
172+
fileValidator1
173+
.Setup(v => v.Validate(file))
174+
.Returns([]);
175+
176+
var fileValidator2 = new Mock<IFileValidator>();
177+
fileValidator2
178+
.Setup(v => v.Validate(file))
179+
.Returns([]);
180+
181+
var recordValidator1 = new Mock<IRecordValidator>();
182+
recordValidator1
183+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
184+
.Returns([]);
185+
186+
var recordValidator2 = new Mock<IRecordValidator>();
187+
recordValidator2
188+
.Setup(v => v.Validate(It.IsAny<FileDataRecord>()))
189+
.Returns([]);
190+
191+
var runner = new ValidationRunner(
192+
[fileValidator1.Object, fileValidator2.Object],
193+
[recordValidator1.Object, recordValidator2.Object]);
194+
195+
// Act
196+
var results = runner.Validate(file);
197+
198+
// Assert
199+
Assert.Empty(results);
200+
}
201+
202+
private static ValidationError BuildValidationError(ValidationErrorScope scope)
203+
{
204+
var validationError = new ValidationError
205+
{
206+
Code = Guid.NewGuid().ToString(),
207+
Error = Guid.NewGuid().ToString(),
208+
Field = Guid.NewGuid().ToString(),
209+
Scope = scope
210+
};
211+
212+
if (scope == ValidationErrorScope.Record)
213+
{
214+
validationError.RowNumber = 1;
215+
}
216+
217+
return validationError;
218+
}
219+
}

tests/ServiceLayer.Mesh.Tests/Functions/FileTransformFunctionTests.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -205,23 +205,4 @@ private static List<ValidationError> DeserializeValidationErrorsFromMeshFile(Mes
205205
ValidationErrorJsonOptions
206206
) ?? [];
207207
}
208-
209-
private class ValidationErrorComparer : IEqualityComparer<ValidationError>
210-
{
211-
public bool Equals(ValidationError? x, ValidationError? y)
212-
{
213-
if (ReferenceEquals(x, y)) return true;
214-
if (x is null || y is null) return false;
215-
216-
return x.Field == y.Field &&
217-
x.Error == y.Error &&
218-
x.Code == y.Code &&
219-
x.RowNumber == y.RowNumber;
220-
}
221-
222-
public int GetHashCode(ValidationError obj)
223-
{
224-
return HashCode.Combine(obj.Field, obj.Error, obj.Code, obj.RowNumber);
225-
}
226-
}
227208
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace ServiceLayer.Mesh.Tests;
2+
3+
public class ValidationErrorComparer : IEqualityComparer<ValidationError>
4+
{
5+
public bool Equals(ValidationError? x, ValidationError? y)
6+
{
7+
if (ReferenceEquals(x, y)) return true;
8+
if (x is null || y is null) return false;
9+
10+
return x.Field == y.Field &&
11+
x.Error == y.Error &&
12+
x.Code == y.Code &&
13+
x.RowNumber == y.RowNumber;
14+
}
15+
16+
public int GetHashCode(ValidationError obj)
17+
{
18+
return HashCode.Combine(obj.Field, obj.Error, obj.Code, obj.RowNumber);
19+
}
20+
}

0 commit comments

Comments
 (0)