@@ -22,63 +22,6 @@ namespace Kepware.Api.Test.ApiClient
2222 public class ProjectLoadTests : TestApiClientBase
2323 {
2424
25- //private async Task ConfigureToServeEndpoints()
26- //{
27- // var projectData = await LoadJsonTestDataAsync();
28-
29- // var channels = projectData.Project?.Channels?.Select(c => new Channel { Name = c.Name, Description = c.Description, DynamicProperties = c.DynamicProperties }).ToList() ?? [];
30-
31- // // Serve project details
32- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project")
33- // .ReturnsResponse(JsonSerializer.Serialize(new Project { Description = projectData?.Project?.Description, DynamicProperties = projectData?.Project?.DynamicProperties ?? [] }), "application/json");
34-
35- // // Serve channels without nested devices
36- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + "/config/v1/project/channels")
37- // .ReturnsResponse(JsonSerializer.Serialize(channels), "application/json");
38-
39- // foreach (var channel in projectData?.Project?.Channels ?? [])
40- // {
41- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}")
42- // .ReturnsResponse(JsonSerializer.Serialize(new Channel { Name = channel.Name, Description = channel.Description, DynamicProperties = channel.DynamicProperties }), "application/json");
43-
44- // if (channel.Devices != null)
45- // {
46- // var devices = channel.Devices.Select(d => new Device { Name = d.Name, Description = d.Description, DynamicProperties = d.DynamicProperties }).ToList();
47- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices")
48- // .ReturnsResponse(JsonSerializer.Serialize(devices), "application/json");
49-
50- // foreach (var device in channel.Devices)
51- // {
52- // var deviceEndpoint = TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices/{device.Name}";
53- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, deviceEndpoint)
54- // .ReturnsResponse(JsonSerializer.Serialize(new Device { Name = device.Name, Description = device.Description, DynamicProperties = device.DynamicProperties }), "application/json");
55-
56-
57- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, deviceEndpoint + "/tags")
58- // .ReturnsResponse(JsonSerializer.Serialize(device.Tags), "application/json");
59-
60- // ConfigureToServeEndpointsTagGroupsRecursive(deviceEndpoint, device.TagGroups ?? []);
61- // }
62- // }
63- // }
64- //}
65-
66- //private void ConfigureToServeEndpointsTagGroupsRecursive(string endpoint, IEnumerable<DeviceTagGroup> tagGroups)
67- //{
68- // var tagGroupEndpoint = endpoint + "/tag_groups";
69-
70- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, tagGroupEndpoint)
71- // .ReturnsResponse(JsonSerializer.Serialize(tagGroups), "application/json");
72-
73- // foreach (var tagGroup in tagGroups)
74- // {
75- // _httpMessageHandlerMock.SetupRequest(HttpMethod.Get, string.Concat(tagGroupEndpoint, "/", tagGroup.Name, "/tags"))
76- // .ReturnsResponse(JsonSerializer.Serialize(tagGroup.Tags), "application/json");
77-
78- // ConfigureToServeEndpointsTagGroupsRecursive(string.Concat(tagGroupEndpoint, "/", tagGroup.Name), tagGroup.TagGroups ?? []);
79- // }
80- //}
81-
8225 [ Theory ]
8326 [ InlineData ( "KEPServerEX" , "12" , 6 , 17 , true ) ]
8427 [ InlineData ( "KEPServerEX" , "12" , 6 , 16 , false ) ]
@@ -88,6 +31,12 @@ public class ProjectLoadTests : TestApiClientBase
8831 public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport (
8932 string productName , string productId , int majorVersion , int minorVersion , bool supportsJsonLoad )
9033 {
34+ // This test will validate that the LoadProjectAsync method correctly loads the project structure and
35+ // content based on whether the connected server version supports JsonProjectLoad. It will compare the loaded project against expected test data to ensure accuracy.
36+ // For servers that support JsonProjectLoad, the test will configure the mock server to serve a full JSON project
37+ // and validate that the loaded project matches the test data exactly.
38+
39+ // Arrange
9140 ConfigureConnectedClient ( productName , productId , majorVersion , minorVersion ) ;
9241
9342 if ( supportsJsonLoad )
@@ -99,8 +48,10 @@ public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport(
9948 await ConfigureToServeEndpoints ( ) ;
10049 }
10150
51+ // Act
10252 var project = await _kepwareApiClient . Project . LoadProjectAsync ( blnLoadFullProject : true ) ;
10353
54+ // Assert
10455 project . IsLoadedByProjectLoadService . ShouldBe ( supportsJsonLoad ) ;
10556
10657 project . ShouldNotBeNull ( ) ;
@@ -149,6 +100,11 @@ public async Task LoadProject_ShouldLoadCorrectly_BasedOnProductSupport(
149100 public async Task LoadProject_ShouldLoadCorrectly_Serialize_BasedOnProductSupport (
150101 string productName , string productId , int majorVersion , int minorVersion , bool supportsJsonLoad )
151102 {
103+ // This test will validate that the LoadProjectAsync method correctly loads the project structure using the optimized recursion method.
104+ // It will compare the loaded project against expected test data to ensure accuracy. The test will configure the mock server to serve
105+ // endpoints to support an optimized recursion load and validate that the loaded project matches the test data exactly.
106+
107+ // Arrange
152108 ConfigureConnectedClient ( productName , productId , majorVersion , minorVersion ) ;
153109
154110 if ( supportsJsonLoad )
@@ -161,10 +117,16 @@ public async Task LoadProject_ShouldLoadCorrectly_Serialize_BasedOnProductSuppor
161117 throw SkipException . ForSkip ( $ "Product { productName } v{ majorVersion } .{ minorVersion } (id={ productId } ) does not support JSON project load. Skipping full-project test case.") ;
162118 }
163119
164- var tagLimitOverride = 100 ; // Set a high tag limit to ensure all tags are loaded for comparison
120+ // Override the tag limit to ensure that we are testing the optimized recursion and selectively load objects based on the tag limit.
121+ // See _data/simdemo_en.json and json chunks in _data/projectLoadSerializeData for data that is served by the mock server for this test.
122+ var tagLimitOverride = 100 ;
123+
165124
125+ // Act
166126 var project = await _kepwareApiClient . Project . LoadProjectAsync ( blnLoadFullProject : true , projectLoadTagLimit : tagLimitOverride ) ;
167127
128+
129+ // Assert
168130 // Optimized recursion is done for this test, which will result in false.
169131 project . IsLoadedByProjectLoadService . ShouldBeFalse ( ) ;
170132
@@ -204,6 +166,12 @@ public async Task LoadProject_ShouldLoadCorrectly_Serialize_BasedOnProductSuppor
204166 CompareTagGroupsRecursive ( ExpectedDevice . TagGroups , LoadedDevice . TagGroups , ExpectedDevice . Name ) ;
205167 }
206168 }
169+
170+ // Verify expected number of calls to the project load endpoints to ensure that the optimized recursion is selectively loading objects based on the tag limit.
171+ foreach ( var uri in _optimizedRecursionUris )
172+ {
173+ _httpMessageHandlerMock . VerifyRequest ( HttpMethod . Get , uri ) ;
174+ }
207175 }
208176
209177 private static void CompareTagGroupsRecursive ( DeviceTagGroupCollection ? expected , DeviceTagGroupCollection ? actual , string parentName )
0 commit comments