Skip to content

Commit 678e958

Browse files
authored
Merge pull request #48 from PTCInc/assorted-cleanup
Assorted cleanup
2 parents 42643ca + 7da2cf1 commit 678e958

16 files changed

Lines changed: 314 additions & 48 deletions

Kepware.Api.Test/ApiClient/AutomaticTagGenerationAsyncTests.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,15 @@ public async Task AutomaticTagGenerationAsync_ShouldReturnKepServerJobPromise_Wh
4848

4949
// Act
5050
var result = await _kepwareApiClient.ApiServices.AutomaticTagGenerationAsync(UNIT_TEST_CHANNEL, UNIT_TEST_DEVICE, TimeSpan.FromSeconds(30));
51+
var jobResult = await result.AwaitCompletionAsync();
5152

5253
// Assert
5354
result.ShouldNotBeNull();
5455
result.Endpoint.ShouldBe(ENDPOINT_TAG_GENERATION);
5556
result.JobTimeToLive.ShouldBe(TimeSpan.FromSeconds(30));
57+
jobResult.Value.ShouldBeFalse();
58+
jobResult.IsSuccess.ShouldBeFalse();
59+
jobResult.ResponseCode.ShouldBe(ApiResponseCode.BadRequest);
5660
}
5761

5862
[Fact]
@@ -113,6 +117,7 @@ public async Task AutomaticTagGenerationAsync_ShouldReturnSuccess_WhenJobComplet
113117
// Assert
114118
completionResult.Value.ShouldBeTrue();
115119
completionResult.IsSuccess.ShouldBeTrue();
120+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.Success);
116121
}
117122

118123
[Fact]
@@ -135,6 +140,7 @@ public async Task AutomaticTagGenerationAsync_ShouldReturnSuccess_WhenJobComplet
135140
// Assert
136141
completionResult.Value.ShouldBeTrue();
137142
completionResult.IsSuccess.ShouldBeTrue();
143+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.Success);
138144
}
139145

140146
[Fact]
@@ -155,6 +161,7 @@ public async Task AutomaticTagGenerationAsync_ShouldReturnFailure_WhenJobFailsAf
155161
// Assert
156162
completionResult.Value.ShouldBeFalse();
157163
completionResult.IsSuccess.ShouldBeFalse();
164+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.Timeout);
158165
}
159166

160167
[Fact]
@@ -180,6 +187,8 @@ public async Task AutomaticTagGenerationAsync_ShouldReturnFailure_WhenJobFailsAf
180187
// Assert
181188
completionResult.Value.ShouldBeFalse();
182189
completionResult.IsSuccess.ShouldBeFalse();
190+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.ServiceUnavailable);
191+
completionResult.Message.ShouldBe(jobStatusFailed.Message);
183192
}
184193
}
185194
}

Kepware.Api.Test/ApiClient/GetProductInfo.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@ public async Task GetProductInfoAsync_ShouldReturnProductInfo_WhenApiRespondsSuc
3636

3737
#region GetProductInfoAsync - SupportsJsonProjectLoadService
3838

39-
//TODO: Add more test cases for TKS versions as well. Different product name
4039
[Theory]
4140
[InlineData("KEPServerEX", "12", 6, 17, true)] // Supports JSON Project Load Service (6.17+)
4241
[InlineData("KEPServerEX", "12", 6, 16, false)] // Does not support it (6.16)
43-
[InlineData("ThingWorxKepwareEdge", "13", 1, 10, true)] // Supports it (1.10+)
42+
[InlineData("ThingworxKepwareServer", "12", 6, 17, true)] // Supports JSON Project Load Service (6.17+)
43+
[InlineData("ThingworxKepwareServer", "12", 6, 16, false)] // Does not support it (6.16)
44+
[InlineData("ThingWorxKepwareEdge", "13", 1, 10, true)] // Supports JSON Project Load Service (1.10+)
4445
[InlineData("ThingWorxKepwareEdge", "13", 1, 9, false)] // Does not support it (1.9)
46+
[InlineData("Kepware Edge", "13", 1, 0, true)] // Supports JSON Project Load Service
4547
[InlineData("UnknownProduct", "99", 10, 0, false)] // Unknown product, should be false
4648
public async Task GetProductInfoAsync_ShouldReturnCorrect_SupportsJsonProjectLoadService(
4749
string productName, string productId, int majorVersion, int minorVersion, bool expectedResult)
@@ -62,8 +64,10 @@ public async Task GetProductInfoAsync_ShouldReturnCorrect_SupportsJsonProjectLoa
6264
#region GetProductInfoAsync - ProductType
6365

6466
[Theory]
65-
[InlineData("KEPServerEX", "12", ProductType.KEPServerEX)]
66-
[InlineData("ThingWorxKepwareEdge", "13", ProductType.ThingWorxKepwareEdge)]
67+
[InlineData("KEPServerEX", "12", ProductType.KepwareServer)]
68+
[InlineData("ThingworxKepwareServer", "12", ProductType.KepwareServer)]
69+
[InlineData("ThingWorxKepwareEdge", "13", ProductType.KepwareEdge)]
70+
[InlineData("Kepware Edge", "13", ProductType.KepwareEdge)]
6771
[InlineData("UnknownProduct", "99", ProductType.Unknown)]
6872
[InlineData("InvalidProduct", "abc", ProductType.Unknown)] // Invalid ID, should be Unknown
6973
public async Task GetProductInfoAsync_ShouldReturnCorrect_ProductType(

Kepware.Api.Test/ApiClient/ProjectApiHandlerTests.cs

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,49 @@ public async Task GetOrCreateChannelAsync_ShouldCreateChannel_WhenChannelDoesNot
7979
Assert.Equal(channelName, result.Name);
8080
}
8181

82+
[Fact]
83+
public async Task GetChannelAsync_ShouldReturnChannel_WhenChannelExists()
84+
{
85+
// Arrange
86+
var channelName = "ExistingChannel";
87+
var channelJson = """
88+
{
89+
"PROJECT_ID": 676550906,
90+
"common.ALLTYPES_NAME": "ExistingChannel",
91+
"common.ALLTYPES_DESCRIPTION": "Example Channel",
92+
"servermain.MULTIPLE_TYPES_DEVICE_DRIVER": "Simulator"
93+
}
94+
""";
95+
96+
_httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channelName}")
97+
.ReturnsResponse(channelJson, "application/json");
98+
99+
// Act
100+
var result = await _projectApiHandler.Channels.GetChannelAsync(channelName);
101+
102+
// Assert
103+
Assert.NotNull(result);
104+
Assert.Equal(channelName, result.Name);
105+
}
106+
107+
[Fact]
108+
public async Task GetChannelAsync_ShouldReturnNull_WhenChannelDoesNotExist()
109+
{
110+
// Arrange
111+
await ConfigureToServeDrivers();
112+
113+
var channelName = "NewChannel";
114+
115+
_httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channelName}")
116+
.ReturnsResponse(HttpStatusCode.NotFound);
117+
118+
// Act
119+
var result = await _projectApiHandler.Channels.GetChannelAsync(channelName);
120+
121+
// Assert
122+
Assert.Null(result);
123+
}
124+
82125
[Fact]
83126
public async Task UpdateChannelAsync_ShouldReturnTrue_WhenUpdateIsSuccessful()
84127
{
@@ -190,6 +233,57 @@ public async Task GetOrCreateDeviceAsync_ShouldCreateDevice_WhenDeviceDoesNotExi
190233
Assert.Equal(deviceName, result.Name);
191234
}
192235

236+
[Fact]
237+
public async Task GetDeviceAsync_ShouldReturnDevice_WhenDeviceExists()
238+
{
239+
// Arrange
240+
await ConfigureToServeDrivers();
241+
var channel = new Channel { Name = "ExistingChannel" };
242+
var deviceName = "ExistingDevice";
243+
var deviceJson = """
244+
{
245+
"PROJECT_ID": 676550906,
246+
"common.ALLTYPES_NAME": "ExistingDevice",
247+
"common.ALLTYPES_DESCRIPTION": "Example Device",
248+
"servermain.DEVICE_CHANNEL_ASSIGNMENT": "ExistingChannel"
249+
}
250+
""";
251+
252+
_httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices/{deviceName}")
253+
.ReturnsResponse(deviceJson, "application/json");
254+
255+
_httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices/{deviceName}/tags")
256+
.ReturnsResponse("[]", "application/json");
257+
258+
_httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices/{deviceName}/tag_groups")
259+
.ReturnsResponse("[]", "application/json");
260+
261+
// Act
262+
var result = await _projectApiHandler.Devices.GetDeviceAsync(channel, deviceName);
263+
264+
// Assert
265+
Assert.NotNull(result);
266+
Assert.Equal(deviceName, result.Name);
267+
}
268+
269+
[Fact]
270+
public async Task GetDeviceAsync_ShouldReturnNull_WhenDeviceDoesNotExist()
271+
{
272+
// Arrange
273+
await ConfigureToServeDrivers();
274+
var channel = new Channel { Name = "ExistingChannel", DeviceDriver = "Simulator" };
275+
var deviceName = "NewDevice";
276+
277+
_httpMessageHandlerMock.SetupRequest(HttpMethod.Get, TEST_ENDPOINT + $"/config/v1/project/channels/{channel.Name}/devices/{deviceName}")
278+
.ReturnsResponse(HttpStatusCode.NotFound);
279+
280+
// Act
281+
var result = await _projectApiHandler.Devices.GetDeviceAsync(channel, deviceName);
282+
283+
// Assert
284+
Assert.Null(result);
285+
}
286+
193287
[Fact]
194288
public async Task UpdateDeviceAsync_ShouldReturnTrue_WhenUpdateIsSuccessful()
195289
{
@@ -269,7 +363,8 @@ public async Task LoadTagGroupsRecursiveAsync_ShouldLoadTagGroupsCorrectly()
269363
.ReturnsResponse("[]", "application/json");
270364

271365
var tagGroup = new DeviceTagGroup { Name = "TagGroup1", Owner = device };
272-
var tagGroups = new List<DeviceTagGroup> { tagGroup };
366+
var tagGroup2 = new DeviceTagGroup { Name = "TagGroup1", Owner = tagGroup };
367+
var tagGroups = new List<DeviceTagGroup> { tagGroup , tagGroup2 };
273368

274369
// Act
275370
await ProjectApiHandler.LoadTagGroupsRecursiveAsync(_kepwareApiClient, tagGroups);
@@ -278,6 +373,8 @@ public async Task LoadTagGroupsRecursiveAsync_ShouldLoadTagGroupsCorrectly()
278373
Assert.NotNull(tagGroup.TagGroups);
279374
Assert.Single(tagGroup.TagGroups);
280375
Assert.Equal("TagGroup1", tagGroup.TagGroups.First().Name);
376+
Assert.NotNull(tagGroup2.TagGroups);
377+
Assert.Empty(tagGroup2.TagGroups);
281378
}
282379

283380
#endregion

Kepware.Api.Test/ApiClient/ReinitializeRuntimeAsyncTests.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,16 @@ public async Task ReinitializeRuntimeAsync_ShouldReturnKepServerJobPromise_WhenA
4646

4747
// Act
4848
var result = await _kepwareApiClient.ApiServices.ReinitializeRuntimeAsync(TimeSpan.FromSeconds(30));
49-
49+
var jobResult = await result.AwaitCompletionAsync();
50+
5051
// Assert
5152
result.ShouldNotBeNull();
5253
result.Endpoint.ShouldBe("/config/v1/project/services/ReinitializeRuntime");
5354
result.JobTimeToLive.ShouldBe(TimeSpan.FromSeconds(30));
55+
jobResult.Value.ShouldBeFalse();
56+
jobResult.IsSuccess.ShouldBeFalse();
57+
jobResult.ResponseCode.ShouldBe(ApiResponseCode.BadRequest);
58+
5459
}
5560

5661
[Fact]
@@ -111,6 +116,7 @@ public async Task ReinitializeRuntimeAsync_ShouldReturnSuccess_WhenJobCompletesS
111116
// Assert
112117
completionResult.Value.ShouldBeTrue();
113118
completionResult.IsSuccess.ShouldBeTrue();
119+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.Success);
114120
}
115121

116122
[Fact]
@@ -133,6 +139,7 @@ public async Task ReinitializeRuntimeAsync_ShouldReturnSuccess_WhenJobCompletesS
133139
// Assert
134140
completionResult.Value.ShouldBeTrue();
135141
completionResult.IsSuccess.ShouldBeTrue();
142+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.Success);
136143
}
137144

138145
[Fact]
@@ -153,6 +160,8 @@ public async Task ReinitializeRuntimeAsync_ShouldReturnFailure_WhenJobFailsAfter
153160
// Assert
154161
completionResult.Value.ShouldBeFalse();
155162
completionResult.IsSuccess.ShouldBeFalse();
163+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.Timeout);
164+
156165
}
157166

158167
[Fact]
@@ -178,6 +187,8 @@ public async Task ReinitializeRuntimeAsync_ShouldReturnFailure_WhenJobFailsAfter
178187
// Assert
179188
completionResult.Value.ShouldBeFalse();
180189
completionResult.IsSuccess.ShouldBeFalse();
190+
completionResult.ResponseCode.ShouldBe(ApiResponseCode.ServiceUnavailable);
191+
completionResult.Message.ShouldBe(jobStatusFailed.Message);
181192
}
182193
}
183194
}

Kepware.Api.TestIntg/ApiClient/ProjectApiHandlerTests.cs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,24 @@ public async Task GetOrCreateChannelAsync_ShouldCreateChannel_WhenChannelDoesNot
4747
var channel = CreateTestChannel();
4848

4949
// Act
50-
var result = await _projectApiHandler.Channels.GetOrCreateChannelAsync(channel.Name, channel.DeviceDriver);
50+
var result = await _projectApiHandler.Channels.GetOrCreateChannelAsync(channel.Name, channel.DeviceDriver!);
51+
52+
// Assert
53+
Assert.NotNull(result);
54+
Assert.Equal(channel.Name, result.Name);
55+
56+
// Clean up
57+
await DeleteAllChannelsAsync();
58+
}
59+
60+
[Fact]
61+
public async Task GetChannelAsync_ShouldReturnChannel_WhenChannelExists()
62+
{
63+
// Arrange
64+
var channel = await AddTestChannel();
65+
66+
// Act
67+
var result = await _projectApiHandler.Channels.GetChannelAsync(channel.Name);
5168

5269
// Assert
5370
Assert.NotNull(result);
@@ -57,6 +74,22 @@ public async Task GetOrCreateChannelAsync_ShouldCreateChannel_WhenChannelDoesNot
5774
await DeleteAllChannelsAsync();
5875
}
5976

77+
[Fact]
78+
public async Task GetChannelAsync_ShouldReturnNull_WhenChannelDoesNotExist()
79+
{
80+
// Arrange
81+
var channel = CreateTestChannel();
82+
83+
// Act
84+
var result = await _projectApiHandler.Channels.GetChannelAsync(channel.Name);
85+
86+
// Assert
87+
Assert.Null(result);
88+
89+
// Clean up
90+
await DeleteAllChannelsAsync();
91+
}
92+
6093
[Fact]
6194
public async Task UpdateChannelAsync_ShouldReturnTrue_WhenUpdateIsSuccessful()
6295
{
@@ -130,6 +163,41 @@ public async Task GetOrCreateDeviceAsync_ShouldCreateDevice_WhenDeviceDoesNotExi
130163
await DeleteAllChannelsAsync();
131164
}
132165

166+
[Fact]
167+
public async Task GetDeviceAsync_ShouldReturnDevice_WhenDeviceExists()
168+
{
169+
// Arrange
170+
var channel = await AddTestChannel();
171+
var device = await AddTestDevice(channel);
172+
173+
// Act
174+
var result = await _projectApiHandler.Devices.GetDeviceAsync(channel, device.Name);
175+
176+
// Assert
177+
Assert.NotNull(result);
178+
Assert.Equal(device.Name, result.Name);
179+
180+
// Clean up
181+
await DeleteAllChannelsAsync();
182+
}
183+
184+
[Fact]
185+
public async Task GetDeviceAsync_ShouldReturnNull_WhenDeviceDoesNotExist()
186+
{
187+
// Arrange
188+
var channel = await AddTestChannel();
189+
var device = CreateTestDevice(channel);
190+
191+
// Act
192+
var result = await _projectApiHandler.Devices.GetDeviceAsync(channel, device.Name);
193+
194+
// Assert
195+
Assert.Null(result);
196+
197+
// Clean up
198+
await DeleteAllChannelsAsync();
199+
}
200+
133201
[Fact]
134202
public async Task UpdateDeviceAsync_ShouldReturnTrue_WhenUpdateIsSuccessful()
135203
{

Kepware.Api.TestIntg/ApiClient/UpdateTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public async Task Update_MultipleItems_ShouldUpdateAll()
6060
var results = await _kepwareApiClient.GenericConfig.UpdateItemsAsync<DeviceTagCollection, Tag>(tags, device);
6161

6262
// Assert
63-
results.Count.ShouldBe(tags.Count);
63+
results.Length.ShouldBe(tags.Count);
6464
results.ShouldAllBe(r => r == true);
6565

6666
// Clean up

Kepware.Api.TestIntg/appsettings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"TestServer": {
55
"Host": "http://localhost",
66
"Port": 57412,
7-
"UserName": "Administrator",
8-
"Password": "ReallyStrongPassword400!"
7+
"UserName": "Test",
8+
"Password": "Kepware400400400"
99
}
1010
}
1111
}

0 commit comments

Comments
 (0)