コード例 #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 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);
        }
コード例 #4
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);
        }
コード例 #5
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());
        }
コード例 #6
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());
        }
コード例 #7
0
        public async Task SetStateNonSuccessHttpResponseCodeReturnNull()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();
            var httpMessageHandlerMock = new Mock <HttpMessageHandler>();

            httpMessageHandlerMock
            .Protected()
            .Setup <Task <HttpResponseMessage> >("SendAsync",
                                                 ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>())
            .ReturnsAsync(
                () => new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.NotFound,         // Set non success return code
                Content    = new StringContent("{}", Encoding.UTF8)
            });

            // Get the default state hass client
            await using var hassClient = await mock.GetHassConnectedClient(false, httpMessageHandlerMock.Object).ConfigureAwait(false);

            var result = await hassClient.SetState("sensor.my_sensor", "new_state", new { attr1 = "hello" }).ConfigureAwait(false);

            // ACT and ASSERT
            Assert.Null(result);
        }
コード例 #8
0
        public async Task ReadEventShouldCancel()
        {
            var mock = new HassWebSocketMock();

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

            var cancelSoon = new CancellationTokenSource(50);
            // ACT & ASSERT
            await Assert.ThrowsAsync <OperationCanceledException>(async() => await hassClient.ReadEventAsync(cancelSoon.Token).ConfigureAwait(false)).ConfigureAwait(false);
        }
コード例 #9
0
        public async Task ConnectWithUriNullThrowsArgumentNullException()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the default state hass client and we add no response messages
            await using var hassClient = mock.GetHassClient();

            await Assert.ThrowsAsync <ArgumentNullException>(
                async() => await hassClient.ConnectAsync(null, "lss", false).ConfigureAwait(false)).ConfigureAwait(false);
        }
コード例 #10
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");
        }
コード例 #11
0
        public async Task ConnectWithStateOtherThanOpenShouldReturnFalse(WebSocketState state)
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the default state hass client
            await using var hassClient = mock.GetHassClient();
            // Set Closed state to fake
            mock.SetupGet(x => x.State).Returns(state);

            // ACT and ASSERT
            Assert.False(await hassClient.ConnectAsync(new Uri("ws://anyurldoesntmatter.org"), "FAKETOKEN", false).ConfigureAwait(false));
        }
コード例 #12
0
        public async Task NoPongMessagePingShouldReturnFalse()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

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

            // No pong message is sent from server...

            // ACT and ASSERT
            Assert.False(await hassClient.PingAsync(2).ConfigureAwait(false));
        }
コード例 #13
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));
        }
コード例 #14
0
        public async Task ConnectAlreadyConnectedThrowsInvalidOperation()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

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

            // ACT AND ASSERT

            // The hass client already connected and should assert error
            await Assert.ThrowsAsync <InvalidOperationException>(async() =>
                                                                 await hassClient.ConnectAsync(new Uri("ws://localhost:8192/api/websocket"), "TOKEN", false).ConfigureAwait(false)).ConfigureAwait(false);
        }
コード例 #15
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));
        }
コード例 #16
0
        public async Task ConnectTimeoutReturnsFalse()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

            // Get the default state hass client and we add no response messages
            await using var hassClient = mock.GetHassClient();

            // Set the timeout to a very low value for testing purposes
            hassClient.SocketTimeout = 20;

            // ACT AND ASSERT
            Assert.False(await hassClient.ConnectAsync(new Uri("ws://localhost:8192/api/websocket"), "TOKEN", false).ConfigureAwait(false));
        }
コード例 #17
0
        public async Task SendingUnknownMessageShouldDiscardAndLogDebug()
        {
            // 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);

            hassClient.SocketTimeout = 20;
            await hassClient.CallService("test", "test", null).ConfigureAwait(false);

            mock.Logger.AssertLogged(LogLevel.Error, Times.Once());
        }
コード例 #18
0
        public async Task CallServiceWithTimeoutShouldReturnFalse()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

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

            hassClient.SocketTimeout = 10;

            // ACT AND ASSERT

            // Do not add a message and force timeout
            Assert.False(await hassClient.CallService("light", "turn_on", new { entity_id = "light.tomas_rum" }).ConfigureAwait(false));
        }
コード例 #19
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);
        }
コード例 #20
0
        public async Task CloseAsyncIsRanOnce()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

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

            await hassClient.CloseAsync().ConfigureAwait(false);

            // ASSERT
            mock.Verify(
                x => x.CloseOutputAsync(It.IsAny <WebSocketCloseStatus>(),
                                        It.IsAny <string>(), It.IsAny <CancellationToken>()),
                Times.Once);
        }
コード例 #21
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());
        }
コード例 #22
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));
        }
コード例 #23
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));
        }
コード例 #24
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());
        }
コード例 #25
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);
        }
コード例 #26
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));
        }
コード例 #27
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);
        }
コード例 #28
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);
        }
コード例 #29
0
        public async Task CallServiceIfCanceledShouldThrowOperationCanceledException()
        {
            // ARRANGE
            var mock = new HassWebSocketMock();

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

            // Do not add a fake service call message result

            // ACT
            var callServiceTask = hassClient.CallService("light", "turn_on", new { entity_id = "light.tomas_rum" });

            hassClient.CancelSource.Cancel();

            // ASSERT
            await Assert.ThrowsAsync <OperationCanceledException>(async() => await callServiceTask.ConfigureAwait(false));
        }
コード例 #30
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());
        }