Skip to content

Commit b17f1e4

Browse files
committed
Update GetSubmodel and GetSubmodelTemplate methods to use SubmodelQueryOptions for improved parameter handling
1 parent deb8148 commit b17f1e4

6 files changed

Lines changed: 52 additions & 30 deletions

File tree

source/AAS.TwinEngine.DataEngine.UnitTests/Api/AasRepository/Handler/AasRepositoryHandlerTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,14 +457,14 @@ public async Task GetSubmodelElementByAasIdAsync_ReturnsElement_WhenSubmodelBelo
457457
Level.deep,
458458
Extent.withoutBlobValue);
459459
var expectedElement = new Property(idShort: IdShortPath, valueType: DataTypeDefXsd.String);
460-
_aasRepositoryService.GetSubmodelElementByAasIdAsync(AasId, SubmodelId, IdShortPath, Arg.Any<CancellationToken>())
460+
_aasRepositoryService.GetSubmodelElementByAasIdAsync(AasId, SubmodelId, IdShortPath, Arg.Any<SubmodelQueryOptions>(), Arg.Any<CancellationToken>())
461461
.Returns(expectedElement);
462462

463463
var result = await _sut.GetSubmodelElementByAasIdAsync(request, CancellationToken.None);
464464

465465
Assert.IsType<Property>(result);
466466
await _aasRepositoryService.Received(1)
467-
.GetSubmodelElementByAasIdAsync(AasId, SubmodelId, IdShortPath, Arg.Any<CancellationToken>());
467+
.GetSubmodelElementByAasIdAsync(AasId, SubmodelId, IdShortPath, Arg.Any<SubmodelQueryOptions>(), Arg.Any<CancellationToken>());
468468
}
469469

470470
[Fact]
@@ -479,7 +479,7 @@ public async Task GetSubmodelElementByAasIdAsync_SubmodelNotInAas_ThrowsSubmodel
479479
idShortPath,
480480
Level.deep,
481481
Extent.withoutBlobValue);
482-
_aasRepositoryService.GetSubmodelElementByAasIdAsync(AasId, SubmodelId, idShortPath, Arg.Any<CancellationToken>())
482+
_aasRepositoryService.GetSubmodelElementByAasIdAsync(AasId, SubmodelId, idShortPath, Arg.Any<SubmodelQueryOptions>(), Arg.Any<CancellationToken>())
483483
.ThrowsAsync(new SubmodelNotFoundException(SubmodelId));
484484

485485
await Assert.ThrowsAsync<SubmodelNotFoundException>(

source/AAS.TwinEngine.DataEngine.UnitTests/Api/SubmodelRepository/Handler/SubmodelRepositoryHandlerTests.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public async Task HandleSubmodel_WithLevelAndExtent_PassesQueryOptionsToService(
4949
{
5050
const string SubmodelId = "NameplateSubmodel";
5151
var encodedId = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(SubmodelId));
52-
var request = new GetSubmodelRequest(encodedId) { Level = Level.deep, Extent = Extent.withBlobValue };
52+
var request = new GetSubmodelRequest(encodedId, Level.deep, Extent.withBlobValue);
5353
var expectedSubmodel = Substitute.For<ISubmodel>();
5454
_submodelRepository
5555
.GetSubmodelAsync(SubmodelId, Arg.Is<SubmodelQueryOptions?>(q => q != null), Arg.Any<CancellationToken>())
@@ -62,19 +62,29 @@ await _submodelRepository.Received(1)
6262
}
6363

6464
[Fact]
65-
public async Task HandleSubmodel_WithNoLevelOrExtent_PassesNullQueryOptionsToService()
65+
public async Task HandleSubmodel_WithDefaultLevelAndExtent_PassesQueryOptionsToService()
6666
{
6767
const string SubmodelId = "NameplateSubmodel";
6868
var encodedId = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(SubmodelId));
6969
var request = new GetSubmodelRequest(encodedId);
7070
_submodelRepository
71-
.GetSubmodelAsync(SubmodelId, (SubmodelQueryOptions?)null, Arg.Any<CancellationToken>())
71+
.GetSubmodelAsync(
72+
SubmodelId,
73+
Arg.Is<SubmodelQueryOptions?>(q => q != null
74+
&& q.Level == Level.deep.ToString()
75+
&& q.Extent == Extent.withoutBlobValue.ToString()),
76+
Arg.Any<CancellationToken>())
7277
.Returns(Substitute.For<ISubmodel>());
7378

7479
await _sut.GetSubmodel(request, CancellationToken.None);
7580

7681
await _submodelRepository.Received(1)
77-
.GetSubmodelAsync(SubmodelId, (SubmodelQueryOptions?)null, Arg.Any<CancellationToken>());
82+
.GetSubmodelAsync(
83+
SubmodelId,
84+
Arg.Is<SubmodelQueryOptions?>(q => q != null
85+
&& q.Level == Level.deep.ToString()
86+
&& q.Extent == Extent.withoutBlobValue.ToString()),
87+
Arg.Any<CancellationToken>());
7888
}
7989

8090
[Fact]
@@ -133,7 +143,7 @@ public async Task HandleSubmodelElement_WithLevelAndExtent_PassesQueryOptionsToS
133143
const string SubmodelId = "NameplateSubmodel";
134144
const string IdShortPath = "Segments.LinkedSegment";
135145
var encodedId = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(SubmodelId));
136-
var request = new GetSubmodelElementRequest(encodedId, IdShortPath) { Level = Level.deep, Extent = Extent.withBlobValue };
146+
var request = new GetSubmodelElementRequest(encodedId, IdShortPath, Level.deep, Extent.withBlobValue);
137147
var submodelElement = Substitute.For<ISubmodelElement>();
138148
_submodelRepository
139149
.GetSubmodelElementAsync(SubmodelId, IdShortPath, Arg.Is<SubmodelQueryOptions?>(q => q != null), Arg.Any<CancellationToken>())

source/AAS.TwinEngine.DataEngine.UnitTests/Api/SubmodelRepository/SubmodelRepositoryControllerTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ await _sut.GetSubmodelAsync(encodedId, AAS.TwinEngine.DataEngine.Api.SubmodelRep
8181
AAS.TwinEngine.DataEngine.Api.SubmodelRepository.Requests.Extent.withBlobValue, CancellationToken.None);
8282

8383
await _handler.Received(1).GetSubmodel(
84-
Arg.Is<GetSubmodelRequest>(r => r.Level == AAS.TwinEngine.DataEngine.Api.SubmodelRepository.Requests.Level.deep
85-
&& r.Extent == AAS.TwinEngine.DataEngine.Api.SubmodelRepository.Requests.Extent.withBlobValue),
84+
Arg.Is<GetSubmodelRequest>(r => r.level == AAS.TwinEngine.DataEngine.Api.SubmodelRepository.Requests.Level.deep
85+
&& r.extent == AAS.TwinEngine.DataEngine.Api.SubmodelRepository.Requests.Extent.withBlobValue),
8686
Arg.Any<CancellationToken>());
8787
}
8888

@@ -111,7 +111,7 @@ public async Task GetSubmodelElementAsync_WithLevelAndExtent_PassesThemToHandler
111111
await _sut.GetSubmodelElementAsync(encodedId, _idShortPath, Level.deep, Extent.withBlobValue, CancellationToken.None);
112112

113113
await _handler.Received(1).GetSubmodelElement(
114-
Arg.Is<GetSubmodelElementRequest>(r => r.Level == Level.deep && r.Extent == Extent.withBlobValue),
114+
Arg.Is<GetSubmodelElementRequest>(r => r.level == Level.deep && r.extent == Extent.withBlobValue),
115115
Arg.Any<CancellationToken>());
116116
}
117117

@@ -126,7 +126,7 @@ public async Task GetAllSubmodelsAsync_ReturnsOkResult_WithSubmodelsDto()
126126
_handler.GetAllSubmodels(Arg.Any<GetAllSubmodelsRequest>(), Arg.Any<CancellationToken>())
127127
.Returns(expectedDto);
128128

129-
var result = await _sut.GetAllSubmodelsAsync(null, null, null, null, null, null, CancellationToken.None);
129+
var result = await _sut.GetAllSubmodelsAsync(null, null, null, null, CancellationToken.None);
130130

131131
var okResult = Assert.IsType<OkObjectResult>(result.Result);
132132
var dto = Assert.IsType<SubmodelsDto>(okResult.Value);
@@ -144,7 +144,7 @@ public async Task GetAllSubmodelsAsync_PassesQueryParamsToHandler()
144144
.Returns(expectedDto);
145145
var request = new GetAllSubmodelsRequest { SemanticId = SemanticId, IdShort = IdShort, Limit = Limit };
146146

147-
await _sut.GetAllSubmodelsAsync(SemanticId, IdShort, Limit, null, null, null, CancellationToken.None);
147+
await _sut.GetAllSubmodelsAsync(SemanticId, IdShort, Limit, null, CancellationToken.None);
148148

149149
await _handler.Received(1).GetAllSubmodels(
150150
Arg.Is<GetAllSubmodelsRequest>(r => r.SemanticId == SemanticId && r.IdShort == IdShort && r.Limit == Limit),

source/AAS.TwinEngine.DataEngine.UnitTests/ApplicationLogic/Services/SubmodelRepository/SemanticId/ElementHandlers/BlobHandlerTests.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public void Extract_ReturnsLeafNode()
5555
[Fact]
5656
public void FillOut_WithLeafNode_SetsBase64Value()
5757
{
58-
var blob = new Blob(contentType: "image/png", idShort: "MyBlob");
58+
var blob = new Blob(contentType: "image/png", idShort: "MyBlob", value: [9]);
5959
var base64 = Convert.ToBase64String(new byte[] { 1, 2, 3 });
6060
var values = new SemanticLeafNode("http://test/blob", base64, DataType.String, Cardinality.One);
6161

@@ -65,6 +65,18 @@ public void FillOut_WithLeafNode_SetsBase64Value()
6565
Equal([1, 2, 3], blob.Value);
6666
}
6767

68+
[Fact]
69+
public void FillOut_WithLeafNodeAndNoTemplateValue_LeavesValueUnset()
70+
{
71+
var blob = new Blob(contentType: "image/png", idShort: "MyBlob");
72+
var base64 = Convert.ToBase64String(new byte[] { 1, 2, 3 });
73+
var values = new SemanticLeafNode("http://test/blob", base64, DataType.String, Cardinality.One);
74+
75+
_sut.FillOut(blob, values, (_, _, _) => { });
76+
77+
Null(blob.Value);
78+
}
79+
6880
[Fact]
6981
public void FillOut_WithBranchNode_DoesNotModifyValue()
7082
{

source/AAS.TwinEngine.DataEngine.UnitTests/ApplicationLogic/Services/SubmodelRepository/SubmodelRepositoryServiceTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ await Assert.ThrowsAsync<InternalDataProcessingException>(() =>
594594
private void ArrangeAttachmentElement(string idShortPath, ISubmodelElement element)
595595
{
596596
var template = TestData.CreateSubmodelWithElement(element, idShortPath);
597-
_templateService.GetSubmodelTemplateAsync(SubmodelId, idShortPath, Arg.Any<CancellationToken>()).Returns(template);
597+
_templateService.GetSubmodelTemplateAsync(SubmodelId, idShortPath, Arg.Any<SubmodelQueryOptions?>(), Arg.Any<CancellationToken>()).Returns(template);
598598
_semanticIdHandler.Extract(Arg.Any<ISubmodel>()).Returns(CreateSubmodelTreeNode(""));
599599
_pluginDataHandler.TryGetValuesAsync(Arg.Any<IReadOnlyList<PluginManifest>>(), Arg.Any<SemanticTreeNode>(), SubmodelId, Arg.Any<CancellationToken>()).Returns(CreateSubmodelTreeNode(""));
600600
_semanticIdHandler.FillOutTemplate(Arg.Any<ISubmodel>(), Arg.Any<SemanticTreeNode>()).Returns(template);
@@ -644,7 +644,7 @@ public async Task GetFileAttachmentAsync_WhenSubmodelNotFound_ThrowsSubmodelElem
644644
const string IdShortPath = "Documents.ProductImage";
645645

646646
_templateService
647-
.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, Arg.Any<CancellationToken>())
647+
.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, Arg.Any<SubmodelQueryOptions?>(), Arg.Any<CancellationToken>())
648648
.ThrowsAsync(new ResourceNotFoundException());
649649

650650
await Assert.ThrowsAsync<SubmodelElementNotFoundException>(() =>

source/AAS.TwinEngine.DataEngine.UnitTests/ApplicationLogic/Services/SubmodelRepository/SubmodelTemplateServiceTests.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public async Task GetSubmodelTemplateAsync_ReturnsNull_WhenElementNotFound()
7474
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
7575
.Returns(expectedSubmodel);
7676

77-
var exception = await Assert.ThrowsAsync<SubmodelElementNotFoundException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, CancellationToken.None));
77+
var exception = await Assert.ThrowsAsync<SubmodelElementNotFoundException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, null, CancellationToken.None));
7878
Assert.Equal("Submodel Element not found.", exception.Message);
7979
}
8080

@@ -83,7 +83,7 @@ public async Task GetSubmodelTemplateAsync_ThrowsException_WhenSubmodelIdIsInval
8383
{
8484
string? submodelId = null;
8585

86-
var exception = await Assert.ThrowsAsync<InternalDataProcessingException>(() => _sut.GetSubmodelTemplateAsync(submodelId!, "idShort", CancellationToken.None));
86+
var exception = await Assert.ThrowsAsync<InternalDataProcessingException>(() => _sut.GetSubmodelTemplateAsync(submodelId!, "idShort", null, CancellationToken.None));
8787
Assert.Equal("Internal Server Error.", exception.Message);
8888
}
8989

@@ -97,7 +97,7 @@ public async Task GetSubmodelTemplateAsync_ReturnsElement_WhenSingleProperty()
9797
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
9898
.Returns(expectedSubmodel);
9999

100-
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, CancellationToken.None);
100+
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, null, CancellationToken.None);
101101
Assert.Equal(GetSemanticId(expectedElement), GetSemanticId(result));
102102
Assert.Equal(expectedElement.SubmodelElements!.Count, result.SubmodelElements!.Count);
103103
Assert.Single(expectedElement.SubmodelElements);
@@ -113,7 +113,7 @@ public async Task GetSubmodelTemplateAsync_ReturnsCustomSubmodel_WhenNestedPrope
113113
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
114114
.Returns(expectedSubmodel);
115115

116-
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, CancellationToken.None);
116+
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, null, CancellationToken.None);
117117

118118
Assert.Equal(GetSemanticId(expectedElement), GetSemanticId(result));
119119
Assert.Equal(expectedElement.SubmodelElements!.Count, result.SubmodelElements!.Count);
@@ -131,15 +131,15 @@ public async Task GetSubmodelTemplateAsync_ReturnsSubmodelElementNotFoundExcepti
131131
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
132132
.Returns(expectedSubmodel);
133133

134-
var exception = await Assert.ThrowsAsync<SubmodelElementNotFoundException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, CancellationToken.None));
134+
var exception = await Assert.ThrowsAsync<SubmodelElementNotFoundException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, IdShortPath, null, CancellationToken.None));
135135
}
136136

137137
[Fact]
138138
public async Task GetSubmodelElementTemplateAsync_ThrowsBadRequestException_WhenSubmodelIdIsEmpty()
139139
{
140140
const string IdShortPath = "ContactInformation0";
141141

142-
var exception = await Assert.ThrowsAsync<InternalDataProcessingException>(() => _sut.GetSubmodelTemplateAsync("", IdShortPath, CancellationToken.None));
142+
var exception = await Assert.ThrowsAsync<InternalDataProcessingException>(() => _sut.GetSubmodelTemplateAsync("", IdShortPath, null, CancellationToken.None));
143143
Assert.IsType<InternalDataProcessingException>(exception);
144144
}
145145

@@ -152,7 +152,7 @@ public async Task GetSubmodelTemplateAsync_ReturnsSubmodel_WhenPathContainsListI
152152
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
153153
.Returns(expectedSubmodel);
154154

155-
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, path, CancellationToken.None);
155+
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, path, null, CancellationToken.None);
156156

157157
Assert.Equal(GetSemanticId(expectedSubmodel), GetSemanticId(result));
158158

@@ -176,7 +176,7 @@ public async Task GetSubmodelTemplateAsync_WithListIndexPath_ReturnsSubmodelWith
176176
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
177177
.Returns(expectedSubmodel);
178178

179-
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, Path, CancellationToken.None);
179+
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, Path, null, CancellationToken.None);
180180

181181
Assert.Equal(GetSemanticId(expectedSubmodel), GetSemanticId(result));
182182

@@ -200,7 +200,7 @@ public async Task GetSubmodelTemplateAsync_Supports_UrlEncoded_ListIndex()
200200
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
201201
.Returns(submodel);
202202

203-
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, Path, CancellationToken.None);
203+
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, Path, null, CancellationToken.None);
204204

205205
Assert.NotNull(result);
206206
}
@@ -216,7 +216,7 @@ public async Task GetSubmodelTemplateAsync_Throws_When_ListIndex_IsNegative()
216216
.Returns(submodel);
217217

218218
await Assert.ThrowsAsync<SubmodelElementNotFoundException>(
219-
() => _sut.GetSubmodelTemplateAsync(SubmodelId, Path, CancellationToken.None));
219+
() => _sut.GetSubmodelTemplateAsync(SubmodelId, Path, null, CancellationToken.None));
220220
}
221221

222222
[Fact]
@@ -229,7 +229,7 @@ public async Task GetSubmodelTemplateAsync_ReturnsSubmodel_WhenTypeValueListElem
229229
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
230230
.Returns(submodel);
231231

232-
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, Path, CancellationToken.None);
232+
var result = await _sut.GetSubmodelTemplateAsync(SubmodelId, Path, null, CancellationToken.None);
233233

234234
Assert.Equal(GetSemanticId(expectedSubmodel), GetSemanticId(result));
235235

@@ -253,7 +253,7 @@ public async Task GetSubmodelTemplateAsync_ThrowsInternalDataProcessingException
253253
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
254254
.Returns(submodel);
255255

256-
await Assert.ThrowsAsync<InternalDataProcessingException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, Path, CancellationToken.None));
256+
await Assert.ThrowsAsync<InternalDataProcessingException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, Path, null, CancellationToken.None));
257257
}
258258

259259
[Fact]
@@ -265,7 +265,7 @@ public async Task GetSubmodelTemplateAsync_ThrowsNotFoundException_WhenPathSegme
265265
_templateProvider.GetFilteredSubmodelTemplateAsync(TemplateId, null, Arg.Any<CancellationToken>())
266266
.Returns(submodel);
267267

268-
await Assert.ThrowsAsync<SubmodelElementNotFoundException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, Path, CancellationToken.None));
268+
await Assert.ThrowsAsync<SubmodelElementNotFoundException>(() => _sut.GetSubmodelTemplateAsync(SubmodelId, Path, null, CancellationToken.None));
269269
}
270270

271271
[Fact]
@@ -322,7 +322,7 @@ public async Task GetSubmodelTemplateAsync_WithIdShortPath_ThrowsSubmodelElement
322322
.ThrowsAsync(new ResourceNotFoundException());
323323

324324
await Assert.ThrowsAsync<SubmodelElementNotFoundException>(
325-
() => _sut.GetSubmodelTemplateAsync(SubmodelId, "SomePath", CancellationToken.None));
325+
() => _sut.GetSubmodelTemplateAsync(SubmodelId, "SomePath", null, CancellationToken.None));
326326
}
327327
#region GetFilteredSubmodelTemplateAsync
328328

0 commit comments

Comments
 (0)