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)); }
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); }
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); }
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); }
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()); }
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()); }
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); }
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); }
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); }
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"); }
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)); }
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)); }
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)); }
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); }
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)); }
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)); }
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()); }
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)); }
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); }
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); }
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()); }
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)); }
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)); }
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()); }
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); }
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)); }
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); }
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); }
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)); }
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()); }