public void Register_ThenAllocHGlobalForBuffer()
        {
            // ARRANGE
            var mockedBroadcastDeviceInterfaceFactory = new Mock<IBroadcastDeviceInterfaceFactory>();
            var mockedMarshallWrapper = new Mock<IMarshalWrapper>();
            var mockedUnsafeNativeMethodsWrapper = new Mock<IUnsafeNativeMethodsWrapper>();
            var mockedProcessHandleResultFactory = new Mock<IProcessHandleResultFactory>();
            var deviceManagement = new DeviceNotifications(
                mockedBroadcastDeviceInterfaceFactory.Object,
                mockedMarshallWrapper.Object,
                mockedUnsafeNativeMethodsWrapper.Object,
                mockedProcessHandleResultFactory.Object);
            var handleReceivesNotifications = new IntPtr(42);
            var devBroadcastDeviceInterface = new BroadcastDeviceInterface();

            mockedBroadcastDeviceInterfaceFactory.Setup(x => x.CreateBroadcastDeviceInterface()).Returns(devBroadcastDeviceInterface);

            // ACT
            deviceManagement.Register(handleReceivesNotifications);

            // ASSERT
            mockedMarshallWrapper.Verify(x => x.AllocHGlobal(devBroadcastDeviceInterface.Size), Times.Once);
        }
        public void Register_WhenStructureToPointerThrowsException_ThenFreeGlobalIsCalled()
        {
            // ARRANGE
            var mockedBroadcastDeviceInterfaceFactory = new Mock<IBroadcastDeviceInterfaceFactory>();
            var mockedMarshallWrapper = new Mock<IMarshalWrapper>();
            var mockedUnsafeNativeMethodsWrapper = new Mock<IUnsafeNativeMethodsWrapper>();
            var mockedProcessHandleResultFactory = new Mock<IProcessHandleResultFactory>();
            var deviceManagement = new DeviceNotifications(
                mockedBroadcastDeviceInterfaceFactory.Object,
                mockedMarshallWrapper.Object,
                mockedUnsafeNativeMethodsWrapper.Object,
                mockedProcessHandleResultFactory.Object);
            var handleReceivesNotifications = new IntPtr(42);
            var devBroadcastDeviceInterface = new BroadcastDeviceInterface();
            var intPtrForBuffer = new IntPtr(111);

            mockedBroadcastDeviceInterfaceFactory.Setup(x => x.CreateBroadcastDeviceInterface()).Returns(devBroadcastDeviceInterface);
            mockedMarshallWrapper.Setup(x => x.AllocHGlobal(devBroadcastDeviceInterface.Size)).Returns(intPtrForBuffer);
            mockedMarshallWrapper.Setup(x => x.StructureToPointer(devBroadcastDeviceInterface, intPtrForBuffer, false)).Throws<InvalidOperationException>();

            // ACT
            var testDelegate = new Assert.ThrowsDelegate(() => deviceManagement.Register(handleReceivesNotifications));

            // ASSERT
            Assert.Throws<InvalidOperationException>(testDelegate);
            mockedMarshallWrapper.Verify(x => x.FreeHGlobal(intPtrForBuffer), Times.Once);
        }
        /// <summary>
        /// The setup device watcher with handle created.
        /// </summary>
        /// <param name="testScheduler">
        /// The test scheduler.
        /// </param>
        /// <param name="mockedHandle">
        /// The mocked Handle.
        /// </param>
        /// <param name="guid">
        /// The guid to use to register for device notifications.
        /// </param>
        /// <param name="message">
        /// The message to use when creating a UsbDeviceNotification.
        /// </param>
        /// <param name="mockedUsbDeviceNotificationFactory">
        /// The mocked Usb Device Notification Factory.
        /// </param>
        /// <param name="mockedMarshalWrapperThrowsException">
        /// The mocked Marshal Wrapper Throws Exception.
        /// </param>
        /// <param name="numberOfNotifications">
        /// The number Of Notifications.
        /// </param>
        /// <returns>
        /// The <see cref="UsbDeviceWatcher"/>.
        /// </returns>
        private TestUsbDeviceWatcher SetupTestDeviceWatcherWithHandleCreated(
            TestScheduler testScheduler,
            Mock<IHandle> mockedHandle,
            Guid guid,
            Message message = default(Message),
            Mock<IUsbDeviceNotificationFactory> mockedUsbDeviceNotificationFactory = null,
            bool mockedMarshalWrapperThrowsException = false,
            int numberOfNotifications = 1)
        {
            const string NAME = "Name";
            var lParam = new IntPtr(42);
            var messageToUse = message == default(Message) ? new Message { Msg = 0 } : message;
            messageToUse.LParam = lParam;
            var guidToUse = guid == Guid.Empty ? Guid.NewGuid() : guid;
            var subject = new Subject<IHandle>();
            var mockedUsbForm = new Mock<IUsbForm>();
            var mockedUsbDeviceNotificationFactoryToUse = mockedUsbDeviceNotificationFactory ?? new Mock<IUsbDeviceNotificationFactory>();
            var mockedMarshalWrapper = new Mock<IMarshalWrapper>();
            var mockedDevBroadcastDeviceInterface = new BroadcastDeviceInterface {Name = NAME, Guid = guidToUse};

            if (mockedMarshalWrapperThrowsException)
            {
                mockedMarshalWrapper.Setup(x => x.PointerToStructure<BroadcastDeviceInterface>(lParam, typeof(BroadcastDeviceInterface))).Throws<InvalidOperationException>();
            }
            else
            {
                mockedMarshalWrapper.Setup(x => x.PointerToStructure<BroadcastDeviceInterface>(lParam, typeof(BroadcastDeviceInterface))).Returns(mockedDevBroadcastDeviceInterface);
            }
            mockedUsbForm.Setup(x => x.Run()).Returns(subject);
            mockedUsbDeviceNotificationFactoryToUse.Setup(x => x.Create(guidToUse, messageToUse, NAME))
                .Returns(() => new UsbDeviceNotification(guidToUse, messageToUse, NAME));

            var testUsbDeviceWatcher = new TestUsbDeviceWatcher(mockedMarshalWrapper.Object, mockedUsbDeviceNotificationFactoryToUse.Object, mockedUsbForm.Object, guidToUse);

            Enumerable.Range(0, numberOfNotifications)
                        .ToList()
                        .ForEach(x => testScheduler.Schedule(() =>
                        {
                            subject.OnNext(mockedHandle.Object);
                            testUsbDeviceWatcher.SimulateMessage(messageToUse);
                        }));

            return testUsbDeviceWatcher;
        }