public void Throws_When_Device_Is_Already_Registered()
        {
            var deviceInfo = DefaultDeviceInfo;

            using var cache = CreateDefaultCache();
            var factory = new TestDeviceFactory(loRaDeviceCache: cache);

            using var device = new LoRaDevice(deviceInfo.DevAddr, deviceInfo.DevEUI, null);
            cache.Register(device);
            Assert.ThrowsAsync <InvalidOperationException>(() => factory.CreateAndRegisterAsync(deviceInfo, this.cancellationToken));
        }
        public async Task When_Init_Fails_Cleaned_Up()
        {
            var connectionManager = new Mock <ILoRaDeviceClientConnectionManager>();

            using var cache = CreateDefaultCache();
            var factory = new TestDeviceFactory(DefaultConfiguration, connectionManager.Object, cache, x => x.Setup(y => y.InitializeAsync(DefaultConfiguration, this.cancellationToken)).ReturnsAsync(false), TestMeter.Instance);
            await Assert.ThrowsAsync <LoRaProcessingException>(() => factory.CreateAndRegisterAsync(DefaultDeviceInfo, this.cancellationToken));

            Assert.False(cache.TryGetByDevEui(this.DefaultDeviceInfo.DevEUI, out _));
            connectionManager.VerifyFailure(factory.LastDeviceMock.Object);
            factory.LastDeviceMock.Protected().Verify(nameof(LoRaDevice.Dispose), Times.Once(), true, true);
        }
        public async Task When_Created_But_Not_Our_Device_It_Is_Not_Initialized_But_Connection_Is_Registered()
        {
            var connectionManager = new Mock <ILoRaDeviceClientConnectionManager>();

            using var cache = CreateDefaultCache();
            var factory = new TestDeviceFactory(DefaultConfiguration, connectionManager.Object, cache, x => x.Object.GatewayID = "OtherGw", TestMeter.Instance);

            var device = await factory.CreateAndRegisterAsync(DefaultDeviceInfo, this.cancellationToken);

            factory.LastDeviceMock.Verify(x => x.InitializeAsync(DefaultConfiguration, this.cancellationToken), Times.Never);
            connectionManager.VerifySuccess(device);
        }
        public void Throws_When_Missing_DeviceInfo()
        {
            var factory    = new TestDeviceFactory();
            var deviceInfo = DefaultDeviceInfo;

            deviceInfo.PrimaryKey = null;

            Assert.ThrowsAsync <ArgumentException>(() => factory.CreateAndRegisterAsync(deviceInfo, CancellationToken.None));

            deviceInfo        = DefaultDeviceInfo;
            deviceInfo.DevEUI = new DevEui(0);
            Assert.ThrowsAsync <ArgumentException>(() => factory.CreateAndRegisterAsync(deviceInfo, this.cancellationToken));
        }
        public async Task When_Created_Successfully_It_Is_Cached()
        {
            var connectionManager = new Mock <ILoRaDeviceClientConnectionManager>();

            using var cache = CreateDefaultCache();
            var factory = new TestDeviceFactory(DefaultConfiguration, connectionManager.Object, cache, meter: TestMeter.Instance);

            var device = await factory.CreateAndRegisterAsync(DefaultDeviceInfo, this.cancellationToken);

            Assert.True(cache.TryGetByDevEui(this.DefaultDeviceInfo.DevEUI, out var cachedDevice));
            Assert.Equal(device, cachedDevice);

            factory.LastDeviceMock.Verify(x => x.InitializeAsync(DefaultConfiguration, this.cancellationToken), Times.Once);
            connectionManager.VerifySuccess(device);
        }