using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Edge.Core.Processor; using Edge.Core.IndustryStandardInterface.Pump; using System.Threading; using Wayne.FDCPOSLibrary; using Mocks; using LanTian_Pump_664_Or_886.MessageEntity; using LanTian_Pump_664_Or_886; using LanTian_Pump_664_Or_886.MessageEntity.Outgoing; using System.Threading.Tasks; using LanTian_Pump_664_Or_886.MessageEntity.Incoming; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.DependencyInjection; using static LanTian_Pump_664_Or_886.PumpGroupParameter; namespace LanTian_Pump_664_Or_886_Test { [TestClass] public class FdcPumpControllerUnitTest { private HalfDuplexActivePollingDeviceProcessor processor; private ComPortCommunicatorMock mockCommunicator; private IFdcPumpController fdcPumpController; [TestInitialize()] public void InitProcessor() { var services = new ServiceCollection(); services.AddLogging(); this.mockCommunicator = new ComPortCommunicatorMock(); mockCommunicator.OnRawDataWriting += (s, a) => { }; this.processor = new HalfDuplexActivePollingDeviceProcessor( new PumpGroupHandler(new PumpGroupParameter() { PumpParameters = new List() { new PumpParameter() { PumpModel = PumpModelEnum.Model_664, PumpAuthorizeMode = PumpAuthorizeModeEnum.FC_Authorize, PumpId = 1, Address = 1, } } }, services.BuildServiceProvider()), mockCommunicator, 100, null); this.fdcPumpController = (processor.Context.Handler as IEnumerable).First(); } [TestMethod] public async Task Should_Send_Polling_Pump_Message_Test() { int pollingMessageSendTimes = 0; this.processor.Context.Outgoing.OnWriting += (s, a) => { if (a.Message is ReadPumpStateRequest) pollingMessageSendTimes++; }; await this.processor.Start(); await Task.Delay(1000); Assert.AreEqual(true, pollingMessageSendTimes >= 1, "polling message should send more than 1 times"); } [TestMethod] public async Task FDC_OFFLINE_State_Test() { int onRawDataWriting = 0; var onStateChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { onStateChangeEventArgs.Add(a); }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; }; Assert.AreEqual(LogicalDeviceState.FDC_OFFLINE, fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_OFFLINE, but now is: " + fdcPumpController.QueryStatusAsync().Result); Assert.AreEqual(0, onRawDataWriting); await this.processor.Start(); Assert.AreEqual(LogicalDeviceState.FDC_OFFLINE, this.fdcPumpController.QueryStatusAsync().Result, "status should be: FDC_OFFLINE, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(500); Assert.AreEqual(true, onRawDataWriting > 0); Assert.AreEqual(0, onStateChangeEventArgs.Count); Assert.AreEqual(LogicalDeviceState.FDC_OFFLINE, this.fdcPumpController.QueryStatusAsync().Result, "status should be: FDC_OFFLINE, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } [TestMethod] public async Task FDC_READY_State_Test() { int onRawDataWriting = 0; var onStateChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { onStateChangeEventArgs.Add(a); }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; var readPumpStateResponse = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.挂枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.FireOnDataReceived(readPumpStateResponse); }; Assert.AreEqual(LogicalDeviceState.FDC_OFFLINE, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_OFFLINE, but now is: " + fdcPumpController.QueryStatusAsync().Result); Assert.AreEqual(0, onRawDataWriting); await processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(500); Assert.AreEqual(true, onRawDataWriting > 0); Assert.AreEqual(1, onStateChangeEventArgs.Count); Assert.AreEqual(LogicalDeviceState.FDC_READY, fdcPumpController.QueryStatusAsync().Result, "status should be: FDC_READY, but now is: " + fdcPumpController.QueryStatusAsync().Result); } [TestMethod] public async Task CallingState_Test() { int onRawDataWriting = 0; var onStateChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { onStateChangeEventArgs.Add(a); }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; var readPumpStateResponse = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.FireOnDataReceived(readPumpStateResponse); }; await this.processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(500); Assert.AreEqual(1, onStateChangeEventArgs.Count, "OnStateChange should be called 1 times: FdcCalling"); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, onStateChangeEventArgs[0].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_CALLING, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } [TestMethod] public async Task CallingState_Test2() { int onRawDataWriting = 0; var onStateChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { onStateChangeEventArgs.Add(a); }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; if (onRawDataWriting >= 2) return; var readPumpStateResponse_NozzleLifted = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_NozzleLifted); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_CALLING, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); var readPumpStateResponse_NozzlePlaceBack = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.挂枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_NozzlePlaceBack); Assert.AreEqual(LogicalDeviceState.FDC_READY, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_READY, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); }; await this.processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(500); Assert.AreEqual(2, onStateChangeEventArgs.Count, "OnStateChange should be called 3 times: FdcCalling, FdcReady"); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, onStateChangeEventArgs[0].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_READY, onStateChangeEventArgs[1].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_READY, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_CALLING, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } [TestMethod] public async Task AuthorizedState_Test() { int onRawDataWriting = 0; var onStateChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { onStateChangeEventArgs.Add(a); }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; if (onRawDataWriting >= 2) return; var readPumpStateResponse_NozzleLifted = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_NozzleLifted); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_CALLING, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); var readPumpStateResponse_NozzlePlaceBack = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.开机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_NozzlePlaceBack); Assert.AreEqual(LogicalDeviceState.FDC_AUTHORISED, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_AUTHORISED, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); }; await this.processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(500); Assert.AreEqual(2, onStateChangeEventArgs.Count, "OnStateChange should be called 3 times: FdcCalling, FDC_AUTHORISED"); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, onStateChangeEventArgs[0].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_AUTHORISED, onStateChangeEventArgs[1].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_AUTHORISED, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_AUTHORISED, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } public TestContext TestContext { get; set; } [TestMethod] public async Task FuelingState_Test() { int onRawDataWriting = 0; int fuelingStatusReportingTimes = 0; var onStateChangeEventArgs = new List(); var onCurrentFuellingStatusChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { this.TestContext.WriteLine("Received a OnStateChange: " + a.NewPumpState); onStateChangeEventArgs.Add(a); }; this.fdcPumpController.OnCurrentFuellingStatusChange += (s, a) => { this.TestContext.WriteLine("Received a OnCurrentFuellingStatusChange, amt: " + a.Transaction.Amount + ", vol: " + a.Transaction.Volumn); onCurrentFuellingStatusChangeEventArgs.Add(a); }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; if (onRawDataWriting == 1) { this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); var readPumpStateResponse_NozzleLifted = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.TestContext.WriteLine("Fire NozzleLifted"); this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_NozzleLifted); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); var readPumpStateResponse_Nozzle开机 = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.开机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.TestContext.WriteLine("Fire Nozzle开机"); this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_Nozzle开机); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } else if (b.Message is ReadFuelDataRequest fuelDataRequest) { var readFuelDataResponse = new ReadFuelDataResponse(); readFuelDataResponse.SetAmountAndVolume(100 + onRawDataWriting, 20 + onRawDataWriting); this.TestContext.WriteLine("Fire FuelDataResponse"); this.mockCommunicator.FireOnDataReceived(readFuelDataResponse); fuelingStatusReportingTimes++; this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } }; await this.processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(1000); Assert.AreEqual(3, onStateChangeEventArgs.Count, "OnStateChange should be called 3 times: FdcCalling, FDC_AUTHORISED, FDC_FUELLING"); Assert.AreEqual(fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.Count, "onCurrentFuellingStatusChangeEventArgs should have many"); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, onStateChangeEventArgs[0].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_AUTHORISED, onStateChangeEventArgs[1].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_FUELLING, onStateChangeEventArgs[2].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_FUELLING, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_FUELLING, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } [TestMethod] public async Task FuelingState_Test1() { /* use FdcPumpController.AuthorizeAsync to auth pump rather than full simulation*/ int onRawDataWriting = 0; int fuelingStatusReportingTimes = 0; int authorizingCalledTimes = 0; var onStateChangeEventArgs = new List(); var onCurrentFuellingStatusChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { this.TestContext.WriteLine("Received a OnStateChange: " + a.NewPumpState); onStateChangeEventArgs.Add(a); }; this.fdcPumpController.OnCurrentFuellingStatusChange += (s, a) => { this.TestContext.WriteLine("Received a OnCurrentFuellingStatusChange, amt: " + a.Transaction.Amount + ", vol: " + a.Transaction.Volumn); onCurrentFuellingStatusChangeEventArgs.Add(a); }; // default is for simulate calling var readPumpStateResponse = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.OnRawDataWriting += async (a, b) => { onRawDataWriting++; if (b.Message is ReadPumpStateRequest readPumpStateRequest) { this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); this.TestContext.WriteLine("Fire Nozzle state: " + readPumpStateResponse.StartOrStopState); this.mockCommunicator.FireOnDataReceived(readPumpStateResponse); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); if (authorizingCalledTimes == 0) { this.TestContext.WriteLine("AuthorizeAsync..."); var authResult = await this.fdcPumpController.AuthorizeWithAmountAsync(1000, 1); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } } else if (b.Message is PresetAmountRequest presetAmountRequest) { this.mockCommunicator.FireOnDataReceived(new PresetAmountResponse()); } else if (b.Message is OpenRequest openRequest) { authorizingCalledTimes++; // to authorized state. readPumpStateResponse = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.开机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; } else if (b.Message is ReadFuelDataRequest fuelDataRequest) { var readFuelDataResponse = new ReadFuelDataResponse(); readFuelDataResponse.SetAmountAndVolume(100 + onRawDataWriting, 20 + onRawDataWriting); this.TestContext.WriteLine("Fire FuelDataResponse"); this.mockCommunicator.FireOnDataReceived(readFuelDataResponse); fuelingStatusReportingTimes++; this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } }; await this.processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(1000); Assert.AreEqual(3, onStateChangeEventArgs.Count, "OnStateChange should be called 3 times: FdcCalling, FDC_AUTHORISED, FDC_FUELLING"); Assert.AreEqual(1, authorizingCalledTimes); Assert.AreEqual(fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.Count, "onCurrentFuellingStatusChangeEventArgs should have many"); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, onStateChangeEventArgs[0].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_AUTHORISED, onStateChangeEventArgs[1].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_FUELLING, onStateChangeEventArgs[2].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_FUELLING, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_FUELLING, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } [TestMethod] public async Task FuelTrxDone_Test() { int onRawDataWriting = 0; int fuelingStatusReportingTimes = 0; var onStateChangeEventArgs = new List(); var onCurrentFuellingStatusChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += (s, a) => { this.TestContext.WriteLine("Received a OnStateChange: " + a.NewPumpState); onStateChangeEventArgs.Add(a); }; this.fdcPumpController.OnCurrentFuellingStatusChange += (s, a) => { this.TestContext.WriteLine("Received a OnCurrentFuellingStatusChange, Finished: " + a.Transaction.Finished + ", amt: " + a.Transaction.Amount + ", vol: " + a.Transaction.Volumn); onCurrentFuellingStatusChangeEventArgs.Add(a); }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; if (onRawDataWriting == 1) { this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); var readPumpStateResponse_NozzleLifted = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.TestContext.WriteLine("Fire NozzleLifted"); this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_NozzleLifted); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); var readPumpStateResponse_Nozzle开机 = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.开机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.TestContext.WriteLine("Fire Nozzle开机"); this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_Nozzle开机); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } else if (b.Message is ReadFuelDataRequest fuelDataRequest) { fuelingStatusReportingTimes++; var readFuelDataResponse = new ReadFuelDataResponse(); readFuelDataResponse.SetAmountAndVolume(100 + fuelingStatusReportingTimes, 20 + fuelingStatusReportingTimes); this.TestContext.WriteLine("Fire FuelDataResponse"); this.mockCommunicator.FireOnDataReceived(readFuelDataResponse); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); if (onRawDataWriting >= 5) { var readPumpStateResponse_NozzleReplaced_And_停机 = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.挂枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.TestContext.WriteLine("Fire NozzleReplaced_And_停机"); this.mockCommunicator.FireOnDataReceived(readPumpStateResponse_NozzleReplaced_And_停机); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } } }; await this.processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(1800); Assert.AreEqual(4, onStateChangeEventArgs.Count, "OnStateChange should be called 3 times: FdcCalling, FDC_AUTHORISED, FDC_FUELLING, FdcReady"); // 1 extra requesting is to generate the final fuel trx, and will not fire event. Assert.AreEqual(fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.Count + 1, "onCurrentFuellingStatusChangeEventArgs should have many"); Assert.AreEqual(1, onCurrentFuellingStatusChangeEventArgs.Where(a => a.Transaction.Finished).Count()); Assert.AreEqual(100 + fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.First(a => a.Transaction.Finished).Transaction.Amount); Assert.AreEqual(20 + fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.First(a => a.Transaction.Finished).Transaction.Volumn); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, onStateChangeEventArgs[0].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_AUTHORISED, onStateChangeEventArgs[1].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_FUELLING, onStateChangeEventArgs[2].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_READY, onStateChangeEventArgs[3].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_READY, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_READY, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } [TestMethod] public async Task FuelTrxDone_Test1() { /* use FdcPumpController.AuthorizeAsync to auth pump rather than full simulation*/ int onRawDataWriting = 0; int fuelingStatusReportingTimes = 0; int authorizingCalledTimes = 0; var onStateChangeEventArgs = new List(); var onCurrentFuellingStatusChangeEventArgs = new List(); this.fdcPumpController.OnStateChange += async (s, a) => { this.TestContext.WriteLine("Received a OnStateChange: " + a.NewPumpState); onStateChangeEventArgs.Add(a); if (a.NewPumpState == LogicalDeviceState.FDC_CALLING) { this.TestContext.WriteLine("AuthorizeWithAmountAsync"); await this.fdcPumpController.AuthorizeWithAmountAsync(1000, 1); } }; this.fdcPumpController.OnCurrentFuellingStatusChange += (s, a) => { this.TestContext.WriteLine("Received a OnCurrentFuellingStatusChange, Finished: " + a.Transaction.Finished + ", amt: " + a.Transaction.Amount + ", vol: " + a.Transaction.Volumn); onCurrentFuellingStatusChangeEventArgs.Add(a); }; // default is for simulate calling var readPumpStateResponse = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.mockCommunicator.OnRawDataWriting += (a, b) => { onRawDataWriting++; if (b.Message is ReadPumpStateRequest _) { this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); this.TestContext.WriteLine("Fire " + readPumpStateResponse.NozzleState + ", " + readPumpStateResponse.StartOrStopState); this.mockCommunicator.FireOnDataReceived(readPumpStateResponse); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } else if (b.Message is PresetAmountRequest presetAmountRequest) { this.TestContext.WriteLine("Fire PresetAmountResponse"); this.mockCommunicator.FireOnDataReceived(new PresetAmountResponse()); } else if (b.Message is OpenRequest openRequest) { authorizingCalledTimes++; // to authorized state. readPumpStateResponse = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.提枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.开机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; } else if (b.Message is ReadFuelDataRequest fuelDataRequest) { fuelingStatusReportingTimes++; var readFuelDataResponse = new ReadFuelDataResponse(); readFuelDataResponse.SetAmountAndVolume(100 + fuelingStatusReportingTimes, 20 + fuelingStatusReportingTimes); this.TestContext.WriteLine("Fire FuelDataResponse"); this.mockCommunicator.FireOnDataReceived(readFuelDataResponse); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); if (onRawDataWriting >= 5) { readPumpStateResponse = new ReadPumpStateResponse { NozzleState = ReadPumpStateResponse.NozzleStateEnum.挂枪, StartOrStopState = ReadPumpStateResponse.StartOrStopStateEnum.停机, ControlState = ReadPumpStateResponse.ControlStateEnum.受控 }; this.TestContext.WriteLine("Fire " + readPumpStateResponse.NozzleState + ", " + readPumpStateResponse.StartOrStopState); this.TestContext.WriteLine("Pump is in state: " + this.fdcPumpController.QueryStatusAsync().Result); } } }; await this.processor.Start(); this.fdcPumpController.OnFdcServerInit(new Dictionary()); await Task.Delay(1800); Assert.AreEqual(4, onStateChangeEventArgs.Count, "OnStateChange should be called 3 times: FdcCalling, FDC_AUTHORISED, FDC_FUELLING, FdcReady"); // 1 extra requesting is to generate the final fuel trx, and will not fire event. Assert.AreEqual(fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.Count + 1, "onCurrentFuellingStatusChangeEventArgs should have many"); Assert.AreEqual(1, onCurrentFuellingStatusChangeEventArgs.Where(a => a.Transaction.Finished).Count()); Assert.AreEqual(100 + fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.First(a => a.Transaction.Finished).Transaction.Amount); Assert.AreEqual(20 + fuelingStatusReportingTimes, onCurrentFuellingStatusChangeEventArgs.First(a => a.Transaction.Finished).Transaction.Volumn); Assert.AreEqual(LogicalDeviceState.FDC_CALLING, onStateChangeEventArgs[0].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_AUTHORISED, onStateChangeEventArgs[1].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_FUELLING, onStateChangeEventArgs[2].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_READY, onStateChangeEventArgs[3].NewPumpState); Assert.AreEqual(LogicalDeviceState.FDC_READY, this.fdcPumpController.QueryStatusAsync().Result, "status should change to: FDC_READY, but now is: " + this.fdcPumpController.QueryStatusAsync().Result); } } }