Skip to content

Commit e14c3d0

Browse files
add/fix unit tests
1 parent 556d727 commit e14c3d0

7 files changed

Lines changed: 819 additions & 40 deletions

File tree

DotNet/DataAcquisition.Domain/Application/Models/Http/QueryPlanApiModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ public class QueryPlanApiModel : IValidatableObject
3535
[DataMember]
3636
[Required(ErrorMessage = "InitialQueries is required.")]
3737
[MinDictionaryCount(1, ErrorMessage = "InitialQueries must contain at least one query configuration.")]
38-
[ValidateQueryConfigDictionary]
38+
[ValidateQueryPlanConfigDictionary]
3939
public Dictionary<string, IQueryConfig> InitialQueries { get; set; } = new();
4040

4141
[DataMember]
4242
[Required(ErrorMessage = "SupplementalQueries is required.")]
4343
[MinDictionaryCount(1, ErrorMessage = "SupplementalQueries must contain at least one query configuration.")]
44-
[ValidateQueryConfigDictionary]
44+
[ValidateQueryPlanConfigDictionary]
4545
public Dictionary<string, IQueryConfig> SupplementalQueries { get; set; } = new();
4646

4747
[IgnoreDataMember, JsonIgnore]

DotNet/DataAcquisition.Domain/Application/Validators/QueryPlanValidator.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,20 @@ private void ValidateResourceIdsParameter(
345345
result.Errors.Add($"{prefix}: Resource value '{parameter.Resource}' is not a valid FHIR ResourceType.");
346346
}
347347

348-
348+
if (!string.IsNullOrWhiteSpace(parameter.Paged))
349+
{
349350
if (!int.TryParse(parameter.Paged, out int pagedVal))
350351
{
351352
result.IsValid = false;
352353
result.Errors.Add($"{prefix}: Paged value '{parameter.Paged}' is not a valid int.");
353354
}
354-
355+
else if (pagedVal < 0)
356+
{
357+
result.IsValid = false;
358+
result.Errors.Add($"{prefix}: Paged value cannot be negative.");
359+
}
360+
}
361+
355362
}
356363

357364
private void ValidateParameterName(
@@ -418,6 +425,7 @@ private void ValidateReferenceQueryConfig(
418425
result.Errors.Add($"{prefix}: OperationType value '{config.OperationType}' is not a valid OperationType enum value.");
419426
}
420427

428+
421429
// Validate Paged value
422430
if (config.Paged < 0)
423431
{

DotNet/DataAcquisition.Domain/Infrastructure/Attributes/ValidateQueryPlanConfigDictionaryAttribute.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace LantanaGroup.Link.DataAcquisition.Domain.Application.Attributes;
99
/// Validates that a dictionary of IQueryConfig contains valid entries with proper structure
1010
/// </summary>
1111
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
12-
public class ValidateQueryConfigDictionaryAttribute : ValidationAttribute
12+
public class ValidateQueryPlanConfigDictionaryAttribute : ValidationAttribute
1313
{
1414
public override bool RequiresValidationContext => true;
1515

@@ -123,8 +123,8 @@ private void ValidateParameterQueryConfig(ParameterQueryConfig config, string ke
123123
errors.Add($"Key '{key}': ResourceIdsParameter at index {i} must have a Resource.");
124124
if (string.IsNullOrWhiteSpace(resourceIds.Paged))
125125
errors.Add($"Key '{key}': ResourceIdsParameter at index {i} must have a Paged value.");
126-
else if (!string.IsNullOrWhiteSpace(resourceIds.Paged) && !int.TryParse(resourceIds.Paged, out _))
127-
errors.Add($"Key '{key}': ResourceIdsParameter at index {i} has invalid Paged value (must be 'true' or 'false').");
126+
else if (!int.TryParse(resourceIds.Paged, out _))
127+
errors.Add($"Key '{key}': ResourceIdsParameter at index {i} has invalid Paged value (must be a valid integer).");
128128
break;
129129
}
130130
}

DotNet/DataAcquisition.Domain/Infrastructure/Models/QueryConfig/Parameter/ResourceIdsParameter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ public class ResourceIdsParameter : IParameter
77
public ParameterType ParameterType { get; set; } = ParameterType.ResourceIds;
88
public string Name { get; set; }
99
public string Resource { get; set; }
10-
public string Paged { get; set; }
10+
public string Paged { get; set; } = "100";
1111
}

DotNet/DataAcquisition.Domain/Infrastructure/Models/QueryConfig/ReferenceQueryConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public class ReferenceQueryConfig : IQueryConfig
88
public QueryConfigType QueryConfigType { get; set; } = QueryConfigType.Reference;
99
public string ResourceType { get; set; }
1010
public OperationType OperationType { get; set; } = OperationType.Search;
11-
public int Paged { get; set; }
11+
public int Paged { get; set; } = 100;
1212

1313
public ReferenceQueryConfig()
1414
{

DotNet/ServiceTests/IntegrationTests/DataAcquisition/Managers/QueryPlanManagerTests.cs

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using LantanaGroup.Link.DataAcquisition.Domain.Application.Managers;
44
using LantanaGroup.Link.DataAcquisition.Domain.Application.Models.Exceptions;
55
using LantanaGroup.Link.DataAcquisition.Domain.Application.Queries;
6+
using LantanaGroup.Link.DataAcquisition.Domain.Application.Validators;
67
using LantanaGroup.Link.DataAcquisition.Domain.Infrastructure;
78
using LantanaGroup.Link.DataAcquisition.Domain.Infrastructure.Context;
89
using LantanaGroup.Link.DataAcquisition.Domain.Infrastructure.Entities;
@@ -33,7 +34,8 @@ private IQueryPlanManager CreateManager(IServiceScope scope)
3334
{
3435
var logger = new Mock<ILogger<QueryPlanManager>>().Object;
3536
var database = scope.ServiceProvider.GetRequiredService<IDatabase>();
36-
return new QueryPlanManager(database, logger);
37+
IQueryPlanValidator validator = new Mock<QueryPlanValidator>().Object;
38+
return new QueryPlanManager(database, logger, validator);
3739
}
3840

3941
[Fact]
@@ -91,7 +93,7 @@ public async Task AddAsync_InvalidInitialQueryOrder_ThrowsIncorrectQueryPlanOrde
9193
var model = CreateInvalidOrderCreateQueryPlanModel(initialInvalid: true, supplementalInvalid: false);
9294

9395
// Act & Assert
94-
var ex = await Assert.ThrowsAsync<IncorrectQueryPlanOrderException>(() => manager.AddAsync(model));
96+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.AddAsync(model));
9597
Assert.Contains("InitialQueries", ex.Message);
9698
}
9799

@@ -104,7 +106,7 @@ public async Task AddAsync_InvalidSupplementalQueryOrder_ThrowsIncorrectQueryPla
104106
var model = CreateInvalidOrderCreateQueryPlanModel(initialInvalid: false, supplementalInvalid: true);
105107

106108
// Act & Assert
107-
var ex = await Assert.ThrowsAsync<IncorrectQueryPlanOrderException>(() => manager.AddAsync(model));
109+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.AddAsync(model));
108110
Assert.Contains("SupplementalQueries", ex.Message);
109111
}
110112

@@ -143,7 +145,7 @@ public async Task AddAsync_AllReferenceQueries_Valid()
143145
}
144146

145147
[Fact]
146-
public async Task AddAsync_EmptyQueries_Valid()
148+
public async Task AddAsync_EmptyInitialAndSupplementalQueries_ThrowsBadRequestException()
147149
{
148150
// Arrange
149151
using var scope = _fixture.ServiceProvider.CreateScope();
@@ -152,13 +154,11 @@ public async Task AddAsync_EmptyQueries_Valid()
152154
model.InitialQueries = new Dictionary<string, IQueryConfig>();
153155
model.SupplementalQueries = new Dictionary<string, IQueryConfig>();
154156

155-
// Act
156-
var result = await manager.AddAsync(model);
157+
// Act & Assert
158+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.AddAsync(model));
157159

158-
// Assert
159-
Assert.NotNull(result);
160-
Assert.Empty(result.InitialQueries);
161-
Assert.Empty(result.SupplementalQueries);
160+
Assert.Contains("InitialQueries cannot be null or empty", ex.Message);
161+
Assert.Contains("SupplementalQueries cannot be null or empty", ex.Message);
162162
}
163163

164164
[Fact]
@@ -171,8 +171,7 @@ public async Task AddAsync_NullInitialQueries_ThrowsDbUpdateException()
171171
model.InitialQueries = null;
172172

173173
// Act & Assert
174-
var ex = await Assert.ThrowsAsync<DbUpdateException>(() => manager.AddAsync(model));
175-
Assert.Contains("NOT NULL constraint failed: queryPlan.InitialQueries", ex.InnerException.Message);
174+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.AddAsync(model));
176175
}
177176

178177
[Fact]
@@ -185,8 +184,7 @@ public async Task AddAsync_NullSupplementalQueries_ThrowsDbUpdateException()
185184
model.SupplementalQueries = null;
186185

187186
// Act & Assert
188-
var ex = await Assert.ThrowsAsync<DbUpdateException>(() => manager.AddAsync(model));
189-
Assert.Contains("NOT NULL constraint failed: queryPlan.SupplementalQueries", ex.InnerException.Message);
187+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.AddAsync(model));
190188
}
191189

192190
[Fact]
@@ -260,7 +258,7 @@ public async Task UpdateAsync_InvalidInitialQueryOrder_ThrowsIncorrectQueryPlanO
260258
var model = CreateInvalidOrderUpdateQueryPlanModel(initialInvalid: true, supplementalInvalid: false);
261259

262260
// Act & Assert
263-
var ex = await Assert.ThrowsAsync<IncorrectQueryPlanOrderException>(() => manager.UpdateAsync(model));
261+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.UpdateAsync(model));
264262
Assert.Contains("InitialQueries", ex.Message);
265263
}
266264

@@ -273,7 +271,7 @@ public async Task UpdateAsync_InvalidSupplementalQueryOrder_ThrowsIncorrectQuery
273271
var model = CreateInvalidOrderUpdateQueryPlanModel(initialInvalid: false, supplementalInvalid: true);
274272

275273
// Act & Assert
276-
var ex = await Assert.ThrowsAsync<IncorrectQueryPlanOrderException>(() => manager.UpdateAsync(model));
274+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.UpdateAsync(model));
277275
Assert.Contains("SupplementalQueries", ex.Message);
278276
}
279277

@@ -291,7 +289,7 @@ public async Task UpdateAsync_NotFound_ThrowsNotFoundException()
291289
var model = CreateValidUpdateQueryPlanModel();
292290

293291
// Act & Assert
294-
await Assert.ThrowsAsync<NotFoundException>(() => manager.UpdateAsync(model));
292+
await Assert.ThrowsAsync<BadRequestException>(() => manager.UpdateAsync(model));
295293
}
296294

297295
[Fact]
@@ -367,7 +365,7 @@ public async Task UpdateAsync_AllReferenceQueries_Valid()
367365
}
368366

369367
[Fact]
370-
public async Task UpdateAsync_EmptyQueries_Valid()
368+
public async Task UpdateAsync_EmptyQueries_Invalid()
371369
{
372370
// Arrange
373371
using var scope = _fixture.ServiceProvider.CreateScope();
@@ -396,12 +394,7 @@ public async Task UpdateAsync_EmptyQueries_Valid()
396394
model.SupplementalQueries = new Dictionary<string, IQueryConfig>();
397395

398396
// Act
399-
var result = await manager.UpdateAsync(model);
400-
401-
// Assert
402-
Assert.NotNull(result);
403-
Assert.Empty(result.InitialQueries);
404-
Assert.Empty(result.SupplementalQueries);
397+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.UpdateAsync(model));
405398
}
406399

407400
[Fact]
@@ -433,8 +426,7 @@ public async Task UpdateAsync_NullInitialQueries_ThrowsDbUpdateException()
433426
model.InitialQueries = null;
434427

435428
// Act & Assert
436-
var ex = await Assert.ThrowsAsync<DbUpdateException>(() => manager.UpdateAsync(model));
437-
Assert.Contains("NOT NULL constraint failed: queryPlan.InitialQueries", ex.InnerException.Message);
429+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.UpdateAsync(model));
438430
}
439431

440432
[Fact]
@@ -466,8 +458,7 @@ public async Task UpdateAsync_NullSupplementalQueries_ThrowsDbUpdateException()
466458
model.SupplementalQueries = null;
467459

468460
// Act & Assert
469-
var ex = await Assert.ThrowsAsync<DbUpdateException>(() => manager.UpdateAsync(model));
470-
Assert.Contains("NOT NULL constraint failed: queryPlan.SupplementalQueries", ex.InnerException.Message);
461+
var ex = await Assert.ThrowsAsync<BadRequestException>(() => manager.UpdateAsync(model));
471462
}
472463

473464
[Fact]
@@ -666,8 +657,37 @@ private CreateQueryPlanModel CreateAllParameterCreateQueryPlanModel()
666657
var model = CreateValidCreateQueryPlanModel();
667658
model.InitialQueries = new Dictionary<string, IQueryConfig>
668659
{
669-
{ "1", new ParameterQueryConfig { ResourceType = "Patient", Parameters = new List<IParameter> { new LiteralParameter { Name = "id", Literal = "123" } } } },
670-
{ "2", new ParameterQueryConfig { ResourceType = "Encounter", Parameters = new List<IParameter> { new ResourceIdsParameter { Name = "patient", Resource = "Patient" } } } }
660+
{
661+
"1",
662+
new ParameterQueryConfig
663+
{
664+
ResourceType = "Patient",
665+
Parameters = new List<IParameter>
666+
{
667+
new LiteralParameter
668+
{
669+
Name = "id",
670+
Literal = "123"
671+
}
672+
}
673+
}
674+
},
675+
{
676+
"2",
677+
new ParameterQueryConfig
678+
{
679+
ResourceType = "Encounter",
680+
Parameters = new List<IParameter>
681+
{
682+
new ResourceIdsParameter
683+
{
684+
Name = "patient",
685+
Resource = "Patient",
686+
Paged = "50"
687+
}
688+
}
689+
}
690+
}
671691
};
672692
return model;
673693
}
@@ -731,7 +751,7 @@ private UpdateQueryPlanModel CreateAllParameterUpdateQueryPlanModel()
731751
model.InitialQueries = new Dictionary<string, IQueryConfig>
732752
{
733753
{ "1", new ParameterQueryConfig { ResourceType = "Patient", Parameters = new List<IParameter> { new LiteralParameter { Name = "id", Literal = "123" } } } },
734-
{ "2", new ParameterQueryConfig { ResourceType = "Encounter", Parameters = new List<IParameter> { new ResourceIdsParameter { Name = "patient", Resource = "Patient" } } } }
754+
{ "2", new ParameterQueryConfig { ResourceType = "Encounter", Parameters = new List<IParameter> { new ResourceIdsParameter { Name = "patient", Resource = "Patient", Paged = "50" } } } }
735755
};
736756
return model;
737757
}

0 commit comments

Comments
 (0)