diff --git a/src/Fakes/NetDaemon.Fakes/DaemonHostTestBase.cs b/src/Fakes/NetDaemon.Fakes/DaemonHostTestBase.cs
index 515f21828..6e338e19a 100644
--- a/src/Fakes/NetDaemon.Fakes/DaemonHostTestBase.cs
+++ b/src/Fakes/NetDaemon.Fakes/DaemonHostTestBase.cs
@@ -7,6 +7,7 @@
using JoySoftware.HomeAssistant.Client;
using Moq;
using NetDaemon.Common;
+using NetDaemon.Common.Fluent;
using NetDaemon.Common.Reactive;
using NetDaemon.Daemon.Storage;
using Xunit;
@@ -24,8 +25,12 @@ public partial class DaemonHostTestBase : IAsyncLifetime
private readonly HassClientMock _defaultHassClientMock;
private readonly HttpHandlerMock _defaultHttpHandlerMock;
private readonly LoggerMock _loggerMock;
+ private Task? _fakeConnectedDaemon;
- internal DaemonHostTestBase()
+ ///
+ /// Default contructor
+ ///
+ public DaemonHostTestBase()
{
_loggerMock = new LoggerMock();
_defaultHassClientMock = HassClientMock.DefaultMock;
@@ -38,6 +43,7 @@ internal DaemonHostTestBase()
_loggerMock.LoggerFactory,
_defaultHttpHandlerMock.Object);
+ _defaultDaemonHost.InternalDelayTimeForTts = 0; // Allow no extra waittime
}
///
@@ -61,7 +67,10 @@ internal DaemonHostTestBase()
///
public LoggerMock LoggerMock => _loggerMock;
- Task IAsyncLifetime.DisposeAsync()
+ ///
+ /// Cleans up test
+ ///
+ public Task DisposeAsync()
{
return Task.CompletedTask;
}
@@ -81,9 +90,9 @@ public dynamic GetDynamicDataObject(string testData = "testdata")
///
/// Converts parameters to dynamics
///
- public (dynamic, ExpandoObject) GetDynamicObject(params (string, object)[] dynamicParameters)
+ public (dynamic, FluentExpandoObject) GetDynamicObject(params (string, object)[] dynamicParameters)
{
- var expandoObject = new ExpandoObject();
+ var expandoObject = new FluentExpandoObject();
var dict = expandoObject as IDictionary;
foreach (var (name, value) in dynamicParameters)
@@ -101,16 +110,44 @@ public virtual Task InitializeAsync()
return Task.CompletedTask;
}
+ ///
+ /// Sets fake current state of entity, adds it if entity not exists
+ ///
+ /// The state to sett
+ public void SetEntityState(HassState state)
+ {
+ DefaultHassClientMock.FakeStates[state.EntityId] = state;
+ }
+
+ ///
+ /// Sets fake current state of entity, adds it if entity not exists
+ ///
+ /// Unique id of entity
+ /// State to set
+ /// Area of entity
+ public void SetEntityState(string entityId, dynamic? state = null, string? area = null)
+ {
+ var entity = new EntityState
+ {
+ EntityId = entityId,
+ Area = area,
+ State = state
+ };
+
+ DefaultDaemonHost.InternalState[entityId] = entity;
+ }
+
///
/// Adds an new instance of app
///
/// The instance of the app to add
- public void AddAppInstance(INetDaemonAppBase app)
+ public async Task AddAppInstance(INetDaemonAppBase app)
{
if (string.IsNullOrEmpty(app.Id))
- throw new ArgumentException("Application needs an unique id, please provide it!");
+ app.Id = Guid.NewGuid().ToString();
DefaultDaemonHost.InternalAllAppInstances[app.Id] = app;
DefaultDaemonHost.InternalRunningAppInstances[app.Id] = app;
+ await app.StartUpAsync(DefaultDaemonHost);
}
///
@@ -127,10 +164,24 @@ public void AddChangedEvent(string entityId, object fromState, object toState)
///
/// Adds a full home assistant fake event
///
- /// Event to fake
- public void AddChangedEvent(HassEvent hassEvent)
+ ///
+ ///
+ public void AddChangeEvent(HassState? fromState, HassState? toState)
{
- DefaultHassClientMock.FakeEvents.Enqueue(hassEvent);
+ DefaultHassClientMock.AddChangeEventFull(fromState, toState);
+ }
+
+ ///
+ /// Adds an simple state change event to NetDaemon to trigger apps
+ ///
+ /// Unique id of the entity
+ /// From state
+ /// To state
+ /// Last updated time
+ /// Last changed time
+ public void AddChangedEvent(string entityId, object fromState, object toState, DateTime lastUpdated, DateTime lastChanged)
+ {
+ DefaultHassClientMock.AddChangedEvent(entityId, fromState, toState, lastUpdated, lastChanged);
}
///
@@ -153,68 +204,97 @@ public void AddCustomEvent(string eventType, dynamic? data)
/// Domain of event
/// Service to call
/// Custom data
- public void AddCallServiceEvent(string domain, string service, dynamic data)
+ public void AddCallServiceEvent(string domain, string service, dynamic? data = null)
{
DefaultHassClientMock.AddCallServiceEvent(domain, service, data);
}
+ ///
+ /// Verifies that a custom event are sent
+ ///
+ /// Name of event
+ public void VerifyEventSent(string ev)
+ {
+ DefaultHassClientMock.Verify(n => n.SendEvent(ev, It.IsAny()));
+ }
+
+ ///
+ /// Verifies that a custom event are sent
+ ///
+ /// Name of event
+ /// Data sent by event
+ public void VerifyEventSent(string ev, object? eventData)
+ {
+ DefaultHassClientMock.Verify(n => n.SendEvent(ev, eventData));
+ }
+
///
/// Verify that a service has been called
///
/// Domain of service
/// The service name
/// Attributes
- public void VerifyCallService(string domain, string service,
+ public void VerifyCallServiceTuple(string domain, string service,
params (string attribute, object value)[] attributesTuples)
{
- DefaultHassClientMock.VerifyCallService(domain, service, attributesTuples);
+ DefaultHassClientMock.VerifyCallServiceTuple(domain, service, attributesTuples);
}
///
- /// Verify that a service been called specific number of times
+ /// Verifies that call_service is called
///
- /// Service name
- /// Times called
- public void VerifyCallServiceTimes(string service, Times times)
+ /// Service domain
+ /// Service to verify
+ /// Data sent by service
+ /// If service was waiting for response
+ /// Number of times called
+ public void VerifyCallService(string domain, string service, object? data = null, bool waitForResponse = false, Moq.Times? times = null)
{
- DefaultHassClientMock.VerifyCallServiceTimes(service, times);
+ DefaultHassClientMock.VerifyCallService(domain, service, data, waitForResponse, times);
}
///
- /// Returns default DaemonHost
+ /// Verifies that call_service is called
///
- /// Timeout in ms
- /// True if use timeout while debug test
- public async Task<(Task, CancellationTokenSource)> ReturnRunningDefauldDaemonHostTask(short milliSeconds = 100, bool overrideDebugNotCancel = false)
+ /// Service domain
+ /// Service to verify
+ /// EntityId to verify
+ /// Data sent by service
+ /// If service was waiting for response
+ /// Number of times called
+ /// Attributes to verify
+ public void VerifyCallService(string domain, string service, string entityId, object? data = null, bool waitForResponse = false, Moq.Times? times = null,
+ params (string attribute, object value)[] attributesTuples)
{
- await InitApps();
- var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
- ? new CancellationTokenSource()
- : new CancellationTokenSource(milliSeconds);
- return (_defaultDaemonHost.Run("host", 8123, false, "token", cancelSource.Token), cancelSource);
+ var serviceObject = new FluentExpandoObject();
+ serviceObject["entity_id"] = entityId;
+ foreach (var (attr, val) in attributesTuples)
+ {
+ serviceObject[attr] = val;
+ }
+
+ DefaultHassClientMock.VerifyCallService(domain, service, serviceObject, waitForResponse, times);
}
+ ///
+ /// Verifies that call_service is called
+ ///
+ /// Service domain
+ /// Service to verify
+ /// If service was waiting for response
+ public void VerifyCallService(string domain, string service, bool waitForResponse = false)
+ {
+ DefaultHassClientMock.VerifyCallService(domain, service, waitForResponse);
+ }
///
- /// Runs the default daemon to process messages until canceled
+ /// Verify that a service been called specific number of times
///
- /// Timeout time
- /// True if debugging should cancel
- ///
- public async Task RunDefaultDaemonUntilCanceled(short milliSeconds = 100, bool overrideDebugNotCancel = false)
+ /// Service name
+ /// Times called
+ public void VerifyCallServiceTimes(string service, Times times)
{
- var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
- ? new CancellationTokenSource()
- : new CancellationTokenSource(milliSeconds);
- try
- {
- await InitApps();
- await _defaultDaemonHost.Run("host", 8123, false, "token", cancelSource.Token).ConfigureAwait(false);
- }
- catch (TaskCanceledException)
- {
- // Expected behaviour
- }
+ DefaultHassClientMock.VerifyCallServiceTimes(service, times);
}
///
@@ -222,7 +302,7 @@ public async Task RunDefaultDaemonUntilCanceled(short milliSeconds = 100, bool o
///
/// Task to wait for
///
- public async Task WaitUntilCanceled(Task task)
+ private async Task WaitUntilCanceled(Task task)
{
try
{
@@ -237,7 +317,7 @@ public async Task WaitUntilCanceled(Task task)
///
/// Initialize applications
///
- public async Task InitApps()
+ private async Task InitApps()
{
foreach (var inst in DefaultDaemonHost.InternalAllAppInstances)
{
@@ -251,13 +331,57 @@ public async Task InitApps()
}
}
+ ///
+ /// Verifies that a state is set
+ ///
+ /// Unique identifier of the entity
+ /// State being set
+ /// Attributes being set
+ public void VerifySetState(string entityId, string state,
+ params (string attribute, object value)[] attributesTuples)
+ {
+ DefaultHassClientMock.VerifySetState(entityId, state, attributesTuples);
+ }
+
+ ///
+ /// Verifies that state being set
+ ///
+ /// Unique identifier of the entity
+ /// How many times it being set
+ public void VerifySetStateTimes(string entityId, Times times)
+ {
+ DefaultHassClientMock.VerifySetStateTimes(entityId, times);
+ }
+
+ ///
+ /// Initialize the fake netdaemon core, must be run in most cases starting a test
+ ///
+ /// Timeout (ms) of how long fake daemon will stay connected and process events
+ /// True if running debug mode should not cancel on timeout
+ protected async Task FakeDaemonInit(short timeout = 200, bool overrideDebugNotCancel = false)
+ {
+ _fakeConnectedDaemon = await GetConnectedNetDaemonTask(timeout, overrideDebugNotCancel);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ protected async Task FakeRunDaemonCoreUntilTimeout()
+ {
+ _ = _fakeConnectedDaemon ??
+ throw new NullReferenceException("No task to process, did you forget to run InitFakeDaemon at the beginning of the test?");
+
+ await WaitUntilCanceled(_fakeConnectedDaemon).ConfigureAwait(false);
+ }
+
///
/// Get already pre-connected mock NetDaemon object
///
/// Timeout in milliseconds
/// True to use timeout while debugging
///
- protected async Task GetConnectedNetDaemonTask(short milliSeconds = 100, bool overrideDebugNotCancel = false)
+ private async Task GetConnectedNetDaemonTask(short milliSeconds = 100, bool overrideDebugNotCancel = false)
{
var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
? new CancellationTokenSource()
@@ -270,13 +394,7 @@ protected async Task GetConnectedNetDaemonTask(short milliSeconds = 100, b
return daemonTask;
}
- ///
- /// Wait until default NetDaemon has connected
- ///
- /// Daemon object
- /// Cancellation token
- ///
- protected async Task WaitForDefaultDaemonToConnect(NetDaemonHost daemonHost, CancellationToken cancellationToken)
+ private async Task WaitForDefaultDaemonToConnect(NetDaemonHost daemonHost, CancellationToken cancellationToken)
{
var nrOfTimesCheckForConnectedState = 0;
diff --git a/src/Fakes/NetDaemon.Fakes/HassClientMock.cs b/src/Fakes/NetDaemon.Fakes/HassClientMock.cs
index 750ca0b1e..a96fa7575 100644
--- a/src/Fakes/NetDaemon.Fakes/HassClientMock.cs
+++ b/src/Fakes/NetDaemon.Fakes/HassClientMock.cs
@@ -17,11 +17,31 @@ namespace NetDaemon.Daemon.Fakes
///
public class HassClientMock : Mock
{
- internal HassAreas Areas = new HassAreas();
- internal HassDevices Devices = new HassDevices();
- internal HassEntities Entities = new HassEntities();
- internal ConcurrentQueue FakeEvents = new();
- internal ConcurrentDictionary FakeStates = new();
+ ///
+ /// Fake areas in HassClient
+ ///
+ ///
+ public HassAreas Areas = new HassAreas();
+
+ ///
+ /// Fake devices in HassClient
+ ///
+ ///
+ public HassDevices Devices = new HassDevices();
+
+ ///
+ /// Fake entities in HassClient
+ ///
+ public HassEntities Entities = new HassEntities();
+
+ ///
+ /// Fake events in HassClient
+ ///
+ public ConcurrentQueue FakeEvents = new();
+ ///
+ /// All current fake entities and it's states
+ ///
+ public ConcurrentDictionary FakeStates = new();
///
/// Default constructor
@@ -104,7 +124,7 @@ public static HassClientMock MockConnectFalse
/// Domain of service
/// Service to fake
/// Data sent by service
- public void AddCallServiceEvent(string domain, string service, dynamic data)
+ public void AddCallServiceEvent(string domain, string service, dynamic? data = null)
{
// Todo: Refactor to smth smarter
FakeEvents.Enqueue(new HassEvent
@@ -196,6 +216,25 @@ public void AddChangedEvent(string entityId, object fromState, object toState)
});
}
+ ///
+ /// Adds a changed event for entity
+ ///
+ /// The from state advanced details
+ /// The to state advanced details
+ public void AddChangeEventFull(HassState? fromState, HassState? toState)
+ {
+ FakeEvents.Enqueue(new HassEvent
+ {
+ EventType = "state_changed",
+ Data = new HassStateChangedEventData
+ {
+ EntityId = toState?.EntityId ?? fromState?.EntityId ?? "",
+ NewState = toState,
+ OldState = fromState
+ },
+ });
+ }
+
///
/// Adds a custom event
///
@@ -254,7 +293,7 @@ public CancellationTokenSource GetSourceWithTimeout(int milliSeconds = 100)
/// Service domain
/// Service to verify
/// Attributes sent by service
- public void VerifyCallService(string domain, string service,
+ public void VerifyCallServiceTuple(string domain, string service,
params (string attribute, object value)[] attributesTuples)
{
var attributes = new FluentExpandoObject();
@@ -264,6 +303,38 @@ public void VerifyCallService(string domain, string service,
Verify(n => n.CallService(domain, service, attributes, It.IsAny()), Times.AtLeastOnce);
}
+ ///
+ /// Verifies that call_service is called
+ ///
+ /// Service domain
+ /// Service to verify
+ /// Data sent by service
+ /// If service was waiting for response
+ /// Number of times called
+ public void VerifyCallService(string domain, string service, object? data = null, bool waitForResponse = false, Moq.Times? times = null)
+ {
+ if (times is not null)
+ Verify(n => n.CallService(domain, service, data!, waitForResponse), times.Value);
+ else
+ Verify(n => n.CallService(domain, service, data!, waitForResponse), Times.AtLeastOnce);
+
+ }
+
+ ///
+ /// Verifies that call_service is called
+ ///
+ /// Service domain
+ /// Service to verify
+ /// If service was waiting for response
+ /// Number of times called
+ public void VerifyCallService(string domain, string service, bool waitForResponse = false, Moq.Times? times = null)
+ {
+ if (times is not null)
+ Verify(n => n.CallService(domain, service, It.IsAny(), waitForResponse), times.Value);
+ else
+ Verify(n => n.CallService(domain, service, It.IsAny(), waitForResponse), Times.AtLeastOnce);
+ }
+
///
/// Verifies service being sent "times" times
///
@@ -274,6 +345,8 @@ public void VerifyCallServiceTimes(string service, Times times)
Verify(n => n.CallService(It.IsAny(), service, It.IsAny(), It.IsAny()), times);
}
+
+
///
/// Verify state if entity
///
diff --git a/tests/NetDaemon.Daemon.Tests/Daemon/DataRepositoryTests.cs b/tests/NetDaemon.Daemon.Tests/Daemon/DataRepositoryTests.cs
index 8619c62e7..3f17c1bfa 100644
--- a/tests/NetDaemon.Daemon.Tests/Daemon/DataRepositoryTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/Daemon/DataRepositoryTests.cs
@@ -7,6 +7,7 @@
using NetDaemon.Common.Fluent;
using NetDaemon.Daemon.Storage;
using Xunit;
+using NetDaemon.Daemon.Fakes;
namespace NetDaemon.Daemon.Tests.Daemon
{
diff --git a/tests/NetDaemon.Daemon.Tests/Daemon/HttpHandlerMock.cs b/tests/NetDaemon.Daemon.Tests/Daemon/HttpHandlerMock.cs
index 8f9225ecd..a44db111c 100644
--- a/tests/NetDaemon.Daemon.Tests/Daemon/HttpHandlerMock.cs
+++ b/tests/NetDaemon.Daemon.Tests/Daemon/HttpHandlerMock.cs
@@ -1,74 +1,74 @@
-using Moq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using NetDaemon.Common;
+// using Moq;
+// using System.Net;
+// using System.Net.Http;
+// using System.Text;
+// using System.Threading;
+// using System.Threading.Tasks;
+// using NetDaemon.Common;
-namespace NetDaemon.Daemon.Tests.Daemon
-{
- public class HttpClientFactoryMock : Mock
- {
- private HttpClient? _httpClient;
- private MockHttpMessageHandler? _handler;
- public MockHttpMessageHandler? MessageHandler => _handler;
+// namespace NetDaemon.Daemon.Tests.Daemon
+// {
+// public class HttpClientFactoryMock : Mock
+// {
+// private HttpClient? _httpClient;
+// private MockHttpMessageHandler? _handler;
+// public MockHttpMessageHandler? MessageHandler => _handler;
- public HttpClientFactoryMock()
- {
- }
+// public HttpClientFactoryMock()
+// {
+// }
- public void SetResponse(string response, HttpStatusCode statusCode = HttpStatusCode.OK)
- {
- _handler = new MockHttpMessageHandler(response, statusCode);
- _httpClient = new HttpClient(_handler);
- Setup(x => x.CreateClient(It.IsAny())).Returns(_httpClient!);
- }
- }
+// public void SetResponse(string response, HttpStatusCode statusCode = HttpStatusCode.OK)
+// {
+// _handler = new MockHttpMessageHandler(response, statusCode);
+// _httpClient = new HttpClient(_handler);
+// Setup(x => x.CreateClient(It.IsAny())).Returns(_httpClient!);
+// }
+// }
- public class HttpHandlerMock : Mock
- {
- private HttpClient? _httpClient;
- private MockHttpMessageHandler? _handler;
+// public class HttpHandlerMock : Mock
+// {
+// private HttpClient? _httpClient;
+// private MockHttpMessageHandler? _handler;
- public MockHttpMessageHandler? MessageHandler => _handler;
+// public MockHttpMessageHandler? MessageHandler => _handler;
- public HttpHandlerMock()
- {
- }
+// public HttpHandlerMock()
+// {
+// }
- public void SetResponse(string response, HttpStatusCode statusCode = HttpStatusCode.OK)
- {
- _handler = new MockHttpMessageHandler(response, statusCode);
- _httpClient = new HttpClient(_handler);
- Setup(x => x.CreateHttpClient(It.IsAny())).Returns(_httpClient!);
- }
- }
+// public void SetResponse(string response, HttpStatusCode statusCode = HttpStatusCode.OK)
+// {
+// _handler = new MockHttpMessageHandler(response, statusCode);
+// _httpClient = new HttpClient(_handler);
+// Setup(x => x.CreateHttpClient(It.IsAny())).Returns(_httpClient!);
+// }
+// }
- public class MockHttpMessageHandler : HttpMessageHandler
- {
- private readonly string _response;
- private readonly HttpStatusCode _StatusCode;
+// public class MockHttpMessageHandler : HttpMessageHandler
+// {
+// private readonly string _response;
+// private readonly HttpStatusCode _StatusCode;
- private string? _requestContent;
+// private string? _requestContent;
- public string? RequestContent => _requestContent;
+// public string? RequestContent => _requestContent;
- public MockHttpMessageHandler(string response, HttpStatusCode statusCode = HttpStatusCode.OK)
- {
- _response = response;
- _StatusCode = statusCode;
- }
+// public MockHttpMessageHandler(string response, HttpStatusCode statusCode = HttpStatusCode.OK)
+// {
+// _response = response;
+// _StatusCode = statusCode;
+// }
- protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
- {
- var responseMessage = new HttpResponseMessage(_StatusCode);
+// protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+// {
+// var responseMessage = new HttpResponseMessage(_StatusCode);
- if (request is not null && request.Content is not null)
- _requestContent = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
+// if (request is not null && request.Content is not null)
+// _requestContent = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
- responseMessage.Content = new ByteArrayContent(Encoding.ASCII.GetBytes(_response));
- return responseMessage;
- }
- }
-}
\ No newline at end of file
+// responseMessage.Content = new ByteArrayContent(Encoding.ASCII.GetBytes(_response));
+// return responseMessage;
+// }
+// }
+// }
\ No newline at end of file
diff --git a/tests/NetDaemon.Daemon.Tests/Daemon/HttpTests.cs b/tests/NetDaemon.Daemon.Tests/Daemon/HttpTests.cs
index 064af692b..7f3be7b0e 100644
--- a/tests/NetDaemon.Daemon.Tests/Daemon/HttpTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/Daemon/HttpTests.cs
@@ -3,6 +3,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
+using NetDaemon.Daemon.Fakes;
using Xunit;
namespace NetDaemon.Daemon.Tests.Daemon
diff --git a/tests/NetDaemon.Daemon.Tests/Daemon/NetDaemonHostTests.cs b/tests/NetDaemon.Daemon.Tests/Daemon/NetDaemonHostTests.cs
index dab9cfe35..4222f1b8c 100644
--- a/tests/NetDaemon.Daemon.Tests/Daemon/NetDaemonHostTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/Daemon/NetDaemonHostTests.cs
@@ -7,6 +7,7 @@
using System.Threading.Tasks;
using NetDaemon.Common;
using Xunit;
+using NetDaemon.Daemon.Fakes;
namespace NetDaemon.Daemon.Tests.Daemon
{
@@ -14,7 +15,7 @@ public class HostTestApp : NetDaemon.Common.NetDaemonApp
{
}
- public class NetDaemonTests : DaemonHostTestBase
+ public class NetDaemonTests : CoreDaemonHostTestBase
{
public NetDaemonTests() : base()
{
@@ -24,8 +25,8 @@ public NetDaemonTests() : base()
public async Task EventShouldCallCorrectFunction()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
dynamic helloWorldDataObject = GetDynamicDataObject(HelloWorldData);
@@ -42,7 +43,7 @@ public async Task EventShouldCallCorrectFunction()
return Task.CompletedTask;
});
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.True(isCalled);
@@ -53,15 +54,16 @@ public async Task EventShouldCallCorrectFunction()
public async Task AttributeServiceCallShouldFindCorrectFunction()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
var app = new AssmeblyDaemonApp();
app.Id = "id";
DefaultDaemonHost.InternalRunningAppInstances[app.Id] = app;
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
// ACT
await app.HandleAttributeInitialization(DefaultDaemonHost).ConfigureAwait(false);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.Single(app.DaemonCallBacksForServiceCalls);
@@ -85,17 +87,16 @@ public async Task GetStateReturnsCorrectEntityState()
// ARRANGE
// Fake what is coming from hass client
- var task = RunDefauldDaemonUntilCanceled();
+ await FakeDaemonInit().ConfigureAwait(false);
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
// ACT
var entity = DefaultDaemonHost.GetState("light.correct_entity");
- await task;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.NotNull(entity);
- Assert.Equal(entity?.State, "on");
+ Assert.Equal("on", entity?.State);
}
// Todo: Add tests to test objects and arrays from the dynamic conversion
@@ -104,6 +105,7 @@ public async Task GetStateReturnsCorrectEntityState()
public async Task OtherEventShouldNotCallCorrectFunction()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
dynamic dataObject = GetDynamicDataObject();
DefaultHassClientMock.AddCustomEvent("CUSTOM_EVENT", dataObject);
@@ -117,26 +119,12 @@ public async Task OtherEventShouldNotCallCorrectFunction()
return Task.CompletedTask;
});
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.False(isCalled);
}
- [Fact]
- public async Task RunConnectedReturnsARunningTask()
- {
- // ARRANGE
-
- // ACT
- var (runTask, _) = ReturnRunningDefauldDaemonHostTask();
- await Task.Delay(10);
-
- // ASSERT
- Assert.False(runTask.IsCompleted || runTask.IsCanceled);
- await runTask;
- }
-
[Fact]
public async Task RunNotConnectedCompletesTask()
{
@@ -164,76 +152,76 @@ public void RunNullReferenceToHassClientShouldThrowException()
public async Task SendEventShouldCallCorrectMethod()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
var eventData = GetDynamicDataObject();
- var task = RunDefauldDaemonUntilCanceled();
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
// ACT
await DefaultDaemonHost.SendEvent("test_event", eventData);
- await task;
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
var expandoObject = (ExpandoObject)eventData;
- DefaultHassClientMock.Verify(n => n.SendEvent("test_event", expandoObject));
+ VerifyEventSent("test_event", expandoObject);
}
[Fact]
public async Task SendEventWithNullDataShouldCallCorrectMethod()
{
// ARRANGE
- var task = RunDefauldDaemonUntilCanceled();
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
await DefaultDaemonHost.SendEvent("test_event");
- await task;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
- DefaultHassClientMock.Verify(n => n.SendEvent("test_event", null));
+ VerifyEventSent("test_event");
}
[Fact]
public async Task SpeakShouldCallCorrectService()
{
+ await FakeDaemonInit().ConfigureAwait(false);
// ARRANGE
- DefaultHassClientMock.FakeStates["media_player.fakeplayer"] = new HassState
+ SetEntityState(new()
{
- EntityId = "media_player.fakeplayer",
- };
+ EntityId = "media_player.fakeplayer"
+ });
DefaultDaemonHost.InternalDelayTimeForTts = 0; // For testing
// ACT
- var (daemonTask, _) = ReturnRunningDefauldDaemonHostTask();
-
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
-
DefaultDaemonHost.Speak("media_player.fakeplayer", "Hello test!");
var (_, expObject) = GetDynamicObject(
("entity_id", "media_player.fakeplayer"),
("message", "Hello test!")
);
-
- await Task.Delay(50);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
- DefaultHassClientMock.Verify(n => n.CallService("tts", "google_cloud_say", expObject, true));
-
- await WaitUntilCanceled(daemonTask);
+ VerifyCallService("tts", "google_cloud_say", expObject, true);
}
[Fact]
public async Task SpeakShouldWaitUntilMediaPlays()
{
// ARRANGE
+ SetEntityState(new()
+ {
+ EntityId = "media_player.fakeplayer",
+ Attributes = new()
+ {
+ ["entity_id"] = "media_player.fakeplayer",
+ ["message"] = "Hello test!",
+ ["media_duration"] = 0.2
+ }
+ }
+ );
// Get a running default Daemon
- var (daemonTask, _) = ReturnRunningDefauldDaemonHostTask(700);
-
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
-
- DefaultDaemonHost.InternalDelayTimeForTts = 0; // Allow now extra waittime
+ await FakeDaemonInit(500).ConfigureAwait(false);
// Expected data call service
var (expectedAttruibutes, expectedAttributesExpObject) = GetDynamicObject(
@@ -241,18 +229,6 @@ public async Task SpeakShouldWaitUntilMediaPlays()
("message", "Hello test!")
);
- // Add the player that we want to fake having with the fake playing 0.1 second media duration
- dynamic currentStateAttributes = new ExpandoObject();
- currentStateAttributes.media_duration = 0.1;
-
- DefaultDaemonHost.InternalState["media_player.fakeplayer"] = new EntityState
- {
- EntityId = "media_player.fakeplayer",
- Attribute = currentStateAttributes
- };
-
- // await Task.Delay(100);
-
// ACT
DefaultDaemonHost.Speak("media_player.fakeplayer", "Hello test!");
DefaultDaemonHost.Speak("media_player.fakeplayer", "Hello test!");
@@ -261,13 +237,12 @@ public async Task SpeakShouldWaitUntilMediaPlays()
await Task.Delay(50);
- DefaultHassClientMock.Verify(n => n.CallService("tts", "google_cloud_say", expectedAttributesExpObject, true), Times.Once);
+ VerifyCallService("tts", "google_cloud_say", expectedAttributesExpObject, true, Times.Once());
- await Task.Delay(150);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// Called twice
- DefaultHassClientMock.Verify(n => n.CallService("tts", "google_cloud_say", expectedAttributesExpObject, true), Times.Exactly(2));
+ VerifyCallService("tts", "google_cloud_say", expectedAttributesExpObject, true, Times.Exactly(2));
- await WaitUntilCanceled(daemonTask);
}
[Fact]
@@ -282,6 +257,7 @@ public async Task StopCallsCloseClient()
public async Task SubscribeChangedStateForEntityWillMakeCorrectCallback()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
string? reportedState = "";
@@ -294,7 +270,7 @@ public async Task SubscribeChangedStateForEntityWillMakeCorrectCallback()
return Task.CompletedTask;
});
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.Equal("on", reportedState);
@@ -304,6 +280,7 @@ public async Task SubscribeChangedStateForEntityWillMakeCorrectCallback()
public async Task SubscribeChangedStateForAllChangesWillMakeCorrectCallbacks()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
DefaultHassClientMock.AddChangedEvent("light.mylight", fromState: "on", toState: "off");
@@ -317,7 +294,7 @@ public async Task SubscribeChangedStateForAllChangesWillMakeCorrectCallbacks()
return Task.CompletedTask;
});
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout();
// ASSERT
Assert.Equal(2, nrOfTimesCalled);
@@ -327,6 +304,7 @@ public async Task SubscribeChangedStateForAllChangesWillMakeCorrectCallbacks()
public async Task ChangedEventHaveNullDataShouldThrowException()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
DefaultHassClientMock.FakeEvents.Enqueue(new HassEvent
{
EventType = "state_changed",
@@ -334,7 +312,7 @@ public async Task ChangedEventHaveNullDataShouldThrowException()
});
// ACT
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
//ASSERT
LoggerMock.AssertLogged(LogLevel.Error, Times.AtLeastOnce());
@@ -344,6 +322,7 @@ public async Task ChangedEventHaveNullDataShouldThrowException()
public async Task CancelChangedStateForSubscriptionWillNotMakeCallback()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
bool isCalled = false;
// ACT
@@ -358,7 +337,7 @@ public async Task CancelChangedStateForSubscriptionWillNotMakeCallback()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.False(isCalled);
@@ -369,8 +348,8 @@ public async Task CancelChangedStateForSubscriptionWillNotMakeCallback()
public async Task CallServiceEventShouldCallCorrectFunction()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
var dynObject = GetDynamicDataObject(HelloWorldData);
- var daemonTask = await GetConnectedNetDaemonTask();
var isCalled = false;
@@ -386,7 +365,7 @@ public async Task CallServiceEventShouldCallCorrectFunction()
DefaultHassClientMock.AddCallServiceEvent("custom_domain", "any_service", dynObject);
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.True(isCalled);
@@ -397,6 +376,7 @@ public async Task CallServiceEventShouldCallCorrectFunction()
public async Task CallServiceEventOtherShouldNotCallFunction()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
var dynObject = GetDynamicDataObject(HelloWorldData);
DefaultHassClientMock.AddCallServiceEvent("custom_domain", "other_service", dynObject);
@@ -411,7 +391,7 @@ public async Task CallServiceEventOtherShouldNotCallFunction()
return Task.CompletedTask;
});
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
Assert.False(isCalled);
Assert.True(string.IsNullOrEmpty(message));
@@ -445,12 +425,12 @@ public async Task DelayStateChangeShouldReturnTrue()
// ARRANGE
// ACT
+ await FakeDaemonInit().ConfigureAwait(false);
using var delayResult = DefaultDaemonApp.DelayUntilStateChange(new string[] { "binary_sensor.pir" }, to: "on");
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
- await RunDefauldDaemonUntilCanceled();
-
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.True(delayResult.Task.Result);
Assert.Empty(DefaultDaemonApp.InternalStateActions);
@@ -460,13 +440,13 @@ public async Task DelayStateChangeShouldReturnTrue()
public async Task DelayStateChangeWithToAndFromShouldReturnTrue()
{
// ARRANGE
-
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
using var delayResult = DefaultDaemonApp.DelayUntilStateChange(new string[] { "binary_sensor.pir" }, to: "on", from: "off");
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.True(delayResult.Task.Result);
@@ -476,14 +456,15 @@ public async Task DelayStateChangeWithToAndFromShouldReturnTrue()
[Fact]
public async Task DelayStateChangeWithToAndFromWrongShouldNotComplete()
{
- // ARRANGE
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
using var delayResult = DefaultDaemonApp.DelayUntilStateChange(new string[] { "binary_sensor.pir" }, to: "on", from: "unknown");
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.False(delayResult.Task.IsCompleted);
@@ -494,13 +475,13 @@ public async Task DelayStateChangeWithToAndFromWrongShouldNotComplete()
public async Task DelayStateLambdaChangeShouldReturnTrue()
{
// ARRANGE
-
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
using var delayResult = DefaultDaemonApp.DelayUntilStateChange(new string[] { "binary_sensor.pir" }, (n, o) => n?.State == "on");
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.True(delayResult.Task.Result);
@@ -511,13 +492,13 @@ public async Task DelayStateLambdaChangeShouldReturnTrue()
public async Task DelayStateLambdaChangeShouldNotComplete()
{
// ARRANGE
-
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
using var delayResult = DefaultDaemonApp.DelayUntilStateChange(new string[] { "binary_sensor.pir" }, (n, o) => n?.State == "on");
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "on", toState: "off");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.False(delayResult.Task.IsCompleted);
@@ -528,13 +509,14 @@ public async Task DelayStateLambdaChangeShouldNotComplete()
public async Task DelayStateChangeCancelShouldReturnFalse()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
using var delayResult = DefaultDaemonApp.DelayUntilStateChange(new string[] { "binary_sensor.pir" }, to: "on");
delayResult.Cancel();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.False(delayResult.Task.Result);
@@ -614,12 +596,13 @@ public async Task StateChangeHasAreaInformation()
EntityId = "binary_sensor.pir",
DeviceId = "device_id"
};
+ await FakeDaemonInit().ConfigureAwait(false);
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", fromState: "off", toState: "on");
// ACT
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.Equal("Correct name", DefaultDaemonHost.InternalState["binary_sensor.pir"].Area);
@@ -629,11 +612,10 @@ public async Task StateChangeHasAreaInformation()
public async Task SetStateShouldKeepSameArea()
{
// ARRANGE
- var task = RunDefauldDaemonUntilCanceled();
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
var state = await DefaultDaemonHost.SetStateAsync("light.ligth_in_area", "on", ("attr", "value"));
- await task;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
/// ASSERT
Assert.Equal("Area", state?.Area);
}
diff --git a/tests/NetDaemon.Daemon.Tests/DaemonHostTestBase.cs b/tests/NetDaemon.Daemon.Tests/DaemonHostTestBase.cs
deleted file mode 100644
index a6040fcd3..000000000
--- a/tests/NetDaemon.Daemon.Tests/DaemonHostTestBase.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Dynamic;
-using System.Threading;
-using System.Threading.Tasks;
-using Moq;
-using NetDaemon.Common.Reactive;
-using NetDaemon.Daemon.Storage;
-using NetDaemon.Daemon.Tests.Daemon;
-using Xunit;
-
-namespace NetDaemon.Daemon.Tests
-{
- public class BaseTestApp : Common.NetDaemonApp { }
-
- public class BaseTestRxApp : NetDaemonRxApp { }
-
- public partial class DaemonHostTestBase : IAsyncLifetime
- {
- private readonly Common.NetDaemonApp _defaultDaemonApp;
- private readonly NetDaemonHost _defaultDaemonHost;
- private readonly BaseTestRxApp _defaultDaemonRxApp;
- private readonly Mock _defaultDataRepositoryMock;
- private readonly HassClientMock _defaultHassClientMock;
- private readonly HttpHandlerMock _defaultHttpHandlerMock;
- private readonly Mock _defaultMockedRxApp;
- private readonly LoggerMock _loggerMock;
- private readonly NetDaemonHost _notConnectedDaemonHost;
-
- internal DaemonHostTestBase()
- {
- _loggerMock = new LoggerMock();
- _defaultHassClientMock = HassClientMock.DefaultMock;
- _defaultDataRepositoryMock = new Mock();
-
- _defaultHttpHandlerMock = new HttpHandlerMock();
- _defaultDaemonHost = new NetDaemonHost(
- _defaultHassClientMock.Object,
- _defaultDataRepositoryMock.Object,
- _loggerMock.LoggerFactory,
- _defaultHttpHandlerMock.Object);
-
- _defaultDaemonApp = new BaseTestApp();
- _defaultDaemonApp.Id = "app_id";
- _defaultDaemonApp.IsEnabled = true;
-
- _defaultDaemonHost.InternalRunningAppInstances[_defaultDaemonApp.Id!] = _defaultDaemonApp;
-
- _defaultDaemonRxApp = new BaseTestRxApp();
- _defaultDaemonRxApp.Id = "app_rx_id";
- _defaultDaemonRxApp.IsEnabled = true;
- _defaultDaemonHost.InternalRunningAppInstances[_defaultDaemonRxApp.Id!] = _defaultDaemonRxApp;
-
- _defaultMockedRxApp = new Mock() { CallBase = true };
- _defaultMockedRxApp.Object.Id = "app_rx_mock_id";
- _defaultMockedRxApp.Object.IsEnabled = true;
- _defaultMockedRxApp.Setup(n => n.CreateObservableIntervall(It.IsAny(), It.IsAny())).Returns(new Mock().Object);
- _defaultDaemonHost.InternalRunningAppInstances[_defaultMockedRxApp.Object.Id!] = _defaultMockedRxApp.Object;
-
- _notConnectedDaemonHost = new NetDaemonHost(HassClientMock.MockConnectFalse.Object, _defaultDataRepositoryMock.Object, _loggerMock.LoggerFactory);
- }
-
- public Common.NetDaemonApp DefaultDaemonApp => _defaultDaemonApp;
-
- public NetDaemonHost DefaultDaemonHost => _defaultDaemonHost;
- public BaseTestRxApp DefaultDaemonRxApp => _defaultDaemonRxApp;
- public Mock DefaultDataRepositoryMock => _defaultDataRepositoryMock;
- public HassClientMock DefaultHassClientMock => _defaultHassClientMock;
- public HttpHandlerMock DefaultHttpHandlerMock => _defaultHttpHandlerMock;
- public Mock DefaultMockedRxApp => _defaultMockedRxApp;
- public string HelloWorldData => "Hello world!";
-
- public LoggerMock LoggerMock => _loggerMock;
-
- public NetDaemonHost NotConnectedDaemonHost => _notConnectedDaemonHost;
-
- async Task IAsyncLifetime.DisposeAsync()
- {
- await _defaultDaemonApp.DisposeAsync().ConfigureAwait(false);
- await _defaultDaemonRxApp.DisposeAsync().ConfigureAwait(false);
- await _defaultDaemonHost.DisposeAsync().ConfigureAwait(false);
- await _defaultMockedRxApp.Object.DisposeAsync().ConfigureAwait(false);
- }
-
- public dynamic GetDynamicDataObject(string testData = "testdata")
- {
- var expandoObject = new ExpandoObject();
- dynamic dynamicData = expandoObject;
- dynamicData.Test = testData;
- return dynamicData;
- }
-
- public (dynamic, ExpandoObject) GetDynamicObject(params (string, object)[] dynamicParameters)
- {
- var expandoObject = new ExpandoObject();
- var dict = expandoObject as IDictionary;
-
- foreach (var (name, value) in dynamicParameters)
- {
- dict[name] = value;
- }
- return (expandoObject, expandoObject);
- }
-
- public async Task InitializeAsync()
- {
- await _defaultDaemonApp.StartUpAsync(_defaultDaemonHost).ConfigureAwait(false);
- await _defaultDaemonRxApp.StartUpAsync(_defaultDaemonHost).ConfigureAwait(false);
- await _defaultMockedRxApp.Object.StartUpAsync(_defaultDaemonHost).ConfigureAwait(false);
- }
-
- public (Task, CancellationTokenSource) ReturnRunningDefauldDaemonHostTask(short milliSeconds = 100, bool overrideDebugNotCancel = false)
- {
- var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
- ? new CancellationTokenSource()
- : new CancellationTokenSource(milliSeconds);
- return (_defaultDaemonHost.Run("host", 8123, false, "token", cancelSource.Token), cancelSource);
- }
-
- public (Task, CancellationTokenSource) ReturnRunningNotConnectedDaemonHostTask(short milliSeconds = 100, bool overrideDebugNotCancel = false)
- {
- var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
- ? new CancellationTokenSource()
- : new CancellationTokenSource(milliSeconds);
- return (_notConnectedDaemonHost.Run("host", 8123, false, "token", cancelSource.Token), cancelSource);
- }
-
- public async Task RunDefauldDaemonUntilCanceled(short milliSeconds = 200, bool overrideDebugNotCancel = false)
- {
- var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
- ? new CancellationTokenSource()
- : new CancellationTokenSource(milliSeconds);
- try
- {
- await _defaultDaemonHost.Run("host", 8123, false, "token", cancelSource.Token).ConfigureAwait(false);
- }
- catch (TaskCanceledException)
- {
- // Expected behaviour
- }
- }
-
- public async Task WaitUntilCanceled(Task task)
- {
- try
- {
- await task.ConfigureAwait(false);
- }
- catch (TaskCanceledException)
- {
- // Expected behaviour
- }
- }
-
- protected async Task GetConnectedNetDaemonTask(short milliSeconds = 100, bool overrideDebugNotCancel = false)
- {
- var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
- ? new CancellationTokenSource()
- : new CancellationTokenSource(milliSeconds);
-
- var daemonTask = _defaultDaemonHost.Run("host", 8123, false, "token", cancelSource.Token);
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, cancelSource.Token);
- return daemonTask;
- }
-
- protected async Task WaitForDefaultDaemonToConnect(NetDaemonHost daemonHost, CancellationToken stoppingToken)
- {
- var nrOfTimesCheckForConnectedState = 0;
-
- while (!daemonHost.Connected && !stoppingToken.IsCancellationRequested)
- {
- await Task.Delay(50, stoppingToken).ConfigureAwait(false);
- if (nrOfTimesCheckForConnectedState++ > 5)
- break;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/tests/NetDaemon.Daemon.Tests/DaemonRunner/Api/ApiTests.cs b/tests/NetDaemon.Daemon.Tests/DaemonRunner/Api/ApiTests.cs
index 439f3eece..25c2cef4b 100644
--- a/tests/NetDaemon.Daemon.Tests/DaemonRunner/Api/ApiTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/DaemonRunner/Api/ApiTests.cs
@@ -23,6 +23,7 @@
using System.Collections.Generic;
using System.Linq;
using NetDaemon.Common.Configuration;
+using NetDaemon.Daemon.Fakes;
namespace NetDaemon.Daemon.Tests.DaemonRunner.Api
{
diff --git a/tests/NetDaemon.Daemon.Tests/DaemonRunner/App/DaemonAppTests.cs b/tests/NetDaemon.Daemon.Tests/DaemonRunner/App/DaemonAppTests.cs
index 497eeefe2..30744d4ec 100644
--- a/tests/NetDaemon.Daemon.Tests/DaemonRunner/App/DaemonAppTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/DaemonRunner/App/DaemonAppTests.cs
@@ -12,6 +12,7 @@
using NetDaemon.Daemon.Config;
using NetDaemon.Service.App;
using Xunit;
+using NetDaemon.Daemon.Fakes;
namespace NetDaemon.Daemon.Tests.DaemonRunner.App
{
diff --git a/tests/NetDaemon.Daemon.Tests/FakesTests/FakeApp.cs b/tests/NetDaemon.Daemon.Tests/FakesTests/FakeApp.cs
new file mode 100644
index 000000000..d96d5c21f
--- /dev/null
+++ b/tests/NetDaemon.Daemon.Tests/FakesTests/FakeApp.cs
@@ -0,0 +1,31 @@
+using System.Linq;
+using System;
+using System.Reactive.Linq;
+using NetDaemon.Common.Reactive;
+
+namespace NetDaemon.Daemon.Tests.Reactive
+{
+
+ /// cool multiple lines
+ public class FakeApp : NetDaemonRxApp
+ {
+ public override void Initialize()
+ {
+ Entity("binary_sensor.kitchen")
+ .StateChanges
+ .Where(e => e.New?.State == "on" && e.Old?.State == "off")
+ .Subscribe(s =>
+ {
+ Entity("light.kitchen").TurnOn();
+ });
+
+ Entity("sensor.temperature")
+ .StateAllChanges
+ .Where(e => e.New?.Attribute?.battery_level < 15)
+ .Subscribe(s =>
+ {
+ this.CallService("notify", "notify", new { title = "Hello from Home Assistant" });
+ });
+ }
+ }
+}
diff --git a/tests/NetDaemon.Daemon.Tests/FakesTests/FakeTests.cs b/tests/NetDaemon.Daemon.Tests/FakesTests/FakeTests.cs
new file mode 100644
index 000000000..30abb5763
--- /dev/null
+++ b/tests/NetDaemon.Daemon.Tests/FakesTests/FakeTests.cs
@@ -0,0 +1,504 @@
+using System;
+using System.Dynamic;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Threading.Tasks;
+using JoySoftware.HomeAssistant.Client;
+using Moq;
+using NetDaemon.Common.Fluent;
+using NetDaemon.Common.Reactive;
+using NetDaemon.Daemon.Fakes;
+using Xunit;
+
+namespace NetDaemon.Daemon.Tests.Reactive
+{
+ ///
+ /// Tests the fluent API parts of the daemon
+ ///
+ ///
+ /// Mainly the tests checks if correct underlying call to "CallService"
+ /// has been made.
+ ///
+ public class FakeTests : CoreDaemonHostTestBase
+ {
+ public FakeTests() : base()
+ {
+ }
+
+ [Fact]
+ public async Task CallServiceShouldCallCorrectFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var (dynObj, expObj) = GetDynamicObject(
+ ("attr", "value"));
+
+ // ACT
+ DefaultDaemonRxApp.CallService("mydomain", "myservice", dynObj);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ VerifyCallServiceTuple("mydomain", "myservice", ("attr", "value"));
+ }
+
+ [Fact]
+ public async Task NewAllEventDataShouldCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.StateAllChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "on", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.True(called);
+ }
+
+ [Fact]
+ public async Task NewEventShouldCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.EventChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddCustomEvent("AN_EVENT", new { somedata = "hello" });
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.True(called);
+ }
+
+ [Fact]
+ public async Task NewEventMissingDataAttributeShouldReturnNull()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ string? missingAttribute = "has initial value";
+
+ // ACT
+ DefaultDaemonRxApp.EventChanges
+ .Subscribe(s =>
+ {
+ missingAttribute = s.Data?.missing_data;
+ });
+
+ var expandoObj = new ExpandoObject();
+ dynamic dynExpObject = expandoObj;
+ dynExpObject.a_parameter = "hello";
+
+ DefaultHassClientMock.AddCustomEvent("AN_EVENT", dynExpObject);
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.Null(missingAttribute);
+ }
+
+ [Fact]
+ public async Task NewStateEventShouldCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.StateChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.True(called);
+ }
+
+ [Fact]
+ public async Task RunScriptShouldCallCorrectFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ var (dynObj, expObj) = GetDynamicObject(
+ ("attr", "value"));
+
+ // ACT
+ DefaultDaemonRxApp.RunScript("myscript");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+
+
+ DefaultHassClientMock.VerifyCallServiceTimes("myscript", Times.Once());
+ }
+
+ [Fact]
+ public async Task RunScriptWithDomainShouldCallCorrectFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var (dynObj, expObj) = GetDynamicObject(
+ ("attr", "value"));
+
+ // ACT
+ DefaultDaemonRxApp.RunScript("script.myscript");
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ DefaultHassClientMock.VerifyCallServiceTimes("myscript", Times.Once());
+ }
+
+ [Fact]
+ public async Task SameStateEventShouldNotCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.StateChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "on", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.False(called);
+ }
+ [Fact]
+ public async Task SetStateShouldReturnCorrectData()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ var (dynObj, expObj) = GetDynamicObject(
+ ("attr", "value"));
+
+ // ACT
+ DefaultDaemonRxApp.SetState("sensor.any_sensor", "on", dynObj);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ DefaultHassClientMock.Verify(n => n.SetState("sensor.any_sensor", "on", expObj));
+ }
+
+ [Fact]
+ public async Task StartupAsyncShouldThrowIfDaemonIsNull()
+ {
+ INetDaemonHost? host = null;
+
+ // ARRANGE ACT ASSERT
+ await Assert.ThrowsAsync(() => DefaultDaemonRxApp.StartUpAsync(host!));
+ }
+
+ [Fact]
+ public async Task StateShouldReturnCorrectEntity()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ // ACT
+ var entity = DefaultDaemonRxApp.State("binary_sensor.pir");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.NotNull(entity);
+ }
+
+ [Fact]
+ public async Task StateShouldReturnNullIfAttributeNotExist()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ // ACT
+ var entity = DefaultDaemonRxApp.State("binary_sensor.pir");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.Null(entity?.Attribute?.not_exists);
+ }
+
+ [Fact]
+ public async Task StatesShouldReturnCorrectEntity()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ // ACT
+ var entity = DefaultDaemonRxApp.States.FirstOrDefault(n => n.EntityId == "binary_sensor.pir");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+ // ASSERT
+ Assert.NotNull(entity);
+ Assert.Equal("binary_sensor.pir", entity?.EntityId);
+ }
+
+ [Fact]
+ public async Task EntityIdsShouldReturnCorrectItems()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ // ACT
+ var entities = DefaultDaemonRxApp.EntityIds.ToList();
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+ // ASSERT
+ Assert.NotNull(entities);
+ Assert.Equal(8, entities.Count());
+ }
+
+ [Fact]
+ public async Task UsingEntitiesLambdaNewEventShouldCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.Entities(n => n.EntityId.StartsWith("binary_sensor.pir"))
+ .StateChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir_2", "off", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.True(called);
+ }
+
+ [Fact]
+ public async Task CallbackObserverAttributeMissingShouldReturnNull()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ string? missingString = "has initial value";
+
+ // ACT
+ DefaultDaemonRxApp.Entities(n => n.EntityId.StartsWith("binary_sensor.pir"))
+ .StateChanges
+ .Subscribe(s =>
+ {
+ missingString = s.New.Attribute?.missing_attribute;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir_2", "off", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.Null(missingString);
+ }
+
+ [Fact]
+ public async Task UsingEntitiesNewEventShouldCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.Entities("binary_sensor.pir", "binary_sensor.pir_2")
+ .StateChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir_2", "off", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.True(called);
+ }
+
+ [Fact]
+ public async Task UsingEntityNewEventShouldCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.Entity("binary_sensor.pir")
+ .StateChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.True(called);
+ }
+
+ [Fact]
+ public async Task UsingEntityNewEventShouldNotCallFunction()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ var called = false;
+
+ // ACT
+ DefaultDaemonRxApp.Entity("binary_sensor.other_pir")
+ .StateChanges
+ .Subscribe(s =>
+ {
+ called = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.False(called);
+ }
+ [Fact]
+ public async Task WhenStateStaysSameForTimeItShouldCallFunction()
+ {
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ bool isRun = false;
+ using var ctx = DefaultDaemonRxApp.StateChanges
+ .Where(t => t.New.EntityId == "binary_sensor.pir")
+ .NDSameStateFor(TimeSpan.FromMilliseconds(50))
+ .Subscribe(e =>
+ {
+ isRun = true;
+ });
+
+ DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ Assert.True(isRun);
+ }
+
+ [Fact]
+ public async Task SavedDataShouldReturnSameDataUsingExpando()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ dynamic data = new ExpandoObject();
+ data.Item = "Some data";
+
+ // ACT
+ DefaultDaemonRxApp.SaveData("data_exists", data);
+ var collectedData = DefaultDaemonRxApp.GetData("data_exists");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // ASSERT
+ Assert.Equal(data, collectedData);
+ }
+
+ [Fact]
+ public async Task GetDataShouldReturnCachedValue()
+ {
+ // ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+ // ACT
+
+ DefaultDaemonRxApp.SaveData("GetDataShouldReturnCachedValue_id", "saved data");
+
+ DefaultDaemonRxApp.GetData("GetDataShouldReturnCachedValue_id");
+
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+ // ASSERT
+ DefaultDataRepositoryMock.Verify(n => n.Get(It.IsAny()), Times.Never);
+ DefaultDataRepositoryMock.Verify(n => n.Save(It.IsAny(), It.IsAny()), Times.Once);
+ }
+
+ [Fact]
+ public async Task TestFakeAppTurnOnCorrectLight()
+ {
+ // Add the app to test
+ await AddAppInstance(new FakeApp());
+
+ // Init NetDaemon core runtime
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ // Fake a changed event from en entity
+ AddChangedEvent("binary_sensor.kitchen", "off", "on");
+
+ // Run the NetDemon Core to process the messages
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // Verify that netdaemon called light.turn_on
+ VerifyCallService("light", "turn_on", "light.kitchen");
+ }
+
+
+ [Fact]
+ public async Task TestFakeAppCallNoteWhenBatteryLevelBelowValue()
+ {
+ // Add the app to test
+ await AddAppInstance(new FakeApp());
+
+ // Init NetDaemon core runtime
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ // Fake a changed event from en entity
+ AddChangeEvent(new()
+ {
+ EntityId = "sensor.temperature",
+ State = 10.0,
+ Attributes = new()
+ {
+ ["battery_level"] = 18.2
+ }
+ }
+ , new()
+ {
+ EntityId = "sensor.temperature",
+ State = 10.0,
+ Attributes = new()
+ {
+ ["battery_level"] = 12.0
+ }
+ });
+
+ // Run the NetDemon Core to process the messages
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
+ // Verify that netdaemon called light.turn_on
+ VerifyCallService("notify", "notify", new { title = "Hello from Home Assistant" });
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/NetDaemon.Daemon.Tests/Fluent/FluentCameraTests.cs b/tests/NetDaemon.Daemon.Tests/Fluent/FluentCameraTests.cs
index 22e282cc3..e187702bf 100644
--- a/tests/NetDaemon.Daemon.Tests/Fluent/FluentCameraTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/Fluent/FluentCameraTests.cs
@@ -3,6 +3,7 @@
using Microsoft.Extensions.Logging;
using Moq;
using NetDaemon.Common;
+using NetDaemon.Daemon.Fakes;
using Xunit;
namespace NetDaemon.Daemon.Tests.Fluent
@@ -14,7 +15,7 @@ namespace NetDaemon.Daemon.Tests.Fluent
/// Mainly the tests checks if correct underlying call to "CallService"
/// has been made.
///
- public class FluentCameraTests : DaemonHostTestBase
+ public class FluentCameraTests : CoreDaemonHostTestBase
{
public FluentCameraTests() : base()
{
@@ -35,7 +36,7 @@ await DefaultDaemonApp
// ASSERT
DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call, ("entity_id", entityId));
+ DefaultHassClientMock.VerifyCallServiceTuple("camera", service_call, ("entity_id", entityId));
}
[Fact]
@@ -53,7 +54,7 @@ await DefaultDaemonApp
// ASSERT
DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call, ("entity_id", entityId));
+ DefaultHassClientMock.VerifyCallServiceTuple("camera", service_call, ("entity_id", entityId));
}
[Fact]
@@ -77,7 +78,7 @@ await DefaultDaemonApp
// ASSERT
DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call, ("entity_id", entityId));
+ DefaultHassClientMock.VerifyCallServiceTuple("camera", service_call, ("entity_id", entityId));
}
[Fact]
@@ -95,7 +96,7 @@ await DefaultDaemonApp
// ASSERT
DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call, ("entity_id", entityId));
+ DefaultHassClientMock.VerifyCallServiceTuple("camera", service_call, ("entity_id", entityId));
}
[Fact]
@@ -112,8 +113,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call,
+ VerifyCallServiceTimes(service_call, Times.Once());
+ VerifyCallServiceTuple("camera", service_call,
("media_player", "media_player.player"),
("format", "anyformat"),
("entity_id", entityId)
@@ -134,8 +135,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call,
+ VerifyCallServiceTimes(service_call, Times.Once());
+ VerifyCallServiceTuple("camera", service_call,
("filename", "filename"),
("duration", 1),
("lookback", 2),
@@ -157,8 +158,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call,
+ VerifyCallServiceTimes(service_call, Times.Once());
+ VerifyCallServiceTuple("camera", service_call,
("filename", "filename"),
("entity_id", entityId)
);
@@ -179,7 +180,7 @@ await DefaultDaemonApp
// ASSERT
DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call, ("entity_id", entityId));
+ DefaultHassClientMock.VerifyCallServiceTuple("camera", service_call, ("entity_id", entityId));
}
[Fact]
@@ -197,7 +198,7 @@ await DefaultDaemonApp
// ASSERT
DefaultHassClientMock.VerifyCallServiceTimes(service_call, Times.Once());
- DefaultHassClientMock.VerifyCallService("camera", service_call, ("entity_id", entityId));
+ DefaultHassClientMock.VerifyCallServiceTuple("camera", service_call, ("entity_id", entityId));
}
[Fact]
diff --git a/tests/NetDaemon.Daemon.Tests/Fluent/FluentEventTests.cs b/tests/NetDaemon.Daemon.Tests/Fluent/FluentEventTests.cs
index 41e521b12..7d18d1879 100644
--- a/tests/NetDaemon.Daemon.Tests/Fluent/FluentEventTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/Fluent/FluentEventTests.cs
@@ -2,6 +2,7 @@
using System.Dynamic;
using System.Threading.Tasks;
using Moq;
+using NetDaemon.Daemon.Fakes;
using NetDaemon.Daemon.Storage;
using Xunit;
diff --git a/tests/NetDaemon.Daemon.Tests/Fluent/FluentTests.cs b/tests/NetDaemon.Daemon.Tests/Fluent/FluentTests.cs
index 9bf1a27bc..a4f02e0e7 100644
--- a/tests/NetDaemon.Daemon.Tests/Fluent/FluentTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/Fluent/FluentTests.cs
@@ -5,6 +5,8 @@
using Microsoft.Extensions.Logging;
using Moq;
using NetDaemon.Common;
+using NetDaemon.Common.Fluent;
+using NetDaemon.Daemon.Fakes;
using Xunit;
namespace NetDaemon.Daemon.Tests.Fluent
@@ -16,7 +18,7 @@ namespace NetDaemon.Daemon.Tests.Fluent
/// Mainly the tests checks if correct underlying call to "CallService"
/// has been made.
///
- public class FluentTests : DaemonHostTestBase
+ public class FluentTests : CoreDaemonHostTestBase
{
public FluentTests() : base()
{
@@ -30,9 +32,7 @@ public async Task EntityOnStateChangedForTimeTurnOffLightCallsCorrectServiceCall
var lastChanged = new DateTime(2020, 1, 1, 1, 1, 1, 20);
var lastUpdated = new DateTime(2020, 1, 1, 1, 1, 1, 50);
- var daemonTask = RunDefauldDaemonUntilCanceled(300); //overrideDebugNotCancel: true
-
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
+ await FakeDaemonInit(300).ConfigureAwait(false);
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -42,27 +42,23 @@ public async Task EntityOnStateChangedForTimeTurnOffLightCallsCorrectServiceCall
.TurnOff()
.Execute();
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "on", "off",
+ AddChangedEvent("binary_sensor.pir", "on", "off",
lastUpdated, lastChanged);
// ASSERT
await Task.Delay(10); // After 10ms we should not have call
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Never());
+ VerifyCallServiceTimes("turn_off", Times.Never());
await Task.Delay(300); // After 30ms we should have call
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Once());
- await daemonTask;
-
-
+ VerifyCallServiceTimes("turn_off", Times.Once());
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
}
[Fact]
public async Task EntityOnStateChangedLamdaTurnOnLightCallsCorrectServiceCall()
{
// ARRANGE
-
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
-
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -71,19 +67,19 @@ public async Task EntityOnStateChangedLamdaTurnOnLightCallsCorrectServiceCall()
.TurnOn()
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.correct_entity"));
}
[Fact]
public async Task EntityOnStateChangedLamdaWithMultipleEntitiesCallsCorrectServiceCall()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
var MotionEnabled = true;
DefaultDaemonApp
@@ -93,19 +89,18 @@ public async Task EntityOnStateChangedLamdaWithMultipleEntitiesCallsCorrectServi
.Toggle()
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("toggle", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "toggle", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("toggle", Times.Once());
+ VerifyCallServiceTuple("light", "toggle", ("entity_id", "light.correct_entity"));
}
[Fact]
public async Task OneEntityWithSeveralShouldCallsCorrectServiceCall()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
-
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -114,20 +109,20 @@ public async Task OneEntityWithSeveralShouldCallsCorrectServiceCall()
.Toggle()
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("toggle", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "toggle", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("toggle", Times.Once());
+ VerifyCallServiceTuple("light", "toggle", ("entity_id", "light.correct_entity"));
}
[Fact]
public async Task EntityOnStateChangedMultipleTimesCallsCorrectServiceCall()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+ await FakeDaemonInit().ConfigureAwait(false);
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ AddChangedEvent("binary_sensor.pir", "off", "on");
+ AddChangedEvent("binary_sensor.pir", "off", "on");
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -136,10 +131,9 @@ public async Task EntityOnStateChangedMultipleTimesCallsCorrectServiceCall()
.TurnOn()
.Execute();
- await RunDefauldDaemonUntilCanceled();
-
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Exactly(2));
- DefaultHassClientMock.VerifyCallService("light", "turn_on",
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+ VerifyCallServiceTimes("turn_on", Times.Exactly(2));
+ VerifyCallServiceTuple("light", "turn_on",
("entity_id", "light.correct_entity"));
}
@@ -147,9 +141,8 @@ public async Task EntityOnStateChangedMultipleTimesCallsCorrectServiceCall()
public async Task EntityOnStateChangedTurnOnLightCallsCorrectServiceCall()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
-
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -158,19 +151,18 @@ public async Task EntityOnStateChangedTurnOnLightCallsCorrectServiceCall()
.TurnOn()
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.correct_entity"));
}
[Fact]
public async Task EntityOnStateChangedEntitiesTurnOnLightCallsCorrectServiceCall()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
-
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -179,19 +171,20 @@ public async Task EntityOnStateChangedEntitiesTurnOnLightCallsCorrectServiceCall
.TurnOn()
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.correct_entity"));
}
[Fact]
public async Task EntityOnStateChangedEntitiesLambdaTurnOnLightCallsCorrectServiceCall()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+ await FakeDaemonInit().ConfigureAwait(false);
+
+ AddChangedEvent("binary_sensor.pir", "off", "on");
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout(); //new CancellationTokenSource(1000);
// Fake the
DefaultDaemonHost.InternalState["light.correct_entity"] = new EntityState
@@ -206,19 +199,19 @@ public async Task EntityOnStateChangedEntitiesLambdaTurnOnLightCallsCorrectServi
.TurnOn()
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.correct_entity"));
}
[Fact]
public async Task EntityOnStateChangedTurnOnLightCallsCorrectServiceCallButNoTurnOff()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+ await FakeDaemonInit().ConfigureAwait(false);
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ AddChangedEvent("binary_sensor.pir", "off", "on");
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -234,21 +227,20 @@ public async Task EntityOnStateChangedTurnOnLightCallsCorrectServiceCallButNoTur
.TurnOff()
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.correct_entity"));
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Never());
+ VerifyCallServiceTimes("turn_off", Times.Never());
}
[Fact]
public async Task EntityOnStateChangedTurnOnLightWithAttributesCallsCorrectServiceCall()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
-
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
DefaultDaemonApp
.Entity("binary_sensor.pir")
@@ -258,10 +250,10 @@ public async Task EntityOnStateChangedTurnOnLightWithAttributesCallsCorrectServi
.WithAttribute("transition", 0)
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on",
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on",
("transition", 0),
("entity_id", "light.correct_entity"));
}
@@ -270,9 +262,9 @@ public async Task EntityOnStateChangedTurnOnLightWithAttributesCallsCorrectServi
public async Task EntityOnStateDefaultTriggerOnAnyStateChange()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
var triggered = false;
// ACT
@@ -286,8 +278,7 @@ public async Task EntityOnStateDefaultTriggerOnAnyStateChange()
})
.Execute();
- await RunDefauldDaemonUntilCanceled();
-
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.True(triggered);
}
@@ -296,9 +287,9 @@ public async Task EntityOnStateDefaultTriggerOnAnyStateChange()
public async Task EntityOnStateNotTriggerOnSameState()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "off");
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "off");
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
var triggered = false;
// ACT
@@ -312,7 +303,7 @@ public async Task EntityOnStateNotTriggerOnSameState()
})
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.False(triggered);
@@ -322,9 +313,9 @@ public async Task EntityOnStateNotTriggerOnSameState()
public async Task EntityOnStateIncludeAttributesTriggerOnSameState()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "off");
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "off");
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
var triggered = false;
// ACT
@@ -338,8 +329,7 @@ public async Task EntityOnStateIncludeAttributesTriggerOnSameState()
})
.Execute();
- await RunDefauldDaemonUntilCanceled();
-
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.True(triggered);
}
@@ -356,8 +346,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("toggle", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "toggle", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("toggle", Times.Once());
+ VerifyCallServiceTuple("light", "toggle", ("entity_id", "light.correct_entity"));
}
[Fact]
@@ -372,8 +362,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_off", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_off", Times.Once());
+ VerifyCallServiceTuple("light", "turn_off", ("entity_id", "light.correct_entity"));
}
[Fact]
@@ -389,7 +379,7 @@ public async Task EntityFuncExceptionLogsError()
.ExecuteAsync());
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Never());
+ VerifyCallServiceTimes("turn_off", Times.Never());
LoggerMock.AssertLogged(LogLevel.Error, Times.AtLeastOnce());
Assert.Equal("Some error", x.Message);
}
@@ -398,8 +388,7 @@ public async Task EntityFuncExceptionLogsError()
public async Task TurnOffEntityLambdaAttributeSelectionCallsCorrectServiceCall()
{
// ARRANGE
- var daemonTask = RunDefauldDaemonUntilCanceled(); //overrideDebugNotCancel: true
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
await DefaultDaemonApp
@@ -409,13 +398,12 @@ await DefaultDaemonApp
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Exactly(3));
- DefaultHassClientMock.VerifyCallService("light", "turn_off", ("entity_id", "light.correct_entity"));
- DefaultHassClientMock.VerifyCallService("light", "turn_off", ("entity_id", "light.correct_entity2"));
- DefaultHassClientMock.VerifyCallService("switch", "turn_off", ("entity_id", "switch.correct_entity"));
-
- await daemonTask;
+ VerifyCallServiceTimes("turn_off", Times.Exactly(3));
+ VerifyCallServiceTuple("light", "turn_off", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTuple("light", "turn_off", ("entity_id", "light.correct_entity2"));
+ VerifyCallServiceTuple("switch", "turn_off", ("entity_id", "switch.correct_entity"));
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
}
[Fact]
@@ -430,17 +418,14 @@ await DefaultDaemonApp
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Never());
+ VerifyCallServiceTimes("turn_off", Times.Never());
}
[Fact]
public async Task TurnOffEntityLamdaSelectionCallsCorrectServiceCall()
{
// ARRANGE
- var daemonTask = RunDefauldDaemonUntilCanceled(); //overrideDebugNotCancel: true
- await WaitForDefaultDaemonToConnect(DefaultDaemonHost, CancellationToken.None);
-
-
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
await DefaultDaemonApp
.Entities(n => n.EntityId.StartsWith("light.correct_entity"))
@@ -449,11 +434,11 @@ await DefaultDaemonApp
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Exactly(2));
- DefaultHassClientMock.VerifyCallService("light", "turn_off", ("entity_id", "light.correct_entity"));
- DefaultHassClientMock.VerifyCallService("light", "turn_off", ("entity_id", "light.correct_entity2"));
+ VerifyCallServiceTimes("turn_off", Times.Exactly(2));
+ VerifyCallServiceTuple("light", "turn_off", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTuple("light", "turn_off", ("entity_id", "light.correct_entity2"));
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
}
[Fact]
@@ -468,10 +453,10 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Exactly(2));
+ VerifyCallServiceTimes("turn_off", Times.Exactly(2));
- DefaultHassClientMock.VerifyCallService("light", "turn_off", ("entity_id", "light.correct_entity"));
- DefaultHassClientMock.VerifyCallService("light", "turn_off", ("entity_id", "light.correct_entity2"));
+ VerifyCallServiceTuple("light", "turn_off", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTuple("light", "turn_off", ("entity_id", "light.correct_entity2"));
}
[Fact]
@@ -485,8 +470,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.correct_entity"));
}
[Fact]
@@ -501,8 +486,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on",
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on",
("brightness", 100),
("entity_id", "light.correct_entity"));
}
@@ -520,8 +505,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on",
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on",
("brightness", 100),
("color_temp", 230),
("entity_id", "light.correct_entity"));
@@ -538,8 +523,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifySetStateTimes("light.correct_entity", Times.Once());
- DefaultHassClientMock.VerifySetState("light.correct_entity", "50");
+ VerifySetStateTimes("light.correct_entity", Times.Once());
+ VerifySetState("light.correct_entity", "50");
}
[Fact]
@@ -554,17 +539,16 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifySetStateTimes("light.correct_entity", Times.Once());
- DefaultHassClientMock.VerifySetState("light.correct_entity", "50", ("attr1", "str_value"));
+ VerifySetStateTimes("light.correct_entity", Times.Once());
+ VerifySetState("light.correct_entity", "50", ("attr1", "str_value"));
}
[Fact]
public async Task EntityOnStateCallFunction()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
-
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
string? actualToState = "";
string? actualFromState = "";
@@ -579,7 +563,7 @@ public async Task EntityOnStateCallFunction()
return Task.CompletedTask;
}).Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
Assert.Equal("on", actualToState);
Assert.Equal("off", actualFromState);
@@ -589,10 +573,9 @@ public async Task EntityOnStateCallFunction()
[Fact]
public async Task EntityOnStateTriggerScript()
{
+ await FakeDaemonInit().ConfigureAwait(false);
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "on", "off");
-
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ AddChangedEvent("binary_sensor.pir", "on", "off");
// ACT
DefaultDaemonApp
@@ -601,14 +584,16 @@ public async Task EntityOnStateTriggerScript()
.RunScript("thescript")
.Execute();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
- DefaultHassClientMock.Verify(n => n.CallService("script", "thescript", It.IsAny(), false));
+ VerifyCallService("script", "thescript", false);
+ // Verify(n => n.CallService("script", "thescript", It.IsAny(), false));
}
[Fact]
public async Task SpeakCallsCorrectServiceCall()
{
+ await FakeDaemonInit().ConfigureAwait(false);
// ARRANGE
DefaultDaemonHost.InternalDelayTimeForTts = 0; // For testing
@@ -618,19 +603,18 @@ await DefaultDaemonApp
.Speak("a message")
.ExecuteAsync();
- var (daemonTask, _) = ReturnRunningDefauldDaemonHostTask();
-
await Task.Delay(20);
- var expObject = new ExpandoObject();
+ var expObject = new FluentExpandoObject();
dynamic expectedAttruibutes = expObject;
expectedAttruibutes.entity_id = "media_player.correct_player";
expectedAttruibutes.message = "a message";
// ASSERT
- DefaultHassClientMock.Verify(n => n.CallService("tts", "google_cloud_say", expObject, true));
+ VerifyCallService("tts", "google_cloud_say", expObject, true);
+ // Verify(n => n.CallService("tts", "google_cloud_say", expObject, true));
- await WaitUntilCanceled(daemonTask);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
}
[Fact]
@@ -644,8 +628,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("media_play", Times.Once());
- DefaultHassClientMock.VerifyCallService("media_player", "media_play", ("entity_id", "media_player.player"));
+ VerifyCallServiceTimes("media_play", Times.Once());
+ VerifyCallServiceTuple("media_player", "media_play", ("entity_id", "media_player.player"));
}
[Fact]
@@ -665,8 +649,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("media_play", Times.Once());
- DefaultHassClientMock.VerifyCallService("media_player", "media_play", ("entity_id", "media_player.player"));
+ VerifyCallServiceTimes("media_play", Times.Once());
+ VerifyCallServiceTuple("media_player", "media_play", ("entity_id", "media_player.player"));
}
[Fact]
@@ -682,7 +666,7 @@ public async Task MediaPlayersFuncExceptionLogsError()
.ExecuteAsync());
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_off", Times.Never());
+ VerifyCallServiceTimes("turn_off", Times.Never());
LoggerMock.AssertLogged(LogLevel.Error, Times.AtLeastOnce());
Assert.Equal("Some error", x.Message);
}
@@ -698,8 +682,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("media_play", Times.Once());
- DefaultHassClientMock.VerifyCallService("media_player", "media_play", ("entity_id", "media_player.player"));
+ VerifyCallServiceTimes("media_play", Times.Once());
+ VerifyCallServiceTuple("media_player", "media_play", ("entity_id", "media_player.player"));
}
[Fact]
@@ -713,8 +697,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("media_pause", Times.Once());
- DefaultHassClientMock.VerifyCallService("media_player", "media_pause", ("entity_id", "media_player.player"));
+ VerifyCallServiceTimes("media_pause", Times.Once());
+ VerifyCallServiceTuple("media_player", "media_pause", ("entity_id", "media_player.player"));
}
[Fact]
@@ -728,8 +712,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("media_play_pause", Times.Once());
- DefaultHassClientMock.VerifyCallService("media_player", "media_play_pause", ("entity_id", "media_player.player"));
+ VerifyCallServiceTimes("media_play_pause", Times.Once());
+ VerifyCallServiceTuple("media_player", "media_play_pause", ("entity_id", "media_player.player"));
}
[Fact]
@@ -743,8 +727,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("media_stop", Times.Once());
- DefaultHassClientMock.VerifyCallService("media_player", "media_stop", ("entity_id", "media_player.player"));
+ VerifyCallServiceTimes("media_stop", Times.Once());
+ VerifyCallServiceTuple("media_player", "media_stop", ("entity_id", "media_player.player"));
}
[Fact]
@@ -758,8 +742,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("select_option", Times.Once());
- DefaultHassClientMock.VerifyCallService("input_select", "select_option",
+ VerifyCallServiceTimes("select_option", Times.Once());
+ VerifyCallServiceTuple("input_select", "select_option",
("entity_id", "input_select.myselect"),
("option", "option1"));
}
@@ -775,8 +759,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("select_option", Times.Once());
- DefaultHassClientMock.VerifyCallService("input_select", "select_option",
+ VerifyCallServiceTimes("select_option", Times.Once());
+ VerifyCallServiceTuple("input_select", "select_option",
("entity_id", "input_select.myselect"),
("option", "option1"));
}
@@ -793,8 +777,8 @@ await DefaultDaemonApp
.ExecuteAsync();
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("select_option", Times.Once());
- DefaultHassClientMock.VerifyCallService("input_select", "select_option",
+ VerifyCallServiceTimes("select_option", Times.Once());
+ VerifyCallServiceTuple("input_select", "select_option",
("entity_id", "input_select.myselect"),
("option", "option1"));
}
@@ -803,15 +787,15 @@ await DefaultDaemonApp
public async Task EntityDelayUntilStateChangeShouldReturnTrue()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ await FakeDaemonInit().ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
var delayResult = DefaultDaemonApp
.Entity("binary_sensor.pir")
.DelayUntilStateChange(to: "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
Assert.True(delayResult.Task.IsCompletedSuccessfully);
Assert.True(delayResult.Task.Result);
@@ -821,15 +805,15 @@ public async Task EntityDelayUntilStateChangeShouldReturnTrue()
public async Task EntityDelayUntilStateChangeLamdaShouldReturnTrue()
{
// ARRANGE
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
+ await FakeDaemonInit().ConfigureAwait(false);
- var cancelSource = DefaultHassClientMock.GetSourceWithTimeout();
+ AddChangedEvent("binary_sensor.pir", "off", "on");
var delayResult = DefaultDaemonApp
.Entity("binary_sensor.pir")
.DelayUntilStateChange((to, _) => to?.State == "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
Assert.True(delayResult.Task.IsCompletedSuccessfully);
Assert.True(delayResult.Task.Result);
@@ -839,11 +823,10 @@ public async Task EntityDelayUntilStateChangeLamdaShouldReturnTrue()
public async Task EntityInAreaOnStateChangedTurnOnLight()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
- var daemonTask = RunDefauldDaemonUntilCanceled(200, overrideDebugNotCancel: true);
-
- while (DefaultDaemonHost.Connected == false)
- await Task.Delay(10).ConfigureAwait(false);
+ // Fake the state
+ SetEntityState("light.ligth_in_area", area: "Area");
// ACT
DefaultDaemonApp
@@ -854,13 +837,13 @@ public async Task EntityInAreaOnStateChangedTurnOnLight()
.Execute();
// light.light_in_area is setup so it has area = Area
- DefaultHassClientMock.AddChangedEvent("light.ligth_in_area", "off", "on");
+ AddChangedEvent("light.ligth_in_area", "off", "on");
- await daemonTask.ConfigureAwait(false);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.correct_entity"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.correct_entity"));
}
[Fact]
@@ -868,10 +851,10 @@ public async Task EntityInAreaOnStateChangedShouldTurnOn()
{
// ARRANGE
- var daemonTask = RunDefauldDaemonUntilCanceled(200, overrideDebugNotCancel: true);
+ await FakeDaemonInit().ConfigureAwait(false);
- while (DefaultDaemonHost.Connected == false)
- await Task.Delay(10).ConfigureAwait(false);
+ // Fake the state
+ SetEntityState("light.ligth_in_area", area: "Area");
// ACT
DefaultDaemonApp
@@ -882,42 +865,41 @@ public async Task EntityInAreaOnStateChangedShouldTurnOn()
.Execute();
// light.light_in_area is setup so it has area = Area
- DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
-
- await daemonTask.ConfigureAwait(false);
+ AddChangedEvent("binary_sensor.pir", "off", "on");
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("turn_on", Times.Once());
- DefaultHassClientMock.VerifyCallService("light", "turn_on", ("entity_id", "light.ligth_in_area"));
+ VerifyCallServiceTimes("turn_on", Times.Once());
+ VerifyCallServiceTuple("light", "turn_on", ("entity_id", "light.ligth_in_area"));
}
[Fact]
public async Task RunScriptShouldCallCorrectService()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
await DefaultDaemonApp.RunScript("testscript").ExecuteAsync();
await DefaultDaemonApp.RunScript("script.testscript").ExecuteAsync();
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
- DefaultHassClientMock.VerifyCallServiceTimes("testscript", Times.Exactly(2));
+ VerifyCallServiceTimes("testscript", Times.Exactly(2));
}
[Fact]
public async Task SendEventShouldCallCorrectService()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
await DefaultDaemonApp.SendEvent("myevent");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
- DefaultHassClientMock.Verify(n => n.SendEvent("myevent", It.IsAny()));
+ VerifyEventSent("myevent");
}
}
diff --git a/tests/NetDaemon.Daemon.Tests/HassClientMock.cs b/tests/NetDaemon.Daemon.Tests/HassClientMock.cs
deleted file mode 100644
index 94106c69e..000000000
--- a/tests/NetDaemon.Daemon.Tests/HassClientMock.cs
+++ /dev/null
@@ -1,322 +0,0 @@
-using JoySoftware.HomeAssistant.Client;
-using Moq;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-using NetDaemon.Common;
-using NetDaemon.Common.Fluent;
-using Xunit;
-
-namespace NetDaemon.Daemon.Tests
-{
- public class HassClientMock : Mock
- {
- internal HassAreas Areas = new HassAreas();
- internal HassDevices Devices = new HassDevices();
- internal HassEntities Entities = new HassEntities();
- internal ConcurrentQueue FakeEvents = new();
- internal ConcurrentDictionary FakeStates = new();
- public HassClientMock()
- {
-#pragma warning disable 8619, 8620
- // Setup common mocks
- Setup(x => x.ConnectAsync(It.IsAny(), It.IsAny(), It.IsAny(),
- It.IsAny(), It.IsAny()))
- .ReturnsAsync(true);
-
- SetupDefaultStates();
-
- SetupGet(x => x.States).Returns(FakeStates);
-
- Setup(x => x.GetAllStates(It.IsAny()))
- .ReturnsAsync(() => { return (IEnumerable)FakeStates.Values; });
-
- Setup(x => x.ReadEventAsync())
- .ReturnsAsync(() => { return FakeEvents.TryDequeue(out var ev) ? ev : null; });
-
- Setup(x => x.ReadEventAsync(It.IsAny()))
- .ReturnsAsync(() => { return FakeEvents.TryDequeue(out var ev) ? ev : null; });
-
- Setup(x => x.GetConfig()).ReturnsAsync(new HassConfig { State = "RUNNING" });
-
- Setup(x => x.SetState(It.IsAny(), It.IsAny(), It.IsAny())).Returns(
- (entityId, state, attributes) =>
- {
- var fluentAttr = (FluentExpandoObject)attributes;
- var attrib = new Dictionary();
- foreach (var attr in (IDictionary)fluentAttr)
- attrib[attr.Key] = attr.Value;
-
- return Task.FromResult(new HassState
- {
- EntityId = entityId,
- State = state,
- Attributes = attrib
- });
- }
- );
-
- Setup(n => n.GetAreas()).ReturnsAsync(Areas);
- Setup(n => n.GetDevices()).ReturnsAsync(Devices);
- Setup(n => n.GetEntities()).ReturnsAsync(Entities);
-
- // Setup one with area
- Devices.Add(new HassDevice { Id = "device_idd", AreaId = "area_idd" });
- Areas.Add(new HassArea { Name = "Area", Id = "area_idd" });
- Entities.Add(new HassEntity
- {
- EntityId = "light.ligth_in_area",
- DeviceId = "device_idd"
- });
- }
-
- public static HassClientMock DefaultMock => new HassClientMock();
-
- ///
- /// Returns a mock that will always return false when connect to Home Assistant
- ///
- public static HassClientMock MockConnectFalse
- {
- get
- {
- var mock = DefaultMock;
- mock.Setup(x => x.ConnectAsync(It.IsAny(), It.IsAny(), It.IsAny(),
- It.IsAny(), It.IsAny()))
- .ReturnsAsync(false);
- return mock;
- }
- }
-
- public void AddCallServiceEvent(string domain, string service, dynamic data)
- {
- // Todo: Refactor to smth smarter
- FakeEvents.Enqueue(new HassEvent
- {
- EventType = "call_service",
- Data = new HassServiceEventData
- {
- Domain = domain,
- Service = service,
- Data = data
- }
- });
- }
-
- public void AddChangedEvent(string entityId, object fromState, object toState, DateTime lastUpdated, DateTime lastChanged)
- {
- // Todo: Refactor to smth smarter
- FakeEvents.Enqueue(new HassEvent
- {
- EventType = "state_changed",
- Data = new HassStateChangedEventData
- {
- EntityId = entityId,
- NewState = new HassState
- {
- State = toState,
- Attributes = new Dictionary
- {
- ["device_class"] = "motion"
- },
- LastChanged = lastChanged,
- LastUpdated = lastUpdated
- },
- OldState = new HassState
- {
- State = fromState,
- Attributes = new Dictionary
- {
- ["device_class"] = "motion"
- }
- }
- }
- });
- }
-
- public void AddChangedEvent(string entityId, object fromState, object toState)
- {
- FakeEvents.Enqueue(new HassEvent
- {
- EventType = "state_changed",
- Data = new HassStateChangedEventData
- {
- EntityId = entityId,
- NewState = new HassState
- {
- EntityId = entityId,
- State = toState,
- Attributes = new Dictionary
- {
- ["device_class"] = "motion"
- },
- LastUpdated = DateTime.Now,
- LastChanged = DateTime.Now
- },
- OldState = new HassState
- {
- EntityId = entityId,
- State = fromState,
- Attributes = new Dictionary
- {
- ["device_class"] = "motion"
- }
- }
- },
- });
- }
-
- public void AddCustomEvent(string eventType, dynamic? data)
- {
- FakeEvents.Enqueue(new HassEvent
- {
- EventType = eventType,
- Data = data
- });
- }
-
- public void AssertEqual(HassState hassState, EntityState entity)
- {
- Assert.Equal(hassState.EntityId, entity.EntityId);
- Assert.Equal(hassState.State, entity.State);
- Assert.Equal(hassState.LastChanged, entity.LastChanged);
- Assert.Equal(hassState.LastUpdated, entity.LastUpdated);
-
- if (hassState.Attributes?.Keys == null || entity.Attribute == null)
- return;
-
- foreach (var attribute in hassState.Attributes!.Keys)
- {
- var attr = entity.Attribute as IDictionary ??
- throw new NullReferenceException($"{nameof(entity.Attribute)} catn be null");
-
- Assert.True(attr.ContainsKey(attribute));
- Assert.Equal(hassState.Attributes[attribute],
- attr![attribute]);
- }
- }
-
- ///
- /// Gets a cancellation source that does not timeout if debugger is attached
- ///
- ///
- ///
- public CancellationTokenSource GetSourceWithTimeout(int milliSeconds = 100)
- {
- return (Debugger.IsAttached)
- ? new CancellationTokenSource()
- : new CancellationTokenSource(milliSeconds);
- }
-
- public void VerifyCallService(string domain, string service,
- params (string attribute, object value)[] attributesTuples)
- {
- var attributes = new FluentExpandoObject();
- foreach (var attributesTuple in attributesTuples)
- ((IDictionary)attributes)[attributesTuple.attribute] = attributesTuple.value;
-
- Verify(n => n.CallService(domain, service, attributes, It.IsAny()), Times.AtLeastOnce);
- }
-
- public void VerifyCallServiceTimes(string service, Times times)
- {
- Verify(n => n.CallService(It.IsAny(), service, It.IsAny(), It.IsAny()), times);
- }
-
- public void VerifySetState(string entity, string state,
- params (string attribute, object value)[] attributesTuples)
- {
- var attributes = new FluentExpandoObject();
- foreach (var attributesTuple in attributesTuples)
- ((IDictionary)attributes)[attributesTuple.attribute] = attributesTuple.value;
-
- Verify(n => n.SetState(entity, state, attributes), Times.AtLeastOnce);
- }
-
- public void VerifySetStateTimes(string entity, Times times)
- {
- Verify(n => n.SetState(entity, It.IsAny(), It.IsAny()), times);
- }
-
- private void SetupDefaultStates()
- {
- FakeStates["light.correct_entity"] = new HassState
- {
- EntityId = "light.correct_entity",
- Attributes = new Dictionary
- {
- ["test"] = 100
- },
- State = "on"
- };
-
- FakeStates["light.correct_entity2"] = new HassState
- {
- EntityId = "light.correct_entity2",
- Attributes = new Dictionary
- {
- ["test"] = 101
- }
- };
-
- FakeStates["switch.correct_entity"] = new HassState
- {
- EntityId = "switch.correct_entity",
- Attributes = new Dictionary
- {
- ["test"] = 105
- }
- };
-
- FakeStates["light.filtered_entity"] = new HassState
- {
- EntityId = "light.filtered_entity",
- Attributes = new Dictionary
- {
- ["test"] = 90
- }
- };
- FakeStates["binary_sensor.pir"] = new HassState
- {
- EntityId = "binary_sensor.pir",
- State = "off",
- Attributes = new Dictionary
- {
- ["device_class"] = "motion"
- }
- };
-
- FakeStates["binary_sensor.pir_2"] = new HassState
- {
- EntityId = "binary_sensor.pir_2",
- State = "off",
- Attributes = new Dictionary
- {
- ["device_class"] = "motion"
- }
- };
-
- FakeStates["media_player.player"] = new HassState
- {
- EntityId = "media_player.player",
- State = "off",
- Attributes = new Dictionary
- {
- ["anyattribute"] = "some attribute"
- }
- };
-
- FakeStates["light.ligth_in_area"] = new HassState
- {
- EntityId = "light.ligth_in_area",
- State = "off",
- Attributes = new Dictionary
- {
- ["anyattribute"] = "some attribute"
- }
- };
- }
- }
-}
\ No newline at end of file
diff --git a/tests/NetDaemon.Daemon.Tests/LoggerMock.cs b/tests/NetDaemon.Daemon.Tests/LoggerMock.cs
deleted file mode 100644
index 879f3ead2..000000000
--- a/tests/NetDaemon.Daemon.Tests/LoggerMock.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-using Microsoft.Extensions.Logging;
-using Moq;
-using System;
-
-namespace NetDaemon.Daemon.Tests
-{
- public class LoggerMock
- {
- public LoggerMock()
- {
- // Setup the mock
- MockLoggerFactory.Setup(x => x.CreateLogger(It.IsAny())).Returns(MockLogger.Object);
- }
-
- public ILoggerFactory LoggerFactory => MockLoggerFactory.Object;
- public Mock MockLoggerFactory { get; } = new();
-
- public ILogger Logger => MockLogger.Object;
- public Mock MockLogger { get; } = new();
-
- ///
- /// Assert if the log has been used at times
- ///
- /// The loglevel being checked
- /// The Times it has been logged
- public void AssertLogged(LogLevel level, Times times)
- {
- MockLogger.Verify(
- x => x.Log(
- level,
- It.IsAny(),
- It.Is((v, t) => true),
- It.IsAny(),
- It.Is>((v, t) => true)), times);
- }
-
- ///
- /// Assert if the log has been used at times
- ///
- /// The loglevel being checked
- /// The Times it has been logged
- public void AssertLogged(LogLevel level, string message, Times times)
- {
- MockLogger.Verify(
- x => x.Log(
- level,
- It.IsAny(),
- It.Is((v, t) => v.ToString() == message),
- It.IsAny(),
- It.Is>((v, t) => true)), times);
- }
-
- ///
- /// Assert if the log has been used at times
- ///
- /// The loglevel being checked
- /// The Times it has been logged
- public void AssertLogged(LogLevel level, Exception exception, string message, Times times)
- {
- MockLogger.Verify(
- x => x.Log(
- level,
- It.IsAny(),
- It.Is((v, t) => v.ToString() == message),
- exception,
- It.Is>((v, t) => true)), times);
- }
- }
-}
\ No newline at end of file
diff --git a/tests/NetDaemon.Daemon.Tests/NetDaemon.Daemon.Tests.csproj b/tests/NetDaemon.Daemon.Tests/NetDaemon.Daemon.Tests.csproj
index ab40b00bb..3c3e6a919 100644
--- a/tests/NetDaemon.Daemon.Tests/NetDaemon.Daemon.Tests.csproj
+++ b/tests/NetDaemon.Daemon.Tests/NetDaemon.Daemon.Tests.csproj
@@ -31,6 +31,7 @@
+
diff --git a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyAppsTests.cs b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyAppsTests.cs
index 0fff33647..441621249 100644
--- a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyAppsTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyAppsTests.cs
@@ -1,6 +1,7 @@
using JoySoftware.HomeAssistant.Client;
using Microsoft.Extensions.Logging;
using Moq;
+using NetDaemon.Daemon.Fakes;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
@@ -28,6 +29,7 @@ public FaultyAppTests() : base()
public async Task ARunTimeErrorShouldLogError()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
App
.Entity("binary_sensor.pir")
@@ -41,7 +43,7 @@ public async Task ARunTimeErrorShouldLogError()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Once());
}
@@ -50,6 +52,7 @@ public async Task ARunTimeErrorShouldLogError()
public async Task ARunTimeErrorShouldNotBreakOtherApps()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
bool eventRun = false;
App
.Entity("binary_sensor.pir")
@@ -73,7 +76,7 @@ public async Task ARunTimeErrorShouldNotBreakOtherApps()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Once());
Assert.True(eventRun);
@@ -84,6 +87,7 @@ public async Task ARunTimeErrorShouldNotBreakOtherApps()
public async Task MissingAttributeShouldNotBreakOtherApps()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
bool eventRun = false;
App
.Entities(e => e.Attribute!.does_not_exist == "yay")
@@ -107,7 +111,7 @@ public async Task MissingAttributeShouldNotBreakOtherApps()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// LoggerMock.AssertLogged(LogLevel.Error, Times.Once());
Assert.True(eventRun);
@@ -118,6 +122,7 @@ public async Task MissingAttributeShouldNotBreakOtherApps()
public async Task MissingEntityShouldNotBreakOtherApps()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
bool eventRun = false;
App
.Entity("binary_sensor.pir")
@@ -141,7 +146,7 @@ public async Task MissingEntityShouldNotBreakOtherApps()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
Assert.True(eventRun);
diff --git a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyRxAppsTests.cs b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyRxAppsTests.cs
index 0e2634857..deebf37fa 100644
--- a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyRxAppsTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/FaultyRxAppsTests.cs
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using Xunit;
using System.Reactive.Linq;
+using NetDaemon.Daemon.Fakes;
namespace NetDaemon.Daemon.Tests.NetDaemonApp
{
@@ -29,6 +30,7 @@ public FaultyRxAppTests() : base()
public async Task ARunTimeErrorShouldLogError()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
App
.Entity("binary_sensor.pir")
@@ -40,7 +42,7 @@ public async Task ARunTimeErrorShouldLogError()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Once());
}
@@ -49,6 +51,7 @@ public async Task ARunTimeErrorShouldLogError()
public async Task MissingEntityShouldNotLogError()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
App
.Entity("binary_sensor.pir")
@@ -60,7 +63,7 @@ public async Task MissingEntityShouldNotLogError()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Never());
}
@@ -69,6 +72,8 @@ public async Task MissingEntityShouldNotLogError()
public async Task MissingEntityShouldNotLogErrorAndNotBreakOtherApps()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
bool eventRun = false, event2Run = false;
App
@@ -97,7 +102,7 @@ public async Task MissingEntityShouldNotLogErrorAndNotBreakOtherApps()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Never());
Assert.True(eventRun);
@@ -109,6 +114,8 @@ public async Task MissingEntityShouldNotLogErrorAndNotBreakOtherApps()
public async Task ARunTimeErrorShouldNotBreakOtherApps()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
bool eventRun = false, event2Run = false;
App
@@ -137,7 +144,7 @@ public async Task ARunTimeErrorShouldNotBreakOtherApps()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Once());
Assert.True(eventRun);
@@ -149,6 +156,8 @@ public async Task ARunTimeErrorShouldNotBreakOtherApps()
public async Task ARunTimeErrorInAttributeSelectorShouldNotBreakOtherApps()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
bool eventRun = false, event2Run = false;
App
@@ -178,7 +187,7 @@ public async Task ARunTimeErrorInAttributeSelectorShouldNotBreakOtherApps()
AddDefaultEvent();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Once());
Assert.True(eventRun);
@@ -191,6 +200,8 @@ public async Task ARunTimeErrorInAttributeSelectorShouldNotBreakOtherApps()
public async Task ToUnavailableShouldNotBreak()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
bool eventRun = false, event2Run = false;
App
@@ -220,7 +231,7 @@ public async Task ToUnavailableShouldNotBreak()
AddEventFakeGoingUnavailable();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Never());
Assert.False(eventRun);
@@ -232,6 +243,8 @@ public async Task ToUnavailableShouldNotBreak()
public async Task FromUnavailableShouldNotBreak()
{
// ARRANGE
+ await FakeDaemonInit().ConfigureAwait(false);
+
bool eventRun = false, event2Run = false;
App
@@ -261,7 +274,7 @@ public async Task FromUnavailableShouldNotBreak()
AddEventFakeFromUnavailable();
- await RunDefauldDaemonUntilCanceled();
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Never());
Assert.False(eventRun);
diff --git a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs
index 0745e44b2..a25def45c 100644
--- a/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/NetDaemonApp/NetDaemonAppTests.cs
@@ -6,6 +6,7 @@
using NetDaemon.Common;
using NetDaemon.Common.Fluent;
using Xunit;
+using NetDaemon.Daemon.Fakes;
namespace NetDaemon.Daemon.Tests.NetDaemonApp
{
diff --git a/tests/NetDaemon.Daemon.Tests/Reactive/RxAppTest.cs b/tests/NetDaemon.Daemon.Tests/Reactive/RxAppTest.cs
index 0adcc1957..5813de977 100644
--- a/tests/NetDaemon.Daemon.Tests/Reactive/RxAppTest.cs
+++ b/tests/NetDaemon.Daemon.Tests/Reactive/RxAppTest.cs
@@ -16,7 +16,7 @@ namespace NetDaemon.Daemon.Tests.Reactive
/// Mainly the tests checks if correct underlying call to "CallService"
/// has been made.
///
- public class RxAppTest : DaemonHostTestBase
+ public class RxAppTest : CoreDaemonHostTestBase
{
public RxAppTest() : base()
{
@@ -26,23 +26,24 @@ public RxAppTest() : base()
public async Task CallServiceShouldCallCorrectFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var (dynObj, expObj) = GetDynamicObject(
("attr", "value"));
// ACT
DefaultDaemonRxApp.CallService("mydomain", "myservice", dynObj);
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
- DefaultHassClientMock.VerifyCallService("mydomain", "myservice", ("attr", "value"));
+ VerifyCallServiceTuple("mydomain", "myservice", ("attr", "value"));
}
[Fact]
public async Task NewAllEventDataShouldCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -54,7 +55,8 @@ public async Task NewAllEventDataShouldCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "on", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.True(called);
@@ -64,7 +66,7 @@ public async Task NewAllEventDataShouldCallFunction()
public async Task NewEventShouldCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -76,7 +78,8 @@ public async Task NewEventShouldCallFunction()
DefaultHassClientMock.AddCustomEvent("AN_EVENT", new { somedata = "hello" });
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.True(called);
@@ -86,7 +89,8 @@ public async Task NewEventShouldCallFunction()
public async Task NewEventMissingDataAttributeShouldReturnNull()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask(200);
+ await FakeDaemonInit().ConfigureAwait(false);
+
string? missingAttribute = "has initial value";
// ACT
@@ -102,7 +106,8 @@ public async Task NewEventMissingDataAttributeShouldReturnNull()
DefaultHassClientMock.AddCustomEvent("AN_EVENT", dynExpObject);
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.Null(missingAttribute);
@@ -112,7 +117,7 @@ public async Task NewEventMissingDataAttributeShouldReturnNull()
public async Task NewStateEventShouldCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -124,7 +129,8 @@ public async Task NewStateEventShouldCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.True(called);
@@ -134,13 +140,14 @@ public async Task NewStateEventShouldCallFunction()
public async Task RunScriptShouldCallCorrectFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var (dynObj, expObj) = GetDynamicObject(
("attr", "value"));
// ACT
DefaultDaemonRxApp.RunScript("myscript");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
@@ -152,13 +159,14 @@ public async Task RunScriptShouldCallCorrectFunction()
public async Task RunScriptWithDomainShouldCallCorrectFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var (dynObj, expObj) = GetDynamicObject(
("attr", "value"));
// ACT
DefaultDaemonRxApp.RunScript("script.myscript");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
DefaultHassClientMock.VerifyCallServiceTimes("myscript", Times.Once());
@@ -168,7 +176,7 @@ public async Task RunScriptWithDomainShouldCallCorrectFunction()
public async Task SameStateEventShouldNotCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -180,7 +188,8 @@ public async Task SameStateEventShouldNotCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "on", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.False(called);
@@ -189,13 +198,14 @@ public async Task SameStateEventShouldNotCallFunction()
public async Task SetStateShouldReturnCorrectData()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var (dynObj, expObj) = GetDynamicObject(
("attr", "value"));
// ACT
DefaultDaemonRxApp.SetState("sensor.any_sensor", "on", dynObj);
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
DefaultHassClientMock.Verify(n => n.SetState("sensor.any_sensor", "on", expObj));
@@ -214,12 +224,13 @@ public async Task StartupAsyncShouldThrowIfDaemonIsNull()
public async Task StateShouldReturnCorrectEntity()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
var entity = DefaultDaemonRxApp.State("binary_sensor.pir");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.NotNull(entity);
@@ -229,12 +240,13 @@ public async Task StateShouldReturnCorrectEntity()
public async Task StateShouldReturnNullIfAttributeNotExist()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
var entity = DefaultDaemonRxApp.State("binary_sensor.pir");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.Null(entity?.Attribute?.not_exists);
@@ -244,11 +256,11 @@ public async Task StateShouldReturnNullIfAttributeNotExist()
public async Task StatesShouldReturnCorrectEntity()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
var entity = DefaultDaemonRxApp.States.FirstOrDefault(n => n.EntityId == "binary_sensor.pir");
- await daemonTask.ConfigureAwait(false);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.NotNull(entity);
Assert.Equal("binary_sensor.pir", entity?.EntityId);
@@ -258,11 +270,11 @@ public async Task StatesShouldReturnCorrectEntity()
public async Task EntityIdsShouldReturnCorrectItems()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
var entities = DefaultDaemonRxApp.EntityIds.ToList();
- await daemonTask.ConfigureAwait(false);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
// ASSERT
Assert.NotNull(entities);
Assert.Equal(8, entities.Count());
@@ -272,7 +284,7 @@ public async Task EntityIdsShouldReturnCorrectItems()
public async Task UsingEntitiesLambdaNewEventShouldCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -285,7 +297,8 @@ public async Task UsingEntitiesLambdaNewEventShouldCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir_2", "off", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.True(called);
@@ -295,7 +308,7 @@ public async Task UsingEntitiesLambdaNewEventShouldCallFunction()
public async Task CallbackObserverAttributeMissingShouldReturnNull()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
string? missingString = "has initial value";
// ACT
@@ -308,7 +321,8 @@ public async Task CallbackObserverAttributeMissingShouldReturnNull()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir_2", "off", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.Null(missingString);
@@ -318,7 +332,7 @@ public async Task CallbackObserverAttributeMissingShouldReturnNull()
public async Task UsingEntitiesNewEventShouldCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -331,7 +345,8 @@ public async Task UsingEntitiesNewEventShouldCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir_2", "off", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.True(called);
@@ -341,7 +356,7 @@ public async Task UsingEntitiesNewEventShouldCallFunction()
public async Task UsingEntityNewEventShouldCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -354,7 +369,8 @@ public async Task UsingEntityNewEventShouldCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.True(called);
@@ -364,7 +380,7 @@ public async Task UsingEntityNewEventShouldCallFunction()
public async Task UsingEntityNewEventShouldNotCallFunction()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
var called = false;
// ACT
@@ -377,7 +393,8 @@ public async Task UsingEntityNewEventShouldNotCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.False(called);
@@ -385,7 +402,7 @@ public async Task UsingEntityNewEventShouldNotCallFunction()
[Fact]
public async Task WhenStateStaysSameForTimeItShouldCallFunction()
{
- var daemonTask = await GetConnectedNetDaemonTask(300);
+ await FakeDaemonInit(300).ConfigureAwait(false);
bool isRun = false;
using var ctx = DefaultDaemonRxApp.StateChanges
@@ -398,7 +415,8 @@ public async Task WhenStateStaysSameForTimeItShouldCallFunction()
DefaultHassClientMock.AddChangedEvent("binary_sensor.pir", "off", "on");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
Assert.True(isRun);
}
@@ -407,7 +425,7 @@ public async Task WhenStateStaysSameForTimeItShouldCallFunction()
public async Task SavedDataShouldReturnSameDataUsingExpando()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
dynamic data = new ExpandoObject();
data.Item = "Some data";
@@ -415,7 +433,8 @@ public async Task SavedDataShouldReturnSameDataUsingExpando()
DefaultDaemonRxApp.SaveData("data_exists", data);
var collectedData = DefaultDaemonRxApp.GetData("data_exists");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
Assert.Equal(data, collectedData);
@@ -425,14 +444,15 @@ public async Task SavedDataShouldReturnSameDataUsingExpando()
public async Task GetDataShouldReturnCachedValue()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask();
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
DefaultDaemonRxApp.SaveData("GetDataShouldReturnCachedValue_id", "saved data");
DefaultDaemonRxApp.GetData("GetDataShouldReturnCachedValue_id");
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
+
// ASSERT
DefaultDataRepositoryMock.Verify(n => n.Get(It.IsAny()), Times.Never);
DefaultDataRepositoryMock.Verify(n => n.Save(It.IsAny(), It.IsAny()), Times.Once);
diff --git a/tests/NetDaemon.Daemon.Tests/Reactive/RxSchedulers.cs b/tests/NetDaemon.Daemon.Tests/Reactive/RxSchedulers.cs
index 4fb1dee8f..11f90ad88 100644
--- a/tests/NetDaemon.Daemon.Tests/Reactive/RxSchedulers.cs
+++ b/tests/NetDaemon.Daemon.Tests/Reactive/RxSchedulers.cs
@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Moq;
+using NetDaemon.Daemon.Fakes;
using Xunit;
namespace NetDaemon.Daemon.Tests.Reactive
@@ -13,7 +14,7 @@ namespace NetDaemon.Daemon.Tests.Reactive
/// Mainly the tests checks if correct underlying call to "CallService"
/// has been made.
///
- public class RxSchedulerTest : DaemonHostTestBase
+ public class RxSchedulerTest : CoreDaemonHostTestBase
{
public RxSchedulerTest() : base()
{
@@ -155,7 +156,7 @@ public void RunEveryHourShouldThrowExceptionOnErrorFormat()
// ACT
// ASSERT
Assert.Throws(() =>
- DefaultMockedRxApp.Object.RunEveryHour("no good input", () => System.Console.WriteLine("Test")));
+ DefaultMockedRxApp.Object.RunEveryHour("no good input", () => System.Console.WriteLine("Test")));
}
[Fact]
@@ -194,13 +195,13 @@ public void RunEveryShouldCallCreateObservableIntervall()
public async Task RunInFailureShouldLogError()
{
// ARRANGE
- var daemonTask = await GetConnectedNetDaemonTask(160);
+ await FakeDaemonInit().ConfigureAwait(false);
// ACT
DefaultDaemonRxApp.RunIn(TimeSpan.FromMilliseconds(100), () => throw new Exception("RxError"));
// ASSERT
await Task.Delay(150);
- await daemonTask;
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
LoggerMock.AssertLogged(LogLevel.Error, Times.Once());
}
@@ -209,7 +210,8 @@ public async Task RunInShouldCallFunction()
{
// ARRANGE
var called = false;
- var daemonTask = await GetConnectedNetDaemonTask(160);
+ await FakeDaemonInit().ConfigureAwait(false);
+
// ACT
DefaultDaemonRxApp.RunIn(TimeSpan.FromMilliseconds(100), () => called = true);
@@ -218,7 +220,7 @@ public async Task RunInShouldCallFunction()
await Task.Delay(150);
- await daemonTask.ConfigureAwait(false);
+ await FakeRunDaemonCoreUntilTimeout().ConfigureAwait(false);
Assert.True(called);
}
}
diff --git a/tests/NetDaemon.Daemon.Tests/SchedulerTests.cs b/tests/NetDaemon.Daemon.Tests/SchedulerTests.cs
index dd6cb9ef9..d19caee0a 100644
--- a/tests/NetDaemon.Daemon.Tests/SchedulerTests.cs
+++ b/tests/NetDaemon.Daemon.Tests/SchedulerTests.cs
@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using NetDaemon.Common;
using Xunit;
+using NetDaemon.Daemon.Fakes;
namespace NetDaemon.Daemon.Tests
{
diff --git a/tests/NetDaemon.Daemon.Tests/TestBaseClasses.cs b/tests/NetDaemon.Daemon.Tests/TestBaseClasses.cs
new file mode 100644
index 000000000..c5f5a7e32
--- /dev/null
+++ b/tests/NetDaemon.Daemon.Tests/TestBaseClasses.cs
@@ -0,0 +1,172 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+using JoySoftware.HomeAssistant.Client;
+using Moq;
+using NetDaemon.Common;
+using NetDaemon.Common.Reactive;
+using NetDaemon.Daemon.Fakes;
+using Xunit;
+
+namespace NetDaemon.Daemon.Tests
+{
+ public class BaseTestApp : Common.NetDaemonApp { }
+
+ public class BaseTestRxApp : NetDaemonRxApp { }
+
+ public class CoreDaemonHostTestBase : DaemonHostTestBase, IAsyncLifetime
+ {
+ private readonly Common.NetDaemonApp _defaultDaemonApp;
+ private readonly BaseTestRxApp _defaultDaemonRxApp;
+ private readonly Mock _defaultMockedRxApp;
+
+ private readonly NetDaemonHost _notConnectedDaemonHost;
+
+ public CoreDaemonHostTestBase() : base()
+ {
+ _defaultDaemonApp = new BaseTestApp();
+ _defaultDaemonApp.Id = "app_id";
+ _defaultDaemonApp.IsEnabled = true;
+
+ DefaultDaemonHost.InternalRunningAppInstances[_defaultDaemonApp.Id!] = _defaultDaemonApp;
+
+ _defaultDaemonRxApp = new BaseTestRxApp();
+ _defaultDaemonRxApp.Id = "app_rx_id";
+ _defaultDaemonRxApp.IsEnabled = true;
+ DefaultDaemonHost.InternalRunningAppInstances[_defaultDaemonRxApp.Id!] = _defaultDaemonRxApp;
+
+ _defaultMockedRxApp = new Mock() { CallBase = true };
+ _defaultMockedRxApp.Object.Id = "app_rx_mock_id";
+ _defaultMockedRxApp.Object.IsEnabled = true;
+ _defaultMockedRxApp.Setup(n => n.CreateObservableIntervall(It.IsAny(), It.IsAny())).Returns(new Mock().Object);
+ DefaultDaemonHost.InternalRunningAppInstances[_defaultMockedRxApp.Object.Id!] = _defaultMockedRxApp.Object;
+
+ _notConnectedDaemonHost = new NetDaemonHost(HassClientMock.MockConnectFalse.Object, DefaultDataRepositoryMock.Object, LoggerMock.LoggerFactory);
+
+ SetupFakeData();
+ }
+
+ public void SetupFakeData()
+ {
+ SetEntityState(
+ new HassState
+ {
+ EntityId = "light.correct_entity",
+ Attributes = new Dictionary
+ {
+ ["test"] = 100
+ },
+ State = "on"
+ });
+ SetEntityState(
+ new HassState
+ {
+ EntityId = "light.correct_entity2",
+ Attributes = new Dictionary
+ {
+ ["test"] = 101
+ },
+ State = "off"
+ });
+
+
+ SetEntityState(new()
+ {
+ EntityId = "switch.correct_entity",
+ Attributes = new Dictionary
+ {
+ ["test"] = 105
+ }
+ });
+
+ SetEntityState(new()
+ {
+ EntityId = "light.filtered_entity",
+ Attributes = new Dictionary
+ {
+ ["test"] = 90
+ }
+ });
+ SetEntityState(new()
+ {
+ EntityId = "binary_sensor.pir",
+ State = "off",
+ Attributes = new Dictionary
+ {
+ ["device_class"] = "motion"
+ }
+ });
+
+ SetEntityState(new()
+ {
+ EntityId = "binary_sensor.pir_2",
+ State = "off",
+ Attributes = new Dictionary
+ {
+ ["device_class"] = "motion"
+ }
+ });
+
+ SetEntityState(new()
+ {
+ EntityId = "media_player.player",
+ State = "off",
+ Attributes = new Dictionary
+ {
+ ["anyattribute"] = "some attribute"
+ }
+ });
+
+ SetEntityState( new()
+ {
+ EntityId = "light.ligth_in_area",
+ State = "off",
+ Attributes = new Dictionary
+ {
+ ["anyattribute"] = "some attribute"
+ }
+ });
+ }
+
+ ///
+ /// Clean-up any initialized test objects
+ ///
+ public new async Task DisposeAsync()
+ {
+ await base.DisposeAsync().ConfigureAwait(false);
+
+ await _defaultDaemonApp.DisposeAsync().ConfigureAwait(false);
+ await _defaultDaemonRxApp.DisposeAsync().ConfigureAwait(false);
+ await _defaultMockedRxApp.Object.DisposeAsync().ConfigureAwait(false);
+ }
+
+ ///
+ /// Initializes on each test run
+ ///
+ public new async Task InitializeAsync()
+ {
+ await base.InitializeAsync().ConfigureAwait(false);
+
+ await _defaultDaemonApp.StartUpAsync(DefaultDaemonHost).ConfigureAwait(false);
+ await _defaultDaemonRxApp.StartUpAsync(DefaultDaemonHost).ConfigureAwait(false);
+ await _defaultMockedRxApp.Object.StartUpAsync(DefaultDaemonHost).ConfigureAwait(false);
+ }
+
+ public BaseTestRxApp DefaultDaemonRxApp => _defaultDaemonRxApp;
+ public Mock DefaultMockedRxApp => _defaultMockedRxApp;
+ public Common.NetDaemonApp DefaultDaemonApp => _defaultDaemonApp;
+ public string HelloWorldData => "Hello world!";
+
+ public (Task, CancellationTokenSource) ReturnRunningNotConnectedDaemonHostTask(short milliSeconds = 100, bool overrideDebugNotCancel = false)
+ {
+ var cancelSource = Debugger.IsAttached && !overrideDebugNotCancel
+ ? new CancellationTokenSource()
+ : new CancellationTokenSource(milliSeconds);
+ return (_notConnectedDaemonHost.Run("host", 8123, false, "token", cancelSource.Token), cancelSource);
+ }
+
+
+ }
+}
\ No newline at end of file