Skip to content

Commit 85761ff

Browse files
committed
feat(api): Add GetDeviceAsync API and testing
1 parent 789de7c commit 85761ff

3 files changed

Lines changed: 123 additions & 2 deletions

File tree

Kepware.Api.Test/ApiClient/ProjectApiHandlerTests.cs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public async Task GetChannelAsync_ShouldReturnChannel_WhenChannelExists()
105105
}
106106

107107
[Fact]
108-
public async Task GetChannelAsync_ShouldCreateChannel_WhenChannelDoesNotExist()
108+
public async Task GetChannelAsync_ShouldReturnNull_WhenChannelDoesNotExist()
109109
{
110110
// Arrange
111111
await ConfigureToServeDrivers();
@@ -233,6 +233,57 @@ public async Task GetOrCreateDeviceAsync_ShouldCreateDevice_WhenDeviceDoesNotExi
233233
Assert.Equal(deviceName, result.Name);
234234
}
235235

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+
236287
[Fact]
237288
public async Task UpdateDeviceAsync_ShouldReturnTrue_WhenUpdateIsSuccessful()
238289
{

Kepware.Api.TestIntg/ApiClient/ProjectApiHandlerTests.cs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public async Task GetChannelAsync_ShouldReturnChannel_WhenChannelExists()
7575
}
7676

7777
[Fact]
78-
public async Task GetChannelAsync_ShouldCreateChannel_WhenChannelDoesNotExist()
78+
public async Task GetChannelAsync_ShouldReturnNull_WhenChannelDoesNotExist()
7979
{
8080
// Arrange
8181
var channel = CreateTestChannel();
@@ -163,6 +163,41 @@ public async Task GetOrCreateDeviceAsync_ShouldCreateDevice_WhenDeviceDoesNotExi
163163
await DeleteAllChannelsAsync();
164164
}
165165

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+
166201
[Fact]
167202
public async Task UpdateDeviceAsync_ShouldReturnTrue_WhenUpdateIsSuccessful()
168203
{

Kepware.Api/ClientHandler/DeviceApiHandler.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,41 @@ public async Task<Device> GetOrCreateDeviceAsync(Channel channel, string name, s
9090
}
9191
#endregion
9292

93+
#region GetDeviceAsync
94+
/// <summary>
95+
/// Gets or creates a device with the specified name and driver in the specified channel.
96+
/// </summary>
97+
/// <param name="channel">The channel to which the device belongs.</param>
98+
/// <param name="name">The name of the device.</param>
99+
/// <param name="cancellationToken">The cancellation token.</param>
100+
/// <returns>A task that represents the asynchronous operation. The task result contains the loaded <see cref="Device"/> or null if it does not exist.</returns>
101+
/// <exception cref="ArgumentNullException">Thrown when the channel is null.</exception>
102+
/// <exception cref="ArgumentException">Thrown when the device name is null or empty.</exception>
103+
/// <exception cref="InvalidOperationException">Thrown when the device cannot be created or loaded.</exception>
104+
public async Task<Device?> GetDeviceAsync(Channel channel, string name, CancellationToken cancellationToken = default)
105+
{
106+
if (channel == null)
107+
throw new ArgumentNullException(nameof(channel));
108+
if (string.IsNullOrEmpty(name))
109+
throw new ArgumentException("Device name cannot be null or empty", nameof(name));
110+
111+
var device = await m_kepwareApiClient.GenericConfig.LoadEntityAsync<Device>(name, channel, cancellationToken: cancellationToken);
112+
113+
if (device != null)
114+
{
115+
device.Tags = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync<DeviceTagCollection, Tag>(device, cancellationToken: cancellationToken).ConfigureAwait(false);
116+
device.TagGroups = await m_kepwareApiClient.GenericConfig.LoadCollectionAsync<DeviceTagGroupCollection, DeviceTagGroup>(device, cancellationToken: cancellationToken).ConfigureAwait(false);
117+
118+
if (device.TagGroups != null)
119+
{
120+
await ProjectApiHandler.LoadTagGroupsRecursiveAsync(m_kepwareApiClient, device.TagGroups, cancellationToken: cancellationToken).ConfigureAwait(false);
121+
}
122+
}
123+
124+
return device;
125+
}
126+
#endregion
127+
93128
#region CreateDeviceAsync
94129
/// <summary>
95130
/// Creates a new device with the specified name and driver in the specified channel.

0 commit comments

Comments
 (0)