public void When_packet_contains_unexpected_parameter_it_must_warn()
        {
            // Arrange
            var buffer = new byte[]
            {
                2,
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('2'),
                ByteFor('3'),
                ByteFor('4'),
                ByteFor('5'),
                ByteFor('6'),
                ByteFor('\t'),
                3
            };
            var logger = new FakeSystemLogger();
            var reader = new PacketReader { ActiveLogger = logger };

            // Act
            reader.Read(buffer);

            // Assert
            logger.WarningMessages.Should().HaveCount(1);
            logger.WarningMessages[0].Should().StartWith(
                "Warning at packet position 5: Ignoring unexpected occurrence of parameter 14 in packet for operation 1.");
        }
        public void When_parameter_format_is_invalid_it_must_throw()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('2'),
                05,
                ByteFor('4'),
                ByteFor('5'),
                ByteFor('6'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Action action = () => reader.Read(buffer);

            // Assert
            action.ShouldThrow<ParameterValueFormatException>()
                .WithMessage(
                    "Error at position 9: Value of NetworkAddressParameter DestinationAddress must consist of 6 characters in range 0-9 or A-F.*");
        }
        public void When_reading_login_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new LoginOperation();

            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
        public void When_operation_code_is_unknown_it_must_throw()
        {
            // Arrange
            byte[] buffer = { 2, ByteFor('1'), ByteFor('1'), ByteFor('\t'), 3 };
            var reader = new PacketReader();

            // Act
            Action action = () => reader.Read(buffer);

            // Assert
            action.ShouldThrow<UnknownOperationException>()
                .WithMessage(
                    "Error at position 1: Unsupported operation code 11.*");
        }
        public void When_checksum_is_invalid_it_must_throw()
        {
            // Arrange
            byte[] buffer = { 2, ByteFor('0'), ByteFor('1'), ByteFor('\t'), ByteFor('6'), 68, 3 };
            var reader = new PacketReader();

            // Act
            Action action = () => reader.Read(buffer);

            // Assert
            action.ShouldThrow<ChecksumMismatchException>()
                .WithMessage(
                    "Error at position 5: Invalid checksum (stored=0x6D, calculated=0x6C).*");
        }
        public void When_reading_visualize_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('0'),
                ByteFor('7'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('8'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('2'),
                ByteFor('3'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('9'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('2'),
                ByteFor('5'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('0'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('1'),
                ByteFor(':'),
                ByteFor('2'),
                ByteFor('5'),
                ByteFor('9'),
                ByteFor('4'),
                ByteFor('3'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('2'),
                ByteFor(':'),
                ByteFor('5'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('3'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('0'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('5'),
                ByteFor(':'),
                ByteFor('2'),
                ByteFor('3'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('A'),
                ByteFor('B'),
                ByteFor('C'),
                ByteFor('D'),
                ByteFor('E'),
                ByteFor('F'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('A'),
                ByteFor('A'),
                ByteFor('B'),
                ByteFor('B'),
                ByteFor('C'),
                ByteFor('C'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('8'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('6'),
                ByteFor('1'),
                ByteFor('2'),
                ByteFor('3'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new VisualizeOperation(new[]
            {
                new WirelessNetworkAddress("ABCDEF"),
                new WirelessNetworkAddress("AABBCC")
            })
            {
                CurrentCompetitorNumber = 123,
                NextCompetitorNumber = 125,
                StartTimer = true,
                PrimaryTimerValue = 25.Seconds().And(943.Milliseconds()),
                SecondaryTimerValue = 16.Seconds().And(123.Milliseconds()),
                FaultCount = 5,
                RefusalCount = 10,
                Eliminated = true,
                PreviousPlacement = 23
            };

            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
        public void When_reading_notify_action_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('5'),
                ByteFor('3'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('5'),
                ByteFor(':'),
                ByteFor('A'),
                ByteFor('B'),
                ByteFor('C'),
                ByteFor('D'),
                ByteFor('E'),
                ByteFor('F'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('6'),
                ByteFor('6'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('5'),
                ByteFor(':'),
                ByteFor('4'),
                ByteFor('5'),
                ByteFor('7'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new NotifyActionOperation(new WirelessNetworkAddress("ABCDEF"))
            {
                InputKeys = RawDeviceKeys.Key2OrPassIntermediate | RawDeviceKeys.Key7,
                SensorTime = TimeSpan.FromMilliseconds(456.75)
            };
            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
        public void When_reading_notify_status_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('5'),
                ByteFor('2'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('5'),
                ByteFor(':'),
                ByteFor('A'),
                ByteFor('B'),
                ByteFor('C'),
                ByteFor('D'),
                ByteFor('E'),
                ByteFor('F'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('6'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('9'),
                ByteFor(':'),
                ByteFor('3'),
                ByteFor('2'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('0'),
                ByteFor(':'),
                ByteFor('3'),
                ByteFor('2'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('1'),
                ByteFor(':'),
                ByteFor('2'),
                ByteFor('5'),
                ByteFor('3'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('2'),
                ByteFor(':'),
                ByteFor('2'),
                ByteFor('4'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('3'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('7'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new NotifyStatusOperation(new WirelessNetworkAddress("ABCDEF"), true,
                DeviceCapabilities.TimeSensor, DeviceRoles.IntermediateTimer3, 253)
            {
                BatteryStatus = 241,
                IsAligned = true,
                ClockSynchronization = ClockSynchronizationStatus.RequiresSync
            };
            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
        public void When_reading_keep_alive_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('5'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('0'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('2'),
                ByteFor('3'),
                ByteFor('.'),
                ByteFor('4'),
                ByteFor('5'),
                ByteFor('6'),
                ByteFor('.'),
                ByteFor('7'),
                ByteFor('8'),
                ByteFor('9'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('2'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new KeepAliveOperation(new Version(123, 456, 789), 1);
            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
        public void When_reading_device_setup_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('0'),
                ByteFor('5'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('6'),
                ByteFor('5'),
                ByteFor('4'),
                ByteFor('3'),
                ByteFor('2'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('6'),
                ByteFor(':'),
                ByteFor('A'),
                ByteFor('B'),
                ByteFor('C'),
                ByteFor('D'),
                ByteFor('E'),
                ByteFor('F'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('9'),
                ByteFor(':'),
                ByteFor('3'),
                ByteFor('1'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new DeviceSetupOperation(new WirelessNetworkAddress("ABCDEF"))
            {
                DestinationAddress = new WirelessNetworkAddress("654321"),
                Capabilities =
                    DeviceCapabilities.ControlKeypad | DeviceCapabilities.NumericKeypad | DeviceCapabilities.StartSensor |
                        DeviceCapabilities.IntermediateSensor | DeviceCapabilities.FinishSensor
            };

            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
        public void When_reading_network_setup_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('0'),
                ByteFor('4'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('A'),
                ByteFor('B'),
                ByteFor('C'),
                ByteFor('D'),
                ByteFor('E'),
                ByteFor('F'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('7'),
                ByteFor(':'),
                ByteFor('1'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('2'),
                ByteFor('0'),
                ByteFor(':'),
                ByteFor('7'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new NetworkSetupOperation(new WirelessNetworkAddress("ABCDEF"), true,
                DeviceRoles.StartTimer | DeviceRoles.FinishTimer | DeviceRoles.Keypad);
            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }
        public void When_reading_alert_operation_it_must_be_correct()
        {
            // Arrange
            byte[] buffer =
            {
                2,
                ByteFor('0'),
                ByteFor('3'),
                ByteFor('\t'),
                ByteFor('0'),
                ByteFor('1'),
                ByteFor('4'),
                ByteFor(':'),
                ByteFor('A'),
                ByteFor('B'),
                ByteFor('C'),
                ByteFor('D'),
                ByteFor('E'),
                ByteFor('F'),
                ByteFor('\t'),
                3
            };
            var reader = new PacketReader();

            // Act
            Operation operation = reader.Read(buffer);

            // Assert
            var expected = new AlertOperation(new WirelessNetworkAddress("ABCDEF"));
            operation.ShouldBeEquivalentTo(expected, options => options.IncludingAllRuntimeProperties());
        }