public async Task RegisterAsyncNewTest()
        {
            //arrange 
            var dbConnection = new UnitTestDbConnection();
            Database.SetInitializer(new CreateFreshDbInitializer());
            var dsb = new DeviceSettingBuilder(dbConnection);

            var deviceSetting = new DeviceSetting
            {
                Name = "Unit Test Device Setting",
                UniqueIdentifier = "DEVICE_SETTING1"
            };

            //act
            var result = await dsb.RegisterAsync(deviceSetting, CancellationToken.None);

            DeviceSetting setting;
            using (var context = new ZvsContext(dbConnection))
            {
                setting =
                    await
                        context.DeviceSettings.FirstOrDefaultAsync(
                            o => o.UniqueIdentifier == deviceSetting.UniqueIdentifier);

            }

            //assert 
            Console.WriteLine(result.Message);
            Assert.IsFalse(result.HasError, result.Message);
            Assert.IsNotNull(setting, "Expected new device setting saved to DB");
        }
        public async Task<Result> RegisterAsync(DeviceSetting deviceSetting, CancellationToken cancellationToken)
        {
            if (deviceSetting == null)
                return Result.ReportError("deviceSetting is null");

            using (var context = new ZvsContext(EntityContextConnection))
            {
                var setting = await context.DeviceSettings
                    .Include(o => o.Options)
                    .FirstOrDefaultAsync(d => d.UniqueIdentifier == deviceSetting.UniqueIdentifier, cancellationToken);

                var changed = false;
                if (setting == null)
                {
                    context.DeviceSettings.Add(deviceSetting);
                    changed = true;
                }
                else
                {
                    PropertyChangedEventHandler handler = (s, a) => changed = true;
                    setting.PropertyChanged += handler;

                    setting.Name = deviceSetting.Name;
                    setting.Description = deviceSetting.Description;
                    setting.ValueType = deviceSetting.ValueType;
                    setting.Value = deviceSetting.Value;

                    setting.PropertyChanged -= handler;

                    var added = deviceSetting.Options.Where(option => setting.Options.All(o => o.Name != option.Name)).ToList();
                    foreach (var option in added)
                    {
                        setting.Options.Add(option);
                        changed = true;
                    }

                    var removed = setting.Options.Where(option => deviceSetting.Options.All(o => o.Name != option.Name)).ToList();
                    foreach (var option in removed)
                    {
                        context.DeviceSettingOptions.Local.Remove(option);
                        changed = true;
                    }
                }

                if (changed)
                    return await context.TrySaveChangesAsync(cancellationToken);

                return Result.ReportSuccess("Nothing to update");
            }
        }
        public async Task RegisterAsyncOptionRemoveTest()
        {
            //arrange 
            var dbConnection = new UnitTestDbConnection();
            Database.SetInitializer(new CreateFreshDbInitializer());
            var dsb = new DeviceSettingBuilder(dbConnection);

            var deviceSetting = new DeviceSetting
            {
                Name = "Unit Test Device Setting",
                UniqueIdentifier = "DEVICE_SETTING1"
            };

            var option1 = new DeviceSettingOption
            {
                Name = "Option 1"
            };
            var option2 = new DeviceSettingOption
            {
                Name = "Option 2"
            };
            deviceSetting.Options.Add(option1);
            deviceSetting.Options.Add(option2);

            using (var context = new ZvsContext(dbConnection))
            {
                context.DeviceSettings.Add(deviceSetting);
                await context.SaveChangesAsync();
            }
            
            deviceSetting.Options.Remove(option2);

            //act
            var result = await dsb.RegisterAsync(deviceSetting, CancellationToken.None);

            DeviceSetting setting;
            using (var context = new ZvsContext(dbConnection))
            {
                setting = await context.DeviceSettings
                        .Include(o => o.Options)
                        .FirstOrDefaultAsync(o => o.UniqueIdentifier == deviceSetting.UniqueIdentifier);

            }

            //assert 
            Console.WriteLine(result.Message);
            Assert.IsFalse(result.HasError, result.Message);
            Assert.IsNotNull(setting, "Expected new device setting saved to DB");
            Assert.IsTrue(setting.Options.Count == 1, "Expected 1 option!");
            Assert.IsTrue(setting.Options[0].Name == option1.Name);
        }
        public async Task RegisterRemovedDeviceSettingOptionTest()
        {
            //Arrange 
            var dbConnection = new StubIEntityContextConnection { NameOrConnectionStringGet = () => "asb-RegisterRemovedDeviceSettingOptionTest" };
            Database.SetInitializer(new CreateFreshDbInitializer());

            var adapterBuilder = new AdapterSettingBuilder(dbConnection, CancellationToken.None);
            var deviceSetting = new DeviceSetting
            {
                Name = "Device Setting 1",
                ValueType = DataType.STRING,
                Value = "Hello World"
            };
            var option1 = new DeviceSettingOption
            {
                Name = "Option 1",
            };
            var option2 = new DeviceSettingOption
            {
                Name = "Option 2",
            };
            deviceSetting.Options.Add(option1);
            deviceSetting.Options.Add(option2);
            using (var context = new ZvsContext(dbConnection))
            {
                context.DeviceSettings.Add(deviceSetting);
                await context.SaveChangesAsync();
            }

            deviceSetting.Options.Remove(option2);

            //act
            var result = await adapterBuilder.RegisterDeviceSettingAsync(deviceSetting);

            DeviceSetting setting;
            using (var context = new ZvsContext(dbConnection))
            {
                setting = await context.DeviceSettings
                    .Include(o => o.Options)
                    .FirstOrDefaultAsync();
            }

            //assert 
            Console.WriteLine(result.Message);
            Assert.IsFalse(result.HasError);
            Assert.IsNotNull(setting, "Setting not found");
            Assert.IsTrue(setting.Options.Count == 1, "Expected 2 options");
            Assert.IsTrue(setting.Options[0].Name == option1.Name, "Name mismatch");
        }
        public async Task RegisterNoUpdateDeviceSettingTest()
        {
            //Arrange 
            var dbConnection = new StubIEntityContextConnection { NameOrConnectionStringGet = () => "asb-RegisterNoUpdateDeviceSettingTest" };
            Database.SetInitializer(new CreateFreshDbInitializer());

            var adapterBuilder = new AdapterSettingBuilder(dbConnection, CancellationToken.None);
            var deviceSetting = new DeviceSetting
            {
                Name = "Device Setting 1",
                ValueType = DataType.STRING,
                Value = "Hello World"
            };

            using (var context = new ZvsContext(dbConnection))
            {
                context.DeviceSettings.Add(deviceSetting);
                await context.SaveChangesAsync();
            }

            //act
            var result = await adapterBuilder.RegisterDeviceSettingAsync(deviceSetting);

            DeviceSetting setting;
            using (var context = new ZvsContext(dbConnection))
            {
                setting = await context.DeviceSettings.FirstOrDefaultAsync();
            }

            //assert 
            Console.WriteLine(result.Message);
            Assert.IsFalse(result.HasError);
            Assert.IsNotNull(setting, "Setting not found");
            Assert.IsTrue(setting.Value == deviceSetting.Value, "Device setting name mismatch");
        }
        public async Task RegisterNewDeviceSettingTest()
        {
            //Arrange 
            var dbConnection = new UnitTestDbConnection();
            Database.SetInitializer(new CreateFreshDbInitializer());
            var adapterBuilder = new AdapterSettingBuilder( dbConnection, CancellationToken.None);
            var deviceSetting = new DeviceSetting
            {
                Name = "Device Setting 1",
                ValueType = DataType.STRING,
                Value = "Hello World"
            };

            //act
            var result = await adapterBuilder.RegisterDeviceSettingAsync(deviceSetting);

            DeviceSetting setting;
            using (var context = new ZvsContext(dbConnection))
            {
                setting = await context.DeviceSettings.FirstOrDefaultAsync();
            }

            //assert 
            Console.WriteLine(result.Message);
            Assert.IsFalse(result.HasError);
            Assert.IsNotNull(setting, "Setting not saved!");
            Assert.IsTrue(setting.Name == deviceSetting.Name, "Device setting name mismatch");
        }
        public async Task RegisterAsyncUpdateTest()
        {
            //arrange 
            var dbConnection = new StubIEntityContextConnection { NameOrConnectionStringGet = () => "dsb-RegisterAsyncUpdateTest" };
            Database.SetInitializer(new CreateFreshDbInitializer());
            var dsb = new DeviceSettingBuilder(dbConnection);

            var deviceSetting = new DeviceSetting
            {
                Name = "Unit Test Device Setting",
                UniqueIdentifier = "DEVICE_SETTING1"
            };

            using (var context = new ZvsContext(dbConnection))
            {
                context.DeviceSettings.Add(deviceSetting);
                await context.SaveChangesAsync();
            }

            deviceSetting.Name = "New Name";

            //act
            var result = await dsb.RegisterAsync(deviceSetting, CancellationToken.None);

            DeviceSetting setting;
            using (var context = new ZvsContext(dbConnection))
            {
                setting =
                    await
                        context.DeviceSettings.FirstOrDefaultAsync(
                            o => o.UniqueIdentifier == deviceSetting.UniqueIdentifier);

            }

            //assert 
            Console.WriteLine(result.Message);
            Assert.IsFalse(result.HasError, result.Message);
            Assert.IsNotNull(setting, "Expected new device setting saved to DB");
            Assert.IsTrue(setting.Name == "New Name");
        }