예제 #1
0
        public async Task GetConfigGetUnexpectedResultThrowsException()
        {
            // ARRANGE
            var mock           = new HassWebSocketMock();
            var mockHassClient =
                new Mock <JoySoftware.HomeAssistant.Client.HassClient>(mock.Logger.LoggerFactory, new TransportPipelineFactoryMock().Object,
                                                                       mock.WebSocketMockFactory.Object, null);


            mockHassClient.CallBase = true;

            // First message from Home Assistant is auth required
            mock.AddResponse(@"{""type"": ""auth_required""}");
            // Next one we fake it is auth ok
            mock.AddResponse(@"{""type"": ""auth_ok""}");

            await mockHassClient.Object.ConnectAsync(new Uri("http://192.168.1.1"), "token", false).ConfigureAwait(false);

            mockHassClient.Setup(n =>
                                 n.SendCommandAndWaitForResponse(
                                     It.IsAny <CommandMessage>(), It.IsAny <bool>()))
            .Returns(
                new ValueTask <HassMessage>(new HassMessage
            {
                Id     = 2,
                Type   = "result",
                Result = "Not correct type as we should test"
            }));

            // ACT AND ASSERT
            var getConfigTask = mockHassClient.Object.GetConfig();

            await Assert.ThrowsAsync <ApplicationException>(async() => await getConfigTask.ConfigureAwait(false));
        }
예제 #2
0
        public async Task SendMessageFailShouldThrowException()
        {
            // ARRANGE
            var mock           = new HassWebSocketMock();
            var mockHassClient =
                new Mock <JoySoftware.HomeAssistant.Client.HassClient>(mock.Logger.LoggerFactory, new TransportPipelineFactoryMock().Object,
                                                                       mock.WebSocketMockFactory.Object, null);


            mockHassClient.CallBase = true;

            // First message from Home Assistant is auth required
            mock.AddResponse(@"{""type"": ""auth_required""}");
            // Next one we fake it is auth ok
            mock.AddResponse(@"{""type"": ""auth_ok""}");

            await mockHassClient.Object.ConnectAsync(new Uri("http://192.168.1.1"), "token", false).ConfigureAwait(false);

            mockHassClient.Setup(n => n.SendMessage(It.IsAny <HassMessageBase>(),
                                                    It.IsAny <bool>())).ThrowsAsync(new ApplicationException("Hello"));
            // ACT AND ASSERT

            await Assert.ThrowsAsync <ApplicationException>(async() =>
                                                            await mockHassClient.Object.CallService("light", "turn_on", null).ConfigureAwait(false)).ConfigureAwait(false);
        }
예제 #3
0
        public async Task SubscribeToEventsReturnsCorrectEvent()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            var subscribeTask = hassClient.SubscribeToEvents();

            // Add result success
            mock.AddResponse(@"{""id"": 2, ""type"": ""result"", ""success"": true, ""result"": null}");
            await subscribeTask.ConfigureAwait(false);

            // Add response event message, see event.json as reference
            mock.AddResponse(HassWebSocketMock.EventMessage);

            // ACT
            HassEvent eventMsg = await hassClient.ReadEventAsync().ConfigureAwait(false);

            // ASSERT, object multiple assertions
            Assert.NotNull(eventMsg);

            Assert.Equal("LOCAL", eventMsg.Origin);
            Assert.Equal(DateTime.Parse("2019-02-17T11:43:47.090511+00:00"), eventMsg.TimeFired);

            var stateMessage = eventMsg.Data as HassStateChangedEventData;

            Assert.True(stateMessage?.EntityId == "binary_sensor.vardagsrum_pir");

            Assert.True(stateMessage.OldState?.EntityId == "binary_sensor.vardagsrum_pir");
            Assert.True(stateMessage.OldState?.Attributes != null &&
                        ((JsonElement)stateMessage.OldState?.Attributes?["battery_level"]).GetInt32() ! == 100);
            Assert.True(((JsonElement)stateMessage.OldState?.Attributes?["on"]).GetBoolean() !);
            Assert.True(((JsonElement)stateMessage.OldState?.Attributes?["friendly_name"]).GetString() ! ==
                        "Rörelsedetektor TV-rum");

            // Test the date and time conversions that it matches UTC time
            DateTime?lastChanged = stateMessage.OldState?.LastChanged;
            // Convert utc date to local so we can compare, this test will be ok on any timezone
            DateTime target = new DateTime(2019, 2, 17, 11, 41, 08, DateTimeKind.Utc).ToLocalTime();

            Assert.True(lastChanged.Value.Year == target.Year);
            Assert.True(lastChanged.Value.Month == target.Month);
            Assert.True(lastChanged.Value.Day == target.Day);
            Assert.True(lastChanged.Value.Hour == target.Hour);
            Assert.True(lastChanged.Value.Minute == target.Minute);
            Assert.True(lastChanged.Value.Second == target.Second);

            // Just test one of the NewStateOne
            Assert.True(stateMessage.NewState?.EntityId == "binary_sensor.vardagsrum_pir");
        }
예제 #4
0
        public async Task GetEntitiesShouldHaveCorrectObject()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            var task = hassClient.GetEntities();

            // Add the service message fake , check service_event.json for reference
            mock.AddResponse(HassWebSocketMock.GetEntitiesMessage);

            // ACT
            // HassEvent eventMsg = await hassClient.ReadEventAsync();
            var result = await task.ConfigureAwait(false);

            var first = result.FirstOrDefault();

            // ASSERT
            Assert.NotNull(result);
            Assert.NotNull(first);
            Assert.Equal("42cdda32a2a3428e86c2e27699d79ead", first.DeviceId);
            Assert.Equal("media_player.tv_uppe2", first.EntityId);

            Assert.Equal(2, result.Count());
        }
예제 #5
0
        public async Task GetServiceShouldHaveCorrectObject()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            var task = hassClient.GetServices();

            // Add the service message fake , check service_event.json for reference
            mock.AddResponse(HassWebSocketMock.GetServiceMessage);

            // ACT
            // HassEvent eventMsg = await hassClient.ReadEventAsync();
            var result = await task.ConfigureAwait(false);

            var first = result.FirstOrDefault();

            // ASSERT
            Assert.NotNull(result);
            Assert.NotNull(first);
            Assert.Equal("homeassistant", first.Domain);

            Assert.Equal(38, result.Count());
            // Assert.Equal("light", serviceEvent.Domain);
            // Assert.Equal("toggle", serviceEvent.Service!);
            // Assert.Equal("light.tomas_rum", c?.GetString());
            // Assert.Equal("light.tomas_rum", serviceEvent.Data.entity_id);
        }
예제 #6
0
        public async Task CallServiceSuccessfulReturnsTrue()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // Service call successful
            mock.AddResponse(@"{
                                      ""id"": 2,
                                      ""type"": ""result"",
                                      ""success"": true,
                                      ""result"": {
                                        ""context"": {
                                          ""id"": ""55cf75a4dbf94680804ef022aa0c67b4"",
                                          ""parent_id"": null,
                                          ""user_id"": ""63b2952cb986474d84be46480c8aaad3""
                                        }
                                      }
                                    }");

            // ACT
            var result = await hassClient.CallService("light", "turn_on", new { entity_id = "light.tomas_rum" }).ConfigureAwait(false);

            // Assert
            Assert.True(result);
        }
예제 #7
0
        public async Task GetAreasShouldHaveCorrectObject()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            var task = hassClient.GetAreas();

            // Add the service message fake , check service_event.json for reference
            mock.AddResponse(HassWebSocketMock.GetAreasMessage);

            // ACT
            // HassEvent eventMsg = await hassClient.ReadEventAsync();
            var result = await task.ConfigureAwait(false);

            var first = result.FirstOrDefault();

            // ASSERT
            Assert.NotNull(result);
            Assert.NotNull(first);
            Assert.Equal("Bedroom", first.Name);
            Assert.Equal("5a30cdc2fd7f44d5a77f2d6f6d2ccd76", first.Id);

            Assert.Equal(3, result.Count());
        }
예제 #8
0
        public async Task WrongMessagesFromHassShouldReturnFalse()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the default state hass client
            await using var hassClient = mock.GetHassClient();

            // First message from Home Assistant is auth required
            mock.AddResponse(@"{""type"": ""auth_required""}");
            // Next one we fake it is auth ok
            mock.AddResponse(@"{""type"": ""result""}");

            // ACT and ASSERT
            // Calls connect without getting the states initially
            Assert.False(await hassClient.ConnectAsync(new Uri("ws://anyurldoesntmatter.org"), "FAKETOKEN", false).ConfigureAwait(false));
        }
예제 #9
0
        public async Task SubscriptToEventTypeShouldReturnEvent(EventType eventType)
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // ACT AND ASSERT
            var subscribeTask = hassClient.SubscribeToEvents(eventType);

            mock.AddResponse(@"{""id"": 2, ""type"": ""result"", ""success"": true, ""result"": null}");
            Assert.True(await subscribeTask.ConfigureAwait(false));
            mock.AddResponse(HassWebSocketMock.EventMessage);
            HassEvent eventMsg = await hassClient.ReadEventAsync().ConfigureAwait(false);

            Assert.NotNull(eventMsg);
        }
예제 #10
0
        public async Task ConnectWithAuthFailLogsErrorAndReturnFalse()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the default state hass client
            await using var hassClient = mock.GetHassClient();

            // First message from Home Assistant is auth required
            mock.AddResponse(@"{""type"": ""auth_required""}");
            // Next one we fake it is auth ok
            mock.AddResponse(@"{""type"": ""auth_invalid""}");

            // ACT and ASSERT
            // Calls connect without getting the states initially
            Assert.False(await hassClient.ConnectAsync(new Uri("ws://anyurldoesntmatter.org"), "FAKETOKEN", false).ConfigureAwait(false));
            // Make sure we logged the error.
            mock.Logger.AssertLogged(LogLevel.Error, Times.AtLeastOnce());
        }
예제 #11
0
        public async Task ClientGetUnexpectedMessageRecoversResultNotNull()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // ACT
            var confTask = hassClient.GetConfig();

            // First add an unexpected message, message id should be 2
            mock.AddResponse(@"{""id"": 12345, ""type"": ""result"", ""success"": false, ""result"": null}");
            // Then add the expected one... It should recover from that...
            mock.AddResponse(HassWebSocketMock.ConfigMessage);

            // ASSERT
            Assert.NotNull(await confTask.ConfigureAwait(false));
        }
예제 #12
0
        public async Task ConnectWithSslShouldStartWithWss()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the default state hass client and we add no response messages
            await using var hassClient = mock.GetHassClient();
            // First message from Home Assistant is auth required
            mock.AddResponse(@"{""type"": ""auth_required""}");
            // Next one we fake it is auth ok
            mock.AddResponse(@"{""type"": ""auth_ok""}");

            // ACT and ASSERT
            // Connect with ssl
            await hassClient.ConnectAsync("localhost", 8123, true, "FAKETOKEN", false).ConfigureAwait(false);

            mock.Verify(
                n => n.ConnectAsync(new Uri("wss://localhost:8123/api/websocket"), It.IsAny <CancellationToken>()),
                Times.Once);
        }
예제 #13
0
        public async Task PingShouldReturnTrue()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the default connected hass client
            await using var hassClient = await mock.GetHassConnectedClient();

            // Fake return pong message
            mock.AddResponse(@"{""type"": ""pong""}");

            // ACT and ASSERT
            Assert.True(await hassClient.PingAsync(1000).ConfigureAwait(false));
        }
예제 #14
0
        public async Task UnsupportedMessageReceivedShouldBeDebugLogged()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Don´t remove, the client does stuff in the background while delay
            // ReSharper disable once UnusedVariable
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            mock.AddResponse(@"{""type"": ""unknown""}");
            await Task.Delay(5).ConfigureAwait(false);

            mock.Logger.AssertLogged(LogLevel.Debug, Times.AtLeast(1));
        }
예제 #15
0
        public async Task WrongMessagesFromHassShouldReturnFalse()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // First message from Home Assistant is auth required
            mock.AddResponse(@"{""type"": ""any_kind_of_type""}");

            await using var pipe = new WebSocketMessagePipeline <HassMessageBase>(mock.Object);

            // ACT
            var msg = await pipe.GetNextMessageAsync(CancellationToken.None);

            Assert.Equal("any_kind_of_type", msg.Type);
        }
예제 #16
0
        public async Task GetConfigGetUnexpectedMessageThrowsException()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // ACT
            var getConfigTask = hassClient.GetConfig();

            // Fake return not expected message, check result_config.json for reference
            mock.AddResponse(@"{""id"": 2,""type"": ""result"", ""success"": true}");

            await Assert.ThrowsAsync <ApplicationException>(async() => await getConfigTask.ConfigureAwait(false));
        }
예제 #17
0
        public async Task ErrorCommandMessageCodeNonStringShouldBeLogged()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            await hassClient.SendMessage(new CallServiceCommand { Domain = "light", Service = "some_service" }).ConfigureAwait(false);

            mock.AddResponse(@"{""id"": 2, ""type"": ""result"", ""success"": false, ""result"": null, ""error"":{""code"": 20, ""message"": ""message""}}");

            await Task.Delay(20).ConfigureAwait(false);

            mock.Logger.AssertLogged(LogLevel.Warning, Times.Once());
        }
예제 #18
0
        public async Task CommandWithUnsuccessfulShouldThrowAggregateException()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // ACT
            Task <HassConfig> confTask = hassClient.GetConfig();

            // Add result not success message
            mock.AddResponse(@"{""id"": 2, ""type"": ""result"", ""success"": false, ""result"": null}");

            // ASSERT
            Assert.Throws <AggregateException>(() => confTask.Result);
        }
예제 #19
0
        public async Task UnsupportedCommandMessageShouldBeLogged()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            await hassClient.SendMessage(new UnknownCommand()).ConfigureAwait(false);

            //UnknownCommand
            mock.AddResponse(@"{""id"": 2, ""type"": ""result"", ""success"": true, ""result"": null}");

            await Task.Delay(20).ConfigureAwait(false);

            mock.Logger.AssertLogged(LogLevel.Error, Times.Once());
        }
예제 #20
0
        public async Task SubscribeToEventsReturnsTrue()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // ACT
            var subscribeTask = hassClient.SubscribeToEvents();

            // Add result success
            mock.AddResponse(@"{""id"": 2, ""type"": ""result"", ""success"": true, ""result"": null}");

            // ASSERT
            Assert.True(await subscribeTask.ConfigureAwait(false));
        }
예제 #21
0
        public async Task EventWithStateIntegerShouldHaveCorrectTypeAndValue()
        {
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // Add response event message, see event.json as reference
            mock.AddResponse(HassWebSocketMock.EventMessageInteger);

            // ACT
            HassEvent eventMsg = await hassClient.ReadEventAsync().ConfigureAwait(false);

            var stateMessage = eventMsg.Data as HassStateChangedEventData;

            Assert.Equal(321, stateMessage?.NewState.State);
            Assert.Equal(123, stateMessage?.OldState.State);
        }
예제 #22
0
        public async Task ReceiveAsyncThrowsExceptionProcessMessageShouldHandleException()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            mock.Setup(x => x.ReceiveAsync(It.IsAny <Memory <byte> >(), It.IsAny <CancellationToken>()))
            .Returns((Memory <byte> buffer, CancellationToken token) =>
            {
                throw new Exception("Unexpected!");
            });


            // ACT AND ASSERT
            var subscribeTask = hassClient.SubscribeToEvents();

            await Task.Delay(100).ConfigureAwait(false);

            // Service call successful
            mock.AddResponse(@"{
                                      ""id"": 2,
                                      ""type"": ""result"",
                                      ""success"": true,
                                      ""result"": {
                                        ""context"": {
                                          ""id"": ""55cf75a4dbf94680804ef022aa0c67b4"",
                                          ""parent_id"": null,
                                          ""user_id"": ""63b2952cb986474d84be46480c8aaad3""
                                        }
                                      }
                                    }");

            await subscribeTask.ConfigureAwait(false);

            await Task.Delay(100).ConfigureAwait(false);

            mock.Logger.AssertLogged(LogLevel.Error, Times.Once());
        }
예제 #23
0
        public async Task ReturningStatesTheCountShouldBeNineteen()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the non connected hass client
            await using var hassClient = mock.GetHassClientNotConnected();

            hassClient.SocketTimeout = 50000;
            // ACT

            var connectTask = hassClient.ConnectAsync(new Uri("ws://localhost:8192/api/websocket"), "TOKEN");

            // Wait until hassclient processes connect sequence
            await mock.WaitUntilConnected().ConfigureAwait(false);

            // Fake return states message
            mock.AddResponse(HassWebSocketMock.StateMessage);
            await connectTask.ConfigureAwait(false);

            // ASSERT
            Assert.Equal(19, hassClient.States.Count);
        }
예제 #24
0
        public async Task ConfigShouldBeCorrect()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // ACT
            Task <HassConfig> getConfigTask = hassClient.GetConfig();

            // Fake return Config message, check result_config.json for reference
            mock.AddResponse(HassWebSocketMock.ConfigMessage);

            var conf = getConfigTask.Result;

            // ASSERT, its an object assertion here so multiple asserts allowed
            // Check result_config.json for reference
            Assert.NotNull(conf);
            Assert.Equal("°C", conf.UnitSystem?.Temperature);
            Assert.Equal("km", conf.UnitSystem?.Length);
            Assert.Equal("g", conf.UnitSystem?.Mass);
            Assert.Equal("L", conf.UnitSystem?.Volume);

            Assert.Contains("binary_sensor.deconz", conf.Components);
            Assert.Equal(62.2398549F, conf.Latitude);
            Assert.Equal(15.4412267F, conf.Longitude);
            Assert.Equal(49, conf.Elevation);

            Assert.Contains("/config/www", conf.WhitelistExternalDirs);
            Assert.Equal("0.87.0", conf.Version);
            Assert.Equal("Home", conf.LocationName);

            Assert.Equal("/config", conf.ConfigDir);
            Assert.Equal("Europe/Stockholm", conf.TimeZone);
        }
예제 #25
0
        public async Task CustomEventShouldHaveCorrectObject()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // Add the service message fake , check service_event.json for reference
            mock.AddResponse(HassWebSocketMock.CustomEventMessage);

            // ACT
            var result = await hassClient.ReadEventAsync().ConfigureAwait(false);

            var customEvent = result?.Data;


            // ASSERT
            Assert.Equal("light.some_light", customEvent?.an_object.entity_id);
            Assert.IsType <object[]>(customEvent?.an_object.value_array);
            var x = customEvent?.an_object.value_array[0];

            Assert.Equal(1, x);
        }
예제 #26
0
        public async Task ServiceEventShouldHaveCorrectObject()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the connected hass client
            await using var hassClient = await mock.GetHassConnectedClient().ConfigureAwait(false);

            // Add the service message fake , check service_event.json for reference
            mock.AddResponse(HassWebSocketMock.ServiceMessage);

            // ACT
            var result = await hassClient.ReadEventAsync().ConfigureAwait(false);

            var         serviceEvent = result?.Data as HassServiceEventData;
            JsonElement?c            = serviceEvent?.ServiceData?.GetProperty("entity_id");

            // ASSERT
            Assert.NotNull(serviceEvent);
            Assert.Equal("light", serviceEvent.Domain);
            Assert.Equal("toggle", serviceEvent.Service !);
            Assert.Equal("light.tomas_rum", c?.GetString());
            Assert.Equal("light.tomas_rum", serviceEvent.Data.entity_id);
        }