<commit_before>/* Copyright 2019 Sannel Software, L.L.C.
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.*/
using Microsoft.EntityFrameworkCore;
using Sannel.House.Devices.Models;
using Sannel.House.Devices.Repositories;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace Sannel.House.Devices.Tests.Repositories
{
	public class DbContextRepositoryTests : BaseTests
	{
		[Fact]
		public void CreateNullTest()
		{
			Assert.Throws<ArgumentNullException>("context",() =>
			{
				new DbContextRepository(null);
			});
		}

		[Fact]
		public async Task GetDevicesListAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "Test 2 Name",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					var device3 = new Device()
					{
						DeviceId = 3,
						Name = "Test 3 Name",
						IsReadOnly = true,
						Description = "Test 3 Description",
						DateCreated = DateTime.UtcNow.AddDays(-1),
						DisplayOrder = 3
					};
					await context.AddRangeAsync(device1, device2, device3);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var result = await repository.GetDevicesListAsync(0, 3);
					Assert.NotNull(result);
					Assert.NotEmpty(result.Data);
					Assert.Equal(3, result.TotalCount);
					Assert.Equal(0, result.Page);
					Assert.Equal(3, result.PageSize);
					var list = result.Data.ToList();
					var device = list[0];
					AssertEqual(device2, device);
					device = list[1];
					AssertEqual(device1, device);
					device = list[2];
					AssertEqual(device3, device);

					result = await repository.GetDevicesListAsync(0, 2);
					Assert.NotNull(result);
					Assert.NotEmpty(result.Data);
					Assert.Equal(2, result.Data.Count());
					Assert.Equal(3, result.TotalCount);
					Assert.Equal(0, result.Page);
					Assert.Equal(2, result.PageSize);
					list = result.Data.ToList();
					device = list[0];
					AssertEqual(device2, device);
					device = list[1];
					AssertEqual(device1, device);

					result = await repository.GetDevicesListAsync(1, 2);
					Assert.NotNull(result);
					Assert.NotEmpty(result.Data);
					Assert.Single(result.Data);
					Assert.Equal(3, result.TotalCount);
					Assert.Equal(1, result.Page);
					Assert.Equal(2, result.PageSize);
					list = result.Data.ToList();
					device = list[0];
					AssertEqual(device3, device);

				}
			}
		}

		[Fact]
		public async Task GetDeviceByIdAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var actual = await repository.GetDeviceByIdAsync(device1.DeviceId);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByIdAsync(50);
					Assert.Null(actual);
				}
			}
		}

		[Fact]
		public async Task GetDeviceByMacAddressAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						MacAddress = 0x3223C00DF70D
					};
					var altId2 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						MacAddress = 0x18CCB5BC7ACD
					};
					var altId3 = new AlternateDeviceId()
					{
						DeviceId = device2.DeviceId,
						DateCreated = DateTime.UtcNow,
						MacAddress = 0xC5275F245FA3
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2, altId3);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var actual = await repository.GetDeviceByMacAddressAsync(altId1.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByMacAddressAsync(altId2.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByMacAddressAsync(altId3.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device2, actual);

					actual = await repository.GetDeviceByMacAddressAsync(0x0FE03C8431F7);
					Assert.Null(actual);
				}
			}
		}

		[Fact]
		public async Task GetDeviceByUuidAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Uuid = Guid.NewGuid()
					};
					var altId2 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Uuid = Guid.NewGuid()
					};
					var altId3 = new AlternateDeviceId()
					{
						DeviceId = device2.DeviceId,
						DateCreated = DateTime.UtcNow,
						Uuid = Guid.NewGuid()
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2, altId3);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var actual = await repository.GetDeviceByUuidAsync(altId1.Uuid.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByUuidAsync(altId2.Uuid.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByUuidAsync(altId3.Uuid.Value);
					Assert.NotNull(actual);
					AssertEqual(device2, actual);

					actual = await repository.GetDeviceByUuidAsync(Guid.Empty);
					Assert.Null(actual);
				}
			}
		}

		[Fact]
		public async Task CreateDeviceAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var repo = new DbContextRepository(context);
					await Assert.ThrowsAsync<ArgumentNullException>("device", () => repo.AddDeviceAsync(null));

					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow
					};

					var actualDevice = await repo.AddDeviceAsync(device1);
					Assert.NotNull(actualDevice);
					Assert.True(actualDevice.DeviceId > 0);
					Assert.Equal(device1.Name, actualDevice.Name);
					Assert.Equal(device1.IsReadOnly, actualDevice.IsReadOnly);
					Assert.Equal(device1.Description, actualDevice.Description);
					Assert.Equal(device1.DateCreated, actualDevice.DateCreated);
					Assert.Equal(1, device1.DisplayOrder);

					var device2 = new Device()
					{
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Device Description 2",
						DateCreated = DateTime.UtcNow,
					};


					actualDevice = await repo.AddDeviceAsync(device2);
					Assert.NotNull(actualDevice);
					Assert.True(actualDevice.DeviceId > 1);
					Assert.Equal(device2.Name, actualDevice.Name);
					Assert.Equal(device2.IsReadOnly, actualDevice.IsReadOnly);
					Assert.Equal(device2.Description, actualDevice.Description);
					Assert.Equal(device2.DateCreated, actualDevice.DateCreated);
					Assert.True(device2.DisplayOrder > device1.DisplayOrder);


					actualDevice = await context.Devices.FirstOrDefaultAsync(i => i.DeviceId == actualDevice.DeviceId);
					Assert.NotNull(actualDevice);
					Assert.True(actualDevice.DeviceId > 1);
					Assert.Equal(device2.Name, actualDevice.Name);
					Assert.Equal(device2.IsReadOnly, actualDevice.IsReadOnly);
					Assert.Equal(device2.Description, actualDevice.Description);
					Assert.Equal(device2.DateCreated, actualDevice.DateCreated);
					Assert.True(device2.DisplayOrder > device1.DisplayOrder);
				}
			}
		}
		
		[Fact]
		public async Task UpdateDeviceAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();
					context.Entry(device2).State = EntityState.Detached;


					var repo = new DbContextRepository(context);
					await Assert.ThrowsAsync<ArgumentNullException>("device", 
						() => repo.UpdateDeviceAsync(null));

					await Assert.ThrowsAsync<ReadOnlyException>(() => repo.UpdateDeviceAsync(device1));

					var orginialDT = device2.DateCreated;
					device2.Name = "Updated Device 2 Name";
					device2.Description = "Updated Description";
					device2.DisplayOrder = 3;
					device2.DateCreated = DateTime.MinValue.AddDays(10);

					var actual = await repo.UpdateDeviceAsync(device2);
					Assert.NotNull(actual);
					Assert.Equal(orginialDT, actual.DateCreated);
					device2.DateCreated = orginialDT;
					AssertEqual(device2, actual);

					// an unknown device attempt to update.
					Assert.Null(await repo.UpdateDeviceAsync(new Device
					{
						DeviceId = 500000
					}));
				}
			}
		}
		[Fact]
		public async Task AddAlternateMacAddressAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var id1 = 0x3223C00DF70D;

					var repo = new DbContextRepository(context);

					var actual = await repo.AddAlternateMacAddressAsync(-1, id1);
					Assert.Null(actual); // No device with -1 id

					actual = await repo.AddAlternateMacAddressAsync(device1.DeviceId, id1);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					var actualAltId = await context.AlternateDeviceIds.FirstOrDefaultAsync(i =>
										i.DeviceId == device1.DeviceId
										&& i.MacAddress == id1);
					Assert.NotNull(actualAltId);
					Assert.True(actualAltId.DateCreated > default(DateTime) 
						&& actualAltId.DateCreated < DateTime.UtcNow, "Suspect Date time was not set correctly");

					await Assert.ThrowsAsync<AlternateDeviceIdException>(() => repo.AddAlternateMacAddressAsync(device1.DeviceId, id1));

				}
			}
		}

		[Fact]
		public async Task AddAlternateUuidAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var id1 = Guid.NewGuid();

					var repo = new DbContextRepository(context);

					var actual = await repo.AddAlternateUuidAsync(-1, id1);
					Assert.Null(actual); // No device with -1 id

					actual = await repo.AddAlternateUuidAsync(device1.DeviceId, id1);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					var actualAltId = await context.AlternateDeviceIds.FirstOrDefaultAsync(i =>
										i.DeviceId == device1.DeviceId
										&& i.Uuid == id1);
					Assert.NotNull(actualAltId);
					Assert.True(actualAltId.DateCreated > default(DateTime) 
						&& actualAltId.DateCreated < DateTime.UtcNow, "Suspect Date time was not set correctly");

					await Assert.ThrowsAsync<AlternateDeviceIdException>(() => repo.AddAlternateUuidAsync(device1.DeviceId, id1));

				}
			}
		}

		[Fact]
		public async Task RemoveAlternateMacAddressAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						MacAddress = 0x3223C00DF70D,
						DateCreated = DateTime.UtcNow
					};
					var altId2 = new AlternateDeviceId
					{
						DeviceId = device1.DeviceId,
						MacAddress = 0x3223C00DF71D,
						DateCreated = DateTime.UtcNow
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2);
					await context.SaveChangesAsync();
					context.Entry(altId1).State = EntityState.Detached;
					context.Entry(altId2).State = EntityState.Detached;

					var repo = new DbContextRepository(context);

					var actual = await repo.RemoveAlternateMacAddressAsync(0x000023300);
					Assert.Null(actual);

					actual = await repo.RemoveAlternateMacAddressAsync(altId1.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					Assert.Null(context.AlternateDeviceIds.FirstOrDefault(i => i.MacAddress == altId1.MacAddress));
					Assert.NotNull(context.AlternateDeviceIds.FirstOrDefault(i => i.MacAddress == altId2.MacAddress));
				}
			}
		}
		
		[Fact]
		public async Task RemoveAlternateUuidAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();<commit_msg>Started Adding Tests around ManufactureIds<commit_after>/* Copyright 2019 Sannel Software, L.L.C.
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.*/
using Microsoft.EntityFrameworkCore;
using Sannel.House.Devices.Models;
using Sannel.House.Devices.Repositories;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace Sannel.House.Devices.Tests.Repositories
{
	public class DbContextRepositoryTests : BaseTests
	{
		[Fact]
		public void CreateNullTest()
		{
			Assert.Throws<ArgumentNullException>("context",() =>
			{
				new DbContextRepository(null);
			});
		}

		[Fact]
		public async Task GetDevicesListAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					var device3 = new Device()
					{
						DeviceId = 3,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 3 Description",
						DateCreated = DateTime.UtcNow.AddDays(-1),
						DisplayOrder = 3
					};
					await context.AddRangeAsync(device1, device2, device3);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var result = await repository.GetDevicesListAsync(0, 3);
					Assert.NotNull(result);
					Assert.NotEmpty(result.Data);
					Assert.Equal(3, result.TotalCount);
					Assert.Equal(0, result.Page);
					Assert.Equal(3, result.PageSize);
					var list = result.Data.ToList();
					var device = list[0];
					AssertEqual(device2, device);
					device = list[1];
					AssertEqual(device1, device);
					device = list[2];
					AssertEqual(device3, device);

					result = await repository.GetDevicesListAsync(0, 2);
					Assert.NotNull(result);
					Assert.NotEmpty(result.Data);
					Assert.Equal(2, result.Data.Count());
					Assert.Equal(3, result.TotalCount);
					Assert.Equal(0, result.Page);
					Assert.Equal(2, result.PageSize);
					list = result.Data.ToList();
					device = list[0];
					AssertEqual(device2, device);
					device = list[1];
					AssertEqual(device1, device);

					result = await repository.GetDevicesListAsync(1, 2);
					Assert.NotNull(result);
					Assert.NotEmpty(result.Data);
					Assert.Single(result.Data);
					Assert.Equal(3, result.TotalCount);
					Assert.Equal(1, result.Page);
					Assert.Equal(2, result.PageSize);
					list = result.Data.ToList();
					device = list[0];
					AssertEqual(device3, device);

				}
			}
		}

		[Fact]
		public async Task GetDeviceByIdAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var actual = await repository.GetDeviceByIdAsync(device1.DeviceId);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByIdAsync(50);
					Assert.Null(actual);
				}
			}
		}

		[Fact]
		public async Task GetDeviceByMacAddressAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						MacAddress = 0x3223C00DF70D
					};
					var altId2 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						MacAddress = 0x18CCB5BC7ACD
					};
					var altId3 = new AlternateDeviceId()
					{
						DeviceId = device2.DeviceId,
						DateCreated = DateTime.UtcNow,
						MacAddress = 0xC5275F245FA3
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2, altId3);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var actual = await repository.GetDeviceByMacAddressAsync(altId1.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByMacAddressAsync(altId2.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByMacAddressAsync(altId3.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device2, actual);

					actual = await repository.GetDeviceByMacAddressAsync(0x0FE03C8431F7);
					Assert.Null(actual);
				}
			}
		}

		[Fact]
		public async Task GetDeviceByUuidAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Uuid = Guid.NewGuid()
					};
					var altId2 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Uuid = Guid.NewGuid()
					};
					var altId3 = new AlternateDeviceId()
					{
						DeviceId = device2.DeviceId,
						DateCreated = DateTime.UtcNow,
						Uuid = Guid.NewGuid()
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2, altId3);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var actual = await repository.GetDeviceByUuidAsync(altId1.Uuid.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByUuidAsync(altId2.Uuid.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByUuidAsync(altId3.Uuid.Value);
					Assert.NotNull(actual);
					AssertEqual(device2, actual);

					actual = await repository.GetDeviceByUuidAsync(Guid.Empty);
					Assert.Null(actual);
				}
			}
		}

		[Fact]
		public async Task GetDeviceByManifactureIdAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Manufacture = "Arduino",
						ManufactureId = "123456789"
					};
					var altId2 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Manufacture = "Zebra",
						ManufactureId = "123456789"
					};
					var altId3 = new AlternateDeviceId()
					{
						DeviceId = device2.DeviceId,
						DateCreated = DateTime.UtcNow,
						Manufacture = "Particle",
						ManufactureId = "ParticleId"
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2, altId3);
					await context.SaveChangesAsync();

					var repository = new DbContextRepository(context);
					var actual = await repository.GetDeviceByManufactureIdAsync(altId1.Manufacture, altId1.ManufactureId);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByManufactureIdAsync(altId2.Manufacture, altId1.ManufactureId);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					actual = await repository.GetDeviceByManufactureIdAsync(altId3.Manufacture, altId3.ManufactureId);
					Assert.NotNull(actual);
					AssertEqual(device2, actual);

					actual = await repository.GetDeviceByManufactureIdAsync("Unknown","Other");
					Assert.Null(actual);
				}
			}
		}

		[Fact]
		public async Task CreateDeviceAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var repo = new DbContextRepository(context);
					await Assert.ThrowsAsync<ArgumentNullException>("device", () => repo.AddDeviceAsync(null));

					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow
					};

					var actualDevice = await repo.AddDeviceAsync(device1);
					Assert.NotNull(actualDevice);
					Assert.True(actualDevice.DeviceId > 0);
					Assert.Equal(device1.Name, actualDevice.Name);
					Assert.Equal(device1.IsReadOnly, actualDevice.IsReadOnly);
					Assert.Equal(device1.Description, actualDevice.Description);
					Assert.Equal(device1.DateCreated, actualDevice.DateCreated);
					Assert.Equal(1, device1.DisplayOrder);

					var device2 = new Device()
					{
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Device Description 2",
						DateCreated = DateTime.UtcNow,
					};


					actualDevice = await repo.AddDeviceAsync(device2);
					Assert.NotNull(actualDevice);
					Assert.True(actualDevice.DeviceId > 1);
					Assert.Equal(device2.Name, actualDevice.Name);
					Assert.Equal(device2.IsReadOnly, actualDevice.IsReadOnly);
					Assert.Equal(device2.Description, actualDevice.Description);
					Assert.Equal(device2.DateCreated, actualDevice.DateCreated);
					Assert.True(device2.DisplayOrder > device1.DisplayOrder);


					actualDevice = await context.Devices.FirstOrDefaultAsync(i => i.DeviceId == actualDevice.DeviceId);
					Assert.NotNull(actualDevice);
					Assert.True(actualDevice.DeviceId > 1);
					Assert.Equal(device2.Name, actualDevice.Name);
					Assert.Equal(device2.IsReadOnly, actualDevice.IsReadOnly);
					Assert.Equal(device2.Description, actualDevice.Description);
					Assert.Equal(device2.DateCreated, actualDevice.DateCreated);
					Assert.True(device2.DisplayOrder > device1.DisplayOrder);
				}
			}
		}
		
		[Fact]
		public async Task UpdateDeviceAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();
					context.Entry(device2).State = EntityState.Detached;


					var repo = new DbContextRepository(context);
					await Assert.ThrowsAsync<ArgumentNullException>("device", 
						() => repo.UpdateDeviceAsync(null));

					await Assert.ThrowsAsync<ReadOnlyException>(() => repo.UpdateDeviceAsync(device1));

					var orginialDT = device2.DateCreated;
					device2.Name = "Updated Device 2 Name";
					device2.Description = "Updated Description";
					device2.DisplayOrder = 3;
					device2.DateCreated = DateTime.MinValue.AddDays(10);

					var actual = await repo.UpdateDeviceAsync(device2);
					Assert.NotNull(actual);
					Assert.Equal(orginialDT, actual.DateCreated);
					device2.DateCreated = orginialDT;
					AssertEqual(device2, actual);

					// an unknown device attempt to update.
					Assert.Null(await repo.UpdateDeviceAsync(new Device
					{
						DeviceId = 500000
					}));
				}
			}
		}
		[Fact]
		public async Task AddAlternateMacAddressAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var id1 = 0x3223C00DF70D;

					var repo = new DbContextRepository(context);

					var actual = await repo.AddAlternateMacAddressAsync(-1, id1);
					Assert.Null(actual); // No device with -1 id

					actual = await repo.AddAlternateMacAddressAsync(device1.DeviceId, id1);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					var actualAltId = await context.AlternateDeviceIds.FirstOrDefaultAsync(i =>
										i.DeviceId == device1.DeviceId
										&& i.MacAddress == id1);
					Assert.NotNull(actualAltId);
					Assert.True(actualAltId.DateCreated > default(DateTime) 
						&& actualAltId.DateCreated < DateTime.UtcNow, "Suspect Date time was not set correctly");

					await Assert.ThrowsAsync<AlternateDeviceIdException>(() => repo.AddAlternateMacAddressAsync(device1.DeviceId, id1));

				}
			}
		}

		[Fact]
		public async Task AddAlternateUuidAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var id1 = Guid.NewGuid();

					var repo = new DbContextRepository(context);

					var actual = await repo.AddAlternateUuidAsync(-1, id1);
					Assert.Null(actual); // No device with -1 id

					actual = await repo.AddAlternateUuidAsync(device1.DeviceId, id1);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					var actualAltId = await context.AlternateDeviceIds.FirstOrDefaultAsync(i =>
										i.DeviceId == device1.DeviceId
										&& i.Uuid == id1);
					Assert.NotNull(actualAltId);
					Assert.True(actualAltId.DateCreated > default(DateTime) 
						&& actualAltId.DateCreated < DateTime.UtcNow, "Suspect Date time was not set correctly");

					await Assert.ThrowsAsync<AlternateDeviceIdException>(() => repo.AddAlternateUuidAsync(device1.DeviceId, id1));

				}
			}
		}

		[Fact]
		public async Task AddAlternateManifactureIdAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};
					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var manufacture = "Particle";
					var manufactureId = "123456";

					var repo = new DbContextRepository(context);

					var actual = await repo.AddAlternateManufactureIdAsync(-1, manufacture, manufactureId);
					Assert.Null(actual); // No device with -1 id

					actual = await repo.AddAlternateManufactureIdAsync(device1.DeviceId, manufacture, manufactureId);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					var actualAltId = await context.AlternateDeviceIds.FirstOrDefaultAsync(i =>
										i.DeviceId == device1.DeviceId
										&& i.Manufacture == manufacture
										&& i.ManufactureId == manufactureId);
					Assert.NotNull(actualAltId);
					Assert.True(actualAltId.DateCreated > default(DateTime) 
						&& actualAltId.DateCreated < DateTime.UtcNow, "Suspect Date time was not set correctly");

					await Assert.ThrowsAsync<AlternateDeviceIdException>(() => repo.AddAlternateManufactureIdAsync(device1.DeviceId, manufacture, manufactureId));

				}
			}
		}

		[Fact]
		public async Task RemoveAlternateMacAddressAsyncTest()
		{

			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						MacAddress = 0x3223C00DF70D,
						DateCreated = DateTime.UtcNow
					};
					var altId2 = new AlternateDeviceId
					{
						DeviceId = device1.DeviceId,
						MacAddress = 0x3223C00DF71D,
						DateCreated = DateTime.UtcNow
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2);
					await context.SaveChangesAsync();
					context.Entry(altId1).State = EntityState.Detached;
					context.Entry(altId2).State = EntityState.Detached;

					var repo = new DbContextRepository(context);

					var actual = await repo.RemoveAlternateMacAddressAsync(0x000023300);
					Assert.Null(actual);

					actual = await repo.RemoveAlternateMacAddressAsync(altId1.MacAddress.Value);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					Assert.Null(context.AlternateDeviceIds.FirstOrDefault(i => i.MacAddress == altId1.MacAddress));
					Assert.NotNull(context.AlternateDeviceIds.FirstOrDefault(i => i.MacAddress == altId2.MacAddress));
				}
			}
		}
		
		[Fact]
		public async Task RemoveAlternateManufactureIdAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();

					var altId1 = new AlternateDeviceId()
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Manufacture = "Particle",
						ManufactureId = "Photon53"
					};
					var altId2 = new AlternateDeviceId
					{
						DeviceId = device1.DeviceId,
						DateCreated = DateTime.UtcNow,
						Manufacture = "Particle",
						ManufactureId = "Photon34"
					};

					await context.AlternateDeviceIds.AddRangeAsync(altId1, altId2);
					await context.SaveChangesAsync();
					context.Entry(altId1).State = EntityState.Detached;
					context.Entry(altId2).State = EntityState.Detached;

					var repo = new DbContextRepository(context);

					var actual = await repo.RemoveAlternateManufactureIdAsync("Particle", "Core");
					Assert.Null(actual);

					actual = await repo.RemoveAlternateManufactureIdAsync(altId1.Manufacture, altId1.ManufactureId);
					Assert.NotNull(actual);
					AssertEqual(device1, actual);

					Assert.Null(context.AlternateDeviceIds.FirstOrDefault(i => i.Manufacture == altId1.Manufacture 
																			&& i.ManufactureId == altId1.ManufactureId));
					Assert.NotNull(context.AlternateDeviceIds.FirstOrDefault(i => i.Manufacture == altId2.Manufacture
																			&& i.ManufactureId == altId2.ManufactureId));
				}
			}
		}

		[Fact]
		public async Task RemoveAlternateUuidAsyncTest()
		{
			using (var connection = OpenConnection())
			{
				using (var context = GetTestDB(connection))
				{
					var device1 = new Device()
					{
						DeviceId = 1,
						Name = "<NAME>",
						IsReadOnly = true,
						Description = "Dest Description",
						DateCreated = DateTime.UtcNow,
						DisplayOrder = 2
					};
					var device2 = new Device()
					{
						DeviceId = 2,
						Name = "<NAME>",
						IsReadOnly = false,
						Description = "Test 2 Description",
						DateCreated = DateTime.UtcNow.AddDays(-2),
						DisplayOrder = 1
					};

					await context.Devices.AddRangeAsync(device1, device2);
					await context.SaveChangesAsync();
{'fraction_non_alphanumeric': 0.10836941546939578, 'fraction_numerical': 0.01798366463294627, 'mean_word_length': 2.8676498572787823, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5397508', 'n_tokens_mistral': 17119, 'n_tokens_neox': 12020, 'n_words': 2599}